public static bool Load(FontParser parser, FontFace font, bool full) { font.RequiresLoad = !full; font.Parser = parser; // Read the magic number: uint magic = parser.ReadUInt32(); if (magic == 0x00010000) { // TTF outline format. } else if (magic == 0x774F4646) { // WOFF 1 return(WoffLoader.Load(1, parser, font)); } else if (magic == 0x774F4632) { // WOFF 2 return(WoffLoader.Load(2, parser, font)); } else { // OpenType (probably) 0x4F54544F // Reset to start: parser.Position = 0; // OpenType. Read the tag (right at the start): string openTypeVersion = parser.ReadTag(); if (openTypeVersion == "OTTO") { // CFF outline format. } else { // Unsupported format. return(false); } } // Table count: int numTables = parser.ReadUInt16(); // Move to p12: parser.Position = 12; for (int i = 0; i < numTables; i++) { // Read the tables tag (e.g. GPOS): string tag = parser.ReadTag(); // Move parser along: parser.Position += 4; // Read the offset: int offset = (int)parser.ReadUInt32(); // Grab the position - this allows the tables to mess it up: int basePosition = parser.Position; // Handle the table now: if (!parser.HandleTable(tag, offset, font)) { return(false); } // Skip meta: parser.Position = basePosition + 4; } if (full) { return(ReadTables(parser, font)); } return(true); }
public static bool Load(int version, FontParser parser, FontFace font) { // Load the V1/V2 header: ushort numTables; LoadHeader(version, parser, out numTables); if (version == 1) { MemoryStream ms = new MemoryStream(parser.Data); // Get the ZLIB compression helper: Compressor zLib = Compression.Get("zlib"); // Read each table next. for (int i = 0; i < numTables; i++) { string tag = parser.ReadTag(); uint offset = parser.ReadUInt32(); uint compLength = parser.ReadUInt32(); uint origLength = parser.ReadUInt32(); parser.ReadUInt32(); // origChecksum // Cache position: int pos = parser.Position; if (compLength != origLength) { // Decompress the table now (zlib) // Seek to table: ms.Position = (int)offset; // Decompressed data: byte[] decompressedTable = new byte[(int)origLength]; // Decompress now into our target bytes: zLib.Decompress(ms, decompressedTable); } else { // Ordinary table. parser.HandleTable(tag, (int)offset, font); } // Restore position: parser.Position = pos; } } else if (version == 2) { // Read each table entry next. The data here is compressed as one single block after the table meta. Woff2Table[] tableHeaders = new Woff2Table[numTables]; int offset = 0; for (int i = 0; i < numTables; i++) { // Read the table entry: byte flags = parser.ReadByte(); string tag; int tagFlag = (flags & 63); if (tagFlag == 63) { tag = parser.ReadTag(); } else { tag = TagLookup[tagFlag]; } ulong origLength = parser.ReadBase128(); ulong transformLength = 0; int transformVersion = (flags >> 6); //0-3 if (tag == "glyf" || tag == "loca") { // transform length: transformLength = parser.ReadBase128(); } offset += (int)origLength; tableHeaders[i] = new Woff2Table(tag, offset, (int)transformLength, transformVersion); } } // All ok: return(true); }