Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support font-relative ch and ic units #32171

Merged
merged 4 commits into from May 2, 2024

Conversation

andreubotella
Copy link
Contributor

@andreubotella andreubotella commented Apr 28, 2024

After #31966, which made it possible for the first time to resolve font-relative CSS units, this change adds support for the ch and ic units.

One difference with the ex unit that was added in that PR is that these units must reflect the advance width of a character (the zero digit in the case of ch, and the CJK water radical for ic) as it would be rendered by the current font group. This means that the size of these units don't only depend on the first available font, in the case where that font does not contain a glyph for that character.

This is implemented by adding the advance width for these two characters as optional fields of FontMetrics, so the advance width computation happens in advance. Then, when the font metrics are queried as part of unit resolution, the font group is searched for the first font containing that character.

This change only implements support for these units in upright typesetting modes, since Servo does not yet have support for vertical writing modes. This means that many of the WPT tests that test for the behavior of these units with vertical writing modes do not pass.

This change also makes a number of WPT tests pass, which relied on the ch and ic units. It, however, also makes the test /css/css-text/white-space/text-wrap-balance-overflow-002.html fail, since it tests text-wrap: balance, which Servo does not yet implement, and it was only previously passing by chance due to the previous behavior of these units.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • There are tests for these changes

@mrobinson mrobinson added the T-linux-wpt-2020 Do a try run of the WPT label Apr 29, 2024
@github-actions github-actions bot removed the T-linux-wpt-2020 Do a try run of the WPT label Apr 29, 2024
Copy link

🔨 Triggering try run (#8876068432) for Linux WPT

components/layout_thread_2020/lib.rs Outdated Show resolved Hide resolved
Copy link

Test results for linux-wpt-layout-2020 from try job (#8876068432):

Flaky unexpected result (17)
  • TIMEOUT [expected OK] /_webgl/conformance/glsl/misc/shader-uniform-packing-restrictions.html (#28103)
  • OK /css/css-fonts/variations/font-weight-matching.html (#20686)
    • PASS [expected FAIL] subtest: Test @font-face matching for weight 99
    • PASS [expected FAIL] subtest: Test @font-face matching for weight 250
    • PASS [expected FAIL] subtest: Test @font-face matching for weight 399
  • FAIL [expected PASS] /css/css-sizing/dynamic-available-size-iframe.html (#31559)
  • TIMEOUT /css/cssom-view/MediaQueryList-extends-EventTarget.html (#25269)
    • FAIL [expected PASS] subtest: listeners for "change" type are called

      assert_equals: expected 1 but got 0
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • PASS [expected FAIL] subtest: load event does not fire on window.open('about:blank')
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)
    • FAIL [expected PASS] subtest: Cross-origin navigation started from unload handler must be ignored

      promise_test: Unhandled rejection with value: object "SecurityError: The operation is insecure."
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • TIMEOUT [expected OK] /html/browsers/history/the-location-interface/assign-replace-from-iframe.html (#31638)
  • OK [expected CRASH] /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected TIMEOUT] subtest: opener of discarded auxiliary browsing context

      assert_object_equals: property "get" expected function "function opener() {
          [native code]
      }" got function "function opener() {
          [native code]
      }"
      

  • OK [expected TIMEOUT] /html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.html (#30970)
  • TIMEOUT [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html (#22667)
  • CRASH [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html (#24057)
  • OK [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html (#24066)
    • FAIL [expected NOTRUN] subtest: Check that popups from a sandboxed iframe do not escape the sandbox

      assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
      

  • OK /html/semantics/forms/form-submission-0/form-submit-iframe-then-location-navigate.html (#29634)
    • FAIL [expected PASS] subtest: Verifies that location navigations take precedence when following form submissions.

      assert_equals: expected "/html/semantics/forms/form-submission-0/resources/location.html" but got "/html/semantics/forms/form-submission-0/resources/form.html"
      

  • OK /html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html (#23205)
    • PASS [expected FAIL] subtest: Check that rel=noopener with target=_self does a normal load
  • TIMEOUT /html/webappapis/scripting/events/compile-event-handler-settings-objects.html (#24246)
    • TIMEOUT [expected FAIL] subtest: The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document

      Test timed out
      

  • OK [expected TIMEOUT] /webmessaging/with-ports/018.html (#24485)
    • PASS [expected TIMEOUT] subtest: origin of the script that invoked the method, javascript:
Stable unexpected results that are known to be intermittent (17)
  • FAIL [expected PASS] /_mozilla/css/dirty_viewport.html (#13731)
  • FAIL [expected PASS] /_mozilla/mozilla/iframe/resize_after_load.html (#13573)
  • OK /css/CSS2/linebox/inline-negative-margin-001.html (#23862)
    • PASS [expected FAIL] subtest: [data-expected-height] 3
    • PASS [expected FAIL] subtest: [data-expected-height] 4
    • PASS [expected FAIL] subtest: [data-expected-height] 5
    • PASS [expected FAIL] subtest: [data-expected-height] 6
  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • PASS [expected FAIL] subtest: Matching font-weight: '501' should prefer '502 510' over '503 520'
    • PASS [expected FAIL] subtest: Matching font-weight: '399' should prefer '400' over '450 460'
    • PASS [expected FAIL] subtest: Matching font-stretch: '100%' should prefer '100%' over '110% 120%'
    • PASS [expected FAIL] subtest: Matching font-stretch: '110%' should prefer '115% 116%' over '105%'
    • PASS [expected FAIL] subtest: Matching font-style: 'italic' should prefer 'italic' over 'oblique 20deg'
    • PASS [expected FAIL] subtest: Matching font-style: 'oblique 20deg' should prefer 'oblique 20deg' over 'oblique 30deg 60deg'
    • PASS [expected FAIL] subtest: Matching font-style: 'oblique 21deg' should prefer 'oblique 0deg' over 'oblique -50deg -20deg'
    • PASS [expected FAIL] subtest: Matching font-style: 'oblique 10deg' should prefer 'italic' over 'oblique 0deg'
    • PASS [expected FAIL] subtest: Matching font-style: 'oblique 10deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg'
    • PASS [expected FAIL] subtest: Matching font-style: 'oblique -10deg' should prefer 'oblique 0deg 10deg' over 'oblique 40deg 50deg'
    • And 2 more unexpected results...
  • OK /css/css-text/white-space/trailing-space-position-001.html (#24585)
    • PASS [expected FAIL] subtest: CSS Test: Positions of trailing collapsible spaces 1
  • OK /css/cssom-view/MediaQueryList-addListener-removeListener.html (#24569)
    • PASS [expected FAIL] subtest: listeners are called correct number of times
  • TIMEOUT /fetch/metadata/generated/element-img-environment-change.sub.html (#30111)
    • FAIL [expected TIMEOUT] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • TIMEOUT [expected NOTRUN] subtest: sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes

      Test timed out
      

  • TIMEOUT [expected OK] /html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.html (#29081)
    • TIMEOUT [expected PASS] subtest: no-referrer referrer policy used to create the starting page

      Test timed out
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted

      assert_array_equals: Pages opened during history navigation expected property 1 to be 5 but got 3 (expected array [6, 5] got [6, 3])
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/track/track-element/no-cuechange-before-play.html (#31014)
    • FAIL [expected TIMEOUT] subtest: Ensure that the 'cuechange' event is not fired before video playback has begun.

      assert_true: Not expecting event, but got canplaythrough event expected true got false
      

  • CRASH [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html (#22647)
  • CRASH [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
  • OK /html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html (#21666)
    • FAIL [expected PASS] subtest: <img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (width:1000px)

      assert_equals: expected "http://web-platform.test:8000/images/green-1x1.png" but got "http://web-platform.test:8000/images/green-16x16.png"
      

  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: 0x00 in name (normal form)

      assert_equals: expected "a%00b=c" but got ""
      

  • TIMEOUT [expected OK] /webmessaging/with-ports/017.html (#24486)
    • TIMEOUT [expected PASS] subtest: origin of the script that invoked the method, about:blank

      Test timed out
      

  • OK [expected ERROR] /workers/constructors/Worker/Worker-constructor.html (#22991)
Stable unexpected results (57)
  • PASS [expected FAIL] /css/CSS2/floats/float-nowrap-hyphen-rewind-1.html
  • FAIL [expected PASS] /css/css-fonts/first-available-font-002.html
  • PASS [expected FAIL] /css/css-text/hyphens/hyphenate-character-001.html
  • PASS [expected FAIL] /css/css-text/hyphens/hyphens-none-014.html
  • PASS [expected FAIL] /css/css-text/hyphens/hyphens-none-015.html
  • PASS [expected FAIL] /css/css-text/line-break/line-break-anywhere-012.html
  • PASS [expected FAIL] /css/css-text/line-break/line-break-anywhere-overrides-uax-behavior-015.html
  • PASS [expected FAIL] /css/css-text/overflow-wrap/overflow-wrap-break-word-007.html
  • PASS [expected FAIL] /css/css-text/text-align/text-align-justify-tabs-001.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-before-first-ideographic-char-001.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-before-first-ideographic-char-002.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-before-first-ideographic-char-003.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-before-first-ideographic-char-014.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-with-ideographic-space-002.html
  • PASS [expected FAIL] /css/css-text/white-space/break-spaces-with-ideographic-space-003.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-008.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-009.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-011.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-018.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-020.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-float-001.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-004.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-005.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-006.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-007.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-008.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-009.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-010.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-011.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-013.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-014.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-015.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-016.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-leading-spaces-017.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-tab-002.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-tab-003.html
  • PASS [expected FAIL] /css/css-text/white-space/pre-wrap-tab-005.html
  • FAIL [expected PASS] /css/css-text/white-space/text-wrap-balance-overflow-002.html
  • PASS [expected FAIL] /css/css-text/white-space/textarea-break-spaces-002.html
  • PASS [expected FAIL] /css/css-text/white-space/textarea-pre-wrap-011.html
  • PASS [expected FAIL] /css/css-text/white-space/trailing-space-align-start.tentative.html
  • PASS [expected FAIL] /css/css-text/white-space/trailing-space-and-text-alignment-003.html
  • PASS [expected FAIL] /css/css-text/white-space/trailing-space-and-text-alignment-004.html
  • PASS [expected FAIL] /css/css-text/white-space/trailing-space-and-text-alignment-rtl-003.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-normal-011.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-001.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-005.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-007.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-008.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-011.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-012.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-014.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-015.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-021.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-022.html
  • PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-023.html
  • PASS [expected FAIL] /css/css-ui/text-overflow-ellipsis-indent-001.html

Copy link

⚠️ Try run (#8876068432) failed.

After servo#31966, which made it possible for the first time to resolve
font-relative CSS units, this change adds support for the `ch` and
`ic` units.

One difference with the `ex` unit that was added in that PR is that
these units must reflect the advance width of a character (the zero
digit in the case of `ch`, and the CJK water radical for `ic`) as it
would be rendered by the current font group. This means that the size
of these units don't only depend on the first available font, in the
case where that font does not contain a glyph for that character.

This is implemented by adding the advance width for these two
characters as optional fields of `FontMetrics`, so the advance width
computation happens in advance. Then, when the font metrics are
queried as part of unit resolution, the font group is searched for the
first font containing that character.

This change only implements support for these units in upright
typesetting modes, since Servo does not yet have support for vertical
writing modes. This means that many of the WPT tests that test for the
behavior of these units with vertical writing modes do not pass.

This change also makes a number of WPT tests pass, which relied on the
`ch` and `ic` units. It, however, also makes the test
`/css/css-text/white-space/text-wrap-balance-overflow-002.html` fail,
since it tests `text-wrap: balance`, which Servo does not yet
implement, and it was only previously passing by chance due to the
previous behavior of these units.
@servo-wpt-sync
Copy link
Collaborator

🤖 Opened new upstream WPT pull request (web-platform-tests/wpt#46007) with upstreamable changes.

@servo-wpt-sync
Copy link
Collaborator

🤖 This change no longer contains upstreamable changes to WPT; closed existing upstream pull request (web-platform-tests/wpt#46007).

@andreubotella andreubotella marked this pull request as ready for review May 1, 2024 16:03
Copy link
Member

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, Andreu. You'll also need to run our version of rustfmt via ./mach fmt and please squash you commits so that the upstream WPT PR is closed properly as well. Thank you. Once that's done I'll send this to the MQ.

@mrobinson
Copy link
Member

🤖 This change no longer contains upstreamable changes to WPT; closed existing upstream pull request (web-platform-tests/wpt#46007).

Oh, I spoke to soon. Our scripts are clever enough to close this upstream PR without needing to squash.

@mrobinson mrobinson enabled auto-merge May 1, 2024 16:11
@mrobinson mrobinson added this pull request to the merge queue May 1, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2024
@mrobinson
Copy link
Member

Looks like there is one more consistently passing test:

    PASS [expected FAIL] /css/css-text/white-space/white-space-pre-wrap-trailing-spaces-021.html

@mrobinson mrobinson enabled auto-merge May 1, 2024 19:18
@mrobinson mrobinson added this pull request to the merge queue May 1, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2024
@mrobinson mrobinson added this pull request to the merge queue May 1, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2024
@mrobinson mrobinson added this pull request to the merge queue May 2, 2024
Merged via the queue into servo:main with commit 8ec5344 May 2, 2024
9 checks passed
@andreubotella andreubotella deleted the ch-ic-units branch May 2, 2024 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants