Variable fonts redux

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Variable fonts redux

Behdad Esfahbod-3
Hi,

Previously I have had implemented and merged support for named-instances in variable fonts, but the generic variation mechanism was not integrated.  I've finished the core of what was left of implementing variable fonts in fontconfig:

  https://github.com/behdad/fontconfig/commits/varfonts2

High-level changes are:

  - Add FC_FONT_VARIATIONS (string): this one is easy.  The library doesn't do anything about it.  It's like FC_FONT_FEATURES. Client sets and then retrieves. Primarily useful for non-standard variation axes,

  - Add FC_VARIABLE (bool), which is at the core of varfont support.

All font patterns that were discovered previously will get FC_VARIABLE=False When querying fonts with (the new) FcFreeTypeQueryFaceAll(), or when face index has top 16 bits (instance index) set to 0x8000, then a pattern is created for the variable font as a whole.  This pattern is only generated if there's actual variation in at least one of weight, width, and optical size axes. This pattern then might have ranges for FC_WEIGHT, FC_WIDTH, and FC_SIZE, and has FC_VARIABLE=True.

  - FC_WIDTH and FC_WEIGHT are now typed as ranges instead of double.

  - Fix matching and comparison logic with ranges to behave as we expect.

  - In FcDefaultSubstitute(), set FC_VARIABLE to false if it's unset.  FC_VARIABLE has very high match priority, so this takes care of backward compatibility with clients that do not support variable fonts by pushing them to the very back of fallback list.

  - In FcFontRenderPrepare, special-case ranges, such that if eg. request is for weight=47, and font has weight=[50,100], then rendered pattern will get weight=50.  For size, special case again, such that if request size=47 and font has size=[50,100], then rendered font will have size=47.

  - For clients that support variable font, eg. pango soon, they have to opt-in.  I could have special-cased matcher for FC_VARIABLE, such that if FC_VARIABLE=True, then both variable and non-variable fonts will be returned, but I didn't like a custom match.  Currently if FC_VARIABLE=True is set then variable fonts will dominate the results, even if they are not the best match.  To solve that:

  - To solve above problem, I added a new value for FcBool: FcDontCare=2.  Pango should set FC_VARIABLE=FcDontCare.  I was hoping to allow clients to tell fontconfig whether, everything else being equal, they prefer variable font or static font, but that needs a very low-priority element, or a hack, and I didn't like either, so I gave up on that.  It's not particularly useful anyway.

Here's what's left, which I'll do in the next few days.  I just wanted to get this out for now.

  - Config compare operations on "dontcare" are not implemented yet,

  - The variable-font pattern currently has FC_STYLE set.  I think I should completely leave out FC_STYLE,

With those fixed, I think this can be merged.  At some point I also like to:

  - Speed up scanning of varfonts that have many named instances.  Voto Serif GX has over 500!  Right now we open the face and do everything from scratch for each named instance.  Can be considerably sped up by opening once and switching coordinates around...

  - Expose slant & italic standard axes as well, but Fontconfig shoves FC_SLANT_ITALIC and FC_SLANT_OBLIQUE in the same element, with these values:

#define FC_SLANT_ROMAN              0
#define FC_SLANT_ITALIC             100
#define FC_SLANT_OBLIQUE            110

The varfonts axis for italic has a 0..1 range, 1 meaning italic.  And the slant axis uses slant angle.  We can:

  - Deprecate FC_SLANT element and add two new ones, eg FC_ITALIC and FC_SLANT_ANGLE.  I don't like this particularly,

  - Repurpose FC_SLANT for *italic*, since the 0..1 range maps nicely to FC_SLANT_ITALIC=100, and add FC_SLANT_ANGLE for the slant.  I don't particularly like to confusing names here either.  So I'm open to suggestions.

A point I'll raise before someone asks:

  - Exposing contents of STAT table or non-standard axes is out of scope for fontconfig.  The rule of thumb is: if it doesn't participate in font selection, it does not belong to fontconfig.  Things that a font dialog needs should be fetched directly using FreeType or HarfBuzz.


Cheers,
--

_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list
Reply | Threaded
Open this post in threaded view
|

Re: Variable fonts redux

Behdad Esfahbod-3
This branch is now IMO complete and ready to be merged:

    https://github.com/behdad/fontconfig/commits/varfonts2

I'll merge tomorrow if there's no comments.

Cheers,
b

On Sat, Sep 16, 2017 at 1:49 PM, Behdad Esfahbod <[hidden email]> wrote:
Hi,

Previously I have had implemented and merged support for named-instances in variable fonts, but the generic variation mechanism was not integrated.  I've finished the core of what was left of implementing variable fonts in fontconfig:

  https://github.com/behdad/fontconfig/commits/varfonts2

High-level changes are:

  - Add FC_FONT_VARIATIONS (string): this one is easy.  The library doesn't do anything about it.  It's like FC_FONT_FEATURES. Client sets and then retrieves. Primarily useful for non-standard variation axes,

  - Add FC_VARIABLE (bool), which is at the core of varfont support.

All font patterns that were discovered previously will get FC_VARIABLE=False When querying fonts with (the new) FcFreeTypeQueryFaceAll(), or when face index has top 16 bits (instance index) set to 0x8000, then a pattern is created for the variable font as a whole.  This pattern is only generated if there's actual variation in at least one of weight, width, and optical size axes. This pattern then might have ranges for FC_WEIGHT, FC_WIDTH, and FC_SIZE, and has FC_VARIABLE=True.

  - FC_WIDTH and FC_WEIGHT are now typed as ranges instead of double.

  - Fix matching and comparison logic with ranges to behave as we expect.

  - In FcDefaultSubstitute(), set FC_VARIABLE to false if it's unset.  FC_VARIABLE has very high match priority, so this takes care of backward compatibility with clients that do not support variable fonts by pushing them to the very back of fallback list.

  - In FcFontRenderPrepare, special-case ranges, such that if eg. request is for weight=47, and font has weight=[50,100], then rendered pattern will get weight=50.  For size, special case again, such that if request size=47 and font has size=[50,100], then rendered font will have size=47.

  - For clients that support variable font, eg. pango soon, they have to opt-in.  I could have special-cased matcher for FC_VARIABLE, such that if FC_VARIABLE=True, then both variable and non-variable fonts will be returned, but I didn't like a custom match.  Currently if FC_VARIABLE=True is set then variable fonts will dominate the results, even if they are not the best match.  To solve that:

  - To solve above problem, I added a new value for FcBool: FcDontCare=2.  Pango should set FC_VARIABLE=FcDontCare.  I was hoping to allow clients to tell fontconfig whether, everything else being equal, they prefer variable font or static font, but that needs a very low-priority element, or a hack, and I didn't like either, so I gave up on that.  It's not particularly useful anyway.

Here's what's left, which I'll do in the next few days.  I just wanted to get this out for now.

  - Config compare operations on "dontcare" are not implemented yet,

  - The variable-font pattern currently has FC_STYLE set.  I think I should completely leave out FC_STYLE,

With those fixed, I think this can be merged.  At some point I also like to:

  - Speed up scanning of varfonts that have many named instances.  Voto Serif GX has over 500!  Right now we open the face and do everything from scratch for each named instance.  Can be considerably sped up by opening once and switching coordinates around...

  - Expose slant & italic standard axes as well, but Fontconfig shoves FC_SLANT_ITALIC and FC_SLANT_OBLIQUE in the same element, with these values:

#define FC_SLANT_ROMAN              0
#define FC_SLANT_ITALIC             100
#define FC_SLANT_OBLIQUE            110

The varfonts axis for italic has a 0..1 range, 1 meaning italic.  And the slant axis uses slant angle.  We can:

  - Deprecate FC_SLANT element and add two new ones, eg FC_ITALIC and FC_SLANT_ANGLE.  I don't like this particularly,

  - Repurpose FC_SLANT for *italic*, since the 0..1 range maps nicely to FC_SLANT_ITALIC=100, and add FC_SLANT_ANGLE for the slant.  I don't particularly like to confusing names here either.  So I'm open to suggestions.

A point I'll raise before someone asks:

  - Exposing contents of STAT table or non-standard axes is out of scope for fontconfig.  The rule of thumb is: if it doesn't participate in font selection, it does not belong to fontconfig.  Things that a font dialog needs should be fetched directly using FreeType or HarfBuzz.


Cheers,
--



--

_______________________________________________
gtk-i18n-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-i18n-list