Ejemplo n.º 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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
 public static PostTable Deserialize(BinaryReader reader, long startOffset)
 {
     reader.BaseStream.Position = startOffset;
     return(new PostTable
     {
         Version = DataTypeConverter.ReadFixed(reader),
         ItalicAngle = DataTypeConverter.ReadFixed(reader),
         UnderlinePosition = DataTypeConverter.ReadShort(reader),
         UnderlineThickness = DataTypeConverter.ReadShort(reader),
         IsFixedPitch = DataTypeConverter.ReadULong(reader),
         MinMemType42 = DataTypeConverter.ReadULong(reader),
         MaxMemType42 = DataTypeConverter.ReadULong(reader),
         MinMemType1 = DataTypeConverter.ReadULong(reader),
         MaxMemType1 = DataTypeConverter.ReadULong(reader)
     });
 }
Ejemplo n.º 5
0
        public static GlyfTable Deserialize(BinaryReader reader, long startOffset, uint length, LocaTable locaTable)
        {
            var table = new GlyfTable();

            reader.BaseStream.Position = startOffset;
            var glyphOffsets =
                locaTable.GlyphOffsets.Select((u, i) => new { GlyphId = i, Offset = u })
                .Where(glyph => glyph.Offset != null)
                .Select(pair => new { pair.GlyphId, Offset = pair.Offset.Value }).ToList();

            for (var i = 0; i < glyphOffsets.Count; i++)
            {
                Glyph glyphToAdd;

                // Peek number of contours
                var glyphStartOffset = reader.BaseStream.Position = glyphOffsets[i].Offset + startOffset;
                var numberOfContours = DataTypeConverter.ReadShort(reader);
                if (numberOfContours >= 0)
                {
                    uint nextGlyphStartOffset;
                    if (i == glyphOffsets.Count - 1)
                    {
                        nextGlyphStartOffset = (uint)(startOffset + length);
                    }
                    else
                    {
                        nextGlyphStartOffset = (uint)(glyphOffsets[i + 1].Offset + startOffset);
                    }

                    // TODO: Remove padded zeros

                    glyphToAdd = SimpleGlyph.Deserialize(reader, glyphStartOffset,
                                                         (uint)(nextGlyphStartOffset - glyphStartOffset));
                }
                else
                {
                    glyphToAdd = CompositeGlyph.Deserialize(reader, glyphStartOffset);
                }
                glyphToAdd.Id = (uint)glyphOffsets[i].GlyphId;
                table.Glyphs.Add(glyphToAdd);
            }

            return(table);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
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);
        }