OpenType 1.9 public beta review

A beta for OpenType 1.9 has been published for two-week public review. This version introduces a significant enhancement in OpenType: a second version of the COLR table (version 1) for color fonts. The new COLR version provide support for gradients and other capabilities in vector colour fonts; the capabilities are very similar to those in SVG Native but can be used in applications that do not have or (for whatever reasons) cannot add support SVG. The new COLR version also provides greater integration with font variations—something that is not supported at all with OT-SVG.

The COLR enhancements were designed jointly with Google, who have been implementing support in the FontTools project, the Skia and Freetype libraries, and in Chrome. It can be tested already in the Chrome Canary builds by browsing to chrome://flags/#colr-v1-fonts to enable the feature. Sample fonts using COLR v1 (with OT-SVG equivalents for comparison) are available at https://github.com/googlefonts/color-fonts

OpenType 1.9 also addresses a number of feedback items that have been reported on the OpenType spec. Among the more significant technical improvements are clarifications of several items related to TrueType outlines and the TrueType hinting language.

The landing page for the beta is at https://docs.microsoft.com/typography/opentype/otspec190/ot190beta. The public review period will end November 26, and the new version will be published shortly after that.

Particular thanks are due to Behdad Esfahbod, Dominik Röttsches, Rod Sheeter, Cosimo Lupo and Dave Crossland for their contribution to and support of the work on COLR v1; to Greg Hitchcock for several contributions including many details regarding TrueType; and to John Hudson, Laurence Penney, any many others who reported issues or contributed valuable input that went into this version.

Comments

  • Grzegorz Luk (gluk)
    Grzegorz Luk (gluk) Posts: 161
    edited November 2021
    Good news!
    It's look COLR format wants to be the winner of "color font formats war" :)
    Is constantly compared with OT-SVG, so I will add what he will miss from my point of view:
    OT-SVG can use open contours and the "stroke" property which allows you to create true single-line fonts (for engraving or CAD as example purposes)
  • Thanks for providing the delta pages - they're very helpful. I can't help wondering, though, if GitHub already has some built-in way of displaying changes to source code files made in response to GitHub issues...
  • Two others I should have called out in acknowledgement:
    • Simon Cozens, with careful attention to detail, reported several issues that are fixed in this update, including clarification of flags in the 'glyf' table.
    • Just van Rossum provided helpful suggestions for representation of transforms in COLR v1 that provide size savings.
  • ...
    Is constantly compared with OT-SVG, so I will add what he will miss from my point of view:
    OT-SVG can use open contours and the "stroke" property which allows you to create true single-line fonts (for engraving or CAD as example purposes)
    I know you've made several OT-SVG fonts. Can you point to examples that use open contours and/or strokes?

    I'd find it interesting if you (someone) were to try to convert some of your OT-SVG fonts to COLR v1 format, both to see how they compare (e.g., COLR v1 ought to provide size savings), but also to see what SVG capabilities were used that aren't supported (yet) in COLR. I'm pretty sure there are several that could be implemented using COLR v1 formats (Big Party, Broshk-Lime, DigitaltS-Fruits...), and some even COLR v0 (e.g., UseYourImagination—I particularly like that one). Some might be a challenge (not clear what SVG caps were used for Digico-Beryl), and quite interesting to attempt (Digiac—a variation axis might be used for animation).
  • Grzegorz Luk (gluk)
    Grzegorz Luk (gluk) Posts: 161
    edited November 2021
    [...] Can you point to examples that use open contours and/or strokes?

    as example: ResamitzSL
    OpenTypeSVG font with open single lines and SVG stroke property


    [...]  I'd find it interesting if you (someone) were to try to convert some of your OT-SVG fonts to COLR v1 format, [...]
    your post aroused my great interest in the COLR/CPAL format, I am already thinking about adapting my generator to this format
  • I might be fighting a lonely fight here but interpreting the wdth axis as a percentage of whatever the font designer considers “normal width” for that font design, as the spec suggests, makes no sense whatsoever and should be removed.

    It does not lead to an intuitive experience for the user who will be confused as to why the very condensed style is at wdth 37 or 43 or something like that, and the very extended at wdth 172 or wherever it lands in percentage of the normal width.

    In the case of a very large family of widths like our GT Flexa, we went with the following setup:
    (wdth axis value — subfamily name)
    0 — X Compressed
    50 — Compressed
    75 — Condensed
    100 — Standard
    125 — Extended
    150 — Expanded
    200 — X Expanded

    This also roughly reflects how the design changes across the wdth axis, thus leading to good and fluid-feeling animations between the widths, while still offering a system that can be understood by the user.
  • John Hudson
    John Hudson Posts: 3,126
    Thierry, to help better understand what you did for GT Flexa, can you add a column to your list of widths indicating what the percentage of Standard width each of the others are? I am trying to understand how your widths are related to the standard wdth axis definition.
  • I think Thierry might be missing the fact that this is not specific to the width axis and variable fonts: the usWidthClass field, with the same definitions, has been in the os/2 table of OpenType since the 1990s. However, certainly variable fonts have made it much more important.

    I am taking it that Thierry is suggesting that each typeface can use its own definition for how condensed is “condensed” and so on. Basically, this is the old status quo of every font family having its own definitions of what labels mean.

    I think fundamentally, there are two options for how any system can be designed, and they have different advantages.

    Thierry’s approach means that fonts can each map width variation to the axis values in different ways, but the labels and values for the standard instances are the same.

    The spec approach means that the values used by fonts are potentially much more compatible across fonts. Set two different fonts at 80 width and you will get roughly the same amount of condensed-ness relative to the regular. Also true if you have width set to 80 and change fonts.

    Unlike Thierry, I see a great deal of value in this, and I am not immediately seeing value in their proposal. But then I have been using the existing system for some years now.
  • Having the width axis be a percentage of the average glyph width also helps with text justification, where a line may need to be 2% wider or narrower to fit the text block. If every font uses a custom range for the width axis, such a system would need to sample the font at different variation coordinates to figure out how to make a line roughly 2% (or any other percentage) wieder or narrower. The width not animating smoothly is an issue that can be addressed on the application layer, not the font layer.
  • John Hudson
    John Hudson Posts: 3,126
    The spec approach means that the values used by fonts are potentially much more compatible across fonts.

    With ‘potentially’ and ‘more’ being key words in that sentence. 

    Set two different fonts at 80 width and you will get roughly the same amount of condensed-ness relative to the regular.
    And ‘relative to the regular’ being the key phrase in that one.

    There remains nothing that defines the relationship of the width of the two regular designs, and hence no possibility of real compatibility in terms of something useful like set width.
  • Paul van der Laan
    Paul van der Laan Posts: 242
    edited November 2021
    Having the width axis be a percentage of the average glyph width also helps with text justification, where a line may need to be 2% wider or narrower to fit the text block. If every font uses a custom range for the width axis, such a system would need to sample the font at different variation coordinates to figure out how to make a line roughly 2% (or any other percentage) wieder or narrower. The width not animating smoothly is an issue that can be addressed on the application layer, not the font layer.
    I'm not sure that you can expect a line of text to be 2% wider when setting the wdth axis to 102. There is a fundamental difference between how much a line of text scales to at a given point on the wdth axis, and when scaling that line horizontally by a certain percentage.

    The wdth axis says something about the width of the shapes themselves but nothing about the metrics of those shapes. In fact – extended styles are usually spaced tighter than normal styles because they're more tailored to headline usage.
  • The width axis coordinates do not need to precisely match the line width, just be close enough. Fine tuning can be archived either by using a binary search algorithm to get from close to perfect or to use width expansion first on all glyphs and fine tune by compressing or expanding spaces. Related: Micro-typographic extensions to the TEX typesetting system by Hàn Thế Thành describes using Multiple Master fonts for justification in section 6.3.3.
  • As Florian says, having wdth be percentage of "normal" is potentially useful for algorithms fitting text, such as justification. There's no assumption that a line of text set with wdth = 102 will be 2% wider than if set with wdth = 100. But it's a heuristic that an algorithm could use for starting and incremental adjustments. Otherwise, an algorithm could assume nothing and would have to start with an extreme adjustment (e.g., go to min to see if it will even be possible to reach the target) and do binary search from there.

    There was no way to define a scale for wdth that allowed for certain comparison between unrelated fonts _and_ also integrate with the "Width" axis that was already widely used in implementations (GDI, CSS, ...).

    Btw, the wdth axis is not something that has been touched for OT 1.9, so is not in scope for the OT 1.9 beta feedback.
  • Grzegorz Luk (gluk)
    Grzegorz Luk (gluk) Posts: 161
    edited November 2021

    [...] The new COLR version provide support for gradients and other capabilities in vector colour fonts; the capabilities are very similar to those in SVG [...]

    I made my first attempts to convert my SVG-OT fonts to COLRv1 and I am wondering why COLRv1 defines linear Gradients with three points p0,p1,p2

    each linear gradient can be defined by only 2 points (like in SVG) so

    At least p2 should be optional. This would reduce the file size and make conversion from SVG easier.
    Explanation from spec:
    "...that provides greater flexibility in controlling the placement and rotation of the gradient ..."
    explains little and does not convince.
  • This went through a few Design iterations, many months ago. Just van Rossum raised the same question and came away satisfied with the design. See https://github.com/googlefonts/colr-gradients-spec/issues/278
  • @Grzegorz Luk (gluk) Btw, I’d recommend using the nanoemoji compiler directly on the SVG docs: there’s been a bunch of work done already to optimize.

    https://github.com/googlefonts/nanoemoji

  • Thierry Blancpain
    Thierry Blancpain Posts: 209
    edited November 2021
    I’m sorry @Peter Constable—I’ve never been a part of standards processes and did not mean to touch on a subject that isn’t even up for discussion. As I’ve already started it, though:
    Thierry, to help better understand what you did for GT Flexa, can you add a column to your list of widths indicating what the percentage of Standard width each of the others are? I am trying to understand how your widths are related to the standard wdth axis definition.
    Measured across a pangram of English alphabet letters, the figures are as follows:

    (Axis value — Subfamily name — Average pangram width compared to average pangram width of Standard Regular style)

    0 — X Compressed — 38.8%
    50 — Compressed — 74.0%
    75 — Condensed — 87.6%
    100 — Standard — 100%
    125 — Extended — 122%
    150 — Expanded — 143.9%
    200 — X Expanded — 188.6%

    One big problem I have with the explanations given above is that they all break apart across different weights. Between the Regular and the Black weight of GT Flexa, there’s up to 19.2% variation in width difference: the X Compressed Black is 58.0% of the Standard Black, but only there’s only a 38.8% difference in the Regular weights. In X Expanded, the variation is still a noticeable 4.7% from the Regular to the Black weight.

    Additionally, even the supposedly normative Standard’s width of course varies quite a lot. If Standard Regular’s width is 100%, Standard Black is 109.5%.

    You really can’t really use this metric to pick the right styles across large families anyway, or the solve justification across the whole range of a large design space. The variation within such families is huge, and will be huge across families as well.

    Meanwhile, humans can obviously work much better with a system of clean, round numbers that follow a type design-driven logic instead of a math-driven logic. Developers who have to pick the Extended Regular weight can use 
    font-variation-settings: "wght" 400, "wdth" 125, "ital" 0; 

    in GT Flexa’s system. In the supposed spec version, this would be 

    font-variation-settings: "wght" 400, "wdth" 122, "ital" 0; 

    Sure, that works okay. But then you want the Expanded instead and it turns into

    font-variation-settings: "wght" 400, "wdth" 150, "ital" 0; 

    vs

    font-variation-settings: "wght" 400, "wdth" 143.9, "ital" 0; 

    I’m not saying GT Flexa’s systems is without flaws, and of course there’s downsides to a less machine-driven approach. 

    But we offer large families as a foundry, and I also develop websites with those large families myself, I can certainly speak to the user-unfriendliness of the spec system. Speaking of in-app usage, trying to select 75% in a slider UI instead of 87.6% is also clearly easier.

  • There's no question that the wdth axis is imperfect, as are software implementations related to it for the past 30 years.

    You really should not use 0 as a wdth value. The OT spec is clear about that:

    "Valid numeric range: Values must be strictly greater than zero."

    Fonts with OS2.usWidthClass set to 0 or with a wdth variable axis using 0 as a minimum are non-conformant, will break inter-operability, potentially mess up some layout algorithms, and make wdth even more imperfect than it already is. Font vendors really shouldn't do that.

    If you want a very small value, use 1, but not 0.