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):
- ttautohint may cause trouble with nested components. Build without hints to see if that changes things.
- Nested components may be causing the issue. Try flattening nested components (probably with the flattenComponents filter in ufo2ft.
High-res, offset-printed version:
Photos highlighting the issue:
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
usesi.mono
, which itself is composed ofdotlessi.mono
anddotaccentcomb
Ainvertedbreve
uses theinvertedbrevecmb.case
, which itself is composed frombrevecomb.case
.Scarondot
uses thedotaccentcomb.case
andcaroncomb.case
, composed of the basicdotaccentcomb
andcircumflexcomb.case
, respectivelycolon_colon.code
uses thecolon
, which itself is composed from twoperiod
s
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-storya
, subsa
fora.simple
(buta.simple
is composed ofa.italic
)ss02
, a single-storyg
, subsg
forg.simple
(butg.simple
is composed ofg.italic
)ss03
, a sans-seriff
, subsf.mono
forf.simple
(butf.simple
is composed off
)ss08
, a seriflessZ
andL
, subsZ
forZ.sans
andL
forL.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.
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:
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:
- decomposing transformed components
- un-nesting components
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:
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:
Update: After decomposing Eth
and Dcroat
in the prep_font.py
script of the Recursive mastering flow, things are building correctly.
- 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.