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 new static Version05MaxpTable Deserialize(BinaryReader reader, long startOffset) { reader.BaseStream.Position = startOffset + DataTypeLength.Fixed; return(new Version05MaxpTable { NumberOfGlyphs = DataTypeConverter.ReadUShort(reader) }); }
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(); } }
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); }
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 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) }); }
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); }
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); }