Documentation
¶
Overview ¶
Package cmap reads PDF CMaps: the code-to-CID mappings of composite fonts and the code-to-Unicode mappings of /ToUnicode streams (ISO 32000-2 §9.7.5, §9.10.3).
A CMap answers two questions, and conflating them is a common source of wrong output. First, how many bytes is the next character code — one, two, or a mixture, decided by the codespace ranges. Second, what does that code mean, which is either a CID to look a glyph up by, or the text the glyph stands for. Both mappings share one syntax, so one parser reads both.
The byte-splitting question is the one that matters most in practice. A reader that assumes two-byte codes because Identity-H is common will mis-split every mixed-width CMap, and because the result is still a sequence of plausible codes it produces confident wrong text rather than an error.
CMap syntax is PostScript, but only a fixed skeleton of it is legal here, so this package reads tokens rather than interpreting a language: the operators it recognizes are listed in the switch in parse, and everything else is skipped. The tokenizer is content's, because the token syntax is the same one.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CMap ¶
type CMap struct {
// Name is the /CMapName, when the CMap declares one.
Name string
// contains filtered or unexported fields
}
CMap maps character codes to CIDs, or to text, or both.
Both because a /ToUnicode CMap and a CID CMap are the same object with different contents, and a font may have either or both. Absent entries are reported as absent rather than as zero: CID 0 is the notdef glyph and the empty string is a legitimate mapping, so the caller must be able to tell "no answer" from "this answer".
func Identity ¶
Identity returns the Identity-H or Identity-V CMap, or false for any other name.
These two are predefined rather than embedded in the file: two-byte codes mapping to the same CID. They are handled here rather than by loading a predefined CMap file because they need no file, and because every composite font in this repo's corpus uses Identity-H.
func Parse ¶
Parse reads a CMap from a stream's decoded bytes.
Unrecognized constructs are skipped rather than rejected. A /ToUnicode stream carrying a stray PostScript procedure is common, and a parser that fails on it throws away every mapping in the file over a construct it did not need to understand.
func TwoByte ¶
TwoByte returns a CMap that reads two-byte codes and maps nothing.
This is the fallback for a composite font naming a predefined CMap this package does not carry. Every predefined CMap in ISO 32000-2 Table 118 except the deprecated ones uses two-byte codes, so splitting the string correctly is still possible even when the CIDs are not; the caller then has code widths right and can fall back to /ToUnicode for meaning. Guessing one-byte codes instead would double the glyph count and garble the text.
func (*CMap) CodeForText ¶
CodeForText returns a code that maps to the given text.
This exists for one question the font package has to ask: which code is the space, so that inter-word gaps can be measured against its width. A composite font gives no other way to find it, since a CID carries no character meaning.
The lowest matching code is returned, so the answer does not depend on map iteration order. Several codes mapping to the same text is normal — a subset font often has more than one space-like glyph — and any of them would have the right width, but a stable answer is what makes the caller's behavior reproducible.
func (*CMap) Codes ¶
Codes splits a PDF string into character codes.
The splitting follows §9.7.6.2: the codespace ranges are matched by byte width, shortest first, and a code whose leading bytes fall in no range is still consumed at the width of the shortest range that its first byte could begin. That last rule is what keeps a malformed string from desynchronizing everything after it — the alternative is to stop, which loses the rest of the text for one bad byte.
A CMap with no codespace ranges reads two-byte codes, because a CMap stream that omits them is malformed and every composite font this applies to uses two-byte codes.
type Code ¶
Code is one character code lifted out of a string, with the byte width it was written in.
The width is carried because the caller needs it: a /W array indexes by CID, but positioning and error reporting work in bytes, and a two-byte code that consumed one byte on a malformed stream must not silently shift everything after it.