parsingfontstruetype

Trouble parsing TrueType font


I need to parse a TrueType font file to extract certain information, and it's going fine, I'm able to parse a lot of table types for a lot of files, except that it's having trouble with one particular file's Glyph Data table ("glyf").

I'm parsing the indexToLoc table so I know where the glyphs are in the table, and when I look at the data for that particular glyph I see this (hex values with my comments):

00 02 numContours
FF D1 Xmin=-47
00 00 YMin=0
04 5D XMax=1117
05 87 YMax=1415
00 08 endPoint=8 so the first contour has 9 points [0, 8]
00 16 endPoint=0x16 so the second contour has 14 points [9, 22]

00 2F instructionLength=47

instructions:
40 2C 04 01 00 04 01 4A 05 01 00 00 02 01 00 02 
61 00 04 04 63 4B 03 01 01 01 64 01 4C 00 00 16
15 14 12 0F 0E 0A 09 00 08 00 08 06 0A 14 2B

Reading flags for first contour (has 9 points)
01 Flag[0] = OnCurve
03 Flag[1] = OnCurve, XShort
2E Flag[2] = XShort, YShort, Repeat, YSameOrPositive
01    Repeat count = 1 so Flag[3]=XShort, YShort, (Repeat), YSameOrPositive
27 Flag[4] = OnCurve, XShort, YShort, YSameOrPositive
0E Flag[5] = XShort, YShort, Repeat
01    Repeat count = 1 so Flag[6] = XShort, YShort, (Repeat)
07 Flag[7] = OnCurve, XShort, YShort
09 Flag[8] = OnCurve, Repeat
01    Repeat count = 1 so Flag[9] = OnCurve, (Repeat)

23 22 26 27 03 21 03 0E 01 2B 01 01 33 03 78 AF 04 08 04 0A 13 08 FE A0 03 29 4D 0E 10 03 65 FD 86 CB 05 16 0D 4C 02 C2 63 02 01 02 D0 12 2B 19 19 2B 13 FD 31 FD FF 0F 0B 01 9E FE 62 0B 0F 05 87 00 00

As you can see, the first contour has 9 points so I'm expecting 9 flag values, but the 9th flag has the 'Repeat' flag set, so I end up with 10 flag values.

Do I just ignore the 'Repeat' flag when it's on the last flag? Or am I doing something else wrong with parsing these bytes?


Solution

  • The 'glyf' table spec doesn't state that the flags array is segmented by contours -- i.e., that a repeat flag can cause a flag to be repeats for points from more than one contour. There are 23 points in all, so the flags array has 23 logical elements. Read flag bytes until you have unpacked 23 logical flags. Following that, start reading the xCoordinates array.