Пример #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;
        }
Пример #2
0
 /**
  * Run the callback for each TT font in the collection.
  *
  * @param trueTypeFontProcessor the object with the callback method.
  * @
  */
 public void ProcessAllFonts(ITrueTypeFontProcessor trueTypeFontProcessor, object tag)
 {
     for (int i = 0; i < numFonts; i++)
     {
         TrueTypeFont font = GetFontAtIndex(i);
         trueTypeFontProcessor(font, tag);
     }
 }
Пример #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;
        }
Пример #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;
        }
Пример #5
0
 /**
  * Get a TT font from a collection.
  *
  * @param name The postscript name of the font.
  * @return The found font, nor null if none is found.
  * @
  */
 public TrueTypeFont GetFontByName(string name)
 {
     for (int i = 0; i < numFonts; i++)
     {
         TrueTypeFont font = GetFontAtIndex(i);
         if (font.Name.Equals(name, StringComparison.Ordinal))
         {
             return(font);
         }
     }
     return(null);
 }
Пример #6
0
        /**
         * Creates a subsetter for the given font.
         *
         * @param ttf the font to be subset
         * @param tables optional tables to keep if present
         */
        public TTFSubsetter(TrueTypeFont ttf, List <string> tables)
        {
            this.ttf        = ttf;
            this.keepTables = tables;

            uniToGID = new SortedDictionary <int, int>();
            glyphIds = new SortedSet <int>();

            // find the best Unicode cmap
            this.unicodeCmap = ttf.GetUnicodeCmapLookup();

            // always copy GID 0
            glyphIds.Add(0);
        }
Пример #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)
        {
            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;
        }
Пример #8
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;
        }
Пример #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;
        }
Пример #10
0
        protected override TTFTable ReadTable(TrueTypeFont font, string tag)
        {
            // todo: this is a stub, a full implementation is needed
            switch (tag)
            {
            case "BASE":
            case "GDEF":
            case "GPOS":
            case "GSUB":
            case "JSTF":
                return(new OTLTable(font));

            case "CFF ":
                return(new CFFTable(font));

            default:
                return(base.ReadTable(font, tag));
            }
        }
Пример #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);
        }
Пример #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();
     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;
 }
Пример #13
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;
 }
Пример #14
0
 public IndexToLocationTable(TrueTypeFont font)
     : base(font)
 {
 }
Пример #15
0
        /**
         * Parse all tables and check if all needed tables are present.
         *
         * @param font the TrueTypeFont instance holding the parsed data.
         * @ If there is an error parsing the TrueType font.
         */
        private void ParseTables(TrueTypeFont font)
        {
            foreach (TTFTable table in font.Tables)
            {
                if (!table.Initialized)
                {
                    font.ReadTable(table);
                }
            }

            bool isPostScript = AllowCFF && font.TableMap.ContainsKey(CFFTable.TAG);

            HeaderTable head = font.Header;

            if (head == null)
            {
                throw new IOException("head is mandatory");
            }

            HorizontalHeaderTable hh = font.HorizontalHeader;

            if (hh == null)
            {
                throw new IOException("hhead is mandatory");
            }

            MaximumProfileTable maxp = font.MaximumProfile;

            if (maxp == null)
            {
                throw new IOException("maxp is mandatory");
            }

            PostScriptTable post = font.PostScript;

            if (post == null && !isEmbedded)
            {
                // in an embedded font this table is optional
                throw new IOException("post is mandatory");
            }

            if (!isPostScript)
            {
                IndexToLocationTable loc = font.IndexToLocation;
                if (loc == null)
                {
                    throw new IOException("loca is mandatory");
                }

                if (font.Glyph == null)
                {
                    throw new IOException("glyf is mandatory");
                }
            }

            if (font.Naming == null && !isEmbedded)
            {
                throw new IOException("name is mandatory");
            }

            if (font.HorizontalMetrics == null)
            {
                throw new IOException("hmtx is mandatory");
            }

            if (!isEmbedded && font.Cmap == null)
            {
                throw new IOException("cmap is mandatory");
            }
        }
Пример #16
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);
        }
Пример #17
0
 public VerticalOriginTable(TrueTypeFont font)
     : base(font)
 {
 }
Пример #18
0
 protected virtual TTFTable ReadTable(TrueTypeFont font, string tag)
 {
     // unknown table type but read it anyway.
     return(new TTFTable(font));
 }
Пример #19
0
 /**
  * Creates a subsetter for the given font.
  *
  * @param ttf the font to be subset
  */
 public TTFSubsetter(TrueTypeFont ttf)
     : this(ttf, null)
 {
 }
Пример #20
0
 public VerticalMetricsTable(TrueTypeFont font)
     : base(font)
 {
 }
 public OS2WindowsMetricsTable(TrueTypeFont font) : base(font)
 {
 }
Пример #22
0
 public KerningTable(TrueTypeFont font) : base(font)
 {
 }
Пример #23
0
 public GlyphSubstitutionTable(TrueTypeFont font) : base(font)
 {
 }
Пример #24
0
 /**
  * Constructor.
  *
  * @param font The font which contains this table.
  */
 public TTFTable(TrueTypeFont font)
 {
     this.font = font;
 }
Пример #25
0
 public GlyphTable(TrueTypeFont font) : base(font)
 {
 }
Пример #26
0
 public PostScriptTable(TrueTypeFont font)
     : base(font)
 {
 }
Пример #27
0
 public HeaderTable(TrueTypeFont font) : base(font)
 {
 }
Пример #28
0
 public HorizontalMetricsTable(TrueTypeFont font) : base(font)
 {
 }
Пример #29
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;
        }
Пример #30
0
 public VerticalHeaderTable(TrueTypeFont font)
     : base(font)
 {
 }