/** * 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; }