/// <summary> Creates a new math variants table by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. </param> public VariantsTable(BinaryReader reader) { Contract.Requires(reader != null); long start = reader.BaseStream.Position;//the index in the reader of the start of this variants table //gather all elements in this variants MinConnectorOverlap = reader.ReadUInt16(); uint verticalGlyphCoverageOffset = reader.ReadUInt16EvenThoughSpecsSays32(); uint horizontalGlyphCoverageOffset = reader.ReadUInt16EvenThoughSpecsSays32(); //get the offsets where the glyph constructions are var verticalGlyphOffsets = new uint[reader.ReadUInt16()]; var horizontalGlyphOffsets = new uint[reader.ReadUInt16()]; for (int i = 0; i < verticalGlyphOffsets.Length; i++) { verticalGlyphOffsets[i] = reader.ReadUInt16EvenThoughSpecsSays32(); } for (int i = 0; i < horizontalGlyphOffsets.Length; i++) { horizontalGlyphOffsets[i] = reader.ReadUInt16EvenThoughSpecsSays32(); } //read the glyph constructions var verticalGlyphConstructions = new GlyphConstruction[verticalGlyphOffsets.Length]; var horizontalGlyphConstructions = new GlyphConstruction[horizontalGlyphOffsets.Length]; for (int i = 0; i < verticalGlyphOffsets.Length; i++) { reader.BaseStream.Position = start + verticalGlyphOffsets[i]; verticalGlyphConstructions[i] = new GlyphConstruction(reader); } for (int i = 0; i < horizontalGlyphOffsets.Length; i++) { reader.BaseStream.Position = start + horizontalGlyphOffsets[i]; horizontalGlyphConstructions[i] = new GlyphConstruction(reader); } //get coverages at their locations: reader.BaseStream.Position = start + verticalGlyphCoverageOffset; VerticalCoverage = reader.ReadCoverageTable(); reader.BaseStream.Position = start + horizontalGlyphCoverageOffset; HorizontalCoverage = reader.ReadCoverageTable(); }
/// <summary> Creates a new header by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. The caller is responsible for disposal. </param> public MathTable(BinaryReader reader) { Contract.Requires(reader != null); Contract.Requires(reader.BaseStream.CanSeek); long mathTableOffset = reader.BaseStream.Position; MainVersion = reader.ReadUInt16(); //section 4.3 of the specs says 16.16 bits for anything of type 'Fixed' (i.e. main version dot subversion) SubVersion = reader.ReadUInt16(); uint offsetToConstantsTable = reader.ReadUInt16EvenThoughSpecsSays32(); uint offsetToGlyphInfo = reader.ReadUInt16EvenThoughSpecsSays32(); uint offsetToVariants = reader.ReadUInt16EvenThoughSpecsSays32(); reader.BaseStream.Position = mathTableOffset + offsetToConstantsTable; Constants = new ConstantsTable(reader); reader.BaseStream.Position = mathTableOffset + offsetToGlyphInfo; Glyphs = new GlyphInfo(reader); reader.BaseStream.Position = mathTableOffset + offsetToVariants; Variants = new VariantsTable(reader); }
/// <summary> Creates a new kern info table by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. </param> /// <param name="kernInfoTableStart"> The offsets to be read are relative to the start of the MathKernInfoTable, which is to be provided as argument here. </param> public KernInfoRecord(BinaryReader reader, long kernInfoTableStart) { Contract.Requires(reader != null); uint topRightKernOffset = reader.ReadUInt16EvenThoughSpecsSays32(); uint topLeftKernOffset = reader.ReadUInt16EvenThoughSpecsSays32(); uint bottomRightKernOffset = reader.ReadUInt16EvenThoughSpecsSays32(); uint bottomLeftKernOffset = reader.ReadUInt16EvenThoughSpecsSays32(); long end = reader.BaseStream.Position; if (topRightKernOffset != 0) { reader.BaseStream.Position = kernInfoTableStart + topRightKernOffset; TopRightKern = new Kern(reader); } if (topLeftKernOffset != 0) { reader.BaseStream.Position = kernInfoTableStart + topLeftKernOffset; TopLeftKern = new Kern(reader); } if (bottomRightKernOffset != 0) { reader.BaseStream.Position = kernInfoTableStart + bottomRightKernOffset; BottomRightKern = new Kern(reader); } if (bottomLeftKernOffset != 0) { reader.BaseStream.Position = kernInfoTableStart + bottomLeftKernOffset; BottomLeftKern = new Kern(reader); } reader.BaseStream.Position = end;//restore position, such that the next KernInfo can be read. It would be neat to do this everywhere, regardless of whether it is necessary. }
/// <summary> Creates a new italics correction info table by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. </param> public ItalicsCorrectionInfoTable(BinaryReader reader) { Contract.Requires(reader != null); long start = reader.BaseStream.Position;//the start of this correction info table uint offsetToCoverageTable = reader.ReadUInt16EvenThoughSpecsSays32(); //read corrections var corrections = new short[reader.ReadUInt16()]; for (int i = 0; i < corrections.Length; i++) { corrections[i] = reader.ReadValueRecord(); } Corrections = new ReadOnlyCollection<short>(corrections); //read coverage table reader.BaseStream.Position = start + offsetToCoverageTable; CoverageTable = reader.ReadCoverageTable(); }
/// <summary> Creates a new math glyph info by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. </param> public KernInfoTable(BinaryReader reader) { Contract.Requires(reader != null); long start = reader.BaseStream.Position; uint coverageOffset = reader.ReadUInt16EvenThoughSpecsSays32(); int count = reader.ReadInt16(); var backingArray = new KernInfoRecord[count]; for (int i = 0; i < count; i++) { backingArray[i] = new KernInfoRecord(reader, start); } KernInfoRecords = new ReadOnlyCollection<KernInfoRecord>(backingArray); if (coverageOffset != 0) { reader.BaseStream.Position = start + coverageOffset; Coverage = reader.ReadCoverageTable(); } }
/// <summary> Creates a new glyph construction table by reading it from the specified stream. </summary> /// <param name="reader"> The correctly positioned stream to read from. </param> public GlyphConstruction(BinaryReader reader) { Contract.Requires(reader != null); Contract.Requires(reader.BaseStream.CanSeek); long start = reader.BaseStream.Position; //the index in the reader of the start of this glyph construction table uint assemblyOffset = reader.ReadUInt16EvenThoughSpecsSays32(); //get glyph variants: var glyphVariants = new GlyphVariantRecord[reader.ReadUInt16()]; for (int i = 0; i < glyphVariants.Length; i++) { glyphVariants[i] = new GlyphVariantRecord(reader); } GlyphVariants = new ReadOnlyCollection<GlyphVariantRecord>(glyphVariants); //get glyph assembly: if (assemblyOffset != 0) { reader.BaseStream.Position = start + assemblyOffset; GlyphAssembly = new GlyphAssemblyTable(reader); } }