public static CmapTable Read(FontStreamReader reader, OffsetTable.Entry entry) { reader.Seek(entry); var version = reader.ReadUInt16(); if (version != 0) { throw new FormatException($"Unexpected version number in cmap table: {version}, expecting 0"); } var numberOfSubtables = reader.ReadUInt16(); var subtables = new Dictionary <Tuple <ushort, ushort>, CmapFormat>(); for (var i = 0; i < numberOfSubtables; i++) { var platformId = reader.ReadUInt16(); var platformSpecificId = reader.ReadUInt16(); var relOffset = reader.ReadUInt32(); var offset = entry.Offset + relOffset; var subtable = ReadSubtable(reader, platformId, platformSpecificId, offset); subtables.Add(Tuple.Create(platformId, platformSpecificId), subtable); } return(new CmapTable(version, subtables)); }
public static FpgmTable Read(FontStreamReader reader, OffsetTable.Entry entry) { reader.Seek(entry); var instructions = reader.ReadArray <byte>(entry.Length, r => r.ReadUInt8); return(new FpgmTable(instructions)); }
public static LocaTable Read(Font font, FontStreamReader reader, OffsetTable.Entry entry) { reader.Seek(entry); var length = entry.Length; var format = font.HeadTable.IndexToLocFormat; switch (format) { case IndexToLocFormat.Short: return(new LocaTable(reader.ReadArray <uint>(length / sizeof(ushort), r => (() => r.ReadUInt16())))); case IndexToLocFormat.Long: return(new LocaTable(reader.ReadArray <uint>(length / sizeof(uint), r => r.ReadUInt32))); default: throw new FormatException($"Invalid IndexToLocFormat: {format}"); } }
public static HeadTable Read(FontStreamReader reader, OffsetTable.Entry entry) { reader.Seek(entry); var version = reader.ReadFixed(); var fontRevision = reader.ReadFixed(); //TODO var checkSumAdjustment = reader.ReadUInt32(); var magicNumber = reader.ReadUInt32(); // 0x5F0F3CF5 if (magicNumber != 0x5F0F3CF5) { throw new FormatException($"Invalid magic number in header: 0x{magicNumber:X}, expecting 0x5F0F3CF5"); } var flags = reader.ReadUInt16(); // bitflags var unitsPerEm = reader.ReadUInt16(); // 64-16384 if (unitsPerEm < 64 || unitsPerEm > 16384) { throw new FormatException($"Invalid units per em in header: {unitsPerEm:X}, expecting a value between 64 and 16384"); } var created = reader.ReadLongDateTime(); var modified = reader.ReadLongDateTime(); var xMin = reader.ReadFWord(); var yMin = reader.ReadFWord(); var xMax = reader.ReadFWord(); var yMax = reader.ReadFWord(); var macStyle = (MacStyle)reader.ReadUInt16(); // bitflags var lowestRecPPEM = reader.ReadUInt16(); var fontDirectionHint = reader.ReadUInt16(); var indexToLocFormat = (IndexToLocFormat)reader.ReadUInt16(); // 0 = short, 1 = long var glyphDataFormat = (GlyphDataFormat)reader.ReadUInt16(); // 0 = current return(new HeadTable(version, fontRevision, flags, unitsPerEm, created, modified, xMin, yMin, xMax, yMax, macStyle, lowestRecPPEM, fontDirectionHint, indexToLocFormat, glyphDataFormat)); }
public static GlyfTable Read(FontStreamReader reader, OffsetTable.Entry entry) { reader.Seek(entry); var glyphs = new List <Glyph>(); while (reader.Position < entry.Offset + entry.Length) { glyphs.Add(ReadGlyph(reader)); while ((reader.Position & 1) != 0) { reader.ReadUInt8(); } } if (reader.Position > entry.Offset + entry.Length) { throw new Exception("Overflow?"); } return(new GlyfTable(glyphs)); }
private static CmapFormat ReadSubtable(FontStreamReader reader, ushort platformId, ushort platformSpecificId, uint offset) { reader.Push(); reader.Seek(offset, SeekOrigin.Begin); var format = reader.ReadUInt16(); CmapFormat result; switch (format) { case 0: result = CmapFormat0.Read(reader, platformId, platformSpecificId); break; case 2: result = CmapFormat2.Read(reader, platformId, platformSpecificId); break; case 4: result = CmapFormat4.Read(reader, platformId, platformSpecificId); break; case 6: result = CmapFormat6.Read(reader, platformId, platformSpecificId); break; case 8: result = CmapFormat8.Read(reader, platformId, platformSpecificId); break; case 10: result = CmapFormat10.Read(reader, platformId, platformSpecificId); break; case 12: result = CmapFormat12.Read(reader, platformId, platformSpecificId); break; case 13: result = CmapFormat13.Read(reader, platformId, platformSpecificId); break; case 14: result = CmapFormat14.Read(reader, platformId, platformSpecificId); break; default: throw new FormatException($"Unexpected cmap subtable format: {format}"); } reader.Pop(); return(result); }