public static CharacterMap ReadCmap(DataReader reader, TableRecord[] tables) { SfntTables.SeekToTable(reader, tables, FourCC.Cmap, required: true); // skip version var cmapOffset = reader.Position; reader.Skip(sizeof(short)); // read all of the subtable headers var subtableCount = reader.ReadUInt16BE(); var subtableHeaders = new CmapSubtableHeader[subtableCount]; for (int i = 0; i < subtableHeaders.Length; i++) { subtableHeaders[i] = new CmapSubtableHeader { PlatformID = reader.ReadUInt16BE(), EncodingID = reader.ReadUInt16BE(), Offset = reader.ReadUInt32BE() }; } // search for a "full" Unicode table first var chosenSubtableOffset = 0u; for (int i = 0; i < subtableHeaders.Length; i++) { var platform = subtableHeaders[i].PlatformID; var encoding = subtableHeaders[i].EncodingID; if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeFull) || (platform == PlatformID.Unicode && encoding == UnicodeEncoding.Unicode32)) { chosenSubtableOffset = subtableHeaders[i].Offset; break; } } // if no full unicode table, just grab the first // one that supports any flavor of Unicode if (chosenSubtableOffset == 0) { for (int i = 0; i < subtableHeaders.Length; i++) { var platform = subtableHeaders[i].PlatformID; var encoding = subtableHeaders[i].EncodingID; if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeBmp) || platform == PlatformID.Unicode) { chosenSubtableOffset = subtableHeaders[i].Offset; break; } } } // no unicode support at all is an error if (chosenSubtableOffset == 0) { throw new Exception("Font does not support Unicode."); } // jump to our chosen table and find out what format it's in reader.Seek(cmapOffset + chosenSubtableOffset); var format = reader.ReadUInt16BE(); switch (format) { case 4: return(ReadCmapFormat4(reader)); default: throw new Exception("Unsupported cmap format."); } }
public static CharacterMap ReadCmap(DataReader reader, TableRecord[] tables) { SfntTables.SeekToTable(reader, tables, FourCC.Cmap, required: true); // skip version var cmapOffset = reader.Position; reader.Skip(sizeof(short)); // read all of the subtable headers var subtableCount = reader.ReadUInt16BE(); var subtableHeaders = new CmapSubtableHeader[subtableCount]; for (int i = 0; i < subtableHeaders.Length; i++) { subtableHeaders[i] = new CmapSubtableHeader { PlatformID = reader.ReadUInt16BE(), EncodingID = reader.ReadUInt16BE(), Offset = reader.ReadUInt32BE() }; } // search for a "full" Unicode table first var chosenSubtableOffset = 0u; for (int i = 0; i < subtableHeaders.Length; i++) { var platform = subtableHeaders[i].PlatformID; var encoding = subtableHeaders[i].EncodingID; if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeFull) || (platform == PlatformID.Unicode && encoding == UnicodeEncoding.Unicode32)) { chosenSubtableOffset = subtableHeaders[i].Offset; break; } } // if no full unicode table, just grab the first // one that supports any flavor of Unicode if (chosenSubtableOffset == 0) { for (int i = 0; i < subtableHeaders.Length; i++) { var platform = subtableHeaders[i].PlatformID; var encoding = subtableHeaders[i].EncodingID; if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeBmp) || platform == PlatformID.Unicode) { chosenSubtableOffset = subtableHeaders[i].Offset; break; } } } // no unicode support at all is an error if (chosenSubtableOffset == 0) throw new Exception("Font does not support Unicode."); // jump to our chosen table and find out what format it's in reader.Seek(cmapOffset + chosenSubtableOffset); var format = reader.ReadUInt16BE(); switch (format) { case 4: return ReadCmapFormat4(reader); default: throw new Exception("Unsupported cmap format."); } }