Exemplo n.º 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 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;
        }
Exemplo n.º 2
0
 /**
  * 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();
 }
Exemplo n.º 3
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.
         * @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;
        }
Exemplo n.º 4
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)
        {
            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;
        }
Exemplo n.º 5
0
 /**
  * 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();
     }
 }
Exemplo n.º 6
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)
        {
            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;
        }
Exemplo n.º 7
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)
        {
            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;
        }
Exemplo n.º 8
0
        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);
            }
        }
Exemplo n.º 9
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)
        {
            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;
        }
Exemplo n.º 10
0
            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
                    };
                }
            }
Exemplo n.º 11
0
        /**
         * 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);
        }
Exemplo n.º 12
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)
 {
     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;
 }
Exemplo n.º 13
0
        /**
         * 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();
        }
Exemplo n.º 14
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)
 {
     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;
 }
Exemplo n.º 15
0
        /**
         * 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);
            }
        }
Exemplo n.º 16
0
        /**
         * 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);
        }
Exemplo n.º 17
0
 /**
  * Constructor. Clients should use the OTFParser to create a new OpenTypeFont object.
  *
  * @param fontData The font data.
  */
 public OpenTypeFont(TTFDataStream fontData) : base(fontData)
 {
 }
Exemplo n.º 18
0
 public override TrueTypeFont NewFont(TTFDataStream raf)
 {
     return(new OpenTypeFont(raf));
 }
Exemplo n.º 19
0
 /**
  * Constructor.  Clients should use the TTFParser to create a new TrueTypeFont object.
  *
  * @param fontData The font data.
  */
 public TrueTypeFont(TTFDataStream fontData)
 {
     data = fontData;
 }
Exemplo n.º 20
0
        /**
         * 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;
            }
        }
Exemplo n.º 21
0
 public TTCDataStream(TTFDataStream stream)
 {
     this.stream = stream;
 }
Exemplo n.º 22
0
 /**
  * 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();
 }
Exemplo n.º 23
0
 private void ReadSubtable0Format0(TTFDataStream data)
 {
     pairs = new PairData0Format0();
     pairs.Read(data);
 }
Exemplo n.º 24
0
        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);
        }
Exemplo n.º 25
0
 public virtual TrueTypeFont NewFont(TTFDataStream raf)
 {
     return(new TrueTypeFont(raf));
 }
Exemplo n.º 26
0
 private void ReadSubtable1(TTFDataStream data)
 {
     Debug.WriteLine("info: Kerning subtable format 1 not yet supported.");
 }
Exemplo n.º 27
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)
        {
            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;
        }
Exemplo n.º 28
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;
        }
Exemplo n.º 29
0
 /**
  * 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;
 }