public static bool Load(FontParser parser, FontFace font, bool full)
        {
            font.RequiresLoad = !full;
            font.Parser       = parser;

            // Read the magic number:
            uint magic = parser.ReadUInt32();

            if (magic == 0x00010000)
            {
                // TTF outline format.
            }
            else if (magic == 0x774F4646)
            {
                // WOFF 1
                return(WoffLoader.Load(1, parser, font));
            }
            else if (magic == 0x774F4632)
            {
                // WOFF 2
                return(WoffLoader.Load(2, parser, font));
            }
            else
            {
                // OpenType (probably) 0x4F54544F

                // Reset to start:
                parser.Position = 0;

                // OpenType. Read the tag (right at the start):
                string openTypeVersion = parser.ReadTag();

                if (openTypeVersion == "OTTO")
                {
                    // CFF outline format.
                }
                else
                {
                    // Unsupported format.
                    return(false);
                }
            }

            // Table count:
            int numTables = parser.ReadUInt16();

            // Move to p12:
            parser.Position = 12;

            for (int i = 0; i < numTables; i++)
            {
                // Read the tables tag (e.g. GPOS):
                string tag = parser.ReadTag();

                // Move parser along:
                parser.Position += 4;

                // Read the offset:
                int offset = (int)parser.ReadUInt32();

                // Grab the position - this allows the tables to mess it up:
                int basePosition = parser.Position;

                // Handle the table now:
                if (!parser.HandleTable(tag, offset, font))
                {
                    return(false);
                }

                // Skip meta:
                parser.Position = basePosition + 4;
            }

            if (full)
            {
                return(ReadTables(parser, font));
            }

            return(true);
        }
Beispiel #2
0
        public static bool Load(int version, FontParser parser, FontFace font)
        {
            // Load the V1/V2 header:
            ushort numTables;

            LoadHeader(version, parser, out numTables);

            if (version == 1)
            {
                MemoryStream ms = new MemoryStream(parser.Data);

                // Get the ZLIB compression helper:
                Compressor zLib = Compression.Get("zlib");

                // Read each table next.
                for (int i = 0; i < numTables; i++)
                {
                    string tag        = parser.ReadTag();
                    uint   offset     = parser.ReadUInt32();
                    uint   compLength = parser.ReadUInt32();
                    uint   origLength = parser.ReadUInt32();
                    parser.ReadUInt32();                     // origChecksum

                    // Cache position:
                    int pos = parser.Position;

                    if (compLength != origLength)
                    {
                        // Decompress the table now (zlib)

                        // Seek to table:
                        ms.Position = (int)offset;

                        // Decompressed data:
                        byte[] decompressedTable = new byte[(int)origLength];

                        // Decompress now into our target bytes:
                        zLib.Decompress(ms, decompressedTable);
                    }
                    else
                    {
                        // Ordinary table.
                        parser.HandleTable(tag, (int)offset, font);
                    }

                    // Restore position:
                    parser.Position = pos;
                }
            }
            else if (version == 2)
            {
                // Read each table entry next. The data here is compressed as one single block after the table meta.
                Woff2Table[] tableHeaders = new Woff2Table[numTables];
                int          offset       = 0;

                for (int i = 0; i < numTables; i++)
                {
                    // Read the table entry:
                    byte flags = parser.ReadByte();

                    string tag;

                    int tagFlag = (flags & 63);

                    if (tagFlag == 63)
                    {
                        tag = parser.ReadTag();
                    }
                    else
                    {
                        tag = TagLookup[tagFlag];
                    }

                    ulong origLength      = parser.ReadBase128();
                    ulong transformLength = 0;

                    int transformVersion = (flags >> 6);                   //0-3

                    if (tag == "glyf" || tag == "loca")
                    {
                        // transform length:
                        transformLength = parser.ReadBase128();
                    }

                    offset += (int)origLength;

                    tableHeaders[i] = new Woff2Table(tag, offset, (int)transformLength, transformVersion);
                }
            }

            // All ok:
            return(true);
        }