/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { int version = data.ReadUnsignedShort(); if (version != 0) { version = (version << 16) | data.ReadUnsignedShort(); } int numSubtables = 0; if (version == 0) { numSubtables = data.ReadUnsignedShort(); } else if (version == 1) { numSubtables = (int)data.ReadUnsignedInt(); } else { Debug.WriteLine($"debug: Skipped kerning table due to an unsupported kerning table version: {version}"); } if (numSubtables > 0) { subtables = new KerningSubtable[numSubtables]; for (int i = 0; i < numSubtables; ++i) { KerningSubtable subtable = new KerningSubtable(); subtable.Read(data, version); subtables[i] = subtable; } } initialized = true; }
/** * Creates a new TrueTypeCollection from a .ttc file. * * @param file The TTC file. * @ If the font could not be parsed. */ public TrueTypeCollection(FileInfo file) { using (var stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { this.stream = new MemoryTTFDataStream(stream); } Initialize(); }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @throws java.io.IOException If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { byte[] bytes = data.Read((int)Length); CFFParser parser = new CFFParser(); cffFont = parser.Parse(bytes, new CFFBytesource(font))[0]; initialized = true; }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { loca = ttf.IndexToLocation; numGlyphs = ttf.NumberOfGlyphs; glyphs = new Dictionary <int, GlyphData>(); // we don't actually read the complete table here because it can contain tens of thousands of glyphs this.data = data; initialized = true; }
/** * This will read the required data from the stream. * * @param data The stream to read the data from. * @param version The version of the table to be read * @ If there is an error reading the data. */ public void Read(TTFDataStream data, int version) { if (version == 0) { ReadSubtable0(data); } else if (version == 1) { ReadSubtable1(data); } else { throw new InvalidOperationException(); } }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { version = data.Read32Fixed(); defaultVertOriginY = data.ReadSignedShort(); int numVertOriginYMetrics = data.ReadUnsignedShort(); origins = new Dictionary <int, int>(numVertOriginYMetrics); for (int i = 0; i < numVertOriginYMetrics; ++i) { int g = data.ReadUnsignedShort(); int y = data.ReadSignedShort(); origins[g] = y; } initialized = true; }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { HorizontalHeaderTable hHeader = ttf.HorizontalHeader; if (hHeader == null) { throw new IOException("Could not get hhea table"); } numHMetrics = hHeader.NumberOfHMetrics; int numGlyphs = ttf.NumberOfGlyphs; int bytesRead = 0; advanceWidth = new int[numHMetrics]; leftSideBearing = new short[numHMetrics]; for (int i = 0; i < numHMetrics; i++) { advanceWidth[i] = data.ReadUnsignedShort(); leftSideBearing[i] = data.ReadSignedShort(); bytesRead += 4; } int numberNonHorizontal = numGlyphs - numHMetrics; // handle bad fonts with too many hmetrics if (numberNonHorizontal < 0) { numberNonHorizontal = numGlyphs; } // make sure that table is never null and correct size, even with bad fonts that have no // "leftSideBearing" table although they should nonHorizontalLeftSideBearing = new short[numberNonHorizontal]; if (bytesRead < Length) { for (int i = 0; i < numberNonHorizontal; i++) { if (bytesRead < Length) { nonHorizontalLeftSideBearing[i] = data.ReadSignedShort(); bytesRead += 2; } } } initialized = true; }
private void ReadSubtable0(TTFDataStream data) { int version = data.ReadUnsignedShort(); if (version != 0) { Debug.WriteLine("info: Unsupported kerning sub-table version: " + version); return; } int length = data.ReadUnsignedShort(); if (length < 6) { throw new IOException("Kerning sub-table too short, got " + length + " bytes, expect 6 or more."); } int coverage = data.ReadUnsignedShort(); if (IsBitsSet(coverage, COVERAGE_HORIZONTAL, COVERAGE_HORIZONTAL_SHIFT)) { this.horizontal = true; } if (IsBitsSet(coverage, COVERAGE_MINIMUMS, COVERAGE_MINIMUMS_SHIFT)) { this.minimums = true; } if (IsBitsSet(coverage, COVERAGE_CROSS_STREAM, COVERAGE_CROSS_STREAM_SHIFT)) { this.crossStream = true; } int format = GetBits(coverage, COVERAGE_FORMAT, COVERAGE_FORMAT_SHIFT); if (format == 0) { ReadSubtable0Format0(data); } else if (format == 2) { ReadSubtable0Format2(data); } else { Debug.WriteLine("debug: Skipped kerning subtable due to an unsupported kerning subtable version: " + format); } }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { VerticalHeaderTable vHeader = ttf.VerticalHeader; if (vHeader == null) { throw new IOException("Could not get vhea table"); } numVMetrics = vHeader.NumberOfVMetrics; int numGlyphs = ttf.NumberOfGlyphs; int bytesRead = 0; advanceHeight = new int[numVMetrics]; topSideBearing = new short[numVMetrics]; for (int i = 0; i < numVMetrics; i++) { advanceHeight[i] = data.ReadUnsignedShort(); topSideBearing[i] = data.ReadSignedShort(); bytesRead += 4; } if (bytesRead < Length) { int numberNonVertical = numGlyphs - numVMetrics; // handle bad fonts with too many vmetrics if (numberNonVertical < 0) { numberNonVertical = numGlyphs; } additionalTopSideBearing = new short[numberNonVertical]; for (int i = 0; i < numberNonVertical; i++) { if (bytesRead < Length) { additionalTopSideBearing[i] = data.ReadSignedShort(); bytesRead += 2; } } } initialized = true; }
public void Read(TTFDataStream data) { int numPairs = data.ReadUnsignedShort(); searchRange = data.ReadUnsignedShort() / 6; int entrySelector = data.ReadUnsignedShort(); int rangeShift = data.ReadUnsignedShort(); pairs = new int[numPairs][]; for (int i = 0; i < numPairs; ++i) { int left = data.ReadUnsignedShort(); int right = data.ReadUnsignedShort(); int value = data.ReadSignedShort(); pairs[i] = new int[3] { left, right, value }; } }
/** * Parse a file and get a true type font. * * @param raf The TTF file. * @return A TrueType font. * @ If there is an error parsing the TrueType font. */ public TrueTypeFont Parse(TTFDataStream raf, string fontName = null) { if (string.Equals(raf.ReadString(4), TrueTypeCollection.TAG, StringComparison.Ordinal)) { raf.Seek(raf.CurrentPosition - 4); TrueTypeCollection fontCollection = new TrueTypeCollection(raf); var nameFont = fontCollection.GetFontByName(fontName); if (nameFont == null) { nameFont = fontCollection.GetFontAtIndex(0); } return(nameFont); } raf.Seek(raf.CurrentPosition - 4); TrueTypeFont font = NewFont(raf); font.Version = raf.Read32Fixed(); int numberOfTables = raf.ReadUnsignedShort(); int searchRange = raf.ReadUnsignedShort(); int entrySelector = raf.ReadUnsignedShort(); int rangeShift = raf.ReadUnsignedShort(); for (int i = 0; i < numberOfTables; i++) { TTFTable table = ReadTableDirectory(font, raf); // skip tables with zero length if (table != null) { font.AddTable(table); } } // parse tables if wanted if (!parseOnDemandOnly) { ParseTables(font); } return(font); }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { version = data.Read32Fixed(); ascender = data.ReadSignedShort(); descender = data.ReadSignedShort(); lineGap = data.ReadSignedShort(); advanceHeightMax = data.ReadUnsignedShort(); minTopSideBearing = data.ReadSignedShort(); minBottomSideBearing = data.ReadSignedShort(); yMaxExtent = data.ReadSignedShort(); caretSlopeRise = data.ReadSignedShort(); caretSlopeRun = data.ReadSignedShort(); caretOffset = data.ReadSignedShort(); reserved1 = data.ReadSignedShort(); reserved2 = data.ReadSignedShort(); reserved3 = data.ReadSignedShort(); reserved4 = data.ReadSignedShort(); metricDataFormat = data.ReadSignedShort(); numberOfVMetrics = data.ReadUnsignedShort(); initialized = true; }
/** * Constructor. * * @param bais the stream to be read * @param glyphTable the Glyphtable containing all glyphs * @ is thrown if something went wrong */ public GlyfCompositeDescript(TTFDataStream bais, GlyphTable glyphTable) : base((short)-1, bais) { this.glyphTable = glyphTable; // Get all of the composite components GlyfCompositeComp comp; do { comp = new GlyfCompositeComp(bais); components.Add(comp); }while ((comp.Flags & GlyfCompositeComp.MORE_COMPONENTS) != 0); // Are there hinting instructions to read? if ((comp.Flags & GlyfCompositeComp.WE_HAVE_INSTRUCTIONS) != 0) { ReadInstructions(bais, (bais.ReadUnsignedShort())); } InitDescriptions(); }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { version = data.Read32Fixed(); fontRevision = data.Read32Fixed(); checkSumAdjustment = data.ReadUnsignedInt(); magicNumber = data.ReadUnsignedInt(); flags = data.ReadUnsignedShort(); unitsPerEm = data.ReadUnsignedShort(); created = data.ReadInternationalDate(); modified = data.ReadInternationalDate(); xMin = data.ReadSignedShort(); yMin = data.ReadSignedShort(); xMax = data.ReadSignedShort(); yMax = data.ReadSignedShort(); macStyle = data.ReadUnsignedShort(); lowestRecPPEM = data.ReadUnsignedShort(); fontDirectionHint = data.ReadSignedShort(); indexToLocFormat = data.ReadSignedShort(); glyphDataFormat = data.ReadSignedShort(); initialized = true; }
/** * This will read the required data from the stream. * * @param glyphTable The glyph table this glyph belongs to. * @param data The stream to read the data from. * @param leftSideBearing The left side bearing for this glyph. * @ If there is an error reading the data. */ public void InitData(GlyphTable glyphTable, TTFDataStream data, int leftSideBearing) { numberOfContours = data.ReadSignedShort(); xMin = data.ReadSignedShort(); yMin = data.ReadSignedShort(); xMax = data.ReadSignedShort(); yMax = data.ReadSignedShort(); boundingBox = new SKRect(xMin, yMin, xMax, yMax); if (numberOfContours >= 0) { // create a simple glyph short x0 = (short)(leftSideBearing - xMin); glyphDescription = new GlyfSimpleDescript(numberOfContours, data, x0); } else { // create a composite glyph glyphDescription = new GlyfCompositeDescript(data, glyphTable); } }
/** * Constructor. * * @param numberOfContours number of contours * @param bais the stream to be read * @param x0 the initial X-position * @ is thrown if something went wrong */ public GlyfSimpleDescript(short numberOfContours, TTFDataStream bais, short x0) : base(numberOfContours, bais) { /* * https://developer.apple.com/fonts/TTRefMan/RM06/Chap6glyf.html * "If a glyph has zero contours, it need not have any glyph data." set the pointCount to zero to initialize * attributes and avoid nullpointer but maybe there shouldn't have GlyphDescript in the GlyphData? */ if (numberOfContours == 0) { pointCount = 0; return; } // Simple glyph description endPtsOfContours = bais.ReadUnsignedShortArray(numberOfContours); int lastEndPt = endPtsOfContours[numberOfContours - 1]; if (numberOfContours == 1 && lastEndPt == 65535) { // PDFBOX-2939: assume an empty glyph pointCount = 0; return; } // The last end point index reveals the total number of points pointCount = lastEndPt + 1; flags = new byte[pointCount]; xCoordinates = new short[pointCount]; yCoordinates = new short[pointCount]; int instructionCount = bais.ReadUnsignedShort(); ReadInstructions(bais, instructionCount); ReadFlags(pointCount, bais); ReadCoords(pointCount, bais, x0); }
/** * Constructor. Clients should use the OTFParser to create a new OpenTypeFont object. * * @param fontData The font data. */ public OpenTypeFont(TTFDataStream fontData) : base(fontData) { }
public override TrueTypeFont NewFont(TTFDataStream raf) { return(new OpenTypeFont(raf)); }
/** * Constructor. Clients should use the TTFParser to create a new TrueTypeFont object. * * @param fontData The font data. */ public TrueTypeFont(TTFDataStream fontData) { data = fontData; }
/** * Constructor. * * @param bais the stream to be read * @ is thrown if something went wrong */ public GlyfCompositeComp(TTFDataStream bais) { flags = bais.ReadSignedShort(); glyphIndex = bais.ReadUnsignedShort();// number of glyph in a font is uint16 // Get the arguments as just their raw values if ((flags & ARG_1_AND_2_ARE_WORDS) != 0) { // If this is set, the arguments are 16-bit (uint16 or int16) argument1 = bais.ReadSignedShort(); argument2 = bais.ReadSignedShort(); } else { // otherwise, they are bytes (uint8 or int8). argument1 = (short)bais.ReadSignedByte(); argument2 = (short)bais.ReadSignedByte(); } // Assign the arguments according to the flags if ((flags & ARGS_ARE_XY_VALUES) != 0) { // If this is set, the arguments are signed xy values xtranslate = argument1; ytranslate = argument2; } else { // otherwise, they are unsigned point numbers. //TODO why unused? // https://docs.microsoft.com/en-us/typography/opentype/spec/glyf // "In the latter case, the first point number indicates the point that is to be matched // to the new glyph. The second number indicates the new glyph’s “matched” point. // Once a glyph is added, its point numbers begin directly after the last glyphs // (endpoint of first glyph + 1). point1 = argument1; point2 = argument2; } // Get the scale values (if any) if ((flags & WE_HAVE_A_SCALE) != 0) { int i = bais.ReadSignedShort(); xscale = yscale = i / (double)0x4000; } else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0) { short i = bais.ReadSignedShort(); xscale = i / (double)0x4000; i = bais.ReadSignedShort(); yscale = i / (double)0x4000; } else if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0) { int i = bais.ReadSignedShort(); xscale = i / (double)0x4000; i = bais.ReadSignedShort(); scale01 = i / (double)0x4000; i = bais.ReadSignedShort(); scale10 = i / (double)0x4000; i = bais.ReadSignedShort(); yscale = i / (double)0x4000; } }
public TTCDataStream(TTFDataStream stream) { this.stream = stream; }
/** * Creates a new TrueTypeCollection from a TTC stream. * * @param stream The TTF file. * @ If the font could not be parsed. */ public TrueTypeCollection(TTFDataStream stream) { this.stream = stream; Initialize(); }
private void ReadSubtable0Format0(TTFDataStream data) { pairs = new PairData0Format0(); pairs.Read(data); }
private TTFTable ReadTableDirectory(TrueTypeFont font, TTFDataStream raf) { TTFTable table; string tag = raf.ReadString(4); switch (tag) { case CmapTable.TAG: table = new CmapTable(font); break; case GlyphTable.TAG: table = new GlyphTable(font); break; case HeaderTable.TAG: table = new HeaderTable(font); break; case HorizontalHeaderTable.TAG: table = new HorizontalHeaderTable(font); break; case HorizontalMetricsTable.TAG: table = new HorizontalMetricsTable(font); break; case IndexToLocationTable.TAG: table = new IndexToLocationTable(font); break; case MaximumProfileTable.TAG: table = new MaximumProfileTable(font); break; case NamingTable.TAG: table = new NamingTable(font); break; case OS2WindowsMetricsTable.TAG: table = new OS2WindowsMetricsTable(font); break; case PostScriptTable.TAG: table = new PostScriptTable(font); break; case DigitalSignatureTable.TAG: table = new DigitalSignatureTable(font); break; case KerningTable.TAG: table = new KerningTable(font); break; case VerticalHeaderTable.TAG: table = new VerticalHeaderTable(font); break; case VerticalMetricsTable.TAG: table = new VerticalMetricsTable(font); break; case VerticalOriginTable.TAG: table = new VerticalOriginTable(font); break; case GlyphSubstitutionTable.TAG: table = new GlyphSubstitutionTable(font); break; default: table = ReadTable(font, tag); break; } table.Tag = tag; table.CheckSum = raf.ReadUnsignedInt(); table.Offset = raf.ReadUnsignedInt(); table.Length = raf.ReadUnsignedInt(); // skip tables with zero length (except glyf) if (table.Length == 0 && !tag.Equals(GlyphTable.TAG, StringComparison.Ordinal)) { return(null); } return(table); }
public virtual TrueTypeFont NewFont(TTFDataStream raf) { return(new TrueTypeFont(raf)); }
private void ReadSubtable1(TTFDataStream data) { Debug.WriteLine("info: Kerning subtable format 1 not yet supported."); }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { formatType = data.Read32Fixed(); italicAngle = data.Read32Fixed(); underlinePosition = data.ReadSignedShort(); underlineThickness = data.ReadSignedShort(); isFixedPitch = data.ReadUnsignedInt(); minMemType42 = data.ReadUnsignedInt(); maxMemType42 = data.ReadUnsignedInt(); mimMemType1 = data.ReadUnsignedInt(); maxMemType1 = data.ReadUnsignedInt(); if (formatType.CompareTo(1.0f) == 0) { /* * This TrueType font file contains exactly the 258 glyphs in the standard Macintosh TrueType. */ glyphNames = new string[WGL4Names.NUMBER_OF_MAC_GLYPHS]; Array.Copy(WGL4Names.MAC_GLYPH_NAMES, 0, glyphNames, 0, WGL4Names.NUMBER_OF_MAC_GLYPHS); } else if (formatType.CompareTo(2.0f) == 0) { int numGlyphs = data.ReadUnsignedShort(); int[] glyphNameIndex = new int[numGlyphs]; glyphNames = new string[numGlyphs]; int maxIndex = int.MinValue; for (int i = 0; i < numGlyphs; i++) { int index = data.ReadUnsignedShort(); glyphNameIndex[i] = index; // PDFBOX-808: Index numbers between 32768 and 65535 are // reserved for future use, so we should just ignore them if (index <= 32767) { maxIndex = Math.Max(maxIndex, index); } } string[] nameArray = null; if (maxIndex >= WGL4Names.NUMBER_OF_MAC_GLYPHS) { nameArray = new string[maxIndex - WGL4Names.NUMBER_OF_MAC_GLYPHS + 1]; for (int i = 0; i < maxIndex - WGL4Names.NUMBER_OF_MAC_GLYPHS + 1; i++) { int numberOfChars = data.ReadUnsignedByte(); nameArray[i] = data.ReadString(numberOfChars); } } for (int i = 0; i < numGlyphs; i++) { int index = glyphNameIndex[i]; if (index >= 0 && index < WGL4Names.NUMBER_OF_MAC_GLYPHS) { glyphNames[i] = WGL4Names.MAC_GLYPH_NAMES[index]; } else if (index >= WGL4Names.NUMBER_OF_MAC_GLYPHS && index <= 32767 && nameArray != null) { glyphNames[i] = nameArray[index - WGL4Names.NUMBER_OF_MAC_GLYPHS]; } else { // PDFBOX-808: Index numbers between 32768 and 65535 are // reserved for future use, so we should just ignore them glyphNames[i] = ".undefined"; } } } else if (formatType.CompareTo(2.5f) == 0) { int[] glyphNameIndex = new int[ttf.NumberOfGlyphs]; for (int i = 0; i < glyphNameIndex.Length; i++) { int offset = data.ReadSignedByte(); glyphNameIndex[i] = i + 1 + offset; } glyphNames = new string[glyphNameIndex.Length]; for (int i = 0; i < glyphNames.Length; i++) { int index = glyphNameIndex[i]; if (index >= 0 && index < WGL4Names.NUMBER_OF_MAC_GLYPHS) { string name = WGL4Names.MAC_GLYPH_NAMES[index]; if (name != null) { glyphNames[i] = name; } } else { Debug.WriteLine($"debug: incorrect glyph name index {index}, valid numbers 0..{WGL4Names.NUMBER_OF_MAC_GLYPHS}"); } } } else if (formatType.CompareTo(3.0f) == 0) { // no postscript information is provided. Debug.WriteLine($"debug: No PostScript name information is provided for the font {font.Name}"); } initialized = true; }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @ If there is an error reading the data. */ public override void Read(TrueTypeFont ttf, TTFDataStream data) { int formatSelector = data.ReadUnsignedShort(); int numberOfNameRecords = data.ReadUnsignedShort(); int offsetToStartOfStringStorage = data.ReadUnsignedShort(); nameRecords = new List <NameRecord>(numberOfNameRecords); for (int i = 0; i < numberOfNameRecords; i++) { NameRecord nr = new NameRecord(); nr.InitData(ttf, data); nameRecords.Add(nr); } foreach (NameRecord nr in nameRecords) { // don't try to read invalid offsets, see PDFBOX-2608 if (nr.StringOffset > Length) { nr.Text = null; continue; } data.Seek(Offset + (2 * 3) + numberOfNameRecords * 2 * 6 + nr.StringOffset); int platform = nr.PlatformId; int encoding = nr.PlatformEncodingId; var charset = Charset.ISO88591; if (platform == NameRecord.PLATFORM_UNICODE) { charset = Charset.UTF16BE; } else if (platform == NameRecord.PLATFORM_WINDOWS) { if (encoding == NameRecord.ENCODING_WIN_SYMBOL || encoding == NameRecord.ENCODING_WIN_UNICODE_BMP) { charset = Charset.UTF16BE; } } else if (platform == NameRecord.PLATFORM_MACINTOSH) { if (encoding == NameRecord.ENCODING_MAC_ROMAN) { charset = Charset.GetEnconding("x-mac-romanian"); } else if (encoding == NameRecord.ENCODING_MAC_JAPANESE) { charset = Charset.GetEnconding("x-mac-japanese"); } else if (encoding == NameRecord.ENCODING_MAC_CHINESE_TRAD) { charset = Charset.GetEnconding("x-mac-chinesetrad"); } else if (encoding == NameRecord.ENCODING_MAC_CHINESE_SIMP) { charset = Charset.GetEnconding("x-mac-chinesesimp"); } else if (encoding == NameRecord.ENCODING_MAC_KOREAN) { charset = Charset.GetEnconding("x-mac-korean"); } else if (encoding == NameRecord.ENCODING_MAC_ARABIC) { charset = Charset.GetEnconding("x-mac-arabic"); } else if (encoding == NameRecord.ENCODING_MAC_HEBREW) { charset = Charset.GetEnconding("x-mac-hebrew"); } else if (encoding == NameRecord.ENCODING_MAC_GREEK) { charset = Charset.GetEnconding("x-mac-greek"); } else if (encoding == NameRecord.ENCODING_MAC_RUSSIAN) { charset = Charset.GetEnconding("x-mac-cyrillic"); } else if (encoding == NameRecord.ENCODING_MAC_THAI) { charset = Charset.GetEnconding("x-mac-thai"); } } else if (platform == NameRecord.PLATFORM_ISO) { switch (encoding) { case 0: charset = Charset.ASCII; break; case 1: //not sure is this is correct?? charset = Charset.UTF16BE; break; case 2: charset = Charset.ISO88591; break; default: break; } } string text = data.ReadString(nr.StringLength, charset); nr.Text = text; } // build multi-dimensional lookup table lookupTable = new Dictionary <int, Dictionary <int, Dictionary <int, Dictionary <int, string> > > >(nameRecords.Count); foreach (NameRecord nr in nameRecords) { // name id if (!lookupTable.TryGetValue(nr.NameId, out var platformLookup)) { platformLookup = new Dictionary <int, Dictionary <int, Dictionary <int, string> > >(); lookupTable[nr.NameId] = platformLookup; } // platform id if (!platformLookup.TryGetValue(nr.PlatformId, out var encodingLookup)) { encodingLookup = new Dictionary <int, Dictionary <int, string> >(); platformLookup[nr.PlatformId] = encodingLookup; } // encoding id if (!encodingLookup.TryGetValue(nr.PlatformEncodingId, out var languageLookup)) { languageLookup = new Dictionary <int, string>(); encodingLookup[nr.PlatformEncodingId] = languageLookup; } // language id / string languageLookup[nr.LanguageId] = nr.Text; } // extract strings of interest fontFamily = GetEnglishName(NameRecord.NAME_FONT_FAMILY_NAME); fontSubFamily = GetEnglishName(NameRecord.NAME_FONT_SUB_FAMILY_NAME); // extract PostScript name, only these two formats are valid psName = GetName(NameRecord.NAME_POSTSCRIPT_NAME, NameRecord.PLATFORM_MACINTOSH, NameRecord.ENCODING_MAC_ROMAN, NameRecord.LANGUGAE_MAC_ENGLISH); if (psName == null) { psName = GetName(NameRecord.NAME_POSTSCRIPT_NAME, NameRecord.PLATFORM_WINDOWS, NameRecord.ENCODING_WIN_UNICODE_BMP, NameRecord.LANGUGAE_WIN_EN_US); } if (psName != null) { psName = psName.Trim(); } initialized = true; }
/** * Constructor. * * @param numberOfContours the number of contours * @param bais the stream to be read * @ is thrown if something went wrong */ public GlyfDescript(short numberOfContours, TTFDataStream bais) { contourCount = numberOfContours; }