/** * <summary>Loads the font data.</summary> */ private void Load( ) { Metrics = new FontMetrics(); // 1. Offset Table. FontData.Seek(0); // Get the outline format! this.OutlineFormat = GetOutlineFormat(FontData.ReadInt()); // Get the number of tables! int tableCount = FontData.ReadUnsignedShort(); tableOffsets = new Dictionary <string, int>(tableCount); // 2. Table Directory. // Skip to the beginning of the table directory! FontData.Skip(6); // Collecting the table offsets... for ( int index = 0; index < tableCount; index++ ) { // Get the table tag! String tag = ReadAsciiString(4); // Skip to the table offset! FontData.Skip(4); // Get the table offset! int offset = FontData.ReadInt(); // Collect the table offset! tableOffsets[tag] = offset; // Skip to the next entry! FontData.Skip(4); } FontName = Load_GetName(NameID_FontPostscriptName); Load_Tables(); Load_CMap(); Load_GlyphWidths(); Load_GlyphKerning(); }
/** * <summary>Gets whether the given data represents a valid Open Font.</summary> */ public static bool IsOpenFont( bytes::IInputStream fontData ) { long position = fontData.Position; fontData.Position = 0; try { GetOutlineFormat(fontData.ReadInt()); } catch (NotSupportedException) { return(false); } finally { fontData.Position = position; } return(true); }
/** * <summary>Gets whether the given data represents a valid Open Font.</summary> */ public static bool IsOpenFont( bytes::IInputStream fontData ) { long position = fontData.Position; try { fontData.Position = 0; GetOutlineFormat(fontData.ReadInt()); // NOTE: An exception is expected to be thrown in case of wrong file format. return(true); } catch { return(false); } finally { fontData.Position = position; } }
/** * <summary>Gets whether the given data represents a valid Open Font.</summary> */ public static bool IsOpenFont(bytes::IInputStream fontData) { long position = fontData.Position; fontData.Seek(0); try { switch (fontData.ReadInt()) { case (0x00010000): // TrueType (standard/Windows). case (0x74727565): // TrueType (legacy/Apple). case (0x4F54544F): // CFF (Type 1). return(true); default: return(false); } } finally { fontData.Seek(position); } }
/** * <summary>Loads the character to glyph index mapping table.</summary> */ private void LoadCMap( ) { /* * NOTE: A 'cmap' table may contain one or more subtables that represent multiple encodings * intended for use on different platforms (such as Mac OS and Windows). * Each subtable is identified by the two numbers, such as (3,1), that represent a combination * of a platform ID and a platform-specific encoding ID, respectively. * A symbolic font (used to display glyphs that do not use standard encodings, i.e. neither * MacRomanEncoding nor WinAnsiEncoding) program's "cmap" table should contain a (1,0) subtable. * It may also contain a (3,0) subtable; if present, this subtable should map from character * codes in the range 0xF000 to 0xF0FF by prepending the single-byte codes in the (1,0) subtable * with 0xF0 and mapping to the corresponding glyph descriptions. */ // Character To Glyph Index Mapping Table ('cmap' table). // Retrieve the location info! int tableOffset; if (!tableOffsets.TryGetValue("cmap", out tableOffset)) { throw new ParseException("'cmap' table does NOT exist."); } int cmap10Offset = 0; int cmap31Offset = 0; // Header. // Go to the number of tables! FontData.Seek(tableOffset + 2); int tableCount = FontData.ReadUnsignedShort(); // Encoding records. for ( int tableIndex = 0; tableIndex < tableCount; tableIndex++ ) { // Platform ID. int platformID = FontData.ReadUnsignedShort(); // Encoding ID. int encodingID = FontData.ReadUnsignedShort(); // Subtable offset. int offset = FontData.ReadInt(); switch (platformID) { case PlatformID_Macintosh: switch (encodingID) { case 0: // Symbolic font. cmap10Offset = offset; break; } break; case PlatformID_Microsoft: switch (encodingID) { case 0: // Symbolic font. break; case 1: // Nonsymbolic font. cmap31Offset = offset; break; } break; } } /* * NOTE: Symbolic fonts use specific (non-standard, i.e. neither Unicode nor * platform-standard) font encodings. */ if (cmap31Offset > 0) // Nonsymbolic. { Metrics.IsCustomEncoding = false; // Go to the beginning of the subtable! FontData.Seek(tableOffset + cmap31Offset); } else if (cmap10Offset > 0) // Symbolic. { Metrics.IsCustomEncoding = true; // Go to the beginning of the subtable! FontData.Seek(tableOffset + cmap10Offset); } else { throw new ParseException("CMAP table unavailable."); } int format; format = FontData.ReadUnsignedShort(); // Which cmap table format? switch (format) { case 0: // Byte encoding table. LoadCMapFormat0(); break; case 4: // Segment mapping to delta values. LoadCMapFormat4(); break; case 6: // Trimmed table mapping. LoadCMapFormat6(); break; default: throw new ParseException("Cmap table format " + format + " NOT supported."); } }