Пример #1
0
        public static CmapTable Read(FontStreamReader reader, OffsetTable.Entry entry)
        {
            reader.Seek(entry);

            var version = reader.ReadUInt16();

            if (version != 0)
            {
                throw new FormatException($"Unexpected version number in cmap table: {version}, expecting 0");
            }

            var numberOfSubtables = reader.ReadUInt16();

            var subtables = new Dictionary <Tuple <ushort, ushort>, CmapFormat>();

            for (var i = 0; i < numberOfSubtables; i++)
            {
                var platformId         = reader.ReadUInt16();
                var platformSpecificId = reader.ReadUInt16();

                var relOffset = reader.ReadUInt32();
                var offset    = entry.Offset + relOffset;

                var subtable = ReadSubtable(reader, platformId, platformSpecificId, offset);
                subtables.Add(Tuple.Create(platformId, platformSpecificId), subtable);
            }

            return(new CmapTable(version, subtables));
        }
Пример #2
0
        public static FpgmTable Read(FontStreamReader reader, OffsetTable.Entry entry)
        {
            reader.Seek(entry);

            var instructions = reader.ReadArray <byte>(entry.Length, r => r.ReadUInt8);

            return(new FpgmTable(instructions));
        }
Пример #3
0
        public static LocaTable Read(Font font, FontStreamReader reader, OffsetTable.Entry entry)
        {
            reader.Seek(entry);

            var length = entry.Length;
            var format = font.HeadTable.IndexToLocFormat;

            switch (format)
            {
            case IndexToLocFormat.Short:
                return(new LocaTable(reader.ReadArray <uint>(length / sizeof(ushort), r => (() => r.ReadUInt16()))));

            case IndexToLocFormat.Long:
                return(new LocaTable(reader.ReadArray <uint>(length / sizeof(uint), r => r.ReadUInt32)));

            default: throw new FormatException($"Invalid IndexToLocFormat: {format}");
            }
        }
Пример #4
0
        public static HeadTable Read(FontStreamReader reader, OffsetTable.Entry entry)
        {
            reader.Seek(entry);

            var version      = reader.ReadFixed();
            var fontRevision = reader.ReadFixed();

            //TODO
            var checkSumAdjustment = reader.ReadUInt32();

            var magicNumber = reader.ReadUInt32(); // 0x5F0F3CF5

            if (magicNumber != 0x5F0F3CF5)
            {
                throw new FormatException($"Invalid magic number in header: 0x{magicNumber:X}, expecting 0x5F0F3CF5");
            }

            var flags = reader.ReadUInt16();      // bitflags

            var unitsPerEm = reader.ReadUInt16(); // 64-16384

            if (unitsPerEm < 64 || unitsPerEm > 16384)
            {
                throw new FormatException($"Invalid units per em in header: {unitsPerEm:X}, expecting a value between 64 and 16384");
            }

            var created  = reader.ReadLongDateTime();
            var modified = reader.ReadLongDateTime();

            var xMin = reader.ReadFWord();
            var yMin = reader.ReadFWord();
            var xMax = reader.ReadFWord();
            var yMax = reader.ReadFWord();

            var macStyle          = (MacStyle)reader.ReadUInt16(); // bitflags
            var lowestRecPPEM     = reader.ReadUInt16();
            var fontDirectionHint = reader.ReadUInt16();
            var indexToLocFormat  = (IndexToLocFormat)reader.ReadUInt16(); // 0 = short, 1 = long
            var glyphDataFormat   = (GlyphDataFormat)reader.ReadUInt16();  // 0 = current

            return(new HeadTable(version, fontRevision, flags, unitsPerEm, created, modified, xMin, yMin, xMax, yMax, macStyle, lowestRecPPEM, fontDirectionHint, indexToLocFormat, glyphDataFormat));
        }
Пример #5
0
        public static GlyfTable Read(FontStreamReader reader, OffsetTable.Entry entry)
        {
            reader.Seek(entry);

            var glyphs = new List <Glyph>();

            while (reader.Position < entry.Offset + entry.Length)
            {
                glyphs.Add(ReadGlyph(reader));

                while ((reader.Position & 1) != 0)
                {
                    reader.ReadUInt8();
                }
            }

            if (reader.Position > entry.Offset + entry.Length)
            {
                throw new Exception("Overflow?");
            }

            return(new GlyfTable(glyphs));
        }
Пример #6
0
        private static CmapFormat ReadSubtable(FontStreamReader reader, ushort platformId, ushort platformSpecificId, uint offset)
        {
            reader.Push();
            reader.Seek(offset, SeekOrigin.Begin);

            var format = reader.ReadUInt16();

            CmapFormat result;

            switch (format)
            {
            case 0: result = CmapFormat0.Read(reader, platformId, platformSpecificId); break;

            case 2: result = CmapFormat2.Read(reader, platformId, platformSpecificId); break;

            case 4: result = CmapFormat4.Read(reader, platformId, platformSpecificId); break;

            case 6: result = CmapFormat6.Read(reader, platformId, platformSpecificId); break;

            case 8: result = CmapFormat8.Read(reader, platformId, platformSpecificId); break;

            case 10: result = CmapFormat10.Read(reader, platformId, platformSpecificId); break;

            case 12: result = CmapFormat12.Read(reader, platformId, platformSpecificId); break;

            case 13: result = CmapFormat13.Read(reader, platformId, platformSpecificId); break;

            case 14: result = CmapFormat14.Read(reader, platformId, platformSpecificId); break;

            default: throw new FormatException($"Unexpected cmap subtable format: {format}");
            }

            reader.Pop();

            return(result);
        }