I am having issue with solving these problems with regard to TTF spec.
uint8 flags[variable] Array of flags
in "glyf"I would like to know if someone could clarify these pieces.
For (1) it says this:
checkSumAdjustment To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory, sum the entire font as a uint32_t, then store 0xB1B0AFBA - sum. (The checksum for the 'head' table will be wrong as a result. That is OK; do not reset it.),
I found two checksum implementations they referenced:
// https://learn.microsoft.com/en-us/typography/opentype/spec/otff
uint32
CalcTableChecksum(uint32 *Table, uint32 Length)
{
uint32 Sum = 0L;
uint32 *Endptr = Table+((Length+3) & ~3) / sizeof(uint32);
while (Table < EndPtr)
Sum += *Table++;
return Sum;
}
uint32 CalcTableChecksum(uint32 *table, uint32 numberOfBytesInTable)
{
uint32 sum = 0;
uint32 nLongs = (numberOfBytesInTable + 3) / 4;
while (nLongs-- > 0)
sum += *table++;
return sum;
}
That is straightforward implementation. My question here is, what goes into the checksum value. So it's like this it seems:
For (2), I'm not sure how to calculate this. It seems I just bundle all the glyphs into like a spritemap and then compute the final size. But it says not to take the bounding box of the glyphs into account I think, so not exactly sure what it means.
For (3), didn't find any documentation on what those variables mean.
For (4), I don't know what this means "uint8 flags[variable] Array of flags". They have the table below, but I am not certain if it is per contour or per glyph or per point.
I also have a related question about understanding compound glyphs here if you knew anything.
In general, you might find the current OpenType specification helpful as it contains a number of updates, clarifications, and corrections that don't appear in the Apple version.
As to your specific questions:
1 head.checksumAdj
calculation
The instructions are reasonably clear, though there is an implied "step zero" of assemble all font data (tables, directory, etc.) into final form and order. Once you have that:
set the value of checkSumAdj
in the head
table to zero
calculate the checksum of just the head
table and store it in the corresponding field in the font's table directory (where tag/checksum/offset/length are stored for all tables included in the font)
calculate the sum of the entire font (sum of all uint32s, just like table checksums), including the modifications in steps 1 and 2.
store 0xB1B0AFBA minus the value from step 3 in head.checkSumAdj
. That's all! The wording about the head checksum appearing incorrect means that if you were to run the checksum calculation on the head
table after storing the final value, it would appear wrong. But that is okay, because that's how it was defined: essentially for the checksum of the head
table, you must ignore (set to 0) the checkSumAdj
value first.
2 head
xMin, xMax, yMin, yMax
This is simply the xMin, xMax, yMin, and yMax of all glyphs. Each glyph xMin, xMax, etc. is quite simply "the minimum (maximum) X (Y) coordinate" of all points (for compound glyphs, you would take that result after composing the glyph, i.e. after applying any shift, scale, or other transformations in the composite glyph definition). In both the head
table and glyph data, the bounding box is an array of 16-bit signed integers. So generally the procedure would be to loop over every glyph, get the calculated bounding box, and as you are doing this, keep track of the X/Y min/max (independently). When you are done with the loop, you'll have the values for the head
table which is essentially a rectangle that includes every coordinate of every glyph in the font.
3 maxp
values
These are reasonably well-defined in the maxp
table definition:
maxPoints
is the maximum number of points of any single non-composite ("simple") glyph
maxContours
is similarly the maximum number of contours of any single non-composite glyph
maxComponentPoints
is the maximum number of points in a composite glyph (i.e. the sum of points of all component glyphs)
maxComponentContours
is similarly the maximum number of contours in a composite glyph
maxTwilightPoints
refers to the maximum number of "twilight" points used in Zone 0 of TrueType instructions. If your font does not make use of TrueType instructions, this (and other instruction-related fields) can be set to zero. You might want to review the "Instructing TrueType Glyphs" and "TrueType Instruction Set" sections of the OpenType specification if you are not familiar with TrueType instructions (often referred to as "hints") and how they are stored in the glyph data.
4 glyf
table simple glyph flags
uint8 flags[variable]
indicates that the length of the flags array is variable. The reason for that is discussed in the specification ("Simple Glyph Flags"):
In logical terms, there is one flag byte element, one x-coordinate, and one y-coordinate for each point. Note, however, that the flag byte elements and coordinate arrays used packed representations. In particular if a logical sequence of flag elements or sequence of x- or y- coordinates is repeated, then the actual flag byte element or coordinate value can be given in a single entry, with special flags used to indicate that this value is repeated for subsequent logical entries.
In other words, the elements of the flags
array, when expanded are per-coordinate, but the actual storage as an array of uint8 is not necessarily (as with the storage of the coordinate data itself). It largely depends on the arrangement of coordinates in each glyph.