Ejemplo n.º 1
0
        public static uint[] ReadTTCHeader(DataReader reader)
        {
            // read the file header; if we have a collection, we want to
            // figure out where all the different faces are in the file
            // if we don't have a collection, there's just one font in the file
            var tag = reader.ReadUInt32();

            if (tag != FourCC.Ttcf)
            {
                return new[] { 0u }
            }
            ;

            // font file is a TrueType collection; read the TTC header
            reader.Skip(4);     // version number
            var count = reader.ReadUInt32BE();

            if (count == 0 || count > MaxFontsInCollection)
            {
                throw new InvalidFontException("Invalid TTC header");
            }

            var offsets = new uint[count];

            for (int i = 0; i < count; i++)
            {
                offsets[i] = reader.ReadUInt32BE();
            }

            return(offsets);
        }
Ejemplo n.º 2
0
        public static TableRecord[] ReadFaceHeader(DataReader reader)
        {
            var tag = reader.ReadUInt32BE();

            if (tag != TTFv1 && tag != TTFv2 && tag != FourCC.True)
            {
                throw new InvalidFontException("Unknown or unsupported sfnt version.");
            }

            var tableCount = reader.ReadUInt16BE();

            reader.Skip(6); // skip the rest of the header

            // read each font table descriptor
            var tables = new TableRecord[tableCount];

            for (int i = 0; i < tableCount; i++)
            {
                tables[i] = new TableRecord {
                    Tag      = reader.ReadUInt32(),
                    CheckSum = reader.ReadUInt32BE(),
                    Offset   = reader.ReadUInt32BE(),
                    Length   = reader.ReadUInt32BE(),
                };
            }

            return(tables);
        }
Ejemplo n.º 3
0
        public unsafe static SbitTable Read(DataReader reader, TableRecord[] tables)
        {
            if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc))
                return null;

            // skip version
            var baseOffset = reader.Position;
            reader.Skip(sizeof(int));

            // load each strike table
            var count = reader.ReadInt32BE();
            if (count > MaxBitmapStrikes)
                throw new InvalidFontException("Too many bitmap strikes in font.");

            var sizeTableHeaders = stackalloc BitmapSizeTable[count];
            for (int i = 0; i < count; i++)
            {
                sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableSize = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableCount = reader.ReadUInt32BE();

                // skip colorRef, metrics entries, start and end glyph indices
                reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2);

                sizeTableHeaders[i].PpemX = reader.ReadByte();
                sizeTableHeaders[i].PpemY = reader.ReadByte();
                sizeTableHeaders[i].BitDepth = reader.ReadByte();
                sizeTableHeaders[i].Flags = (BitmapSizeFlags)reader.ReadByte();
            }

            // read index subtables
            var indexSubTables = stackalloc IndexSubTable[count];
            for (int i = 0; i < count; i++)
            {
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset);
                indexSubTables[i] = new IndexSubTable
                {
                    FirstGlyph = reader.ReadUInt16BE(),
                    LastGlyph = reader.ReadUInt16BE(),
                    Offset = reader.ReadUInt32BE()
                };
            }

            // read the actual data for each strike table
            for (int i = 0; i < count; i++)
            {
                // read the subtable header
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset);
                var indexFormat = reader.ReadUInt16BE();
                var imageFormat = reader.ReadUInt16BE();
                var imageDataOffset = reader.ReadUInt32BE();


            }

            return null;
        }
Ejemplo n.º 4
0
        public static uint[] ReadTTCHeader(DataReader reader)
        {
            // read the file header; if we have a collection, we want to
            // figure out where all the different faces are in the file
            // if we don't have a collection, there's just one font in the file
            var tag = reader.ReadUInt32();
            if (tag != FourCC.Ttcf)
                return new[] { 0u };

            // font file is a TrueType collection; read the TTC header
            reader.Skip(4);     // version number
            var count = reader.ReadUInt32BE();
            if (count == 0 || count > MaxFontsInCollection)
                throw new InvalidFontException("Invalid TTC header");

            var offsets = new uint[count];
            for (int i = 0; i < count; i++)
                offsets[i] = reader.ReadUInt32BE();

            return offsets;
        }
Ejemplo n.º 5
0
        public static void ReadPost(DataReader reader, TableRecord[] tables, ref FaceHeader header)
        {
            if (!SeekToTable(reader, tables, FourCC.Post))
            {
                return;
            }

            // skip over version and italicAngle
            reader.Skip(sizeof(int) * 2);

            header.UnderlinePosition  = reader.ReadInt16BE();
            header.UnderlineThickness = reader.ReadInt16BE();
            header.IsFixedPitch       = reader.ReadUInt32BE() != 0;
        }
Ejemplo n.º 6
0
        public static TableRecord[] ReadFaceHeader(DataReader reader)
        {
            var tag = reader.ReadUInt32BE();
            if (tag != TTFv1 && tag != TTFv2 && tag != FourCC.True)
                throw new InvalidFontException("Unknown or unsupported sfnt version.");

            var tableCount = reader.ReadUInt16BE();
            reader.Skip(6); // skip the rest of the header

            // read each font table descriptor
            var tables = new TableRecord[tableCount];
            for (int i = 0; i < tableCount; i++)
            {
                tables[i] = new TableRecord
                {
                    Tag = reader.ReadUInt32(),
                    CheckSum = reader.ReadUInt32BE(),
                    Offset = reader.ReadUInt32BE(),
                    Length = reader.ReadUInt32BE(),
                };
            }

            return tables;
        }
Ejemplo n.º 7
0
        public static void ReadLoca(DataReader reader, TableRecord[] tables, IndexFormat format, uint *table, int count)
        {
            SeekToTable(reader, tables, FourCC.Loca, required: true);

            if (format == IndexFormat.Short)
            {
                // values are ushort, divided by 2, so we need to shift back
                for (int i = 0; i < count; i++)
                {
                    *table++ = (uint)(reader.ReadUInt16BE() << 1);
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    *table++ = reader.ReadUInt32BE();
                }
            }
        }
Ejemplo n.º 8
0
        public static CharacterMap ReadCmap(DataReader reader, TableRecord[] tables)
        {
            SfntTables.SeekToTable(reader, tables, FourCC.Cmap, required: true);

            // skip version
            var cmapOffset = reader.Position;

            reader.Skip(sizeof(short));

            // read all of the subtable headers
            var subtableCount   = reader.ReadUInt16BE();
            var subtableHeaders = new CmapSubtableHeader[subtableCount];

            for (int i = 0; i < subtableHeaders.Length; i++)
            {
                subtableHeaders[i] = new CmapSubtableHeader
                {
                    PlatformID = reader.ReadUInt16BE(),
                    EncodingID = reader.ReadUInt16BE(),
                    Offset     = reader.ReadUInt32BE()
                };
            }

            // search for a "full" Unicode table first
            var chosenSubtableOffset = 0u;

            for (int i = 0; i < subtableHeaders.Length; i++)
            {
                var platform = subtableHeaders[i].PlatformID;
                var encoding = subtableHeaders[i].EncodingID;
                if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeFull) ||
                    (platform == PlatformID.Unicode && encoding == UnicodeEncoding.Unicode32))
                {
                    chosenSubtableOffset = subtableHeaders[i].Offset;
                    break;
                }
            }

            // if no full unicode table, just grab the first
            // one that supports any flavor of Unicode
            if (chosenSubtableOffset == 0)
            {
                for (int i = 0; i < subtableHeaders.Length; i++)
                {
                    var platform = subtableHeaders[i].PlatformID;
                    var encoding = subtableHeaders[i].EncodingID;
                    if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeBmp) ||
                        platform == PlatformID.Unicode)
                    {
                        chosenSubtableOffset = subtableHeaders[i].Offset;
                        break;
                    }
                }
            }

            // no unicode support at all is an error
            if (chosenSubtableOffset == 0)
            {
                throw new Exception("Font does not support Unicode.");
            }

            // jump to our chosen table and find out what format it's in
            reader.Seek(cmapOffset + chosenSubtableOffset);
            var format = reader.ReadUInt16BE();

            switch (format)
            {
            case 4: return(ReadCmapFormat4(reader));

            default: throw new Exception("Unsupported cmap format.");
            }
        }
Ejemplo n.º 9
0
        public unsafe static SbitTable Read(DataReader reader, TableRecord[] tables)
        {
            if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc))
            {
                return(null);
            }

            // skip version
            var baseOffset = reader.Position;

            reader.Skip(sizeof(int));

            // load each strike table
            var count = reader.ReadInt32BE();

            if (count > MaxBitmapStrikes)
            {
                throw new Exception("Too many bitmap strikes in font.");
            }

            var sizeTableHeaders = stackalloc BitmapSizeTable[count];

            for (int i = 0; i < count; i++)
            {
                sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableSize   = reader.ReadUInt32BE();
                sizeTableHeaders[i].SubTableCount  = reader.ReadUInt32BE();

                // skip colorRef, metrics entries, start and end glyph indices
                reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2);

                sizeTableHeaders[i].PpemX    = reader.ReadByte();
                sizeTableHeaders[i].PpemY    = reader.ReadByte();
                sizeTableHeaders[i].BitDepth = reader.ReadByte();
                sizeTableHeaders[i].Flags    = (BitmapSizeFlags)reader.ReadByte();
            }

            // read index subtables
            var indexSubTables = stackalloc IndexSubTable[count];

            for (int i = 0; i < count; i++)
            {
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset);
                indexSubTables[i] = new IndexSubTable
                {
                    FirstGlyph = reader.ReadUInt16BE(),
                    LastGlyph  = reader.ReadUInt16BE(),
                    Offset     = reader.ReadUInt32BE()
                };
            }

            // read the actual data for each strike table
            for (int i = 0; i < count; i++)
            {
                // read the subtable header
                reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset);
                var indexFormat     = reader.ReadUInt16BE();
                var imageFormat     = reader.ReadUInt16BE();
                var imageDataOffset = reader.ReadUInt32BE();
            }

            return(null);
        }
Ejemplo n.º 10
0
        public static CharacterMap ReadCmap(DataReader reader, TableRecord[] tables)
        {
            SfntTables.SeekToTable(reader, tables, FourCC.Cmap, required: true);

            // skip version
            var cmapOffset = reader.Position;
            reader.Skip(sizeof(short));

            // read all of the subtable headers
            var subtableCount = reader.ReadUInt16BE();
            var subtableHeaders = new CmapSubtableHeader[subtableCount];
            for (int i = 0; i < subtableHeaders.Length; i++)
            {
                subtableHeaders[i] = new CmapSubtableHeader
                {
                    PlatformID = reader.ReadUInt16BE(),
                    EncodingID = reader.ReadUInt16BE(),
                    Offset = reader.ReadUInt32BE()
                };
            }

            // search for a "full" Unicode table first
            var chosenSubtableOffset = 0u;
            for (int i = 0; i < subtableHeaders.Length; i++)
            {
                var platform = subtableHeaders[i].PlatformID;
                var encoding = subtableHeaders[i].EncodingID;
                if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeFull) ||
                    (platform == PlatformID.Unicode && encoding == UnicodeEncoding.Unicode32))
                {

                    chosenSubtableOffset = subtableHeaders[i].Offset;
                    break;
                }
            }

            // if no full unicode table, just grab the first
            // one that supports any flavor of Unicode
            if (chosenSubtableOffset == 0)
            {
                for (int i = 0; i < subtableHeaders.Length; i++)
                {
                    var platform = subtableHeaders[i].PlatformID;
                    var encoding = subtableHeaders[i].EncodingID;
                    if ((platform == PlatformID.Microsoft && encoding == WindowsEncoding.UnicodeBmp) ||
                         platform == PlatformID.Unicode)
                    {

                        chosenSubtableOffset = subtableHeaders[i].Offset;
                        break;
                    }
                }
            }

            // no unicode support at all is an error
            if (chosenSubtableOffset == 0)
                throw new Exception("Font does not support Unicode.");

            // jump to our chosen table and find out what format it's in
            reader.Seek(cmapOffset + chosenSubtableOffset);
            var format = reader.ReadUInt16BE();
            switch (format)
            {
                case 4: return ReadCmapFormat4(reader);
                default: throw new Exception("Unsupported cmap format.");
            }
        }
Ejemplo n.º 11
0
        public static void ReadLoca(DataReader reader, TableRecord[] tables, IndexFormat format, uint* table, int count)
        {
            SeekToTable(reader, tables, FourCC.Loca, required: true);

            if (format == IndexFormat.Short)
            {
                // values are ushort, divided by 2, so we need to shift back
                for (int i = 0; i < count; i++)
                    *table++ = (uint)(reader.ReadUInt16BE() << 1);
            }
            else
            {
                for (int i = 0; i < count; i++)
                    *table++ = reader.ReadUInt32BE();
            }
        }
Ejemplo n.º 12
0
        public static void ReadPost(DataReader reader, TableRecord[] tables, ref FaceHeader header)
        {
            if (!SeekToTable(reader, tables, FourCC.Post))
                return;

            // skip over version and italicAngle
            reader.Skip(sizeof(int) * 2);

            header.UnderlinePosition = reader.ReadInt16BE();
            header.UnderlineThickness = reader.ReadInt16BE();
            header.IsFixedPitch = reader.ReadUInt32BE() != 0;
        }