예제 #1
0
        /**
         * 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;
        }