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

Strawman for COLR without CPAL #205

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Strawman for COLR without CPAL #205

wants to merge 1 commit into from

Conversation

rsheeter
Copy link
Contributor

@rsheeter rsheeter commented Jan 12, 2021

COLR has long been understood to stand for Composition Of LayeRs :D

Idea is that if CPAL is absent you can safely assume the font paints only the foreground color, much as glyf or cff do today. The intent would be to make it plausible for an environment that rejects COLR entirely today to accept it when CPAL is absent.

Inspired by #88.

Edit: I'm increasingly convinced this is a solid idea; removed note about just playing with the idea.

OFF_AMD2_WD.md Outdated Show resolved Hide resolved
OFF_AMD2_WD.md Outdated Show resolved Hide resolved
OFF_AMD2_WD.md Outdated Show resolved Hide resolved
OFF_AMD2_WD.md Outdated Show resolved Hide resolved
@PeterConstable
Copy link
Collaborator

I'm really not convinced that COLR without CPAL is a good idea. Some of the structures we've defined for COLRv1 would be useful for composite glyph descriptions, but I don't think using COLR itself for that purpose is the right approach. I see at least the following issues here:

  • Some parts of the COLRv1 formats simply would not be useful for composite monochrome glyph descriptions, and so parsing of COLRv1 would need to be different depending on the context.
  • It would conflate two different things into the one table, adding complexity in tooling or in interpreting data in COLR.
  • It would create a significant new vector for introducing cycles in the graph: PaintGlyph. That's an added complication when rendering either monochrome or colour glyphs. (It might be inevitable with an extension to monochrome composites, but it doesn't need to be added to COLR processing.)
  • Any extension for new monochrome composites will end up resulting in fonts that aren't supported in existing software. If the extensions were, say, in a new glf2 table, then it would be obvious: an existing rasterizer simply wouldn't attempt to render that font. But if an extension is using a combination of existing glyf and COLR tables, then existing software would attempt to render the font producing garbage display results.

@rsheeter rsheeter changed the title Strawman for monochromatic COLR Strawman for COLR without CPAL Jan 12, 2021
@rsheeter
Copy link
Contributor Author

@behdad pointed out that rasterizers support foreground+opacity already due to anti-aliasing so I think I've gone too far in my limitations; will revise.

Thinking "aloud", we'll need to review compositing modes to see if any take you to places outside of what you can reach via foreground+opacity. My instinct is that only the non-separable modes are likely to have that issue.

@PeterConstable let's recast this as simply allowing COLR to exist w/o CPAL. I will update to reduce the limitations and we can see if that makes things feel better.

@behdad
Copy link
Collaborator

behdad commented Jan 12, 2021

My instinct is that only the non-separable modes are likely to have that issue.

That was my hunch as well. But looking into it, I think all blend-modes are problematic; so only the Porter-Duff compositing modes with normal blend are find. To be verified.

@PeterConstable
Copy link
Collaborator

I commented on this in issue 88: I think only the Porter-Duff modes would be relevant for monochrome since the channel values for source and backdrop would always be the same.

@davelab6
Copy link
Member

davelab6 commented Jan 13, 2021 via email

@rsheeter
Copy link
Contributor Author

I think all blend-modes are problematic

Agreed; https://www.w3.org/TR/compositing-1/#blendingnormal might be ok but we didn't add that as a composite mode.

@rsheeter rsheeter force-pushed the monochrome branch 6 times, most recently from c271751 to 7e78ddd Compare January 13, 2021 04:54
@rsheeter
Copy link
Contributor Author

PR updated to say COLR without CPAL is ok but you can't have blend modes.

@PeterCon
Copy link

I think Peter's last point there is worth discussing. I don't quite follow, peter - isn't this true of any COLR v0 renderer seeing v1 data?

If an app supports COLR v0 and encounters a COLR v1 colour font, it will ignore any v1 data that it doesn't recognize. Either one of two things happens:

  • If the font has some COLR v0 data (as well as v1), the app can display those colour glyphs; it will display the monochrome glyphs for all other glyphs.
  • If the font has only v1 data, the app won't see no colour glyph data and display the monochrome glyphs for all glyphs.

So, the app displays reasonable text, it just doesn't utilize the latest capabilities of the font.

@rsheeter
Copy link
Contributor Author

if an extension is using a combination of existing glyf and COLR tables, then existing software would attempt to render the font producing garbage display results

So, the app displays reasonable text, it just doesn't utilize the latest capabilities of the font.

It might display reasonable text, subject to the font author spending development time and filesize on good base glyphs.

IIUC the key capability you lose by using COLR vs a new table is that you can't cause a renderer to skip over the font entirely as you could with an entirely new outline table (only true if that table replaces the existing one, if it augments it you have similar problems). That's a tradeoff, but potentially a good one. Do we really want a new table to define outlines, as opposed to adding more sophisticated ways to reuse outlines from the tables we already have? - I like that COLR chose to augment rather than replace what existed before.

Speculating about potential users of COLR for components:

  • An OS can have a pretty good idea about what it supports and likely wouldn't ship a font in its stack it knew didn't work.
  • A network delivery system can choose to send an alternate version (a less compact glyf/cff equivalent or bitmaps depending on what COLR capabilities were used) to some clients.
  • Anything where you need to embed the font and be confident it works on another rendering environment (off-hand pdf, word, printing) might need a way to make an alternate version to embed, a simplified subset if you like

@vlevantovsky
Copy link

vlevantovsky commented Jan 13, 2021

Thinking out loud. Considering:

Some parts of the COLRv1 formats simply would not be useful for composite monochrome glyph descriptions, and so parsing of COLRv1 would need to be different depending on the context.

It would conflate two different things into the one table, adding complexity in tooling or in interpreting data in COLR.

if an extension is using a combination of existing glyf and COLR tables, then existing software would attempt to render the font producing garbage display results.

vs.

If an app supports COLR v0 and encounters a COLR v1 colour font, it will ignore any v1 data that it doesn't recognize. Either one of two things happens:

If the font has some COLR v0 data (as well as v1), the app can display those colour glyphs; it will display the monochrome glyphs for all other glyphs.

If the font has only v1 data, the app won't see no colour glyph data and display the monochrome glyphs for all glyphs.

I think that successful deployment of COLR without CPAL depends on three separate (and somewhat independent) parts of the approach:

  • the quality of font design - we've seen plenty of examples when good creative thinking combined with limited existing tools produces wonderful results that push the boundaries of what we considered possible! At the same time, there are plenty of examples of bad designs that simply do not work right.
  • the robustness of font tools that translate the design intent into a set of font tables. When the design intent is known, there can be a lot done with the right tools doing the right job, and accounting for limitations of COLR for composite monochrome glyph descriptions could definitely be part of the process.
  • the resilience of implementations that need to interpret any possible combination of font tables presented for rendering. I don't think that implementations should be responsible for second-guessing design intent in an attempt to fix what could be a mistake. We just need to make sure that the spec provides a clear guidance on what can be done, and then just let implementations do what they already do - ignore the data that they don't recognize or do not understand, and attempt to render what they can.

@PeterConstable
Copy link
Collaborator

I may have misunderstood what others have in mind here. But it appears the suggestion is that there would be two distinct processing modes that involve different validations, hence additional code complexity in implementations.

Suppose we had COLRv1 implementations for the design and functionality in mind before COLR w/o CPAL was considered. With that, a font could be created using COLR v1 formats and a CPAL table that has exactly one palette entry specifying 0xFFFF (foreground colour). COLR v1 processing could be applied normally without needing any special validations. Certain things non-alpha gradients, blend modes) might not be useful, but they would not likely be used for that reason, and also aren't harmful.

In terms of achievable visual results, it seems that would provide the same as what you all have in mind for COLR w/o CPAL. In that case, what benefits would we be after by spec'ing COLR w/o CPAL and two distinct processing modes?

@behdad
Copy link
Collaborator

behdad commented Jan 13, 2021

I may have misunderstood what others have in mind here.

I think you are. For a client that implements the colorful model, there's no modification needed whatsoever. We are however, sanctioning conditions that a COLRv1 font can constrain itself to, to be usable in colorless contexts.

Suppose we had COLRv1 implementations for the design and functionality in mind before COLR w/o CPAL was considered. With that, a font could be created using COLR v1 formats and a CPAL table that has exactly one palette entry specifying 0xFFFF (foreground colour).

You seem to have misunderstood the COLR/CPAL model. 0xFFFF is used in lieu of a palette entry index...

@PeterConstable
Copy link
Collaborator

You seem to have misunderstood the COLR/CPAL model. 0xFFFF is used in lieu of a palette entry index...

Fine, small memory lapse. Revise my scenario to the font having a CPAL with whatever (or no) entries, with only palette entry index 0xFFFF used.

We are however, sanctioning conditions that a COLRv1 font can constrain itself to, to be usable in colorless contexts.

So, in implementation contexts that don't support colour, but that support this different usage of COLR. What's the benefit of having the relevant data in the COLR table versus using a subset of the formats in a distinct table for this particular purpose?

Also, suppose the graph contains a PaintGlyph, but that glyph ID has an entry in the BaseGlyphV1List: Does the graph then incorporate the graph for that glyph ID (i.e., PaintGlyph now duplicates the functionality of PaintColrGlyph)?

OFF_AMD2_WD.md Outdated Show resolved Hide resolved
OFF_AMD2_WD.md Outdated Show resolved Hide resolved
@rsheeter
Copy link
Contributor Author

What's the benefit of having the relevant data in the COLR table versus using a subset of the formats in a distinct table for this particular purpose?

The intent of the proposed change is a small subset of COLR is excised in a scenario where it doesn't make sense, IMHO not enough to justify forking the table. If we were stripping out and modifying COLR substantially I'd agree with making a new table.

Intended benefit is ease of implementation for people who support both modes and lack of an almost duplicate table. If you add another table that supports non-color glyphs, can it be a base glyph for COLR? - I think things get weird with two tables that are mostly identical.

suppose the graph contains a PaintGlyph, but that glyph ID has an entry in the BaseGlyphV1List: Does the graph then incorporate the graph for that glyph ID

I don't see a need to change the behavior of PaintGlyph? - COLR is still built on top of an outline table, PaintGlyph still sources from there.

@rsheeter rsheeter marked this pull request as ready for review January 13, 2021 23:44
@PeterConstable
Copy link
Collaborator

I don't see a need to change the behavior of PaintGlyph? - COLR is still built on top of an outline table, PaintGlyph still sources from there.

But isn't the point to have a new way to define composites? In a colour font, a PaintGlyph could reference a glyf entry that is a composite, and the outline of the composite glyph is used as a clip path. But now we want a different way to define composites.

So, suppose (for sake of discussion) GID 42 is to be a composite defined using the COLR mechanism. It has an entry in the BaseGlyphV1List. But suppose I also want to use that composite outline as a clip path in another COLR glyph definition. I can't use outline data for gid 42 from the glyf table since any outline data there is not the composite outline that I want.

And what does glyf entry 42 contain anyway? For the COLR definition, we require it to have a bounding box. So, maybe it has two points for diagonal opposite corners. But then it's not a composite from the glyf perspective; how does the app know that it should not use that glyf data directly? Does it just see that there's a COLR without CPAL and then, based on that heuristic, it's expected to look first for GID 42 in a COLR BaseGlyphV1List and, only if not found there, then look at the glyf data?

If so, is such an implicit heuristic what we want to use in the format going forward, rather than explicit declarations?

@rsheeter rsheeter force-pushed the monochrome branch 2 times, most recently from e004fb6 to 0bfb4e4 Compare January 14, 2021 04:26
@rsheeter
Copy link
Contributor Author

rsheeter commented Jan 14, 2021

But isn't the point to have a new way to define composites?

Maybe "composite" is a bit overloaded in the font context. I see this as looking at what we did for COLR v1 and realizing what we have is useful for non-color (only foreground + alpha) scenarios if we do two things:

  1. Offer a well defined way to indicate this font shouldn't be deemed colorful (today COLR == colorful according to Consider CPAL/COLR for solving the white-on-black-with-overlaps issue #3 (comment))
  2. Ensure we really are non-color when CPAL is absent
    • We have given the user tools to reach colors that violate our definition of "non-color" so we take those away when non-color

@PeterConstable
Copy link
Collaborator

Maybe "composite" is a bit overloaded in the font context....

I get that much. I definitely see value in leveraging parts of COLRv1 for monochrome fonts; especially

  • P-D compositing modes
  • transforms
  • variation integration for transforms
  • re-use mechanisms

I'm just not yet convinced by the approach (e.g., compat issues).

For the scenario I mentioned, using a COLR "composites" as a clip region, you'd have to add to descriptions of PaintGlyph that, in a +COLR/-CPAL font, when a PaintGlyph is encountered the app must look for a COLR definition for that glyph and, if present, compute the outline for that glyph, then use that as the clip path. Unless we don't want to allow that (it might be that the same results could always be achieved in a slightly different way that utilizes PaintColrLayers or PaintColrGlyph), in which case some additional validation might be needed to say that a PaintGlyph must not reference a glyph that is a COLRv1 base glyph.

@rsheeter
Copy link
Contributor Author

using a COLR "composites" as a clip region

I would have expected this to be done via PaintComposite with no change to the definition of PaintGlyph but perhaps I'm missing a reason that doesnt' work?

@PeterConstable
Copy link
Collaborator

PaintComposite takes rendered source and backdrop bitmaps and combines them. PaintGlyph provides a clip path. The scenario I'm referring to would be if the glyph outline you want for the clip path is something constructed using COLR.

As I say, it may be that the desired result can always be obtained by extending the graph in some way and not referring to a glyph using PaintGlyph. But in any case, it seems like something would need to be said about a case in which a PaintGlyph refers to a GID that itself is a base glyph in the BaseGlyphV1List.

@rsheeter rsheeter force-pushed the monochrome branch 3 times, most recently from e765453 to c600c54 Compare January 15, 2021 06:15
@rsheeter
Copy link
Contributor Author

PaintComposite takes rendered source and backdrop bitmaps and combines them. PaintGlyph provides a clip path.

I think I'm beginning to see. A few thoughts that may or may not help :)

  • The authors intent was that PaintGlyph "Paint a non-COLR glyph" (from https://github.com/googlefonts/colr-gradients-spec#c-structures)
    • I don't immediately see that we need to change that intent
    • 5.7.11.2.5.5 says it shall be a valid gid with an outline in glyf, cff, or cff2; maybe that should be more explicit that it does not reference COLR glyphs?
  • I don't think we should fixate too much on PaintGlyph clipping being different than a clip via PaintComposite (e.g. Source In)
    • Think of it as described in the C++ structures (non-ISO content) section: // Paint a non-COLR glyph, filled as indicated by paint.
    • PaintGlyph could be implemented using the composite operations if one really wanted.
  • I'm not immediately seeing a reason the PaintGlyph clipping would be superior to PaintComposite?
    • Bear in mind an implementation doesn't have to compute PaintComposite as two bitmaps getting merged. For example, it could recognize it would be better setup a clip path in some cases.
  • If there is a problem here I don't think it's limited to the COLR without CPAL scenario
    • Using a COLR glyph to clip or mask another COLR glyph should be achievable regardless of CPAL presence

That leads me to think that if there is a problem we should file a separate issue for it because the problem exists regardless of whether COLR is valid without CPAL.

@rsheeter
Copy link
Contributor Author

Per VC with Peter, Cosimo:

  • 5.7.11.2.5.5 should spell out that it does NOT match COLR glyphs
  • 5.7.11.2.5.11 should say "conceptually" rendered into two bitmaps

@behdad
Copy link
Collaborator

behdad commented Jan 15, 2021

I'm still against saying color index is ignored and 0xFFFF assumed.

Here's counterproposal: keep out-of-bounds color indices illegal. Make a nullptr Paint offset mean a solid foreground paint. That saves much more.

@PeterConstable
Copy link
Collaborator

Per VC with Peter, Cosimo:

* 5.7.11.2.5.5 should spell out that it does NOT match COLR glyphs

PR #216

* 5.7.11.2.5.11 should say "conceptually" rendered into two bitmaps

Commit added to PR #214

@rsheeter
Copy link
Contributor Author

Make a nullptr Paint offset mean a solid foreground paint

Much better, made it so, thank you.

Base automatically changed from master to main March 1, 2021 21:46
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.

8 participants