FontCollectionHeader ReadTTCHeader(ByteOrderSwappingBinaryReader input) { //https://docs.microsoft.com/en-us/typography/opentype/spec/otff#ttc-header //TTC Header Version 1.0: //Type Name Description //TAG ttcTag Font Collection ID string: 'ttcf' (used for fonts with CFF or CFF2 outlines as well as TrueType outlines) //uint16 majorVersion Major version of the TTC Header, = 1. //uint16 minorVersion Minor version of the TTC Header, = 0. //uint32 numFonts Number of fonts in TTC //Offset32 offsetTable[numFonts] Array of offsets to the OffsetTable for each font from the beginning of the file //TTC Header Version 2.0: //Type Name Description //TAG ttcTag Font Collection ID string: 'ttcf' //uint16 majorVersion Major version of the TTC Header, = 2. //uint16 minorVersion Minor version of the TTC Header, = 0. //uint32 numFonts Number of fonts in TTC //Offset32 offsetTable[numFonts] Array of offsets to the OffsetTable for each font from the beginning of the file //uint32 dsigTag Tag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature) //uint32 dsigLength The length (in bytes) of the DSIG table (null if no signature) //uint32 dsigOffset The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature) var ttcHeader = new FontCollectionHeader(); ttcHeader.majorVersion = input.ReadUInt16(); ttcHeader.minorVersion = input.ReadUInt16(); uint numFonts = input.ReadUInt32(); int[] offsetTables = new int[numFonts]; for (uint i = 0; i < numFonts; ++i) { offsetTables[i] = input.ReadInt32(); } ttcHeader.numFonts = numFonts; ttcHeader.offsetTables = offsetTables; // if (ttcHeader.majorVersion == 2) { ttcHeader.dsigTag = input.ReadUInt32(); ttcHeader.dsigLength = input.ReadUInt32(); ttcHeader.dsigOffset = input.ReadUInt32(); if (ttcHeader.dsigTag == 0x44534947) { //Tag indicating that a DSIG table exists //TODO: goto DSIG add read signature } } return(ttcHeader); }
public Typeface Read(Stream stream) { var little = BitConverter.IsLittleEndian; using (BinaryReader input = new ByteOrderSwappingBinaryReader(stream)) { UInt32 version = input.ReadUInt32(); UInt16 tableCount = input.ReadUInt16(); UInt16 searchRange = input.ReadUInt16(); UInt16 entrySelector = input.ReadUInt16(); UInt16 rangeShift = input.ReadUInt16(); var tables = new List <TableEntry>(tableCount); for (int i = 0; i < tableCount; i++) { tables.Add(TableEntry.ReadFrom(input)); } var header = Head.From(FindTable(tables, "head")); var maximumProfile = MaxProfile.From(FindTable(tables, "maxp")); var glyphLocations = new GlyphLocations(FindTable(tables, "loca"), maximumProfile.GlyphCount, header.WideGlyphLocations); var glyphs = Glyf.From(FindTable(tables, "glyf"), glyphLocations); var cmaps = CmapReader.From(FindTable(tables, "cmap")); var horizontalHeader = HorizontalHeader.From(FindTable(tables, "hhea")); var horizontalMetrics = HorizontalMetrics.From(FindTable(tables, "hmtx"), horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount); return(new Typeface(header.Bounds, header.UnitsPerEm, glyphs, cmaps, horizontalMetrics)); } }