Commit Graph

67 Commits

Author SHA1 Message Date
Sam Atkins
4ea87db0a8 LibWeb/CSS: Load all fonts through FontFace::load()
The spec requires us to follow the steps in FontFace::load() whenever a
font is loaded. The simplest way to do so, is to make that the only way
we load fonts. :^)

To support this, FontFace::load() uses its connected CSSFontFaceRule's
ParsedFontFace if it's available.

The 1 regression in generic-family-keywords-003.html seems to be a false
positive: we don't support the system-ui font keyword.
2026-02-24 15:44:32 +00:00
Callum Law
e6669482e6 LibWeb: Parse font-variant-alternates functions 2026-02-20 22:01:44 +00:00
Callum Law
6705bd187c LibWeb: Account for generic font families in FontFaceSet::load()
Fixes a regression in d998a0a which was crashing the imported test
2026-02-19 12:00:52 +01:00
Callum Law
6d73a3e85f LibWeb: Parse @font-feature-values at-rule
We don't yet support the `font-display` descriptor as part of this
2026-02-17 12:25:27 +00:00
Callum Law
784911fb6d LibWeb: Implement CSSFontFeatureValuesRule 2026-02-17 12:25:27 +00:00
Callum Law
fcdc05a4ee LibWeb: Implement CSSFontFeatureValuesMap
This will be used within `CSSFontFeatureValuesRule`
2026-02-17 12:25:27 +00:00
Callum Law
f36d0407ec Tests: Import some @font-feature-values tests 2026-02-17 12:25:27 +00:00
Callum Law
11d524bda4 LibWeb: Support CSS font-optical-sizing property 2026-02-03 11:44:25 +00:00
Andreas Kling
35839af2d2 LibWeb: Optimize getComputedStyle() to avoid layout when possible
Previously, getComputedStyle() would always call update_layout() for
most properties. This was expensive since layout involves a full tree
traversal even when only style information is needed.

This change introduces a more granular approach:
- Properties needing layout computation (used values like width/height)
  still call update_layout()
- Properties needing a layout node for resolved value computation
  (colors, border widths, etc.) also call update_layout()
- All other properties now only call update_style()

The set of properties needing layout node for resolution is now defined
in Properties.json via the "needs-layout-node-for-resolved-value" flag,
rather than being hardcoded. This is generated into a new function
property_needs_layout_node_for_resolved_value().
2026-01-26 12:40:36 +01:00
Callum Law
9b20fe6902 LibWeb: Promote font-style to ValueType
This means we now allow oblique angles when parsing the `font`
shorthand.

This also required us to rename the existing `FontStyle` enum to
`FontStyleKeyword`
2026-01-13 10:21:26 +00:00
Callum Law
1c1476f728 LibWeb: Don't compute font-feature-settings until compute-time
Previously we applied the computation logic (i.e. deduplication and
sorting of tags) at parse time
2026-01-13 10:21:26 +00:00
Callum Law
252e1d86bd LibWeb: Dont serialize font with non-initial reset-only sub-properties 2026-01-13 10:21:26 +00:00
Tim Ledbetter
e4fb4d7c1a LibWeb: Extract animation-composition value from keyframe at-rules
Previously, we weren't respecting the value of this property, so the
composite operation always defaulted to
`AnimationComposition::Replace`.
2026-01-06 12:58:54 +01:00
Sam Atkins
40b25f631b Tests: Re-import some border- and outline-width tests
Some subtests changed in response to this CSSWG resolution:
https://github.com/w3c/csswg-drafts/issues/11494#issuecomment-2675800489

Basically, `border-style: none` now affects the used value of
`border-width`, not the computed value. (And the same for `outline`
properties.)

This affects way more tests than I expected because
interpolation-testcommon.js now adds tests for composition.
2025-12-15 21:28:19 +01:00
Sam Atkins
29666e1d83 LibWeb/DOM: Invalidate children with relative font-weight/font-size
`font-weight` and `font-size` both can have keywords that are relative
to their inherited value, and so need recomputing when that changes.

Fixes all but one subtest in font-weight-computed.html, because that
remaining one uses container-query units. No font-size tests seem to be
affected: font-size-computed.html doesn't update the parent element's
`font-size` so this invalidation bug didn't apply.
2025-11-20 12:22:03 +01:00
Sam Atkins
7d2f631d4c LibWeb/CSS: Handle whitespace better in font-language-override strings
The rules for strings here are:
- 4 ASCII characters long
- Shorter ones are right-padded with spaces before use
- Trailing whitespace is always removed when serializing

We previously always padded them during parsing, which was incorrect.
This commit flips it around so we trim trailing whitespace when parsing.

We don't yet actually use this property's value for anything. Once we do
so, maybe we'll care more about them being stored as 4 characters
always, but for now this avoids us needing a special step during
computation.
2025-11-18 17:22:03 +01:00
Callum Law
831e471444 LibWeb: Support top-level tree counting functions
Adds support for `sibling-index()` and `sibling-count()` when parsing
`<number>` and `<integer>`. This is achieved by a new
`TreeCountingFunctionStyleValue` class which is converted within
`absolutized` to `NumberStyleValue` and `IntegerStyleValue` respectively

There are still a few kinks to work out in order to support these
everywhere, namely:
 - There are some `StyleValue`s which aren't absolutized (i.e. those
   which are stored within another `StyleValue` without an
   `absolutize()` method.
 - We don't have a way to represent this new `StyleValue` within
   `{Number,Integer}OrCalculated`. This would be fixed if we were to
   instead just use the `StyleValue` classes until style computation at
   which time they would be absolutized into their respective
   primitives (double, i64, etc) bypassing the need for *OrCalculated
   entirely.
2025-10-20 16:12:08 +01:00
Callum Law
28451b16c9 LibWeb: Absolutize StyleValues before computing font properties
We also avoid prematurely constructing CSSPixels when computing
font-size which gains us a couple of test passes
2025-10-20 16:12:08 +01:00
Callum Law
e675b95f51 LibWeb: Add absolutized method to OpenTypeTaggedStyleValue 2025-10-07 10:50:01 +01:00
Tim Ledbetter
b64cb89b9d LibWeb: Implement compositing of font-variation-settings values 2025-09-26 11:20:54 +01:00
Tim Ledbetter
f9452b77b7 LibWeb: Implement interpolation of font-variation-settings values 2025-09-26 11:20:54 +01:00
Tim Ledbetter
83ad5ce8a2 LibWeb: Don't deduplicate font-variation-settings values at parse time
We now only deduplicate and sort the computed value of the
`font-variation-settings` property.
2025-09-26 11:20:54 +01:00
Tim Ledbetter
27de4fdcea LibWeb: Clamp interpolated font-style angle
This change adds the allowed angle range to the `font-style` property
definition. This allows these angles to be clamped after interpolation.

Ideally, the generator should be updated so that we can specify the
angle is in degrees. This would allow us to make use of this
information during parsing, which we can't do currently because we
don't know what the unit is. Using this value for interpolation
purposes is fine because the angle has been converted to its canonical
unit by this point.
2025-09-24 11:40:38 +01:00
Callum Law
e17d91780d LibWeb: Clamp computed value for font-style oblique angle
Values outside [-90deg,90deg] are invalid and should be clamped
2025-09-19 10:06:33 +01:00
Callum Law
dc41d045d8 LibWeb: Store font-style in ComputedProperties in computed form 2025-09-19 10:06:33 +01:00
Callum Law
335c8c7ffb LibWeb: Store font-width in ComputedProperties in computed form 2025-09-19 10:06:33 +01:00
Callum Law
b52525b454 LibWeb: Convert font-width percentages to keywords when serializing font 2025-09-19 10:06:33 +01:00
Callum Law
39484e2027 LibWeb: Store font-weight in ComputedProperties in computed form
We now also more closely follow the spec when computing values for
font-weight and we now:
 - Support relative lengths in `calc()`s
 - Properly clamp `calc()`s
 - Support relative keywords (e.g. lighter, bolder)
 - Respect that font-weight can be a non-integer number.

This does expose a few false positives in the font-weight-computed.html
WPT test. This is because we don't recompute non-inherited font-weight
within `recompute_inherited_style` which means that relative keyword
values can fall out of sync with their parent's value. These previously
passed as we treated `bolder` and `lighter` as aliases for `bold` and
`normal` respectively.
2025-09-19 10:06:33 +01:00
Callum Law
cfbe0244d4 LibWeb: Use computed value of font-size in keyframes
Remaining test failures in font-size-interpolation-00* are either:
 - Rounding of font-size to CSSPixels when setting the expected value
 - Not clamping negative values from the point of view of
   getComputedStyle (used values are still clamped)
2025-09-19 10:06:33 +01:00
Callum Law
64d2f0d55a LibWeb: Avoid overwriting non-animated font-size when computing font
Previously if we would overwrite the non-animated font-size with the
animated font-size if it was set.

Gains us 8 WPT tests and means we now fail 9 others in line with other
browsers.
2025-09-19 10:06:33 +01:00
Callum Law
3b6d17cd42 LibWeb: Import a bunch of CSS font related tests
Done in distinct commit to see progress over multiple following commits
2025-09-19 10:06:33 +01:00
Tim Ledbetter
96b628fe21 LibWeb: Clamp interpolated values to their accepted range 2025-09-07 14:50:36 +01:00
Callum Law
56c4e8199b LibWeb: Clamp negative font-size when loading font
`font-size` can end up with a negative value - either due to `calc`
being resolved using the old method which doesn't clamp the value, or
interpolation - in this case we should clamp negative values to zero.

Gains us 36 new WPT passes and fixes crashes in the three imported
tests.
2025-09-01 12:28:53 +01:00
Callum Law
778da0175e LibWeb: Clamp and censor top-level calc results
We now clamp the values returned from calc into the allowed range (where
we know it) and censor any `NaN`s to `0` both when we resolve and when
we serialize.

Gains us 76 WPT passes.
2025-08-11 17:10:04 +01:00
Tim Ledbetter
9b6da84fff LibWeb/CSS: Implement the font-kerning property
This sets whether the kerning information stored on the current font is
used.
2025-06-23 13:26:48 +01:00
Tim Ledbetter
689dff3ee8 Tests: Synchronize imported tests with the WPT repository 2025-06-22 23:51:34 +02:00
Tim Ledbetter
7faeef8d0d LibWeb: Treat font-variant values with unknown keywords as invalid 2025-06-15 16:44:51 +02:00
Tim Ledbetter
64728aef6c LibWeb: Disallow non-ASCII font-language-override values 2025-06-14 16:05:04 -04:00
Tim Ledbetter
c55f281475 LibWeb: Disallow empty font-language-override string values 2025-06-14 16:05:04 -04:00
Jelle Raaijmakers
4b6489917b LibGfx: Disable tech(variations) font support for now
We apparently don't support it in the right way, since it causes the
wrong font to display on https://ladybird.org.
2025-06-12 11:04:37 +01:00
Sam Atkins
5a1c73d7e2 LibGfx+LibWeb: Update definitions of supported font formats and features
Based very scientifically on what's listed here:
https://harfbuzz.github.io/what-does-harfbuzz-do.html

I've moved the code into LibGfx because including a HarfBuzz header
directly from LibWeb is a little unpleasant. But the Gfx::FontTech enum
follows the CSS definitions for font features for simplicity.

TrueType collections are supported. SVG and Embedded OpenType are not,
but they're not widely supported by other browsers so that's fine.

Most of the features are completely supported by HarfBuzz, so we can
just return true. Graphite support is optional (and it appears we use a
build of HarfBuzz without it) but there's a define we can check.
Incremental Font Transfer is a whole separate thing that we definitely
don't support yet.
2025-06-05 12:10:29 +01:00
Sam Atkins
d611806f18 LibWeb/CSS: Parse and use tech() in @font-face { src } 2025-06-05 12:10:29 +01:00
Callum Law
670c247937 LibWeb: Resolve FIXME around shorthand properties in remove_property()
This exposes some false-positive sub-tests in the font-computed.html
test which are now correctly marked as failed.
2025-06-04 16:34:31 +01:00
Sam Atkins
f5cd853597 LibWeb/CSS: Avoid calling to_font_weight() when serializing font
This function attempts to resolve `lighter` and `bolder`, which we don't
want to do when serializing - that should happen in style computation.

This has the unexpected bonus of 37 more WPT passes!
2025-05-24 13:35:30 +01:00
Sam Atkins
ea44a1c2c7 LibWeb/CSS: Don't treat "-foo" as vendor-prefixed
To be vendor-prefixed, an ident has to start with a '-', then have
another '-' later. If the ident simply starts with a '-' then that's
perfectly fine.

Fixes 62 in-tree WPT subtests. :^)
2025-05-23 19:39:23 +01:00
Sam Atkins
f5825ab18c LibWeb/CSS: Stop erasing font-variant-css2 value in font shorthand
We don't want to reset the values of `font-variant-*` here, as that will
override whatever our parsed font-variant-css2 was, so stop doing that.

Also, font-stretch is mentioned in the spec, but it's a legacy name
alias for font-width, so we don't need to do anything for it.

Gets us 319 WPT passes!
2025-05-23 19:39:23 +01:00
Andreas Kling
59e2416b61 LibWeb: Handle format(woff-variations) etc in @font-face src values
"format(woff-variations)" and pals are supposed to expand like so:
"format(woff) tech(variations)".

However, since we don't support tech() yet, this patch just adds a small
hack where we still treat "woff-variations" as "woff" so that fonts
load and get used, even if we don't make use of the variations yet.
2025-05-23 16:36:56 +02:00
Andreas Kling
2d064116ab Tests: Import a WPT test for @font-face format specifiers 2025-05-23 16:36:56 +02:00
Andreas Kling
734bc2a0ea AK: Strip trailing zero decimals in default formatting of float numbers
This gives us a more human-looking serialization of numbers by default,
and in case a fixed number of decimal digits is actually wanted, we
still have the 'f' specifier.
2025-05-18 17:23:34 +02:00
Sam Atkins
233022c473 LibWeb/CSS: Allow empty trailing group when parsing comma-separated list
There's discussion in the linked spec issue, but the short version is,
this algorithm will see "foo,bar," as a list of two groups, with "foo"
in the first group and "bar" in the second. However, users of this want
to get a list of three groups, with the last one being empty. So, do
that!
2025-05-17 07:53:24 +01:00