/// <summary> /// Reads the Offset and Directory tables. If the FontFileStream represents /// a TrueType collection, this method will look for the aforementioned /// tables belonging to <i>fontName</i>. /// </summary> /// <remarks> /// This method can handle a TrueType collection. /// </remarks> protected void ReadTableHeaders() { // Check for possible TrueType collection string tag = Encoding.ASCII.GetString(stream.ReadTag()); if (tag == TableNames.Ttcf) { // Skip Version field - will be either 1.0 or 2.0 stream.Skip(PrimitiveSizes.ULong); // Number of fonts in TrueType collection int numFonts = (int)stream.ReadULong(); bool foundFont = false; for (int i = 0; i < numFonts && !foundFont; i++) { // Offset from beginning of file to a font's subtable uint directoryOffset = stream.ReadULong(); // Set a restore point since the code below will alter the stream position stream.SetRestorePoint(); stream.Position = directoryOffset; header = new TrueTypeHeader(); header.Read(stream); // To ascertain whether this font is the one we're looking for, // we must read the 'name' table. if (!header.Contains(TableNames.Name)) { throw new Exception("Unable to parse TrueType collection - missing 'head' table."); } // If font name is not supplied, select the first font in the colleciton; // otherwise must have an exact match NameTable nameTable = (NameTable)GetTable(TableNames.Name); if (fontName == String.Empty || nameTable.FullName == fontName) { foundFont = true; } // Stream will now point to the next directory offset stream.Restore(); } // We were unable to locate font in collection if (!foundFont) { throw new Exception("Unable to locate font '" + fontName + "' in TrueType collection"); } } else { stream.Position = 0; // Read Offset and Directory tables header = new TrueTypeHeader(); header.Read(stream); } }
protected internal void Read(FontFileStream stream) { // Skip sfnt version (0x00010000 for version 1.0). stream.Skip(PrimitiveSizes.Fixed); // Number of tables int numTables = stream.ReadUShort(); // Skip searchRange, entrySelector and rangeShift entries (3 x ushort) stream.Skip(PrimitiveSizes.UShort*3); directoryEntries = new Hashtable(numTables); for (int i = 0; i < numTables; i++) { DirectoryEntry entry = new DirectoryEntry( stream.ReadTag(), // 4-byte identifier. stream.ReadULong(), // CheckSum for this table. stream.ReadULong(), // Offset from beginning of TrueType font file. stream.ReadULong() // Length of this table. ); directoryEntries.Add(entry.TableName, entry); } }
protected internal void Read(FontFileStream stream) { // Skip sfnt version (0x00010000 for version 1.0). stream.Skip(PrimitiveSizes.Fixed); // Number of tables int numTables = stream.ReadUShort(); // Skip searchRange, entrySelector and rangeShift entries (3 x ushort) stream.Skip(PrimitiveSizes.UShort * 3); directoryEntries = new Hashtable(numTables); for (int i = 0; i < numTables; i++) { DirectoryEntry entry = new DirectoryEntry( stream.ReadTag(), // 4-byte identifier. stream.ReadULong(), // CheckSum for this table. stream.ReadULong(), // Offset from beginning of TrueType font file. stream.ReadULong() // Length of this table. ); directoryEntries.Add(entry.TableName, entry); } }