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

[glyf] Variable components #42

Closed
behdad opened this issue Sep 22, 2021 · 25 comments
Closed

[glyf] Variable components #42

behdad opened this issue Sep 22, 2021 · 25 comments

Comments

@behdad
Copy link
Member

behdad commented Sep 22, 2021

To address two limitations:

To be written...

Update: The >64k part was moved to #59

@JeremieHornus
Copy link

I think we can draw a parallel between variable components and non-linear-interpolations, the first enabling the second.
Enabling two axes of a variable glyph to move together simultaneously, with 2 corner sources (or masters) as quadratic-inverse (see https://github.com/BlackFoundryCom/bezier-interpolation) results in nice bezier interpolation.
Currently the drawback is that one need to set twice the same quadratic-inverse master at each side corners of the glyph's design-space, resulting in waste of size at binary level as well as tedious workflow for designers. But an implementation could take this into account so that there is no need to store them twice.
Note that more complex non-linear interpolations (with 2 intermediate steps istead of only one for quadratic-inverse) can be obtained with 3 cubic-inverse sources and 3 axes.

AtomicElement.mp4

@behdad
Copy link
Member Author

behdad commented Feb 11, 2022

  • Access glyph indices >64k,

Suggesting that we use numberOfContours of -2 to mean compositeGlyphs similar to existing compositeGlyphs just with 24bit gid storage instead of 16bit; otherwise same storage format.

@Lorp
Copy link
Collaborator

Lorp commented Feb 14, 2022

The spec says any negative value indicates a composite. I’ve only ever seen -1 in fonts I’ve looked at, but it would be good to do a survey, if anyone has a million fonts, @twardoch?

@behdad
Copy link
Member Author

behdad commented Feb 14, 2022

The spec says any negative value indicates a composite.

Well, it says: "

If the number of contours is greater than or equal to zero, this is a simple glyph. If negative, this is a composite glyph — the value -1 should be used for composite glyphs.
"

@Lorp
Copy link
Collaborator

Lorp commented Feb 14, 2022

In the Version 1.9 currently on microsoft.com it states:

If numberOfContours is negative, a composite glyph description is used.
Note: A numberOfContours value of -1 is recommended to indicate a composite glyph.

... which is weaker than “-1 should be used”.

@behdad
Copy link
Member Author

behdad commented Feb 14, 2022

In the Version 1.9 currently on microsoft.com it states:

I quoted from other part of the same page :)).

@Lorp
Copy link
Collaborator

Lorp commented Feb 14, 2022

How about we regard numberOfContours as a bit field (with bit 15 always set, and with all bits set by default), to allow various future glyph encodings or features? To flag 24-bit glyphIds we can unset bit 0, resulting in a value of, er, -2.

@Lorp
Copy link
Collaborator

Lorp commented Feb 14, 2022

Thanks for this nice video, @JeremieHornus.

I assume that any axes used in components are to be “locked” in terms of the user adjusting axes. So in this example, the axes straight, bending*1, bending*2, pinch*1 and pinch*2 would be locked in position by the component mechanism (and be hidden from the UI), while weight would work as normal. Is that correct?

@BlackFoundry
Copy link

Yes that's correct, these 'coupled' axes would be hidden from the font user's view, only used when actually instatiating the variable components into another glyph. But even the 'weight' axis could be a local one only used at the glyph level (as opposed to the 'wght' axis of the font).

@Lorp
Copy link
Collaborator

Lorp commented Feb 14, 2022

How does a rasterizer distinguish the two types of axis? (Let’s forget about HOI for a moment.) A flag in fvar?

@behdad
Copy link
Member Author

behdad commented Feb 15, 2022

A flag in fvar?

There's already a "private" flag in fvar.

@BlackFoundry
Copy link

BlackFoundry commented Feb 15, 2022

yeah that's likely enough to set these local axes "private".
With @justvanrossum we made a "VarC" table optimizing the number of required private axes "recycling" them when needed: https://github.com/BlackFoundryCom/rcjk-tools and https://github.com/BlackFoundryCom/variable-components-spec but this kind of data could well be stored in a "glyf" v2.0 table for example…

@Lorp
Copy link
Collaborator

Lorp commented Feb 16, 2022

The existing HIDDEN_AXIS flag is not sufficient, is it?

I’m assuming these component variation deltas are stored using normal encoding in the gvar table, along with the normal deltas for the user-facing axes. The variation engine needs to know that these axes are never to be adjusted on a font-wide level (whether by a human or a machine), because that would lead to a conflict between the font’s designspace location and the component’s designspace location within a composite glyph. Therefore I believe we require a new flag for these axes that declares any axis settings at the font level must be ignored.

EDIT: I see that @justvanrossum @behdad @rsheeter discussed this here, with @justvanrossum proposing the component’s axis setting simply overrides a global axis setting and some discussion about whether “offsetting” should be allowed (I presume this means that conflicting global and component deltas would be summed).

@behdad
Copy link
Member Author

behdad commented Feb 18, 2022

The existing HIDDEN_AXIS flag is not sufficient, is it?

I’m assuming these component variation deltas are stored using normal encoding in the gvar table, along with the normal deltas for the user-facing axes. The variation engine needs to know that these axes are never to be adjusted on a font-wide level (whether by a human or a machine), because that would lead to a conflict between the font’s designspace location and the component’s designspace location within a composite glyph. Therefore I believe we require a new flag for these axes that declares any axis settings at the font level must be ignored.

EDIT: I see that @justvanrossum @behdad @rsheeter discussed this here, with @justvanrossum proposing the component’s axis setting simply overrides a global axis setting and some discussion about whether “offsetting” should be allowed (I presume this means that conflicting global and component deltas would be summed).

As per your edit, I don't see the extra need. The component simply overrides the value. It's up to the designer / tooling to ensure that this makes sense. In other words, an old engineering rule holds: Garbage In, Garbage Out.

@Lorp
Copy link
Collaborator

Lorp commented Feb 19, 2022

Consensus is override or sum?

(I tentatively vote sum, just in case it’s useful. But others have been working with real fonts, so I defer to them.)

@behdad
Copy link
Member Author

behdad commented Feb 19, 2022

How about we regard numberOfContours as a bit field (with bit 15 always set, and with all bits set by default), to allow various future glyph encodings or features? To flag 24-bit glyphIds we can unset bit 0, resulting in a value of, er, -2.

Forget about numberOfContours for now. componentFlags already has 4 bits available. I'm going to use (0x2000) to mean "glyphID is 24bit" for now.

@rsheeter
Copy link
Contributor

Consensus is override or sum?

I'm not aware of data to support picking one or the other yet?

behdad added a commit to fonttools/fonttools that referenced this issue Jul 3, 2022
behdad added a commit to fonttools/fonttools that referenced this issue Jul 5, 2022
behdad added a commit to fonttools/fonttools that referenced this issue Jul 8, 2022
behdad added a commit to fonttools/fonttools that referenced this issue Jul 8, 2022
behdad added a commit to harfbuzz/harfbuzz that referenced this issue Jul 12, 2022
behdad added a commit to harfbuzz/harfbuzz that referenced this issue Jul 12, 2022
behdad added a commit to harfbuzz/harfbuzz that referenced this issue Jul 12, 2022
@behdad behdad added the Implemented Implemented in HarfBuzz or doesn't need to label Jul 12, 2022
@behdad
Copy link
Member Author

behdad commented Jul 12, 2022

How about we regard numberOfContours as a bit field (with bit 15 always set, and with all bits set by default), to allow various future glyph encodings or features? To flag 24-bit glyphIds we can unset bit 0, resulting in a value of, er, -2.

Forget about numberOfContours for now. componentFlags already has 4 bits available. I'm going to use (0x2000) to mean "glyphID is 24bit" for now.

I split off the >64k glyph access into #59

@behdad behdad removed >64k expansion Implemented Implemented in HarfBuzz or doesn't need to labels Jul 12, 2022
@behdad behdad changed the title [glyf] Composite glyphs 2.0 [glyf] Variable components Jul 12, 2022
behdad added a commit to harfbuzz/harfbuzz that referenced this issue Jul 12, 2022
behdad added a commit to fonttools/fonttools that referenced this issue Jul 12, 2022
behdad added a commit to fonttools/fonttools that referenced this issue Jul 12, 2022
@behdad
Copy link
Member Author

behdad commented Aug 22, 2022

This is my current thinking:

There will be a new table that holds an ItemVariationStore and possibly an "adjustment list". Then each composite in the glyph table can refer to an adjustment in the adjustment list when invoking a component glyph.

An adjustment in the adjustment list will list a number of axes and variation-store indices for the adjustments to be made to that axis before rendering the glyph invoked.

@behdad
Copy link
Member Author

behdad commented Aug 22, 2022

The adjustment-list can use a DeltaSetIndexMap structure, then components need to encode a start offset and number of entries.

@justvanrossum
Copy link
Collaborator

Our current Variable Component system also requires a fully variable transformation, in function close to the COLRv1 transform/scale/rotate/etc Paints.

@behdad
Copy link
Member Author

behdad commented Aug 22, 2022

Our current Variable Component system also requires a fully variable transformation, in function close to the COLRv1 transform/scale/rotate/etc Paints.

Ah, right. Then I think a new composite glyph format is needed.

@behdad
Copy link
Member Author

behdad commented Aug 22, 2022

Okay, then something similar to:
https://github.com/BlackFoundryCom/variable-components-spec

but without the VarStore, and embedded in glyf table as a new glyph composite type with numberOfContours=-2.

@justvanrossum
Copy link
Collaborator

I'm working on a proposal to store Variable Component data in UFO: https://github.com/BlackFoundryCom/variable-components-in-ufo. I will soon make some test/demo fonts, and will implement it as part of Fontra.

I would like this to be in line with what we expect Variable Components to be able to do in OpenType, so we can use this as a source format.

@behdad behdad removed the WIP label Feb 7, 2023
@behdad
Copy link
Member Author

behdad commented Feb 7, 2023

@behdad behdad closed this as completed Feb 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants