<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>I'm not surprised at this -- that seems like the right decision
      for the general case. Some sort of flag (or flags) to influence
      that might make sense for COLR 3.</p>
    <p>However, that's a separate issue from whether hinting could be
      made to work with variable compositing, where one would at least
      want the option, and more specifically whether hinting could work
      with both glyf and CFF2 if the compositing info were in a distinct
      table. I think:</p>
    <ol>
      <li>It's clear that hinting could work the same way with glyf
        whether the data were in the glyf table or separate from it, as
        long as there were flags specifics to that case.</li>
      <li>One can define analogous flags for CFF2. There does seem to be
        a viable compositing model for PostScript-style hinting.   </li>
    </ol>
    <div class="moz-cite-prefix">Skef</div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">On 8/23/23 06:47, Hin-Tak Leung wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:1360908239.413629.1692798434665@mail.yahoo.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div class="ydpf7fcda6eyahoo-style-wrap"
style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;font-size:16px;">
        <div>TL;DR.. I just like to point out that, having looked at
          google's COLR code in skia/chrome recently, I believe I have
          noticed that google folks have disabled hinting for color
          fonts in skia/chrome. I don't know of the reason (you can
          check skia/chrome commit log yourself), but this probably make
          sense for two reasons: color fonts tend to be used at much
          larger sizes, for which hinting matters less; 2nd reason, it
          is a whole lot of complication if you have to think about
          sub-pixel rendering and color fringes/artefacts from
          interaction of colour fonts with sub-pixel rendering...</div>
        <div><br>
        </div>
        <div>In other words, hinting of color fonts is either not
          needed, or too complicated to implement:-).</div>
        <div><br>
        </div>
        <div id="ydpf7fcda6eyahoo_quoted_3778027519"
          class="ydpf7fcda6eyahoo_quoted">
          <div
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;color:#26282a;">
            <div> On Tuesday, 22 August 2023 at 08:08:03 BST, Skef
              Iterum <a class="moz-txt-link-rfc2396E" href="mailto:skef@skef.org"><skef@skef.org></a> wrote: </div>
            <div><br>
            </div>
            <div><br>
            </div>
            <div>
              <div id="ydpf7fcda6eyiv2857710162">
                <div>
                  <p>Since the TypeCon meeting last week I've been
                    preoccupied with a number of questions about the
                    variable composite proposal.  I hope these are the
                    good, potentially productive kind of question rather
                    than the crabby, lets-just-not-do-this type, but
                    they aren't small. I'm wondering if things might be
                    significantly better with some significant changes.<br>
                    <br>
                    I've boiled these thoughts into two interrelated
                    multi-part questions, which I have added as issues
                    in the boring-expansion-spec GitHub repository and
                    will reproduce here. The linked issues seem like
                    good contexts for subsequent discussion.<br>
                  </p>
                  <h4>Should variable composites be in the glyf table,
                    and why? (<a
href="https://github.com/harfbuzz/boring-expansion-spec/issues/103"
                      rel="nofollow" target="_blank"
                      moz-do-not-send="true">#103</a>)<br>
                  </h4>
                  <p>I think I understand how we got to the current
                    proposal. Roughly:<br>
                  </p>
                  <ol>
                    <li>The variable composites specification extends
                      the current glyf composites mechanism.</li>
                    <li>Leaving variable composites in the glyf table
                      saves some bytes, in that the offsets can remain
                      in loca and you share the Tuple Variation Store
                      offsets with gvar.</li>
                  </ol>
                  <p>However:<br>
                  </p>
                  <ol>
                    <li>Maybe the overall variable composites system
                      shouldn't be so directly derived from the glyf
                      mechanism (see the other question).</li>
                    <li>Everything proposed would seem to apply just as
                      well to pulling outlines out of a CFF2 table.</li>
                    <li>We already have a model for how to do this in an
                      external table, that being COLR.</li>
                  </ol>
                  <p>Right now, a system that understands COLR starts by
                    looking in that table for an entry. If it finds one,
                    it pulls path data from either glyf or CFF(2). If it
                    doesn't, it falls back to glyf or CFF(2).  All of
                    this happens "below"/subsequent to shaping:<br>
                    <br>
                    (shaping) -> COLR -> (glyf | CFF(2))<br>
                    <br>
                    It seems like what "variable compositing" amounts to
                    is an additional, simplified shaping step. Call it
                    "intra-glyph shaping", which occurs here:<br>
                    <br>
                    (inter-glyph shaping) -> COLR -> (intra-glyph
                    shaping) -> (glyf | CFF2)<br>
                    <br>
                    The only reason the system doesn't already look like
                    this is that the compositing data is stored in the
                    glyf table.<br>
                  </p>
                  <p>Set aside the question of other potential changes
                    and just consider the current proposal: If one
                    wanted to have this mechanism for CFF2 also, would
                    it be substantially different? If it had to live
                    inside the CFF2 table it would be formatted
                    differently (with blends instead of a separate tuple
                    variation store, perhaps using floats instead of
                    fixed-point values of different scales, etc.) But
                    would the meaning of the parameters be any
                    different? Would other parameters be needed, or
                    redundant, in the CFF2 case?  I don't see how, or
                    why.<br>
                    <br>
                    So suppose the system worked this way instead:<br>
                  </p>
                  <ol>
                    <li>Variable composite data is in its own table,
                      call it "vcmp". It has some top-level mechanism
                      for mapping data to GIDs analogous to that of
                      COLR. The per-glyph tuple variation stores could
                      be at an offset within the data.</li>
                    <li>For the sake of argument, leave the per-glyph
                      format exactly like it is now, except for an
                      additional `hint flags` field in the component
                      record (and minus the stuff needed to play nice in
                      the glyf table, like `numberOfContours`).</li>
                    <li>Prohibit the use of the existing `glyf`
                      composite mechanism when using this separate
                      table.</li>
                    <li>Specify that when there is path data for a GID
                      in the (glyf | CFF(2)) table, and that GID also
                      has a composite entry, the path data is added with
                      no transformation to the composite data. (This was
                      asked for toward the end of the TypeCon meeting.)</li>
                    <li>Specify that when there is hinting data for a
                      GID in the (glyf | CFF(2)) table, (TrueType
                      instructions or CFF stems) and that GID also has a
                      composite entry, the relationship of the
                      additional hinting data to the component hinting
                      data is determined by the hint flags.</li>
                  </ol>
                  <p>The main thing to work out with this system would
                    be the details of the hint flags, but those problems
                    are analogous for the two path data sources.  Maybe
                    you need different flags for glyf and for CFF2 —
                    which could overlap, because one assumes mixing
                    sources is off the table — but in each case the only
                    thing to be worked out is how to reconcile the
                    hinting data. (We know this because we already have
                    COLR, so we already have implementations that grab
                    data from the bottom-level tables, alter the points
                    according to affine transformations, and render the
                    results.)</p>
                  <p>This change would have these cons:<br>
                  </p>
                  <ol>
                    <li>A modest increase in size, due redundant
                      loca/gvar/vcmp offset entries and duplication
                      across the tuple variation stores (header,
                      regions).</li>
                    <li>?</li>
                  </ol>
                  <p>And these pros:<br>
                  </p>
                  <ol>
                    <li>Assuming someone does the work of specifying the
                      hinting behavior for CFF2, the system would work
                      just as well with CFF2 and glyf. This reduces
                      pressure on glyf format changes. CFF2 already goes
                      above 64k glyphs, already supports cubics, and can
                      already losslessly represent quadratics as cubics
                      (at the cost of using floating point values in the
                      conversion, when that precision is needed).</li>
                    <li>If the composite system needs to do other
                      things, its internal structure doesn't need to be
                      so closely tied to the older glyf composite
                      mechanism.</li>
                  </ol>
                  <p>Note: Although I can't make any promises, I've
                    thought through some of what one would need to say
                    about CFF2 hinting and variable components. It does
                    seem like there could be a viable model here where
                    overall hinting quality could approach that of the
                    current system. ("Decompositing" to CFF (or CFF2)
                    would involve some hinting compromises, but that's
                    already true for CFF2 to CFF because of overlap.)</p>
                  <h4>Variable Compositing is analogous to shaping. So
                    what about substitution? (<a
href="https://github.com/harfbuzz/boring-expansion-spec/issues/104"
                      rel="nofollow" target="_blank"
                      moz-do-not-send="true">#104</a>)<br>
                  </h4>
                  <p>I noted in the other question that "variable
                    compositing" seems to amount to an additional,
                    simplified shaping step. However, as specified the
                    system only includes an analog of positioning, and
                    lacks an analog of substitution.<br>
                    <br>
                    Let's consider a specific case.<br>
                    <br>
                    Suppose that you are working in a model that has
                    three conceptual layers: atoms, molecules, and
                    glyphs. Perhaps these are exposed by a font editor.<br>
                    <br>
                    For a given molecule, the designer decides she wants
                    the outline of one atom to change within one
                    sub-region of design space, and a different atom to
                    change within a slightly different sub-region of
                    design space. The molecule is used in 25 different
                    glyphs. With the existing proposal it seems like
                    there are two options:<br>
                  </p>
                  <ol>
                    <li>Force the designer to play tricks with the
                      masters so that all versions of the atom
                      interpolate, and then position the masters in
                      design space right next to each other for quick
                      interpolations. This increases the burden on the
                      designer.</li>
                    <li>Allow the designer to specify different,
                      non-interpolable versions of an atom in different
                      subspaces of design space, and sort things out in
                      the compiled font.</li>
                  </ol>
                  <p>In our example, it seems like the only option for 2
                    with the current proposal would be to use GSUB's
                    `rvrn` or something similar. Given that the molecule
                    has four versions (for each permutation of default
                    and altered atom), you would need 100 GIDs to handle
                    the 25 glyphs. You would also need to either
                    duplicate the composite data for the other,
                    always-present atoms across the four molecules, or
                    add another "base molecule" layer into the hierarchy
                    to collect that data together to avoid duplication.<br>
                    <br>
                    Now, of course, in *some* cases you'll need to do
                    something like this anyway: mainly when swapping an
                    atom affects the metrics of the ultimate glyph. But
                    such cases seem like the exception rather than the
                    rule.<br>
                    <br>
                    So:<br>
                  </p>
                  <ol>
                    <li>Should there be some more targeted way of
                      supporting this sort of case in a variable
                      composite model?</li>
                    <li>Does this suggest that the model should draw a
                      little bit more from GSUB/GPOS and perhaps be less
                      closely tied to the older glyf model? (For
                      example, you might need distinct positioning data
                      for the different atoms that can be substituted
                      into a molecule, perhaps loosely analogous to
                      distinct contextual positioning GPOS rules that
                      could apply after a substitution.)</li>
                  </ol>
                  <p><br>
                  </p>
                </div>
              </div>
              _______________________________________________<br>
              mpeg-otspec mailing list<br>
              <a href="mailto:mpeg-otspec@lists.aau.at" rel="nofollow"
                target="_blank" moz-do-not-send="true"
                class="moz-txt-link-freetext">mpeg-otspec@lists.aau.at</a><br>
              <a
                href="https://lists.aau.at/mailman/listinfo/mpeg-otspec"
                rel="nofollow" target="_blank" moz-do-not-send="true"
                class="moz-txt-link-freetext">https://lists.aau.at/mailman/listinfo/mpeg-otspec</a><br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>