public static GlyphDataTable Load(TrueTypeDataBytes data, TrueTypeHeaderTable table, HeaderTable headerTable, IndexToLocationTable indexToLocationTable) { data.Seek(table.Offset); var offsets = indexToLocationTable.GlyphOffsets; var entryCount = offsets.Length; var glyphCount = entryCount - 1; var glyphs = new IGlyphDescription[glyphCount]; for (var i = 0; i < glyphCount; i++) { if (offsets[i] == offsets[i + 1]) { // empty glyph continue; } data.Seek(offsets[i] + table.Offset); var contourCount = data.ReadSignedShort(); var minX = data.ReadSignedShort(); var minY = data.ReadSignedShort(); var maxX = data.ReadSignedShort(); var maxY = data.ReadSignedShort(); var bounds = new TrueTypeGlyphBounds(minX, minY, maxX, maxY); // If the number of contours is greater than or equal zero it's a simple glyph. if (contourCount >= 0) { glyphs[i] = ReadSimpleGlyph(data, contourCount, bounds); } else { } } return(new GlyphDataTable(table, glyphs)); }
public static IndexToLocationTable Load(TrueTypeDataBytes data, TrueTypeHeaderTable table, HeaderTable headerTable, BasicMaximumProfileTable maximumProfileTable) { const short shortFormat = 0; const short longFormat = 1; data.Seek(table.Offset); var format = headerTable.IndexToLocFormat; var glyphCount = maximumProfileTable.NumberOfGlyphs + 1; var offsets = new long[glyphCount]; switch (format) { case shortFormat: { // The local offset divided by 2 is stored. for (int i = 0; i < glyphCount; i++) { offsets[i] = data.ReadUnsignedShort() * 2; } break; } case longFormat: { // The actual offset is stored. data.ReadUnsignedIntArray(offsets, glyphCount); break; } default: throw new InvalidOperationException($"The format {format} was invalid for the index to location (loca) table."); } return(new IndexToLocationTable(table, offsets)); }