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

Consider CPAL/COLR for solving the white-on-black-with-overlaps issue #3

Closed
Lorp opened this issue Apr 2, 2020 · 8 comments · Fixed by #37
Closed

Consider CPAL/COLR for solving the white-on-black-with-overlaps issue #3

Lorp opened this issue Apr 2, 2020 · 8 comments · Fixed by #37
Milestone

Comments

@Lorp
Copy link

Lorp commented Apr 2, 2020

I would be pleased if another issue can be considered in this round of CPAL/COLR updates.

The “white on black” issue concerns colour-inverted b/w glyphs as seen in this image, from @adobe-fonts’s white-on-black-vf repo, which contains a test font with this glyph.

67e45d00-818a-11e9-8166-bcc146b20892

Top: actual behaviour. Bottom: desired behaviour

As can be seen, the “white” or transparent parts of the glyph cannot use the overlapping contours that are useful in the “black“ or opaque parts of variable fonts.

In May 2019 @readroberts started a discussion on the otfontvar@unicode.org list (subject line Need new path fill rule for variable fonts with white on black glyphs), in which I suggested a COLR/CPAL approach. Later that month, @kenlunde posted the Adobe test font mentioned above to GitHub. In August 2019, Read summarized three possible approaches in an issue posted to the opentype-variations repo: “White on Black” VF Rasterization Issue:

  1. a new rendering rule treating negative and positive winding differently
  2. a COLR/CPAL solution
  3. support for more complex graphics operations proposed by Renzhi Li

Read’s summary is well worth reading in full. He comes out firmly in favour of (1), a new rendering rule.

To me the rendering rule solution seems lined up for years of incompatibilities while rasterizers catch up, elegant only if we had a blank sheet. As Read acknowledges, it requires methods to export normal text glyphs as composited graphic objects for the vast number of system components that use OpenType fonts.

Back to COLR/CPAL

It seems to me that COLR/CPAL is a pretty good solution. It is explicitly about layers. And it has a built-in fallback mechanism (to a b/w simple or composite glyph) for rasterizers that don’t support it (or that version of the tables). It lacks the ability to define masks, but we can spec that easily. An updated COLR table would define certain layers as "mask". We already have one special value in COLR, 0xFFFF:

A palette entry index value of 0xFFFF is a special case indicating that the text foreground color (defined by a higher-level client) should be used and shall not be treated as actual index into CPAL ColorRecord array. — COLR table specification

We can define 0xFFFE as the “mask” paletteIndex. Any layer “coloured” with paletteIndex 0xFFFE would punch holes in whatever had been built up so far.

Typical use would be to have a single mask layer at the top of the stack, but it may be useful to have multiple mask layers at various positions in the stack.

COLR glyphs already piggy-back on top of the existing rasterizers, and this extra step seems to me less onerous than updating the core rasterizer. The SVG <clipPath> element makes this technique easily translatable to SVG.

Read had three objections to the COLR solution, which I list here for consideration:

The problem is really one of rasterization for normal text fonts. Since the ‘COLR’ table conveys the meaning of being a color font, it doesn’t seem to be the right place to be solving this problem, which is fundamentally a non-color one. Also, this could lead to problems with heuristics, such as font classification.

There may also be some loss of effectiveness of anti-aliasing and hinting. Text renderers have been heavily optimized over the years for different environments. We suspect that some of this optimization could be lost when the ‘white’ paths are applied as a mask.

Use of the ‘COLR’ table currently requires explicit opt-in on the part of the user, which is passed down through the API. This new use of the ‘COLR’ table would need to differentiate between the current use case, which is opt-in only, and the new use case, which involves the ‘COLR’ table being applied to the glyphs in question.

In respect of the anti-aliasing and hinting issue, it may be a worthwhile optimization for renderers, when processing COLR glyphs that only use paletteIndices 0xFFFF (opaque) and 0xFFFE (transparent), to use a rasterizer path tuned for font rendering.

@rsheeter
Copy link
Contributor

Since the ‘COLR’ table conveys the meaning of being a color font

I don't think we should take this meaning. It's just a layer font.

I believe that if we merge #37 we have the desired support for hole-punching. PTAL.

@Lorp
Copy link
Author

Lorp commented Sep 10, 2020

Great to see this new proposal #37. I was talking to @twardoch a while ago about COLR/CPAL v2 v1* being used for all composite glyphs.

* current COLR/CPAL are v0

@twardoch
Copy link

twardoch commented Sep 10, 2020 via email

@twardoch
Copy link

twardoch commented Sep 10, 2020 via email

@davelab6
Copy link
Member

I'm not sure how useful this is for "all" composite glyphs; seems too hack-y to me. The problems like google/fonts#2666 aren't best solved by COLRv1 support, but by proper handling of overlapping contours/components.

@Lorp
Copy link
Author

Lorp commented Sep 11, 2020

@davelab6 I agree, but that’s not a composite bug. (Let’s hope Apple fixes it soon, whether by deleting the complex text codepath or another method.)

The intent of my comment was to mark my approval that the future COLR/CPAL, with the transform 2x3 matrix, advances from having some aspects in common with traditional composites, to having a clear superset of capability.

@behdad
Copy link
Collaborator

behdad commented Sep 11, 2020

We still are going to mark a font as colorful if it has COLR table. Put another way, in a context where color is not available, this table might and probably should be ignored.

@davelab6
Copy link
Member

the future COLR/CPAL, with the transform 2x3 matrix, advances from having some aspects in common with traditional composites, to having a clear superset of capability

Got it. I don't see an issue with CPAL v2 edging ahead, and then updating glyf to math the capability set (as was decided to postpone to v2 in #8)

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 a pull request may close this issue.

5 participants