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

Add read / write support for CFF private DICT data #759

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Commits on Sep 9, 2024

  1. cff: Correct private DICT definition

    [why]
    FamilyBlues has two Ops, probably a copy and paste leftover.
    And two Ops are missing.
    
    This is now in line with CFF and CFF2 fonts.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii authored and Connum committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    08c751e View commit details
    Browse the repository at this point in the history
  2. cff: Fix private DICT processing

    [why]
    Tests (would) fail with FDArrayTest257.otf
    
    [how]
    Some sanity checks have been ommited, add them in and process the
    structures only if there is anything.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii authored and Connum committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    aabf3b8 View commit details
    Browse the repository at this point in the history
  3. cff: Implement private DICT reading and writing for CFF and CFF2

    [why]
    The hinting of CFF (1 and 2) Open Type fonts is usually
    entirely in their private DICT data. To preserve the
    hinting - which is needed to make the font rendering look
    good and as expected - the private DICT data needs to be
    read and written.
    
    [how]
    Parts of the needed code seem to be added already in
    preparation for CFF2. I guess there was a misunderstanding
    or a mixture of versions, but the private DICT did not
    change between CFF1 and CFF2, and we need to always use
    the PRIVATE_DICT_META_CFF2, the link given in its
    definition is the same as given with link [1] for CFF1.
    See also [2]. So firstly we always refer to 'version 2',
    as the previous code did also but only in one case.
    
    The OtherBlues and FamilyOtherBlues operators must occur
    after the BlueValues and FamilyBlues operators, respectively.
    This is implicitely guaranteed by the way the private DICT is
    set up and finally Object.keys() works.
    
    For writing the delta values the encoding function is missing
    and so that is added. encode.delta() just calls encode.number()
    repeatedly, figuratively speaking.
    
    Last but not least the correct private DICT length has to be set.
    
    [1] https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
    [2] https://learn.microsoft.com/en-us/typography/opentype/otspec180/cff2#appendixD
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii authored and Connum committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    07e6e67 View commit details
    Browse the repository at this point in the history
  4. cff: Humanify user facing way "delta"s are handled

    [why]
    At the moment the delta values are not de- or encoded. The delta format
    is a packed format to have the smallest possible values in the array of
    numbers (i.e. relative to the previous number).
    But usually users do not face this but are shown absolute values; in
    all other font specific applications.
    
    For example
    BlueValues [ 500, 550 ]      // User sees the BlueZone is from 500 to 550
    Encoded as [ 500, 50 ]
    
    opentype.js at the moment does not translate these deltas in any way and
    users must know this and use the inconvenient 'packed' encoding format.
    
    [how]
    Convert the read relative delta values to absolute coordinates in the
    blueValues (and other) properties, that users can interact with.
    
    On font encoding time the absolute coordinates are converted back to
    relative ones and encoded in the font file.
    
    [note]
    https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
    
        The second and subsequent numbers in a delta are encoded as the
        difference between successive values. For example, an array a0,
        a1, ..., an would be encoded as: a0 (a1–a0) (a2–a1) ..., (an–a(n–1))
    
    This is done because small numbers can be encoded with fewer bytes and
    the total aim is to reduce the size.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    ffcfd38 View commit details
    Browse the repository at this point in the history
  5. ccf: Fix wrong type of private DICT StemSnap*

    [why]
    The StemSnapH and StemSnapV values are deltas, according to [1].
    
    Also noticed that HERE we have deltas with an odd number of values, so
    the check for even number of elements is wrong.
    
    [how]
    Change data type and remove check on read/write.
    Adapt test.
    
    [1] https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
        (CFF version 1.0, Table 23 'Private DICT Operators')
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    37a8e21 View commit details
    Browse the repository at this point in the history
  6. cff: Fix not-handling subrs

    [why]
    The code does not handle subrs, but it includes a previously existing
    subrs operator in the private DICT which throws all the offsets off.
    
    [how]
    Either include the subrs subtable and keep the subrs operator, or drop
    both. This commits just drops the operator (for simplicity).
    
    Proper subrs handling can be added later on.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    392a6b7 View commit details
    Browse the repository at this point in the history
  7. cff: test: Roundtrip check of private DICT

    [why]
    Writing of the private DICT has been added together with the translation
    of delta values from transport encoding to readable and back. But there
    is no automated test to see if something breaks.
    
    [how]
    Take one of the fonts in test/fonts/ and run in through ttx to see its
    private DICT data analyzed by someone else.
    
    Add a test that also reads that fond and checks some of the private DICT
    values.
    
    Write the font into a buffer and read it back in; repeat the check on
    the read back font. This also checks if writing is correct.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    dad7f74 View commit details
    Browse the repository at this point in the history
  8. cff: Revert to use different private DICTs for CFF and CFF2

    [why]
    While CFF has no `vsindex` operator in the private DICT it is a
    defaulted operator in CFF2. This can not be really disentangled with the
    current code and the opertor ends up erroreously written to CFF fonts
    (where it is usually ignored).
    
    [how]
    It took a bit time to understand the CFF version code (that I believe is
    not finished), but reinstate that code with different tables to be used.
    
    Sorry I messed with the code in the first place; I had overlooked the
    `vsindex` operator and how a defaulted operator in the tables turn out
    in the written files.
    
    I just reverted the version 'detection' code as it was, not checking
    anything. Note that there still is one hard-coded `2` somewhere, but
    that was already there when I started.
    
    Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
    Finii committed Sep 9, 2024
    Configuration menu
    Copy the full SHA
    332c8f2 View commit details
    Browse the repository at this point in the history