public static void ReadGlyph( DataReader reader, int glyphIndex, int recursionDepth, BaseGlyph[] glyphTable, uint glyfOffset, uint glyfLength, uint *loca ) { // check if this glyph has already been loaded; this can happen // if we're recursively loading subglyphs as part of a composite if (glyphTable[glyphIndex] != null) { return; } // prevent bad font data from causing infinite recursion if (recursionDepth > MaxRecursion) { throw new InvalidFontException("Bad font data; infinite composite recursion."); } // check if this glyph doesn't have any actual data GlyphHeader header; var offset = loca[glyphIndex]; if ((glyphIndex < glyphTable.Length - 1 && offset == loca[glyphIndex + 1]) || offset >= glyfLength) { // this is an empty glyph, so synthesize a header header = default(GlyphHeader); } else { // seek to the right spot and load the header reader.Seek(glyfOffset + loca[glyphIndex]); header = new GlyphHeader { ContourCount = reader.ReadInt16BE(), MinX = reader.ReadInt16BE(), MinY = reader.ReadInt16BE(), MaxX = reader.ReadInt16BE(), MaxY = reader.ReadInt16BE() }; if (header.ContourCount < -1 || header.ContourCount > MaxContours) { throw new InvalidFontException("Invalid number of contours for glyph."); } } if (header.ContourCount > 0) { // positive contours means a simple glyph glyphTable[glyphIndex] = ReadSimpleGlyph(reader, header.ContourCount); } else if (header.ContourCount == -1) { // -1 means composite glyph var composite = ReadCompositeGlyph(reader); var subglyphs = composite.Subglyphs; // read each subglyph recrusively for (int i = 0; i < subglyphs.Length; i++) { ReadGlyph(reader, subglyphs[i].Index, recursionDepth + 1, glyphTable, glyfOffset, glyfLength, loca); } glyphTable[glyphIndex] = composite; } else { // no data, so synthesize an empty glyph glyphTable[glyphIndex] = new SimpleGlyph { Points = new Point[0], ContourEndpoints = new int[0] }; } // save bounding box var glyph = glyphTable[glyphIndex]; glyph.MinX = header.MinX; glyph.MinY = header.MinY; glyph.MaxX = header.MaxX; glyph.MaxY = header.MaxY; }
public static void ReadGlyph( DataReader reader, int glyphIndex, int recursionDepth, BaseGlyph[] glyphTable, uint glyfOffset, uint glyfLength, uint* loca ) { // check if this glyph has already been loaded; this can happen // if we're recursively loading subglyphs as part of a composite if (glyphTable[glyphIndex] != null) return; // prevent bad font data from causing infinite recursion if (recursionDepth > MaxRecursion) throw new InvalidFontException("Bad font data; infinite composite recursion."); // check if this glyph doesn't have any actual data GlyphHeader header; var offset = loca[glyphIndex]; if ((glyphIndex < glyphTable.Length - 1 && offset == loca[glyphIndex + 1]) || offset >= glyfLength) { // this is an empty glyph, so synthesize a header header = default(GlyphHeader); } else { // seek to the right spot and load the header reader.Seek(glyfOffset + loca[glyphIndex]); header = new GlyphHeader { ContourCount = reader.ReadInt16BE(), MinX = reader.ReadInt16BE(), MinY = reader.ReadInt16BE(), MaxX = reader.ReadInt16BE(), MaxY = reader.ReadInt16BE() }; if (header.ContourCount < -1 || header.ContourCount > MaxContours) throw new InvalidFontException("Invalid number of contours for glyph."); } if (header.ContourCount > 0) { // positive contours means a simple glyph glyphTable[glyphIndex] = ReadSimpleGlyph(reader, header.ContourCount); } else if (header.ContourCount == -1) { // -1 means composite glyph var composite = ReadCompositeGlyph(reader); var subglyphs = composite.Subglyphs; // read each subglyph recrusively for (int i = 0; i < subglyphs.Length; i++) ReadGlyph(reader, subglyphs[i].Index, recursionDepth + 1, glyphTable, glyfOffset, glyfLength, loca); glyphTable[glyphIndex] = composite; } else { // no data, so synthesize an empty glyph glyphTable[glyphIndex] = new SimpleGlyph { Points = new Point[0], ContourEndpoints = new int[0] }; } // save bounding box var glyph = glyphTable[glyphIndex]; glyph.MinX = header.MinX; glyph.MinY = header.MinY; glyph.MaxX = header.MaxX; glyph.MaxY = header.MaxY; }