arrowtype/recursive

Printing issues due to running TTF fonts through a PostScript 3 printer

arrowtype opened this issue · 9 comments

Printing issues have occurred from printing static TTF fonts via printers using PostScript 3. It seems that these issues can be solved by instead printing with static OTF fonts.

This is a WIP issue meant to document the issue and potential fixes that could be made in TTF files to prevent the issue in future releases.

Possible causes (and things to test):

  1. ttautohint may cause trouble with nested components. Build without hints to see if that changes things.
  2. Nested components may be causing the issue. Try flattening nested components (probably with the flattenComponents filter in ufo2ft.

High-res, offset-printed version:

recursive_test_print-2020_10_12 2

Photos highlighting the issue:

58p

17p

61p

From https://pypi.org/project/afdko/, 2.5.64958 (released 2015-11-22), there seems to be a reference to this issue:

[tx et all.] Fix really old bug in reading TTF fonts, reported by Belleve Invis. TrueType glyphs with nested component references and x/y offsets or translation get shifted.

Further, reliable sources have informed me that some printers use tx under the hood for some operations, and that once a printer ships with PostScript (or a clone of it), that version is never updated with bug patches. So, a problem that existed pre-2015 in tx could very well be lurking in printers or print software today and for many years to come.

Finding: in almost every case of a glyph that is printed incorrectly, the thing that is misaligned is a nested component. Examples:

  • fi.mono uses i.mono, which itself is composed of dotlessi.mono and dotaccentcomb
  • Ainvertedbreve uses the invertedbrevecmb.case, which itself is composed from brevecomb.case.
  • Scarondot uses the dotaccentcomb.case and caroncomb.case, composed of the basic dotaccentcomb and circumflexcomb.case, respectively
  • colon_colon.code uses the colon, which itself is composed from two periods

Not all rendering errors are due to nested components. On the “OpenType Features” page, glyphs subbed in with stylistic sets are also misaligned in a similar way – even though they are not nested components.

  • ss01, a single-story a, subs a for a.simple (but a.simple is composed of a.italic)
  • ss02, a single-story g, subs g for g.simple (but g.simple is composed of g.italic)
  • ss03, a sans-serif f, subs f.mono for f.simple (but f.simple is composed of f)
  • ss08, a serifless Z and L, subs Z for Z.sans and L for L.sans. These alts are not components but still print badly.

Still, because I am not using stylistic sets in the specimen often, about 99% of the issues are from nested components. And therefore, I will probably still find or make a script to un-nest components and run this on TTFs.

Tested this on my home printers. An HP Laser printer failed quite badly (worse than the offset print), while a Canon InkJet worked fine.

recursive_test_print-2020_10_12 1

recursive_test_print-2020_10_12

Test 1: build without TTFautohint

It was suggested to me that TTFautohint may be getting misinterpreted by PostScript 3 (or similar code), and that I should try building the fonts without autohinting. I have done this in a branch and found that results are still bad on my home printer:

result

Test 2: unnest components in build

I will edit the build to un-nest components – hopefully this will work with the ufo2ft filter. (Actually, I now realize that I could just edit this filter in a single UFO, then quickly generate that with FontMake, before running the full build. Obvious, yet it didn’t occur to me at first.)

To be continued...

Okay! Nice, it appears that the TTF prints well if I do two things:

  1. decomposing transformed components
  2. un-nesting components

commit permalink

ttf-print-alignment-test-flattened_components--2020_12_15

These changes can be automated with ufo2ft filters, placed into a UFO’s lib.plist in this order:

<key>com.github.googlei18n.ufo2ft.filters</key>
    <array>
      <dict>
        <key>name</key>
        <string>decomposeTransformedComponents</string>
        <key>pre</key>
        <integer>1</integer>
      </dict>
      <dict>
        <key>name</key>
        <string>flattenComponents</string>
        <key>pre</key>
        <integer>1</integer>
      </dict>
    </array>

I still need to test this in the full build and in actual specimen layouts, but this seems to solve the problems. Will report additional information when I can conclude all tests.

Unexpected issue from flattening & decomposing steps: the Dcroat has been broken. Here is is in the var TTF, missing a crossbar:

image

The Dcroat is based on the Eth, which itself is the D + a drawn contour for a crossbar. This is works fine in prior versions, but seems to trip of the ufo2ft filters. I will try to add the Eth to a decomposition filter step before the other steps, I suppose.

Update 1: even if I try to add both Eth and Dcroat to the decomposeComponents ufo2ft filter, the problem persists:

1bc2f04

Update: After decomposing Eth and Dcroat in the prep_font.py script of the Recursive mastering flow, things are building correctly.

aaacb9c

  • Before I merge these changes into the main branch, I will need to visually diff the character set, to make sure there are no other unexpected changes like the Dcroat.

The static build is currently blocked on #427. Will explore this further to get things building with the updates.

See PR #428 for details, but this is now working, as far as I can test at home!

scan--ttf-print-alignment-test-flattened_components--2020_12_28

Will build a release with this update shortly.