Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /**
         * Write the subfont to the given output stream.
         *
         * @param os the stream used for writing. It will be closed by this method.
         * @ if something went wrong.
         * @throws IllegalStateException if the subset input empty.
         */
        public void WriteToStream(Stream os)
        {
            if (glyphIds.Count == 0 && uniToGID.Count == 0)
            {
                Debug.WriteLine("info: font subset input empty");
            }

            AddCompoundReferences();

            using (var output = new BinaryWriter(os, Charset.ASCII, true))
            {
                long[] newLoca = new long[glyphIds.Count + 1];

                // generate tables in dependency order
                byte[] head = buildHeadTable();
                byte[] hhea = buildHheaTable();
                byte[] maxp = BuildMaxpTable();
                byte[] name = BuildNameTable();
                byte[] os2  = BuildOS2Table();
                byte[] glyf = BuildGlyfTable(newLoca);
                byte[] loca = BuildLocaTable(newLoca);
                byte[] cmap = BuildCmapTable();
                byte[] hmtx = BuildHmtxTable();
                byte[] post = BuildPostTable();

                // save to TTF in optimized order
                Dictionary <string, byte[]> tables = new Dictionary <string, byte[]>(StringComparer.Ordinal);
                if (os2 != null)
                {
                    tables["OS/2"] = os2;
                }
                if (cmap != null)
                {
                    tables["cmap"] = cmap;
                }
                tables["glyf"] = glyf;
                tables["head"] = head;
                tables["hhea"] = hhea;
                tables["hmtx"] = hmtx;
                tables["loca"] = loca;
                tables["maxp"] = maxp;
                if (name != null)
                {
                    tables["name"] = name;
                }
                if (post != null)
                {
                    tables["post"] = post;
                }

                // copy all other tables
                foreach (KeyValuePair <string, TTFTable> entry in ttf.TableMap)
                {
                    string   tag   = entry.Key;
                    TTFTable table = entry.Value;

                    if (!tables.ContainsKey(tag) && (keepTables == null || keepTables.Contains(tag, StringComparer.Ordinal)))
                    {
                        tables[tag] = ttf.GetTableBytes(table);
                    }
                }

                // calculate checksum
                long checksum = WriteFileHeader(output, tables.Count);
                long offset   = 12L + 16L * tables.Count;
                foreach (var entry in tables)
                {
                    checksum += WriteTableHeader(output, entry.Key, offset, entry.Value);
                    offset   += (entry.Value.Length + 3) / 4 * 4;
                }
                checksum = 0xB1B0AFBAL - (checksum & 0xffffffffL);

                // update checksumAdjustment in 'head' table
                head[8]  = (byte)(((uint)checksum) >> 24);
                head[9]  = (byte)(((uint)checksum) >> 16);
                head[10] = (byte)(((uint)checksum) >> 8);
                head[11] = (byte)checksum;
                foreach (byte[] bytes in tables.Values)
                {
                    WriteTableBody(output, bytes);
                }
            }
        }