hmtx transform - thinking out loud

Folks,

As I am getting my hands on the spec piece related to 'hmtx' transform, a question came up that I would like to discuss with the group.
In order to setup the discussion, here is the hmtx table structure:

typedef struct   _longHorMetric {
         USHORT   advanceWidth;
         SHORT            lsb;
}  longHorMetric;

longHorMetric [numberOfHMetrics]; /* provides aw and lsb values for all proportional glyphs in a font */
SHORT leftSideBearing [numGlyphs - numberOfHMetrics]; /* optional, provides lsb values for all monospaced glyphs in a font */

(As you can see, the second leftSideBearing array is an optional component which could have a length of zero if numGlyphs = numberOfHMetrics, otherwise it contains the lsb values for the run of monospaced glyphs that all share the same advanceWidth.)

Here is the issue I am trying to resolve - besides the transform number bitfield (two bits of flags which are supposed to be set to '01' for the hmtx table) we have only one tool in our possession to signal whether the table has or has not been transformed - the "transformLength field. However, there are three possible cases to consider:

1)    A font that has only proportional glyphs with lsb values encoded as part of longHorMetircs array (and empty leftSideBearing array);

2)    A font that has only monospaced glyphs with longHorMetric represented by a single value followed by the leftSideBearing array of lsb values;

3)    A font that has a run of proportional glyphs followed by a run of monospaced glyphs (such as e.g. a Chinese font that has proportional Latin glyphs followed by monospaced Kanji), where the longHorMetric array will include the lsb values for proportional glyphs and leftSideBearing array will provide lsb for monospaced portion.

The first two cases are easy - once we check and confirmed that lsb values in an array match the xMin for each glyph we can simply remove them from the 'hmtx' table and encode the new transformLength in woff2 table directory. However, in case 3, there may be fonts that

a)      Have lsb values matching xMin for the proportional glyphs but not for monospaced, therefore while lsb field of longHorMetric can be eliminated the leftSideBearing array must stay;

b)      Vice versa, the lsb values of the proportional glyphs don't match the xMins but the monospaced portion of the font does; therefore, we would need to keep longHorMetric[] as is but can eliminate the leftSideBearing[];

c)       Both proportional and monospaced glyph runs are well-behaved where lsb = xMin for all glyphs, and both lsb field of the longHorMetric and the leftSideBearing[] can be eliminated.

Last option 3c would be easy to implement since it's similar to "all or nothing approach" we take for cases 1) and 2). Supporting options 3a and 3b however would also be desired (especially option 3b for a large CJK font) but they require additional signaling to indicate what part of the hmtx data was eliminated and which one stayed. I am struggling to come up with the way to accommodate this additional signaling.

Any creative ideas would be greatly appreciated!

Thank you,
Vlad

Received on Friday, 4 September 2015 02:09:31 UTC