public static LocaTable Deserialize(BinaryReader reader, long startOffset, ushort numberOfGlyphs, LocaTableVersion version) { var table = new LocaTable(); reader.BaseStream.Position = startOffset; table.GlyphOffsets.AddRange(Enumerable.Range(0, numberOfGlyphs).Select <int, uint?>(i => { var offset = ReadNextOffset(reader, version); // Peek next offset var restorePosition = reader.BaseStream.Position; var nextOffset = ReadNextOffset(reader, version); reader.BaseStream.Position = restorePosition; // Empty outline check if (offset == nextOffset) { return(null); } return(offset); })); return(table); }
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); }