Implementing TrueType support for PostScript output
I (JeremiasMaerki) was asked to compile some pointers and hints concerning the addition of TrueType/OpenType support for PostScript output. At the moment (May 2010), we only support Type 1 fonts in PostScript output.
The PostScript renderer/painter shall learn to support Asian fonts including Chinese, Japanese and Thai fonts. (This does not necessarily mean the inclusion of non-LR-TB writing modes!)
- All the CJK Fonts that we have found from open source and commercial providers have been either TTF CID-keyed or OTF with CFF glyphs. So FOP must support both CID-keyed and OTF with CFF glyphs.
All the CJK Fonts that we have found appear to be very large, i.e. > 5 Mb, so the Postscript Renderer needs to be able to support sub-setting to keep the output size down to reasonable levels.
Gathered hints and thoughts
Implementing TrueType support for Asian fonts ultimately requires the introduction of CID-keyed fonts much like we have in PDF output. Some of the supplemental technical notes associated with the PostScript reference are going to be important here, so it's a good idea to follow the references in the PS reference.
TrueType support was introduced during the transition from PS level 2 to 3. Some late level 2 interpreters (version >= 2010) have support for Type 42 (TrueType) fonts. Of the level 3 interpreters, all do. We should limit support for TrueType to level 3 PostScript so we can reduce support issues and the complexity of having to deal with Type 42 fonts.
There are several approaches to handling TrueType fonts, like in PDF. One is to create multiple single-byte encodings like we do for Type 1 fonts (encoding-mode="single-byte" in FOP's configuration). The other is CID-keyed fonts which are a bit more complex (default mode with PDF output when using TTF fonts). All the CJK fonts that we've found appear to be CID-keyed fonts, so we need to support the extra complexity of CID-keyed.
It seems to be possible to incrementally define a TTF font in PS (keyword: GlyphDirectory). However, that could interfere with DSC-compatibility (i.e. when people want to extract single pages from a larger PS file. The Windows PS drivers I checked all performed incremental font definition and used indexes into the GlyphDirectory for glyph selection. I think that's not what we'll want. We should probably go for full font embedding and then use the GID from the TTF file to access the glyphs.
Keep in mind that full font embedding may offer the possibility to pre-install a font on the printer and just reference it in PostScript. However, I've never worked with TrueType fonts on PostScript so I can't tell how it works and if GhostScript supports this, too.
At any rate, don't miss the informative figure 5.10 on page 367 in PSLR 3rd edition and compare that with figure 5.5 on page 329 (the one for Type 1 fonts). It shows how PostScript resolved input data to actual glyphs.
I'm not sure about the implications, but page 369 says that most "show" variants cannot be used with CID fonts. That means that the way text is generated may have to be changed significantly when a CID-keyed font is used.
On the FOP side, most of the font loading code can probably be reused. PS needs more or less the same information as PDF. Hex encoders are available, too. With single-byte mode, you'll get a SingleByteFont. With Unicode mode, you'll get a MultiByteFont. In case writing CMap resources is necessary, take a look at the code in the PDF library. The CMap file format is directly used by PDF so factoring out the specifics may be possible. Other important classes on the FOP side are:
When implementing this don't forget that there are three places where TrueType-specific code may have to be implemented:
- PSTextPainter (for SVG text)
For OpenType fonts with CFF glyphs, it may actually make sense to add CFF support to our TrueType/OpenType loading code and try to use the CFF glyphs in PostScript since PS supports CFF fonts (Type 2 fonts). However, I don't know if there are any insurmountable differences between PS CFF support and CFF support of OpenType. But probably not.
An important task is probably checking the Adobe Glyph list if all the necessary Chinese glyphs have Adobe names. If not, it may get difficult to support Chinese with multiple single-byte encodings. But even if that is so (and it probably is), it may actually be worthwhile to do single-byte before the CID approach to flatten the learning curve a bit.
Finally, always keep DSC-compliance in mind. It should be possible to create a large PS spool file with FOP and the printer operator should be able to extract certain pages using a DSC tool (i.e. his spooler) for reprints without actually having to run the full PS program and suppressing the unwanted pages. To test this, the DSC parser in XML Graphics Commons can be used. XGC has a demo program (DSCProcessingExample1.java) that can extract pages.