Commit graph

85 commits

Author SHA1 Message Date
Tim Ledbetter
57103da08d LibGfx+LibWeb: Make emoji font fallback presentation-aware
Previously, font selection ignored the Unicode emoji presentation of a
code point. Emoji-capable code points were always resolved through
pre-baked color emoji and symbol fonts. Text-default code points which
lacked the `Emoji_Presentation` property, were therefore rendered as
color emoji rather than text. We now classify each code point's default
presentation from its `Emoji_Presentation` property and any trailing
variation selector.
2026-06-20 23:51:46 +02:00
Tim Ledbetter
bebcf95883 LibGfx: Remove bogus early return from Font::is_emoji_font() 2026-06-20 23:51:46 +02:00
Tim Ledbetter
0be802797a LibGfx: Cache font-independent shape data in the font shaping cache
The shaping cache previously stored HarfBuzz buffers keyed by string,
and `shape_text()` rebuilt a fresh `GlyphRun` on every call. Cache the
font-independent shape data instead, so repeated shaping of the same
input skips both the HarfBuzz call and the glyph-vector build.
2026-06-09 17:35:54 +02:00
Andreas Kling
0d947fa833 LibGfx: Clamp HarfBuzz font scaling
Clamp the CSS pixel size used for HarfBuzz font scales before passing
it to the int-sized HarfBuzz API. Also accumulate shaped advances
in double precision while measuring text. Very large web-provided font
sizes can otherwise overflow before layout clamps dimensions.

Add a reduced crash test for laying out text with a huge font size.
2026-06-08 01:04:08 +02:00
Andreas Kling
164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00
Andreas Kling
1eb541ce9e LibGfx: Avoid copying macOS system font data
Keep CoreText system UI fonts backed by their CoreGraphics font instead
of opening the Skia typeface stream during font matching. Opening that
stream copies the full macOS system font data into SkData, which is very
expensive when CSS font computation asks for several system UI faces.

Let Typeface subclasses provide the HarfBuzz face creation path, and use
HarfBuzz's CoreText integration for these macOS system fonts. Clone Skia
font variations through SkTypeface::makeClone() so variation handling no
longer depends on rebuilding a typeface from the raw font stream.
2026-05-28 01:49:35 +01:00
Aliaksandr Kalenik
2d34ba4318 LibIPC+LibGfx: Add IPC serialization for typefaces
Display-list resource transactions need to carry fonts across an IPC
boundary without making LibWeb know how each typeface stores its bytes.
Add a LibGfx-owned Typeface IPC representation so callers can encode
and decode typefaces directly.

Anonymous-buffer and Core::Resource-backed typefaces serialize through
their retained backing. System typefaces serialize as family and style
data, with macOS system UI typefaces carrying their SystemUIFontKind
from creation so the receiver can rematch them through CoreText.

This is preparatory work required to add IPC between the main and
compositor threads.
2026-05-21 11:45:06 +01:00
Aliaksandr Kalenik
e181686f7e LibGfx: Add IPC serialization for FontVariationSettings
The compositor IPC path needs variable-font axes to survive transport
with the font data that owns them. Add LibGfx-local specializations for
FontVariationSettings, compile the new implementation into LibGfx, and
expose the stored settings from Font so later font serializers can read
them without reaching into the class internals.

This is preparatory work required to add IPC between the main and
compositor threads.
2026-05-21 11:45:06 +01:00
Andreas Kling
43f38a1ebe LibWeb: Use macOS system UI fonts
Teach font-family parsing about system-ui, then route macOS UI generic
families through CoreText. This makes -apple-system, system-ui,
ui-serif, ui-sans-serif, ui-monospace, and ui-rounded resolve to the
same system designs as Safari.

The CoreText result is converted back into a Skia typeface and still
uses the existing HarfBuzz shaping path. CSS weight and width continue
through the normal font variation settings.
2026-05-20 18:03:29 +02:00
Andreas Kling
94560426ab LibGfx: Use CSS pixels for HarfBuzz ptem
HarfBuzz uses ptem for AAT trak table lookup. Match other browsers
for macOS system fonts by passing the CSS pixel size instead of the
physical point size.
2026-05-20 18:03:29 +02:00
Aliaksandr Kalenik
22fc50e606 LibGfx: Remove unused dpi_x/dpi_y params and m_x_scale/m_y_scale 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
0166f555eb LibGfx: Remove unused FontStyleMapping helpers 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
8e616a1ec0 LibGfx: Remove unused FontPixelMetrics::size 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
86280aa6a6 LibGfx: Remove unused FontPixelMetrics::line_gap 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
19071f186a LibGfx: Remove unused FontPixelMetrics::line_spacing() 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
d53924c2da LibGfx: Remove unused Font::baseline() 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
65fc171b20 LibGfx: Inline Font::scaled_with_size into with_size
The only caller of scaled_with_size was with_size itself.
2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
00bfb41bdd LibGfx: Remove unused Font::metrics() and preferred_line_height() 2026-05-19 20:34:27 +02:00
Aliaksandr Kalenik
4cd8e84dff LibGfx+LibWeb: Keep loaded font bytes shareable
Future compositor-side rendering will need WebContent to share typefaces
with the compositor process over IPC. If a typeface already keeps its
backing bytes in anonymous shared memory, IPC encoding can clone that
buffer handle instead of allocating a new shared buffer and copying the
same font data during upload.
2026-05-19 09:20:38 +02:00
Aliaksandr Kalenik
6f6dbd1703 LibGfx: Remove FontData wrapper
FontData was added when the WOFF and WOFF2 typeface wrappers went
away, so decoded TTF buffers and resource-backed font data could be
kept alive after Typeface loaded from non-owned ReadonlyBytes.

The ownership cases are now small enough to keep directly on the
typeface objects. Store resource-backed fonts in Typeface via a
Core::Resource RefPtr, keep copied or decoded bytes in ByteBuffer
members, and have the WOFF loaders pass decoded buffers directly to
Typeface.
2026-05-19 09:20:38 +02:00
Andreas Kling
e3117c12c0 LibGfx: Don't load the same font file multiple times in PathFontProvider
fontconfig's font directory list may contain overlapping entries
(e.g. both /usr/share/fonts and /usr/share/fonts/truetype/msttcorefonts)
and our recursive walk was visiting each .ttf/.otf/.ttc several times
and mmap'ing it once per visit. On a typical Linux system this resulted
in 2-3 mappings per file before any actual rendering.

Track each font's filesystem path and skip files we've already loaded.
Drops WebContent's font-file VMA count from ~7400 to ~2500 on my box.
2026-05-08 22:56:14 +02:00
Aliaksandr Kalenik
f56745b15b LibWeb: Store display list resources separately
Commands used to keep rendering resources directly in the variant:
image frames, external content and video sources, filters, SVG paint
styles, and nested display lists. That makes the command stream own its
dependencies and prevents it from becoming a POD-like byte buffer.

Add DisplayListResourceStorage and replace those command fields with
stable resource IDs. The storage deduplicates resources by their
existing IDs and can copy only the resources referenced by a captured
command sequence, giving the future IPC boundary a clear list of
resources that must be communicated to the rasterization process.
2026-05-08 20:45:17 +02:00
Andreas Kling
732063aca9 LibGfx: Skip copying font data when loading fallback typeface
When Skia's openStream() returns a memory-backed stream, retain it
on TypefaceSkia::Impl so the underlying bytes stay alive, and
reference them directly instead of copying into a ByteBuffer.

This pattern is used regularly inside Skia, so it seems fair game.
2026-04-22 14:20:33 +02:00
Johan Dahlin
75ae9abe7a LibGfx: Re-enable tech(variations) font support 2026-04-21 16:40:43 +02:00
Andreas Kling
e1d35d7da9 LibWeb+LibGfx: Decompress WOFF2 fonts off the main thread
Add an off-thread preparation step for downloaded vector fonts so
WOFF2 resources can be decompressed before LibWeb tries to create a
typeface from them. This avoids doing the conversion work on the main
thread during @font-face loading.

Expose raw WOFF2-to-TTF conversion from LibGfx's WOFF2 loader and use
that from the new preparation path. Keeping the libwoff2 integration
in LibGfx preserves the layering between LibWeb and the third-party
decoder while still letting LibWeb schedule the work off-thread.
2026-04-18 23:46:20 +02:00
Tim Ledbetter
77b9fcf7f9 LibWeb+LibWebView: Select generic font families based on requested style
Pass the requested font weight and slope to generic_font_name() and use
them to select the most suitable font family. Families that have the
exact requested weight are strongly preferred, followed by families with
more style variety.

This ensures that when CSS requests bold text with a generic font family
like `serif`, we select a family that actually supports bold weights
rather than one that only has regular weight.

Co-authored-by: Jelle Raaijmakers <jelle@ladybird.org>
2026-03-24 15:08:24 +01:00
Jelle Raaijmakers
61abdfe658 LibGfx: Load all font faces from TrueType Collection files
Parse the TTC header to determine the number of fonts in the collection
and load each one individually. This ensures that all font weights and
styles bundled in a TTC file are available for font matching.
2026-03-24 15:08:24 +01:00
Jelle Raaijmakers
a870fbfa1c LibGfx: Use u32 for TTC collection index
Using an unsigned type makes more sense for a TTC collection index,
even though Skia eventually accepts a signed value.
2026-03-24 15:08:24 +01:00
Tim Ledbetter
2b7ead2c44 LibGfx+LibWebView: Use Skia to resolve generic font families 2026-03-24 15:08:24 +01:00
Davi Gomes
6d77c9edd1 Libraries: Move #pragma once above include headers
The #pragma once was placed after the #include directives instead of
immediately after the copyright comment, inconsistent with every other
header file
2026-03-22 14:05:44 +01:00
Andreas Kling
f146294b23 LibGfx: Make Font atomically ref-counted
Font objects are cached per-Typeface with non-atomic RefCounted, but
GlyphRun (which is AtomicRefCounted) holds a NonnullRefPtr<Font const>
and can be destroyed on the rendering thread when tearing down display
lists. This created a data race on the Font refcount, leading to
use-after-free crashes in Typeface::font() where the cache's
NonnullRefPtr would point to memory already freed by a concurrent
unref.
2026-03-14 21:34:27 -05:00
Jelle Raaijmakers
57a9c795d3 LibGfx+LibRegex: Prevent double hashing of values
We had three instances of `pair_int_hash()` being called with a value
that was pulled through `u32_hash()`, which is not necessary - both
arguments to `pair_int_hash()` will be properly hashed.
2026-02-23 16:44:07 +01:00
Ben Wiederhake
fb7095ab88 LibCore: Remove unused header in Resource 2026-02-21 19:27:35 +01:00
Callum Law
1be9f1ae9d LibWeb: Move Gfx::FontVariantAlternates to CSS namespace
This is only ever used in the CSS namespace
2026-02-20 22:01:44 +00:00
Callum Law
1faaf83121 LibWeb: Move Gfx::FontVariantLigatures to the CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Callum Law
afc6b7b24c LibWeb: Move Gfx::FontVariantLigatures to the CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Callum Law
f0dd7ec4e9 LibWeb: Move Gfx::FontVariantEastAsian to CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Jelle Raaijmakers
1745926fc6 AK+Everywhere: Use MurmurHash3 for int/u64 hashing
Rework our hash functions a bit for significant better performance:

* Rename int_hash to u32_hash to mirror u64_hash.
* Make pair_int_hash call u64_hash instead of multiple u32_hash()es.
* Implement MurmurHash3's fmix32 and fmix64 for u32_hash and u64_hash.

On my machine, this speeds up u32_hash by 20%, u64_hash by ~290%, and
pair_int_hash by ~260%.

We lose the property that an input of 0 results in something that is not
0. I've experimented with an offset to both hash functions, but it
resulted in a measurable performance degradation for u64_hash. If
there's a good use case for 0 not to result in 0, we can always add in
that offset as a countermeasure in the future.
2026-02-20 22:47:24 +01:00
Callum Law
11d524bda4 LibWeb: Support CSS font-optical-sizing property 2026-02-03 11:44:25 +00:00
Callum Law
b55023fad3 LibGfx+LibWeb: Resolve font features per font rather than per element
Previously we would resolve font features
(https://drafts.csswg.org/css-fonts-4/#feature-variation-precedence)
per element, while this works for the current subset of the font feature
resolution algorithm that we support, some as yet unimplemented parts
require us to know whether we are resolving against a CSS @font-face
rule, and if so which one (e.g. applying descriptors from the @font-face
rule, deciding which @font-feature-values rules to apply, etc).

To achieve this we store the data required to resolve font features in a
struct and pass that to `FontComputer` which resolves the font features
and stores them with the computed `Font`.

We no longer need to invalidate the font shaping cache when features
change since the features are defined per font (and therefore won't ever
change).
2026-02-02 14:11:43 +00:00
Callum Law
c93336c72f LibGfx: Implement hash functions for some more types
We are going to be using these types in HashTable keys in a future
commit.
2026-02-02 14:11:43 +00:00
Callum Law
5917a8c1c8 LibGfx+LibWeb: Allow setting FontVariationSettings for default font
While our default font supporting variations is unlikely, this is
nevertheless required for our fallback font to be considered equal to
it's non-default/fallback equivalent (i.e. `font-family: serif`) which
in turn is required for LineBuilder to merge chunks into a single
fragment.
2026-02-02 14:11:43 +00:00
Callum Law
c35ecc8b1c LibWeb: Respect font-width for variable fonts 2026-01-21 23:49:25 +01:00
Callum Law
3f97f1579f LibGfx: Remove default parameters for some font related functions
We always pass these values so there is no need for default parameters
2026-01-21 23:49:25 +01:00
Callum Law
89a360e643 LibGfx+LibWeb: Remove unused FontWeight.h 2026-01-21 23:49:25 +01:00
Tim Ledbetter
3e704e0fd6 LibGfx+LibWeb: Fall back to system fonts for missing glyphs
When rendering text, if none of the fonts in the cascade list contain a
glyph for a given code point, we now query Skia's font manager to find
a system font that can render it.
2026-01-21 14:01:35 +01:00
ayeteadoe
ee3aa865af Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-17 12:00:33 +01:00
Andreas Kling
2577c5ce67 Revert "Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port"
This reverts commit ac9688ea1e.

Broke the build on arm64 Linux.
2025-12-15 14:12:34 -06:00
ayeteadoe
ac9688ea1e Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-15 10:56:27 +01:00
ayeteadoe
59c963f98f Meta+LibGfx: Remove fontconfig dependency on Windows
Previously when launching a UI process and/or a WebContent process on
Windows, the following message would be output to the console:

Fontconfig error: Cannot load default config file: No such file: (null)

Apparently on Windows, you have to provide a font .conf file to
fontconfig explicitly. Since we are not doing that, the default fonts
that are backed off to are not ideal.

Similar to how we aren't using fontconfig on Android, Windows also has
native font infrastructure in terms of both a collection of System
installed fonts as well as skia support for font managers that use
native Windows APIs. With that, we can remove the usage of fontconfig
entirely and improve the fonts used on websites like ladybird.org or
google.com.
2025-11-22 07:51:55 -05:00