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); }
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); }
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); }
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) }); }
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); }
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); }
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); }