Skip to content

fonts: Add synthetic bold face support for Windows#39633

Merged
jdm merged 20 commits intoservo:mainfrom
minghuaw:feat/synth-bold-windows
Oct 10, 2025
Merged

fonts: Add synthetic bold face support for Windows#39633
jdm merged 20 commits intoservo:mainfrom
minghuaw:feat/synth-bold-windows

Conversation

@minghuaw
Copy link
Copy Markdown
Contributor

@minghuaw minghuaw commented Oct 2, 2025

This PR follows #39519 and adds synthetic bold face support for Windows platform.

Testing: There are existing WPT testcases for font synthesis (wpt/css/css-fonts/font-synthesis-*). A new test that checks for "double emboldening" (a bold font gets emboldened again) is getting added to the upstream WPT repo (web-platform-tests/wpt#55313)
Depends on: servo/dwrote-rs#70, servo/dwrote-rs#71
Part of #39637

@minghuaw minghuaw requested a review from nicoburns as a code owner October 2, 2025 09:28
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 2, 2025
Signed-off-by: Minghua Wu <[email protected]>
@TimvdLippe TimvdLippe added the T-linux-wpt Do a try run of the WPT label Oct 2, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Oct 2, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 2, 2025

🔨 Triggering try run (#18190861332) for Linux (WPT)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 2, 2025

Test results for linux-wpt from try job (#18190861332):

Flaky unexpected result (25)
  • OK /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.

      assert_equals: version expected 1 but got 9007199254740991
      

  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • FAIL [expected PASS] subtest: WebGL test #45

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #47

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #49

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #51

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • PASS [expected FAIL] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
  • FAIL [expected PASS] /css/CSS2/css1/c5501-mrgn-t-000.xht
  • FAIL [expected PASS] /css/CSS2/text/text-align-white-space-002.xht
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-schema-credit-007.xht
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-well-formed-006.xht
  • FAIL [expected PASS] /css/WOFF2/privatedata-noeffect-001.xht
  • FAIL [expected PASS] /css/WOFF2/tabledata-non-zero-loca-001.xht
  • FAIL [expected PASS] /css/css-fonts/font-face-style-default-variable.html
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted serif (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-rounded (drawing text in a canvas)
  • PASS [expected FAIL] /css/css-fonts/system-ui-zh.html (#39563)
  • FAIL [expected PASS] /css/css-text/text-transform/text-transform-upperlower-018.html
  • PASS [expected FAIL] /css/selectors/invalidation/any-link-attribute-removal.html (#35054)
  • TIMEOUT /fetch/metadata/generated/css-images.sub.tentative.html (#29047)
    • TIMEOUT [expected PASS] subtest: background-image sec-fetch-site - Not sent to non-trustworthy same-origin destination

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: background-image sec-fetch-site - Not sent to non-trustworthy cross-site destination

      Test timed out
      

  • TIMEOUT [expected CRASH] /html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html (#20768)
    • FAIL [expected PASS] subtest: Tests that a fragment navigation in the unload handler will not block the initial navigation

      assert_equals: expected "" but got "#fragment"
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_2.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected PASS] subtest: opener of discarded auxiliary browsing context

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

  • ERROR [expected OK] /html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html (#25046)
  • TIMEOUT [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
    • NOTRUN [expected FAIL] subtest: Check that popups from a sandboxed iframe do not escape the sandbox
  • ERROR [expected OK] /html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-pushstate.html
  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • FAIL [expected PASS] subtest: print() during unload

      assert_array_equals: expected property 1 to be "destination" but got "error: window.print is not a function" (expected array ["start", "destination"] got ["start", "error: window.print is not a function"])
      

  • OK /webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html (#22849)
    • FAIL [expected PASS] subtest: buffer-stitching-2

      assert_approx_equals: Stitched sine‑wave buffers at sample rate 43800 sample[6585] |-1.0984321196741693e+34 - -0.9523686170578003| = 1.0984321196741693e+34 &gt; 0.0038986 expected -0.9523686170578003 +/- 0.0038986 but got -1.0984321196741693e+34
      

Stable unexpected results that are known to be intermittent (37)
  • OK /FileAPI/url/url-with-fetch.any.worker.html (#21517)
    • FAIL [expected PASS] subtest: Revoke blob URL after calling fetch, fetch should succeed

      promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_get.any.html (#38942)
    • PASS [expected FAIL] subtest: Attempts to retrieve a record that doesn't exist
  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() =&gt; {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() =&gt; {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • FAIL [expected PASS] /_mozilla/css/iframe/hide_and_show.html (#15265)
  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /_webgl/conformance/rendering/texture-switch-performance.html (#23384)
    • FAIL [expected PASS] subtest: WebGL test #0

      assert_true: Texture switching significantly hurt performance - achieved 74 frames in 2.013 seconds (0.43 times baseline performance) expected true got false
      

  • OK /_webgl/conformance2/rendering/texture-switch-performance.html (#23384)
    • FAIL [expected PASS] subtest: WebGL test #0

      assert_true: Texture switching significantly hurt performance - achieved 74 frames in 2.022 seconds (0.44 times baseline performance) expected true got false
      

  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 1

      assert_equals: expected "80px" but got "41.45px"
      

    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 2

      assert_equals: expected "80px" but got "41.45px"
      

  • PASS [expected FAIL] /css/css-fonts/system-ui-ja-vs-zh.html (#39601)
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Single value - name is missing
  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • ERROR [expected TIMEOUT] /fetch/fetch-later/quota/same-origin-iframe/max-payload.https.window.html (#35210)
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/multiple-iframes.https.window.html (#35176)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • FAIL [expected PASS] subtest: sec-fetch-dest

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

  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html (#29048)
    • FAIL [expected PASS] subtest: Navigating to a different document with location.href

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1" but got "about:blank"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • FAIL [expected PASS] subtest: load event does not fire on window.open('about:blank')

      assert_unreached: load should not be fired Reached unreachable code
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html (#28697)
    • PASS [expected FAIL] subtest: aElement.click() before the load event must NOT replace
  • TIMEOUT /html/browsers/history/the-history-interface/001.html (#12580)
    • FAIL [expected PASS] subtest: traversing history must also traverse hash changes

      assert_equals: (this could cause other failures later on) expected "" but got "test"
      

  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html (#22647)
  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html (#22667)
    • TIMEOUT [expected FAIL] subtest: Check that popups from a sandboxed iframe escape the sandbox if allow-popups-to-escape-sandbox is used

      Test timed out
      

  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html (#24057)
    • FAIL [expected TIMEOUT] subtest: Check that popups from a sandboxed iframe escape the sandbox if allow-popups-to-escape-sandbox is used

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

  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html (#24066)
    • NOTRUN [expected FAIL] subtest: Check that popups from a sandboxed iframe do not escape the sandbox
  • OK /html/semantics/forms/historical.html (#28568)
    • FAIL [expected PASS] subtest: &lt;input name=isindex&gt; should not be supported

      assert_regexp_match: expected object "/\?isindex=x$/" but got "about:blank"
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete &gt; Original domComplete
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventEnd &gt; Original domContentLoadedEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventEnd &gt; Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart &gt; Original loadEventStart
  • OK /preload/preload-error.sub.html (#37177)
    • PASS [expected FAIL] subtest: success (fetch): main
    • PASS [expected FAIL] subtest: CORS (fetch): main
  • TIMEOUT /preload/preload-resource-match.https.html (#38088)
    • PASS [expected TIMEOUT] subtest: Loading module (use-credentials) with link (anonymous) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading module (use-credentials) with link (use-credentials) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (same-origin) with link (same-origin) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (no-cors) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (anonymous) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (no-cors) with link (use-credentials) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (no-cors) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (anonymous) should reuse the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (anonymous) with link (use-credentials) should discard the preloaded response
    • PASS [expected NOTRUN] subtest: Loading style (use-credentials) with link (no-cors) should discard the preloaded response
    • And 1 more unexpected results...
  • OK [expected TIMEOUT] /resource-timing/nested-context-navigations-iframe.html (#24311)
    • PASS [expected TIMEOUT] subtest: Test that crossorigin iframe navigations are not observable by the parent, even after history navigations by the parent
    • PASS [expected NOTRUN] subtest: Test that cross-site iframe navigations are not observable by the parent, even after history navigations by the parent
    • PASS [expected NOTRUN] subtest: Test that iframe navigations are not observable by the parent
    • PASS [expected NOTRUN] subtest: Test that crossorigin iframe navigations are not observable by the parent
    • PASS [expected NOTRUN] subtest: Test that cross-site iframe navigations are not observable by the parent
    • PASS [expected NOTRUN] subtest: Test that iframe refreshes are not observable by the parent
    • PASS [expected NOTRUN] subtest: Test that crossorigin iframe refreshes are not observable by the parent
    • PASS [expected NOTRUN] subtest: Test that cross-site iframe refreshes are not observable by the parent
  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected FAIL] subtest: Navigate a window via anchor with javascript:-urls in enforcing mode.
  • OK /webdriver/tests/classic/take_element_screenshot/scroll_into_view.py (#39306)
    • FAIL [expected PASS] subtest: test_scroll_into_view

      AssertionError: assert 'iVBORw0KGgoAAAANSUhEUgAAAI4AAAARCAYAAAALzZSeAAACoUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a/+3d/9nV/8xV+cq656Uf393/89lauu+tcjeKZxHHmv93ovtre3efEXf3GuuuqFoPJMP/MzP8Of/dmfcccdd3Ds2DGuuuqFoPJMf/3Xf80rvdIrcezYMa666l9A5ZkuXbrEbDbjqqteBATAm7/5m/P1X//1fMu3fAuS+PRP/3QA7rvvPt71Xd+Va665hmuvvZb3eq/34sKFC9zvvvvu413f9V255ppruPbaa3mv93ovLly4wFX/5xEAP//zP8+HfdiH8UEf9EHY5vM///MBeMd3fEcuXbrEX//1X/Pnf/7n3H777bzHe7wH93vHd3xHLl26xF//9V/z53/+59x+++28x3u8B1f9n0flBXja057G7/zO7/D0pz+dG264AYCv/dqv5SVe4iW4++67WS6X/M7v/A5Pf/rTueGGGwD42q/9Wl7iJV6Cu+++m+uvv56r/s8ieAFuv/12aq08+MEP5n4Pf/jDAbj99tu5/fbbqbXy4Ac/mPs9/OEPB+D222/nqv/TCF6Am2++mWmauO2227jfU57yFABuvvlmbr75ZqZp4rbbbuN+T3nKUwC4+eabuer/NIIX4KEPfSiv+ZqvyYd92Idx9913c/vtt/ORH/mRvMmbvAnXX389D33oQ3nN13xNPuzDPoy7776b22+/nY/8yI/kTd7kTbj++uu56v80ghfiR37kR9ja2uIlX/IlebmXezluvPFGvvd7v5f7/ciP/AhbW1u85Eu+JC/3ci/HjTfeyPd+7/dy1f956O/+7u/84i/+4lx11Yvq7//+76lcddW/HpWrrvrXowL8/d//PVdd9a/APwJaQbF56DF3BwAAAABJRU5ErkJggg==' == 'iVBORw0KGgoAAAANSUhEUgAAAI4AAAARCAYAAAALzZSeAAACoUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a/+3d/9nV/8xV+cq656Uf393/89wTON48h7vdd7sb29zYu/+Itz1VUvBJVn+pmf+Rn+7M/+jDvuuINjx45x1VUvBJVn+uu//mte6ZVeiWPHjnHVVf8CKs906dIlZrMZV131IiAA3vzN35yv//qv51u+5VuQxKd/+qcDcN999/Gu7/quXHPNNVx77bW813u9FxcuXOB+9913H+/6ru/KNddcw7XXXst7vdd7ceHCBa76P48A+Pmf/3k+7MM+jA/6oA/CNp//+Z8PwDu+4zty6dIl/vqv/5o///M/5/bbb+c93uM9uN87vuM7cunSJf76r/+aP//zP+f222/nPd7jPbjq/zwqL8DTnvY0fud3foenP/3p3HDDDQB87dd+LS/xEi/B3XffzXK55Hd+53d4+tOfzg033ADA137t1/ISL/ES3H333Vx//fVc9X8WwQtw++23U2vlwQ9+MPd7+MMfDsDtt9/O7bffTq2VBz/4wdzv4Q9/OAC33347V/2fRvAC3HzzzUzTxG233cb9nvKUpwBw8803c/PNNzNNE7fddhv3e8pTngLAzTffzFX/pxG8AA996EN5zdd8TT7swz6Mu+++m9tvv52P/MiP5E3e5E24/vrreehDH8prvuZr8mEf9mHcfffd3H777XzkR34kb/Imb8L111/PVf+nEbwQP/IjP8LW1hYv+ZIvycu93Mtx44038r3f+73c70d+5EfY2triJV/yJXm5l3s5brzxRr73e7+Xq/7PQ3/3d3/nF3/xF+eqq15Uf//3f0/lqqv+9ahcddW/HpWrrvrXowL8/d//PVdd9a/APwJma7F5RQE/xgAAAABJRU5ErkJggg=='
      

  • OK [expected ERROR] /webxr/render_state_update.https.html (#27535)
  • OK [expected ERROR] /workers/baseurl/alpha/sharedworker-in-worker.html (#21315)
Stable unexpected results (2)
  • OK [expected TIMEOUT] /_webgl/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html
    • PASS [expected NOTRUN] subtest: Overall test
  • FAIL [expected PASS] /css/WOFF2/metadatadisplay-schema-extension-028.xht

@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 2, 2025

⚠️ Try run (#18190861332) failed.

Copy link
Copy Markdown
Contributor

@xiaochengh xiaochengh left a comment

Choose a reason for hiding this comment

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

LGTM with nits

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Oct 2, 2025
@minghuaw minghuaw mentioned this pull request Oct 2, 2025
8 tasks
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 2, 2025
minghuaw added 3 commits October 4, 2025 16:18
@minghuaw
Copy link
Copy Markdown
Contributor Author

minghuaw commented Oct 5, 2025

I didn't realize that the FontInstance map in both the system font service and webfont instances were not including FontInstanceFlags in the map key. The latest commit fce9e8c adds the flags into the keys. This was causing problem there are text with font-synthesis-weight: auto and font-synthesis-weight: none on the same page.

@minghuaw minghuaw requested review from jdm and xiaochengh October 5, 2025 17:12
github-merge-queue bot pushed a commit that referenced this pull request Oct 7, 2025
…synthesizing bold face for FreeType platform (#39681)

The previous implementation in #39519 mistakenly used the
`FontTemplateDescriptor` to determine whether the font face itself is
already bold. This PR fixes that by using the `usWeightClass` in the
`OS/2` table of the font face to determine if the font face is bold
already.

Testing: A new testcase
`/tests/wpt/mozilla/tests/css/font_synthesis_weight_static_bold.html` is
getting added in #39633. This test checks whether a bold font face gets
"double emboldened"
Depends on: #39633

---------

Signed-off-by: Minghua Wu <[email protected]>
Signed-off-by: minghuaw <[email protected]>
Co-authored-by: Martin Robinson <[email protected]>
@atouchet
Copy link
Copy Markdown
Contributor

atouchet commented Oct 7, 2025

dwrote was updated in #39699.

@minghuaw minghuaw force-pushed the feat/synth-bold-windows branch from b279715 to 2fdaec1 Compare October 8, 2025 01:25
@minghuaw
Copy link
Copy Markdown
Contributor Author

minghuaw commented Oct 8, 2025

dwrote was updated in #39699.

Thanks! Updated the branch to main. This PR is ready for another quick review @xiaochengh (I've added FontInstanceFlags as part of the font instance map key since the last review).

@minghuaw minghuaw requested a review from mrobinson October 9, 2025 03:53
@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Oct 9, 2025
@xiaochengh
Copy link
Copy Markdown
Contributor

LGTM, thanks. Please let me know if it's ready to merge.

@minghuaw
Copy link
Copy Markdown
Contributor Author

LGTM, thanks. Please let me know if it's ready to merge.

Let me test this with the new WPT test

@minghuaw
Copy link
Copy Markdown
Contributor Author

LGTM, thanks. Please let me know if it's ready to merge.

This is ready to get merged. Thanks!

@jdm jdm added this pull request to the merge queue Oct 10, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Oct 10, 2025
Merged via the queue into servo:main with commit 2f82537 Oct 10, 2025
26 of 27 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Oct 10, 2025
@minghuaw minghuaw deleted the feat/synth-bold-windows branch October 10, 2025 05:44
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.

7 participants