Typophile

Font embedding

Tuom Larsen

Hello,

I'm trying to embed a OTF font into PDF 1.3. From what I understood the best way is to use Composite Type0 Fonts, i.e. CID-keyed fonts, either with TrueType or PS fonts.

My question is, may I just drop, i.e. simply not copy, certain tables from original font to the PDF while embedding? In other words, PDF specs says, one only needs "head", "hhea", "loca", "maxp", "cvt", "prep", "glyf", "hmtx", "fpgm" - if I type a text in PDF using just glyph indexes (Type0) - is the font going to work even if I drop all the other tables, including "cmap", "GLYF", "GPOS", ..? Sane for TrueType and CFF? Of course I update its checksum and Offset Table and Table Record entries accordingly.

Each font embedded inside of a PDF consists of two "parts": a font dictionary and a font program.

My understanding is — but this is just me reading the spec — that in general, PDF allows the following font dictionaries and programs (Program Key / Program Subtype / Dictionary Subtype):

  • FontFile/—/Type1: name-keyed Type 1 font, uncompressed (PDF 1.0)
  • FontFile/—/MMType1: name-keyed Multiple Master font, uncompressed (PDF 1.0)
  • FontFile2/—/TrueType: GID-keyed TrueType font (PDF 1.1)
  • FontFile3/Type1C/Type1: name-keyed Type 1-based CFF font (PDF 1.2)
  • FontFile3/Type1C/MMType1: name-keyed Multiple Master-based CFF font (PDF 1.2)
  • FontFile2/—/CIDFontType2: CID-keyed TrueType-based font (PDF 1.3)
  • FontFile3/CIDFontType0C/CIDFontType0: CID-keyed Type 1-based CFF font (PDF 1.3)
  • FontFile3/OpenType/Type1: name-keyed Type 1-based CFF font with OpenType tables (PDF 1.6)
  • FontFile3/OpenType/CIDFontType0: CID-keyed Type 1-based CFF font with OpenType tables (PDF 1.6)
  • FontFile3/OpenType/TrueType: GID-keyed TrueType font with OpenType tables (PDF 1.6)
  • FontFile3/OpenType/CIDFontType2: CID-keyed TrueType-based font with OpenType tables (PDF 1.6)

Most font types should also include /ToUnicode and /CMap structures. CIDFontType2 font should also include a /CIDToGIDMap structure. FontFile3/OpenType font types should instead include the OpenType "cmap" table.

  • Type 1 fonts are typically converted into a CFF structure, either name-keyed or CID-keyed.
  • OpenType TT (.ttf) and TrueType fonts are typically represented as a TrueType structure, either without conversion (GID-keyed) or converted into a CID-keyed form.
  • For OpenType PS (.otf) fonts, there is a substantial difference: older PDF formats (from 1.2) only allowed the embedding of the CFF structure that is part of the OpenType font, without the additional OpenType tables. PDF 1.6 allows embedding of entire OpenType PS (.otf) fonts, with the "CFF " table as well as other tables ("cmap" etc., but also "GSUB", "GPOS" etc.). This latter form can also be used to embed OpenType TT (.ttf) fonts.

So, for PDF 1.2 and above, you can embed Type 1 and OpenType PS (.otf) fonts as font dictionaries in the name-keyed CFF format or in the CID-keyed CIDFontType0 CFF format, and in addition as font programs in the FontFile3/Type1C name-keyed CFF format or in the FontFile3/CIDFontType0C CID-keyed CFF format. For PDF 1.6 and above, you can also embed the entire OpenType PS (.otf) fonts as FontFile3/OpenType programs.

Analogously, for PDF 1.2 and above, you can embed OpenType TT (.ttf) and TrueType fonts as font dictionaries in the GID-keyed TrueType form or the CID-keyed CIDFontType2 form, and in addition as form programs in the FontFile2 GID-based or CID-based TrueType-based form. For PDF 1.6 and above, you can also embed the entire OpenType TT (.ttf) fonts as FontFile2/OpenType fonts.

The choice which format to choose is basically: which minimal PDF format you want to support. The easiest thing to do would be to go with FontFile3/OpenType programs, but that only gives you support for PDF 1.6 and above, which is pretty recent. For older PDF formats (1.2 and above would be most sensible), you should deal with the whole mess of various formats available.

I would say that the most sensible thing would be to always try to use the simplest format available. For example, if the font is a non-CJK OpenType PS (.otf) for or a Type 1 font, I'd embed it as FontFile3/Type1C/Type1 (which is PDF 1.2), or perhaps as FontFile3/CIDFontType0C/CIDFontType0 (which is PDF 1.3). If the font is an OpenType TT (.ttf) or TrueType font, I'd embed it as FontFile2/—/TrueType (which is PDF 1.1) or perhaps as FontFile2/—/CIDFontType2 (which is PDF 1.3).

Sorry, I wish it all were simpler :)

Best,
Adam

Ps. Please note that all of my recommendations apply to non-CJK fonts. For CJK (Chinese/Japanese/Korean) fonts, you'll be best to always embed them as CID-based fonts, but you'll need to make sure that the appropriate standard /CMap is selected whenever possible, to avoid duplication of data.

Yet another issue I haven't mentioned is subsetting. Embedding fonts as FontFile3/OpenType/* or FontFile2/—/TrueType makes sense mostly if you're embedding entire fonts. Otherwise, especially for FontFile3/OpenType/*, subsetting is quite challenging. Again, in this case, using CID-based fonts (FontFile3/CIDFontType0C/CIDFontType0 and FontFile2/—/CIDFontType2) may be the easiest — and these are probably the two formats you should "get right" first.

Remember that between FontFile3/CIDFontType0C/CIDFontType0 and FontFile2/—/CIDFontType2 there is a *fundamental* difference: FontFile3/CIDFontType0C/CIDFontType0 basically embeds just the "CFF" portion of the font, without any other tables. On top of that, a /ToUnicode CMap is recommended.

FontFile2/—/CIDFontType2 embeds the *entire* sfnt font structure (some tables may be removed, but they also may be kept), and then you need to add a /CIDToGIDMap "Identity" structure and also a /ToUnicode CMap that basically duplicates the TrueType font's "cmap" table. At least this is how I understand it.

At least this is how I understand it :)

Hey Adam,

thanks a lot for the very detailed answer.

As I said above, I'm targeting PDF 1.3 so full OTF is unfortunately not an option.

I read the specs more-or-less in similar way, except for a few details:

/ToUnicode - is there only to support copy-and-paste of the text from PDF but is not really needed for font program to work

/CIDToGIDMap - this is especially confusing, since its requirement varies from spec version to version. The very last version says, it's optional

/CMap - the most important field for this topic - I was thinking that I could write "/Encoding/Identity-H" and "/Ordering (Identity)" basically saying that I will be setting the text not in Unicode code points but in the form of position indexes of the glyphs in font program. For example, to write "ABC" I wont write "ABC" or "\x61\x62\x63" or (whatever the notation is), but "\1\2\3\" if "a" was the first glyph in the font, "b" the second, ... In such way /CMap is not needed, as well. But I'm not sure I understood the specs well.

To rephrase my question, if I have OTF font which I want to embed in PDF 1.3, is it ok to drop all but the above mentioned tables, effectively converting OTF to, say, TTF and hence making it suitable for embedding in PDF 1.3? Do the above tables depend on other tables or not? If I use, say, just plain Latin 1, I find the glyph indexes in font's cmap, right? And everything needed for the glyphs to draw is in "glyf" table... And if I use, say, ligatures I somehow query the font and search for the indexes again, so for "fi" I will write "\73456", instead of "\66\69", am I right? So no other tables should be needed?

It all seems to me rather complicated (off-topic: *), the most simple way out, in my eyes, is to use "FontFile2/-/CIDFontType2" and "FontFile3/CIDFontType0C/CIDFontType0" but I'm not sure how to prepare a font file for embedding so it remains intact...

* is there even small chance that one day there will be widespread support for XML fonts? Or completely new, non-legacy font format?

I just saw your ps.

FontFile3/CIDFontType0C/CIDFontType0 basically embeds just the "CFF" portion of the font, without any other tables

What do you mean by this? "Required Tables" + "CFF"?
http://www.microsoft.com/typography/otspec/otff.htm#otttables

And yes, I would like to embed the whole font, rather than its subset. And no CJK so far.

Tuom,

> What do you mean by this? "Required Tables" + "CFF"?

No, the story goes like this: at the beginning, there was Type 1, and the CID-keyed Type 1-based fonts. Then Adobe invented the CFF structure to represent both these font types in a compressed font. And when OpenType was developed by Microsoft as TrueType Open, Adobe thought that the easiest way to put PostScript glyph descriptions inside of an OpenType font (i.e. an "sfnt" structure) is to put the entire CFF structure as a new table named "CFF " (with a trailing space).

So we have two basic structures:
* the CFF structure which is a compressed form of any PostScript font, and basically only lives inside of PDF files
* the sfnt structure which is used in TrueType and OpenType fonts, where the glyphs are stored as a "glyf" table (for TrueType-based fonts) and as a "CFF " table (for PostScript-based fonts). This structure can live inside of a PDF file, and then it has Adobe's PDF requirements as to which tables are necessary, or it can live as a standalone desktop font (with the .ttf or .otf file extension), and is then subject to the OpenType spec's requirements. The tables required by the PDF spec and the tables required by the OpenType spec are not the same requirements.

TrueType-based fonts: FontFile2/—/TrueType, FontFile2/—/CIDFontType2, FontFile3/OpenType/TrueType and FontFile3/OpenType/CIDFontType2 all contain the sfnt structure with a "glyf" table, and additional tables.

PostScript-based fonts: FontFile3/Type1C/Type1 and FontFile3/CIDFontType0C/CIDFontType0 only contain the "bare" CFF structure, not the sfnt structure. So there is no way to put "other tables" there, because the concept of "tables" applies to the sfnt structure. On the other hand, FontFile3/OpenType/Type1 and FontFile3/OpenType/CIDFontType0 all contain the sfnt structure with a "CFF " table, and additional tables. The "CFF " table is identical to the CFF structure, but wrapped inside of the sfnt structure which allows room for other tables.

Again: the PDF spec lists the "required" tables within that structure (separately for those with a "glyf" table and for those with the "CFF " table), but this is not the same list of tables as the tables required when the sfnt structure is a standalone desktop font with the .ttf or .otf file extension (then it is subject to OpenType spec's requirements).

As for your other questions, it's a bit beyond my expertise, but I've alerted some Adobe people to have a look at this thread, so hopefully they can tune in in the coming days.

Best,
Adam

Hm, ok, I read it four times and I think I somewhat got it. Thank you once more, and thanks for asking the people!

Btw, dear Adobe people, how to correctly compute "StemV"?

As Adam pointed out, font embedding in PDF is somewhat (or extraordinarily, depending on your point of view) complex, which is why we developed libraries to do this work.

I can make a couple of comments.

/CIDToGIDMap is useful only for CID-keyed fonts, and its purpose is to map CIDs (used by /ToUnicode) to GIDs in the embedded font.

One should never embed an entire CID-keyed font, due to size. For example, even if the user specifies that 100% of the glyphs in a font are to be embedded, the font-embedding functions of our PDF libraries will subset, including only the glyphs for the characters that are referenced in the document, then embed. This is for reasons of practicality. Name-keyed fonts, of course, will have all of their glyphs embedded if the user specifies 100%.

With regard to computing StemV, I think that it'd simply be taken from the /StdVW value of the embedded font's hint dictionary.

I assume you meant Adobe PDF Library SDK - unfortunately for me (or everyone but Adobe) it is closed source software and therefore it is not possible to look inside how things work. Please, don't get me wrong, I appreciate your reply, it's just I'm not really sure how I should process further.

I read that /StdVW is part of Type 1 only - what about TrueType? I found that W3C recommends to read "cvt " but I couldn't find anything inside that table..?

Have you explored the document entitled Font Embedding Guidelines for Adobe Third Party Developers yet?

I just have, thanks for the pointer.

Captured from web.archive.org on 9 Sep 2014. view this capture