In servo, each `LocalFontIdentifier` has an `fn index() -> u32`, which
returns the index of the font within the font file in case it is a font
collection (`.ttc` instead of `.ttf`). The way this index is obtained is
platform-dependent.
On systems using `fontconfig`, we get the index by querying `FC_INDEX`:
d2c78db981/components/fonts/platform/freetype/font_list.rs (L109-L112)
There is a sneaky bug here: In addition to the aforementioned face
index, the value for `FC_INDEX` contains the index of the named instance
of the face in the upper 16 bits. This behaviour is completely
undocumented, but FreeType uses the same format:
https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_open_face.
This wasn't a problem for the longest time, because the only consumer of
the `index` value coming from fontconfig was FreeType. However, sometime
after
29e618dcf7,
we started also passing it to`read-fonts` . `read-fonts` expects only
the face index, causing it to return errors as seen in
https://github.com/servo/servo/issues/39209.
The fix is to seperate the two indices when storing them in a
`LocalFontDescriptor` and pass only the lower 16 bits to `read-fonts`.
I'm unsure whether we should continue passing the named instance index
to FreeType since we don't actually support variable fonts, but I've
opted to keep the current behaviour for now.
Fixes: https://github.com/servo/servo/issues/39209
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
#39112 restricts accessibility for some font functions, exposing some
functions that haven't been used for a long time. Now it is detected by
Lint as dead code.
Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
This change marks all items that are not used by other crates as
`pub(crate)` instead of `pub`.
Additionally, I've removed all code that turned out to be unused. I
think most of it was used only by `layout-2013`.
Testing: The correctness of these changes is verified by the compiler,
so no tests are needed.
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Helvetica isn't quite right but it's a better default choice than a
monospaced font like Menlo (it should be some variant of Apple's San
Francisco font, but that isn't easily exposed)
Testing: Untested, but matches the font family used for `sans-serif` so
it should be safe
Signed-off-by: Darryl Pogue <darryl@dpogue.ca>
This is necessary so that `constellation_traits` can get these types via
a
dependency on `fonts_traits`. This will allow sending IPC channels to
shared
workers so that they can have access to a shared `FontContext` from
`script`.
Testing: This just moves code between crates, so is covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
The `font-types` crate is the tiny type-only base crate of `fontations`.
This uses a strongly typed representation of open type tags, and allows
us to remove our custom macro for creating them.
---------
Signed-off-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
The new version of the functions return `Result` types.
Testing: No tests because this should not change behavior.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Instead of copying the font table data in memory and parsing it with the
`truetype` crate, use a non-copying API from DirectWrite to implement a
`fontations` `TableProvider`. This has two benefits:
- We remove the dependency on the `truetype` crate finally.
- We do not have to make an in-memory copy of the table data when
parsing the table.
The hope is that the `TableProvider` will be more generally useful in
the future.
Testing: There are no automated tests for Windows, but I manually
verified
that the data retrived via `fontations` matched that retrived by
`truetype`.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Unlike other platforms where we read the default axis values and combine
it with variations from style to make the font face, we set the
variations from the style when creating the font face and then read the
final variations from the face. It seems that DirectWrite does the
normalization of variation values internally.
This depends on servo/dwrote-rs#68.
Testing: We currently don't have tests for Windows, but variation
support is
covered by the WPT tests.
Fixes: This is part of #38800.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This change adds font variation support for macOS. The main bulk of the
change is reading the default, min, and max values for each variation
axis from the font and instantiating a new CoreText font with the
appropriate values.
In addition, fonts with variations are now properly cached in the
CoreText font cache.
Testing: There are no tests for this change as we do not run WPT tests
for
macOS and font variations are currently turned off by default.
Eventually,
when the feature is turned on there will be test for it. These changes
are just laying the groundwork for the full implementation.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
# Objective
Ensure that functionality which uses the raw font data (such as
rendering text to canvas) works correctly on macOS when the specified
font is a system font that lives in an OpenType Collection (`.ttc`)
file.
## Changes made
- The `read_data_from_file` in each backend now returns a `index: u32`
in addition to `data: Vec<u8>`
- The `data` field on the `Font` type has been renamed to `raw` and the
`data` method on the `Font` type has been renamed to `raw_font`. This
allows the index to be cached as computing is moderately expensive on
macOS (on the order of 100 microseconds).
- Both of the above now store/return a `struct RawFont` instead of a
`FontData` where `RawFont` is defined as `struct RawFont { data:
FontData, index: u32 }`.
- The users of the `data` method have been updated to use the cached
index from `data` rather than calling `.index()` each time.
---------
Signed-off-by: Nico Burns <nico@nicoburns.com>
This change adds support for variable fonts via the
[`font-variation-settings`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings)
property.
There are three areas where we need to set the variation values:
* Webrender (`compositor.rs`), for drawing the glyphs
* Harfbuzz (`shaper.rs`), for most shaping tasks
* PlatformFont (`fonts/platform/`), for horizontal advances and kerning
For now, freetype is the only platform shaper that supports variable
fonts. I can't easily test the fonts with non-freetype shapers. Thats
why variable fonts are behind the `layout_variable_fonts_enabled` pref,
which is disabled by default.
<img width="1250" height="710" alt="image"
src="https://github.com/user-attachments/assets/1aee1407-f3a2-42f6-a106-af0443fcd588"
/>
<details><summary>HTML test file</summary>
```html
<style>
@font-face {
font-family: "Amstelvar VF";
src: url("https://mdn.github.io/shared-assets/fonts/variable-fonts/AmstelvarAlpha-VF.woff2")
format("woff2-variations");
font-weight: 300 900;
font-stretch: 35% 100%;
font-style: normal;
font-display: swap;
}
p {
font:
1.2em "Amstelvar VF",
Georgia,
serif;
font-size: 4rem;
margin: 1rem;
display: inline-block;
}
.p1 {
font-variation-settings: "wght" 300;
}
.p2 {
font-variation-settings: "wght" 625;
}
.p3 {
font-variation-settings: "wght" 900;
}
</style>
<div>
<p class="p1">Weight</p>
<span>(font-variation-settings: "wght" 300)</span>
</div>
<div>
<p class="p2">Weight</p>
<span>(font-variation-settings: "wght" 625)</span>
</div>
<div>
<p class="p3">Weight</p>
<span>(font-variation-settings: "wght" 900)</span>
</div>
</div>
```
</details>
https://github.com/user-attachments/assets/9e21101a-796a-49fe-b82c-8999d8fa9ee1
Testing: Needs decision on whether we want to enable the pref in CI
Works towards https://github.com/servo/servo/issues/37236
Depends on https://github.com/servo/stylo/pull/230
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This will make it easier in a followup to include the normalized font
variations in the return value. This also make
`PlatformFont::ensure_h_kern_subtable` work on the instance instead of
being a struct method. Finally, all `PlatformFont` methods are combined
into a single impl block.
Testing: This should not change behavior and is thus covered by existing
tests.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Testing: only safety annotations change, no tests are required.
Fixes: https://github.com/servo/servo/issues/38627
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Use skrifa instead of freetype for extracting raw table data. Allows us
to replace unsafe Freetype code with safe Skrifa code. Also allows us to
avoid copying the table data. Instead we return Arc'd data.
---------
Signed-off-by: Nico Burns <nico@nicoburns.com>
Fixed some clippy lints which were in the OHOS code.
Testing: Normal testcases apply and changes are trivial.
Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Use `read-fonts` to read font tables for FreeType fonts. This is the
first step to using fontations throughout Servo. The main benefit here
is that we no longer need to provide our own table data structures and
we can read tables from these fonts without making copies of the table
contents.
Testing: This should not change observable behavior and is covered by
existing WPT tests. I have run some manual microbenchmarks and have not
noticed any changes in performance that are larger than the general
noise.
This adds a new memory map of the font file for local fonts, but this
should be very cheap as FreeType is already doing this internally and
subsequent maps should just reuuse the existing memory-mapped file.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Fix warnings from `components/fonts/platform/windows/font.rs` and
`components/fonts/platform/windows/font_list.rs` due to deprecations
from dwrote.
Testing: none, should behave as it did before
---------
Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
There was a typo in how underline thickness (in pixels) was converted
to app units. It was interpreting the pixel value as an f64 app unit
value, which meant that the resulting thickness was 1/60 of the value
expected.
Testing: macOS does not currently run WPT tests, so it is difficult to
test
this one. I have manually confirmed that underlines now show up and are
the
expected thickness.
Fixes: #36945
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
* Migrate to 2024 edition
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
* Allow unsafe_op_in_unsafe_fn lint
This lint warns by default in the 2024
edition, but is *way* too noisy for servo.
We might enable it in the future, but not now.
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
* Compile using the 2024 edition
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
* Use 2024 style edition
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
* Reformat all code
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
The new version of rust has more checks trying to prevent mistakes
around order of operations and shifts.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This codeblock contains chinese, japanese and korean characters,
so we add the simplified chinese and the CJK fallback fonts.
Additionally, we add the new CJK fallback font for the koren and
japanese unicode blocks, since the KR and JP fallback fonts
don't seem to be present on the latest OH versions anymore.
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
* ohos: Fix more clippy warnings
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
* Remove unnecessary `macro_use`
We can use `use` instead. Removes a warning about
unused macro_use on OpenHarmony.
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
---------
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
* ohos: Remove unnecessary library links
`ohos-sys` now correctly links all required libraries, so we
don't need to specify them here again.
We still specify `ace_napi.z`, since we use napi via `napi-ohos`, which currently does not add the required link.
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
* Disable some unused functions on ohos/android
- get_default_url()
- parse_url_or_filename()
- add_noto_fallback_families
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
* ohos: Remove unneeded import
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
---------
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
This removes unused code in order to reduce the number of compiler
warnings on the Android build. Some of this code might be used in the
future and it can be restored from git commit history.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
* fixed some clippy warnings
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
* Delete extra file
Signed-off-by: chickenleaf <lashwinib@gmail.com>
* preserved newline in compositionevent.rs
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: chickenleaf <lashwinib@gmail.com>
* removed the newline in PrototypeList
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
* removed the trailing whitespace
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
---------
Signed-off-by: L Ashwin B <lashwinib@gmail.com>
Signed-off-by: chickenleaf <lashwinib@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
System fonts used to be instantiated using the system font loader and
this change restores that behavior. In addition, on macOS and FreeType
platforms font data for system fonts is loaded using memory mapping. The
benefit is that system font loaders typically are able to cache fonts in
system memory (using memory mapping, for instance) and we'd like to load
them in a the way most compatible with other applications.
On my Linux system, this manages to get the overhead of loading a very
large font down from 10ms to approximately 1ms. Subsequent runs show
even less overhead. We've measured similar gains on macOS systems.
Currently, system font data must be loaded into memory manually for
canvas and this is unlikely to change even with a switch to `vello`. The
use of explicit memmory mapping should help in this case -- though it
probably won't be possible to use this properly on macOS and Windows if
we ever want to load fonts from TTCs properly.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This is done by no longer forwarding compositor-bound messages through
SystemFontService and making `FontContext` non-generic:
- Messages from the `FontContext` to the `Compositor` no longer need to be
forwarded through the `SystemFontService`. Instead send these messages
directly through the script IPC channel to the `Compositor`.
- Instead of adding a mock `SystemFontServiceProxy`, simply implement a
mock `SystemFontService` on the other side of an IPC channel in the
`font_context` unit test. This allows making `FontContext`
non-generic, greatly simplifying the code. The extra complexity moves
into the unit test.
These changes necessitate adding a new kind of `FontIdentifier`,
`FontIdentifier::Mock` due to the fact that local fonts have
platform-specific identifiers. This avoids having to pretend like the
system font service can have web fonts -- which was always a bit of a
hack.
These two changes are combined into one PR because they both require
extensive and similar chages in the font_context unit test which
dependended on the details of both of them.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This makes the determination of whether or not to use fast shaping
platform independent. Previously it was less stringent for Windows,
leading to using it in cases where a font had a GSUB or GPOS table --
which broke proper shaping.
In addition, the test is made platform independent and expanded to be
more complete.
Finally, comments are added indicating that "fast shaping" will be
removed.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This changes modifes the way that font data is sent over IPC channels.
Instead of serializing the data or sending it via IPC byte senders, font
data is copied into shared memory and a copy of the handle is sent over
the channel.
There is also the idea of sending the file handle of the on disk data of
system fonts. This could be implemented as a further followup once there
is an abstraction in `ipc-channel` over file handles.
To accomplish this, a `FontData` abstraction is added, which also allows
caching an in-memory shared `Arc<Vec<u8>>` version of the data (neeeded
by some APIs). This could also be a place for caching font tables in the
future.
Finally, the `FontCacheThread` is renamed to the `SystemFontService`
while the proxy for this is now named `SystemFontServiceProxy`.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Previously if a font didn't have a space advance and it was needed to
make advances for tabs, Servo would try to read the advance from the
font. If the font didn't have a space glyph, Servo would panic. This
fixes that issue by making the space advance part of the `FontMetrics`
of a font (like Gecko) and falling back properly if that glyph doesn't
exist. The rendered glyph is still the "space" glyph, but we make
sure to select a font that supports that glyph explicitly.
This prevents a crash, but tabs still aren't handled properly. In
reality, tab stops should be calculated in layout and the size of
the space character of the current font shouldn't come into play.
The addition of the space advance metric will make this easier.
Fixes#32970.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
* ohos: Add `ohos_mock` cfg.
This allows using the Linux build together with the `ohos`
font code, using the fonts ship in the `previewer` directory of the OH SDK.
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
* ohos: Detect installed fonts
Scan the systems font folder to detect installed fonts,
derive their associated font names and generate the font list
based on that.
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
* Use hardcoded filepaths for HMOS Color emojis
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
* Also support parsing OH 4.x Noto fonts
Currently we don't have an easy way to test the OH version
from the fonts module, so the parsing code has to be extended.
Once the OH 5.0 beta has a reliable fontconfig.json filemap,
then we can probably get rid of most of the parsing code,
and hardcode the OH 4.x Note fonts as a fallback.
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
---------
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
This adds support for generic font families in Servo and allows for
configuration of them as well as their default font sizes. One
interesting fix here is that now monospace default to 13px, like it does
in other browsers.
In addition to that, this exposes a new interface in Stylo which allows
setting a default style. This is quite useful for fonts, but also for
other kinds of default style settings -- like text zoom.
Fixes#8371.
Fixes#14773.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
The input for this function commonly comes from a `LowercaseString`,
while our actual font family name has cases.
Since font family lookup should be case-neutral, we do a compare
ignoring the ascii case.
I'm not too familiar with the CSS standard so I'm not 100% sure
if this is sufficient, or if we need to use a different method
to compare strings for arbitrary non-ascii font names.
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
The fallback behavior seems to have changed recently.
Now we need to explicitly add a fallback for `serif`
otherwise no font is selected.
Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
This crate only takes care of fonts now as graphics related things are
split into other crates. In addition, this exposes data structures at
the top of the crate, hiding the implementation details and making it
simpler to import them.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>