Пример #1
0
        public static HmtxTable Deserialize(BinaryReader reader, long startOffset, ushort numberOfHorizontalMetrics,
                                            ushort numberOfGlyphs)
        {
            var table = new HmtxTable();

            reader.BaseStream.Position = startOffset;

            table.HorizontalMetrics.AddRange(
                Enumerable.Range(0, numberOfHorizontalMetrics).Select(i => new HorizontalMetric
            {
                AdvanceWidth    = DataTypeConverter.ReadUShort(reader),
                LeftSideBearing = DataTypeConverter.ReadShort(reader)
            }));

            var remainingAdvanceWidth = table.HorizontalMetrics.Last().AdvanceWidth;

            table.HorizontalMetrics.AddRange(
                Enumerable.Range(0, numberOfGlyphs - numberOfHorizontalMetrics).Select(i => new HorizontalMetric
            {
                AdvanceWidth    = remainingAdvanceWidth,
                LeftSideBearing = DataTypeConverter.ReadShort(reader)
            }));

            return(table);
        }
Пример #2
0
 public new static Version05MaxpTable Deserialize(BinaryReader reader, long startOffset)
 {
     reader.BaseStream.Position = startOffset + DataTypeLength.Fixed;
     return(new Version05MaxpTable {
         NumberOfGlyphs = DataTypeConverter.ReadUShort(reader)
     });
 }
Пример #3
0
        private static uint ReadNextOffset(BinaryReader reader, LocaTableVersion version)
        {
            switch (version)
            {
            case LocaTableVersion.Long:
                return(DataTypeConverter.ReadULong(reader));

            case LocaTableVersion.Short:
                return((uint)(DataTypeConverter.ReadUShort(reader) * 2));

            default:
                throw new NotImplementedException();
            }
        }
Пример #4
0
        public static Format0Subtable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new Format0Subtable();

            reader.BaseStream.Position = startOffset + 2 * DataTypeLength.UShort;
            table.Language             = DataTypeConverter.ReadUShort(reader);

            for (uint i = 0; i < 256; i++)
            {
                table.CharGlyphIdMap[i] = reader.ReadByte();
            }

            return(table);
        }
Пример #5
0
        public static Format4Subtable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new Format4Subtable();

            reader.BaseStream.Position = startOffset + 2 * DataTypeLength.UShort;
            table.Language             = DataTypeConverter.ReadUShort(reader);

            var segmentCount = DataTypeConverter.ReadUShort(reader) / 2;

            reader.BaseStream.Position += 3 * DataTypeLength.UShort;
            var segmentEnds =
                Enumerable.Range(0, segmentCount).Select(i => DataTypeConverter.ReadUShort(reader)).ToArray();

            reader.BaseStream.Position += DataTypeLength.UShort;
            var segmentStarts =
                Enumerable.Range(0, segmentCount).Select(i => DataTypeConverter.ReadUShort(reader)).ToArray();
            var idDeltas =
                Enumerable.Range(0, segmentCount).Select(i => DataTypeConverter.ReadShort(reader)).ToArray();
            var startOfIdRangeOffsets = reader.BaseStream.Position;
            var idRangeOffsets        =
                Enumerable.Range(0, segmentCount).Select(i => DataTypeConverter.ReadUShort(reader)).ToArray();

            for (var i = 0; i < segmentCount; i++)
            {
                for (var codePoint = segmentStarts[i]; codePoint <= segmentEnds[i]; codePoint++)
                {
                    if (idRangeOffsets[i] == 0)
                    {
                        table.CharGlyphIdMap[codePoint] = (ushort)((idDeltas[i] + codePoint) % 65536);
                    }
                    else
                    {
                        reader.BaseStream.Position = idRangeOffsets[i] + 2 * (codePoint - segmentStarts[i]) +
                                                     startOfIdRangeOffsets + DataTypeLength.UShort * i;
                        var glyphIdRaw = DataTypeConverter.ReadUShort(reader);
                        if (glyphIdRaw != 0)
                        {
                            table.CharGlyphIdMap[codePoint] = (ushort)((glyphIdRaw + idDeltas[i]) % 65536);
                        }
                    }
                    if (codePoint == ushort.MaxValue)
                    {
                        break;
                    }
                }
            }

            return(table);
        }
Пример #6
0
        public static CompositeGlyph Deserialize(BinaryReader reader, long startOffset)
        {
            var glyph = new CompositeGlyph();

            reader.BaseStream.Position = startOffset + DataTypeLength.Short;

            glyph.XMin = DataTypeConverter.ReadShort(reader);
            glyph.YMin = DataTypeConverter.ReadShort(reader);
            glyph.XMax = DataTypeConverter.ReadShort(reader);
            glyph.YMax = DataTypeConverter.ReadShort(reader);

            do
            {
                var component = new GlyphComponent
                {
                    Flags   = (ComponentFlags)DataTypeConverter.ReadUShort(reader),
                    GlyphId = DataTypeConverter.ReadUShort(reader)
                };
                var dataLength = 0;
                if (component.Flags.HasFlag(ComponentFlags.Arg1And2AreWords))
                {
                    dataLength += DataTypeLength.UShort * 2;
                }
                else
                {
                    dataLength += DataTypeLength.UShort;
                }
                if (component.Flags.HasFlag(ComponentFlags.WeHaveAScale))
                {
                    dataLength += DataTypeLength.F2Dot14;
                }
                else if (component.Flags.HasFlag(ComponentFlags.WeHaveAnXAndYScale))
                {
                    dataLength += DataTypeLength.F2Dot14 * 2;
                }
                else if (component.Flags.HasFlag(ComponentFlags.WeHaveATwoByTwo))
                {
                    dataLength += DataTypeLength.F2Dot14 * 4;
                }
                component.TransformationData = reader.ReadBytes(dataLength);
                glyph.Components.Add(component);
            } while (glyph.Components.Last().Flags.HasFlag(ComponentFlags.MoreComponents));
            if (glyph.Components.Last().Flags.HasFlag(ComponentFlags.WeHaveInstructions))
            {
                glyph.Instructions = reader.ReadBytes(DataTypeConverter.ReadUShort(reader));
            }
            return(glyph);
        }
Пример #7
0
        public static Format6Subtable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new Format6Subtable();

            reader.BaseStream.Position = startOffset + 2 * DataTypeLength.UShort;
            table.Language             = DataTypeConverter.ReadUShort(reader);

            var firstCode  = DataTypeConverter.ReadUShort(reader);
            var entryCount = DataTypeConverter.ReadUShort(reader);

            for (uint i = 0; i < entryCount; i++)
            {
                table.CharGlyphIdMap[firstCode + i] = DataTypeConverter.ReadUShort(reader);
            }

            return(table);
        }
 public new static Version10MaxpTable Deserialize(BinaryReader reader, long startOffset)
 {
     reader.BaseStream.Position = startOffset + DataTypeLength.Fixed;
     return(new Version10MaxpTable
     {
         NumberOfGlyphs = DataTypeConverter.ReadUShort(reader),
         MaxPoints = DataTypeConverter.ReadUShort(reader),
         MaxContours = DataTypeConverter.ReadUShort(reader),
         MaxCompositePoints = DataTypeConverter.ReadUShort(reader),
         MaxCompositeContours = DataTypeConverter.ReadUShort(reader),
         MaxZones = DataTypeConverter.ReadUShort(reader),
         MaxTwilightPoints = DataTypeConverter.ReadUShort(reader),
         MaxStorage = DataTypeConverter.ReadUShort(reader),
         MaxFunctionDefs = DataTypeConverter.ReadUShort(reader),
         MaxInstructionDefs = DataTypeConverter.ReadUShort(reader),
         MaxStackElements = DataTypeConverter.ReadUShort(reader),
         MaxSizeOfInstructions = DataTypeConverter.ReadUShort(reader),
         MaxComponentElements = DataTypeConverter.ReadUShort(reader),
         MaxComponentDepth = DataTypeConverter.ReadUShort(reader)
     });
 }
Пример #9
0
        public static HheaTable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new HheaTable();

            reader.BaseStream.Position = startOffset;

            table.Version               = DataTypeConverter.ReadFixed(reader);
            table.Ascender              = DataTypeConverter.ReadFword(reader);
            table.Descender             = DataTypeConverter.ReadFword(reader);
            table.LineGap               = DataTypeConverter.ReadFword(reader);
            table.AdvanceWidthMax       = DataTypeConverter.ReadUFword(reader);
            table.MinLeftSideBearing    = DataTypeConverter.ReadFword(reader);
            table.MinRightSideBearing   = DataTypeConverter.ReadFword(reader);
            table.XMaxExtent            = DataTypeConverter.ReadFword(reader);
            table.CaretSlopeRise        = DataTypeConverter.ReadShort(reader);
            table.CaretSlopeRun         = DataTypeConverter.ReadShort(reader);
            table.CaretOffset           = DataTypeConverter.ReadShort(reader);
            reader.BaseStream.Position += DataTypeLength.Short * 4;
            table.MetricDataFormat      = DataTypeConverter.ReadShort(reader);
            table.NumberOfHMetrics      = DataTypeConverter.ReadUShort(reader);

            return(table);
        }
Пример #10
0
        public static HeadTable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new HeadTable();

            reader.BaseStream.Position = startOffset;

            table.Version               = DataTypeConverter.ReadFixed(reader);
            table.FontRevision          = DataTypeConverter.ReadFixed(reader);
            reader.BaseStream.Position += 2 * DataTypeLength.ULong;
            table.Flags                 = DataTypeConverter.ReadUShort(reader);
            table.UnitsPerEm            = DataTypeConverter.ReadUShort(reader);
            table.CreateTime            = DataTypeConverter.ReadLongDateTime(reader);
            table.ModifyTime            = DataTypeConverter.ReadLongDateTime(reader);
            table.XMin                  = DataTypeConverter.ReadShort(reader);
            table.YMin                  = DataTypeConverter.ReadShort(reader);
            table.XMax                  = DataTypeConverter.ReadShort(reader);
            table.YMax                  = DataTypeConverter.ReadShort(reader);
            table.MacStyle              = DataTypeConverter.ReadUShort(reader);
            table.LowestRecPpem         = DataTypeConverter.ReadUShort(reader);
            reader.BaseStream.Position += DataTypeLength.Short;
            table.LocaTableVersion      = (LocaTableVersion)DataTypeConverter.ReadShort(reader);

            return(table);
        }
Пример #11
0
        public static CmapTable Deserialize(BinaryReader reader, long startOffset)
        {
            var table = new CmapTable();

            reader.BaseStream.Position = startOffset;

            table.Version = DataTypeConverter.ReadUShort(reader);

            var numberOfSubtables = DataTypeConverter.ReadUShort(reader);
            var platformIds       = new ushort[numberOfSubtables];
            var encodingIds       = new ushort[numberOfSubtables];
            var offsets           = new uint[numberOfSubtables];

            for (var i = 0; i < numberOfSubtables; i++)
            {
                platformIds[i] = DataTypeConverter.ReadUShort(reader);
                encodingIds[i] = DataTypeConverter.ReadUShort(reader);
                offsets[i]     = DataTypeConverter.ReadULong(reader);
            }
            var offsetSubtableMap = new Dictionary <uint, CmapSubtable>();

            for (var i = 0; i < numberOfSubtables; i++)
            {
                if (offsetSubtableMap.ContainsKey(offsets[i])) // Multiple map
                {
                    offsetSubtableMap[offsets[i]].Environments.Add(new Environment
                    {
                        EncodingId     = encodingIds[i],
                        PlatformId     = platformIds[i],
                        SubtableOffset = offsets[i]
                    });
                    continue;
                }

                var          subtableStartOffset = reader.BaseStream.Position = startOffset + offsets[i];
                var          format = DataTypeConverter.ReadUShort(reader);
                CmapSubtable subtable;
                switch (format)
                {
                case 0:
                    subtable = Format0Subtable.Deserialize(reader, subtableStartOffset);
                    break;

                case 4:
                    subtable = Format4Subtable.Deserialize(reader, subtableStartOffset);
                    break;

                case 6:
                    subtable = Format6Subtable.Deserialize(reader, subtableStartOffset);
                    break;

                case 12:
                    subtable = Format12Subtable.Deserialize(reader, subtableStartOffset);
                    break;

                default:
                    throw new NotImplementedException();
                }
                subtable.Environments.Add(new Environment
                {
                    PlatformId     = platformIds[i],
                    EncodingId     = encodingIds[i],
                    SubtableOffset = offsets[i]
                });
                offsetSubtableMap[offsets[i]] = subtable;
                table.Subtables.Add(subtable);
            }
            return(table);
        }