Closed Bug 1740530 Opened 2 years ago Closed 2 years ago

Rendering support for COLRv1 fonts

Categories

(Core :: Graphics: Text, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
105 Branch
Tracking Status
firefox105 --- fixed

People

(Reporter: jfkthame, Assigned: jfkthame)

References

Details

(Keywords: dev-doc-complete)

Attachments

(10 files, 13 obsolete files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

We currently render COLRv0 glyphs in thebes via gfxFont::RenderColorGlyph. We should extend this to handle the COLRv1 table, with its richer set of rendering and compositing operations.

Severity: -- → S4

Chromium 98 has implemented it.

The above patches appear to work well for a number of COLRv1 fonts I have tried. Not yet implemented: any validation of the tables, they're just assumed to be well-formed; and any support for the variation versions of the paint records.

(Also converted a bunch of internal struct definitions to use type names
based on the OT spec instead of the AutoSwap_* types from gfxFontUtils.)

Depends on D152162

Depends on D153076

Normalize gradient stops to match Chrome's rendering.

Can you provide a bit of info as to what the issue was?

Is there an ambiguity in the OT spec that should be clarified to ensure interoperability between implementations?

Flags: needinfo?(jfkthame)

(In reply to pgcon6 from comment #11)

Normalize gradient stops to match Chrome's rendering.

Can you provide a bit of info as to what the issue was?

Is there an ambiguity in the OT spec that should be clarified to ensure interoperability between implementations?

This was about how things work when the color line isn't defined from stops at 0.0 to 1.0 but instead (say) from 0.2 to 0.8 ... my initial implementation didn't handle this, and I was getting a result that differed from what I see in Chrome. I don't think it was particularly a spec issue, just a mismatch between the OT gradient expectations and our graphics backend that needed to be accounted for.

Flags: needinfo?(jfkthame)

Depends on D153871

Depends on D153875

Depends on D153876

Depends on D153877

Depends on D153880

Assignee: nobody → jfkthame
Attachment #9285852 - Attachment description: WIP: Bug 1740530 - Move COLR font support functions from gfxUtils into their own class. → Bug 1740530 - patch 1 - Move COLR font support functions from gfxUtils into their own class. r=#gfx-reviewers
Status: NEW → ASSIGNED
Attachment #9285853 - Attachment description: WIP: Bug 1740530 - Simplify COLR-glyph rendering a bit, by calling COLRFonts methods directly from gfxFont instead of via gfxFontEntry wrappers. → Bug 1740530 - patch 2 - Simplify COLR-glyph rendering a bit, by calling COLRFonts methods directly from gfxFont instead of via gfxFontEntry wrappers. r=#gfx-reviewers
Attachment #9285854 - Attachment description: WIP: Bug 1740530 - Replace GetColorGlyphLayers and the layer-rendering code in gfxFont with a zero-copy implementation in COLRFonts. → Bug 1740530 - patch 3 - Replace GetColorGlyphLayers and the layer-rendering code in gfxFont with a zero-copy implementation in COLRFonts. r=#gfx-reviewers
Attachment #9288658 - Attachment description: WIP: Bug 1740530 - Tidy up color-palette access a bit, and support access to palettes other than 0 (though not yet exposed to content). → Bug 1740530 - patch 4 - Use harfbuzz color-palette access functions, instead of rolling our own. r=#gfx-reviewers
Attachment #9285857 - Attachment description: WIP: Bug 1740530 - Implement support for COLRv1 glyph paint graphs (not including variation formats yet). → Bug 1740530 - patch 5 - Implement support for COLRv1 glyphs represented as acyclic graphs of paint records. r=#gfx-reviewers
Attachment #9288669 - Attachment description: WIP: Bug 1740530 - Update old COLRv0 code to better align with spec naming; improve some validation. → Bug 1740530 - patch 6 - Update old COLRv0 code to better align with spec naming, and refactor COLRv1 header. r=#gfx-reviewers
Attachment #9286017 - Attachment is obsolete: true
Attachment #9287494 - Attachment is obsolete: true
Attachment #9288668 - Attachment is obsolete: true
Attachment #9288667 - Attachment is obsolete: true
Attachment #9288666 - Attachment is obsolete: true
Attachment #9288664 - Attachment is obsolete: true
Attachment #9288663 - Attachment is obsolete: true
Attachment #9288662 - Attachment is obsolete: true
Attachment #9288661 - Attachment is obsolete: true
Attachment #9288660 - Attachment is obsolete: true
Attachment #9288659 - Attachment is obsolete: true
Attachment #9288769 - Attachment is obsolete: true
Attachment #9287496 - Attachment is obsolete: true
Attachment #9287495 - Attachment is obsolete: true
Attachment #9286017 - Attachment is obsolete: false
Attachment #9286017 - Attachment description: WIP: Bug 1740530 - Route COLRv1 fonts on macOS through our COLR-rendering path; only COLRv0 can use the native Core Text support. → Bug 1740530 - patch 7 - Route COLRv1 fonts on macOS through our COLR-rendering path; only COLRv0 can use the native Core Text support. r=#gfx-reviewers

The font here is a copy of Ahem with a COLRv1 table added, using various of the
COLRv1 paint and transform tables. This is far from an exhaustive set of tests,
but serves to check that basic rendering functionality is working.

The reference file uses CSS blocks filled with gradients, etc, to simulate the
expected rendering of the colored Ahem glyphs. This is unlikely to be a perfect
match in any but the simplest cases, thanks to antialiasing, pixel-rounding, etc.,
but the results are visually indistinguishable, or virtually so, and the amount
of "fuzz" is far less than the differences would be in the case of the COLRv1
glyphs actually being mis-rendered.

(There's a try run without the fuzz annotations at
https://treeherder.mozilla.org/jobs?repo=try&revision=4a2e2f7190661614ecddd223dd7178589d0ec5f2
where the results can be viewed in reftest-analyzer.)

We may eventually want to move this or similar tests into WPT, but I'm expecting
more extensive test coverage to be a co-operative effort with the other vendors
who are also implementing support, so this is intended as an interim step just to
ensure we have the basic functionality tested in-tree.

Depends on D154585

Depends on: 1715546
Attachment #9289769 - Attachment description: Bug 1740530 - patch 8 - Expose COLRv1 support via the CSS @font-face tech() function if the pref is enabled. r=#gfx-reviewers → Bug 1740530 - patch 9 - Expose COLRv1 support via the CSS @font-face tech() function if the pref is enabled. r=#gfx-reviewers
Attachment #9289770 - Attachment description: Bug 1740530 - patch 9 - Basic reftests for COLRv1 font rendering. r=#gfx-reviewers → Bug 1740530 - patch 10 - Basic reftests for COLRv1 font rendering. r=#gfx-reviewers
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/8b26219a4294
patch 1 - Move COLR font support functions from gfxUtils into their own class. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/fdc71479fcd9
patch 2 - Simplify COLR-glyph rendering a bit, by calling COLRFonts methods directly from gfxFont instead of via gfxFontEntry wrappers. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/a95e62dc9288
patch 3 - Replace GetColorGlyphLayers and the layer-rendering code in gfxFont with a zero-copy implementation in COLRFonts. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/4db61d87c172
patch 4 - Use harfbuzz color-palette access functions, instead of rolling our own. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/768df8b3c770
patch 5 - Implement support for COLRv1 glyphs represented as acyclic graphs of paint records. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/275eb6c4900b
patch 6 - Update old COLRv0 code to better align with spec naming, and refactor COLRv1 header. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/4c3cb20a5203
patch 7 - Route COLRv1 fonts on macOS through our COLR-rendering path; only COLRv0 can use the native Core Text support. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/cc1a41e1bf44
patch 8 - Guard against cycles in the paint graph during Paint() and GetBoundingRect(). r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/dfcb59684ed2
patch 9 - Expose COLRv1 support via the CSS @font-face tech() function if the pref is enabled. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/afbcf312dbaf
patch 10 - Basic reftests for COLRv1 font rendering. r=gfx-reviewers,lsalzman

Fixed the -Werror=subobject-linkage error; re-landing.

Flags: needinfo?(jfkthame)
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/e6523049b675
patch 1 - Move COLR font support functions from gfxUtils into their own class. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/429601610f26
patch 2 - Simplify COLR-glyph rendering a bit, by calling COLRFonts methods directly from gfxFont instead of via gfxFontEntry wrappers. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/673f9010ea75
patch 3 - Replace GetColorGlyphLayers and the layer-rendering code in gfxFont with a zero-copy implementation in COLRFonts. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/02d6294b7a6d
patch 4 - Use harfbuzz color-palette access functions, instead of rolling our own. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/06f7b45d044a
patch 5 - Implement support for COLRv1 glyphs represented as acyclic graphs of paint records. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/1c9205a0193f
patch 6 - Update old COLRv0 code to better align with spec naming, and refactor COLRv1 header. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/10b6bafbbd9a
patch 7 - Route COLRv1 fonts on macOS through our COLR-rendering path; only COLRv0 can use the native Core Text support. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/cf530e9fea50
patch 8 - Guard against cycles in the paint graph during Paint() and GetBoundingRect(). r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/adc2b1544c4c
patch 9 - Expose COLRv1 support via the CSS @font-face tech() function if the pref is enabled. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/6f6a55195489
patch 10 - Basic reftests for COLRv1 font rendering. r=gfx-reviewers,lsalzman

Backed out for causing reftest failures on colrv1.

Push with failures

Failure log
Reftest analyzer

Backout link

Flags: needinfo?(jfkthame)

Sigh... my try run didn't quite cover all platforms, so we need a small adjustment to fuzz numbers.

Flags: needinfo?(jfkthame)
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/2be4a1d5ac07
patch 1 - Move COLR font support functions from gfxUtils into their own class. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/13ae409d093a
patch 2 - Simplify COLR-glyph rendering a bit, by calling COLRFonts methods directly from gfxFont instead of via gfxFontEntry wrappers. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/5d1de3ed837b
patch 3 - Replace GetColorGlyphLayers and the layer-rendering code in gfxFont with a zero-copy implementation in COLRFonts. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/4354a0d7248f
patch 4 - Use harfbuzz color-palette access functions, instead of rolling our own. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/7bacec3b6ce1
patch 5 - Implement support for COLRv1 glyphs represented as acyclic graphs of paint records. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/d0a5d11277bb
patch 6 - Update old COLRv0 code to better align with spec naming, and refactor COLRv1 header. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/bf0dd96b4423
patch 7 - Route COLRv1 fonts on macOS through our COLR-rendering path; only COLRv0 can use the native Core Text support. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/e1ffdf0a6056
patch 8 - Guard against cycles in the paint graph during Paint() and GetBoundingRect(). r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/a5e90bc3b2e1
patch 9 - Expose COLRv1 support via the CSS @font-face tech() function if the pref is enabled. r=gfx-reviewers,lsalzman
https://hg.mozilla.org/integration/autoland/rev/a23ef2de9176
patch 10 - Basic reftests for COLRv1 font rendering. r=gfx-reviewers,lsalzman
Regressions: 1786002
See Also: → 1786002

FF105 Docs for this can be tracked in https://github.com/mdn/content/issues/20106

Can I please confirm that the way this is used is to specify the @font-face src: descriptor's "tech(...) syntax for an OTF font with gfx.font_rendering.colr_v1.enabed true? So something like:

@font-face {
  font-family: "MyCOLFRv1Font";
  src: url("MyCOLFRv1Font.otf") format(opentype)  tech(color-COLRv1);
}

Specifically, I want to be sure that you can't do this, for example, using https://developer.mozilla.org/en-US/docs/Web/API/FontFace/FontFace or any other way?

Flags: needinfo?(jfkthame)

It's not necessary to use the tech(...) syntax in order to load a COLRv1 font (any more than it is necessary to provide format(...)). If the colr_v1 pref is enabled, such a font can be used by simply giving its name, e.g.

@font-face {
  font-family: "MyCOLRv1Font";
  src: url("MyCOLRv1Font.otf");
}

or

var f = new FontFace("MyFamilyName", "url(colorfont.otf)");
document.fonts.add(f);

The tech(...) syntax can be used to determine whether a given technology (e.g. COLRv1) is supported, so that the author can provide suitable fallbacks depending on what the browser supports. This applies equally to the src descriptor in a @font-face rule or the source parameter to the FontFace constructor, just like format(...).

So an author could do something like:

@font-face {
  font-family: "MyFancyFont";
  src: url("MyFallbackFont.otf");
  src: url("MyCOLRv1Font.otf") tech(color-COLRv1),
       url("MySVGOTfont.ttf") tech(color-SVG),
       url("MyCOLRv0Font.ttf") tech(color-COLRv0),
       url("MyBitmapfont.ttf") tech(color-CBDT),
       url("MyFallbackFont.otf");
}

to load a fallback if the tech() syntax is not supported, but for browsers that do understand tech(), choose among several different resources depending on the rendering capabilities available.

Flags: needinfo?(jfkthame)
Blocks: 1788945

Thanks Jonathan. FYI, docs for this ended up being an update to browser compatibility to indicate supported in @font-face along with a note about the feature in the MDN experimental features section.
We should revisit more about what this allows when this is no longer behind a preference.

Depends on: 1791686
Regressions: 1866883
You need to log in before you can comment on or make changes to this bug.