public unsafe static SbitTable Read(DataReader reader, TableRecord[] tables) { if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc)) return null; // skip version var baseOffset = reader.Position; reader.Skip(sizeof(int)); // load each strike table var count = reader.ReadInt32BE(); if (count > MaxBitmapStrikes) throw new InvalidFontException("Too many bitmap strikes in font."); var sizeTableHeaders = stackalloc BitmapSizeTable[count]; for (int i = 0; i < count; i++) { sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE(); sizeTableHeaders[i].SubTableSize = reader.ReadUInt32BE(); sizeTableHeaders[i].SubTableCount = reader.ReadUInt32BE(); // skip colorRef, metrics entries, start and end glyph indices reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2); sizeTableHeaders[i].PpemX = reader.ReadByte(); sizeTableHeaders[i].PpemY = reader.ReadByte(); sizeTableHeaders[i].BitDepth = reader.ReadByte(); sizeTableHeaders[i].Flags = (BitmapSizeFlags)reader.ReadByte(); } // read index subtables var indexSubTables = stackalloc IndexSubTable[count]; for (int i = 0; i < count; i++) { reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset); indexSubTables[i] = new IndexSubTable { FirstGlyph = reader.ReadUInt16BE(), LastGlyph = reader.ReadUInt16BE(), Offset = reader.ReadUInt32BE() }; } // read the actual data for each strike table for (int i = 0; i < count; i++) { // read the subtable header reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset); var indexFormat = reader.ReadUInt16BE(); var imageFormat = reader.ReadUInt16BE(); var imageDataOffset = reader.ReadUInt32BE(); } return null; }
protected override void ReadContentFrom(BinaryReader reader) { // load each strike table int beginPos = (int)reader.BaseStream.Position; var count = reader.ReadInt32(); if (count > MaxBitmapStrikes) { throw new Exception("Too many bitmap strikes in font."); } var sizeTableHeaders = new BitmapSizeTable[count]; int skipLen = sizeof(uint) + sizeof(ushort) * 2 + 12 * 2; for (int i = 0; i < count; i++) { sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32(); sizeTableHeaders[i].SubTableSize = reader.ReadUInt32(); sizeTableHeaders[i].SubTableCount = reader.ReadUInt32(); // skip colorRef, metrics entries, start and end glyph indices reader.BaseStream.Position += skipLen; sizeTableHeaders[i].PpemX = reader.ReadByte(); sizeTableHeaders[i].PpemY = reader.ReadByte(); sizeTableHeaders[i].BitDepth = reader.ReadByte(); sizeTableHeaders[i].Flags = (BitmapSizeFlags)reader.ReadByte(); } // read index subtables var indexSubTables = new IndexSubTable[count]; for (int i = 0; i < count; i++) { reader.BaseStream.Seek(beginPos + sizeTableHeaders[i].SubTableOffset, SeekOrigin.Begin); indexSubTables[i] = new IndexSubTable { FirstGlyph = reader.ReadUInt16(), LastGlyph = reader.ReadUInt16(), Offset = reader.ReadUInt32() }; } // read the actual data for each strike table for (int i = 0; i < count; i++) { // read the subtable header reader.BaseStream.Seek(beginPos + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset, SeekOrigin.Begin); var indexFormat = reader.ReadUInt16(); var imageFormat = reader.ReadUInt16(); var imageDataOffset = reader.ReadUInt32(); } }
public static SbitTable Read(BinaryReader reader, TableRecord[] tables) { if (!SfntTables.SeekToTable(reader, tables, FourCC.Eblc)) { return(null); } // skip version var baseOffset = reader.Position(); reader.Skip(sizeof(int)); // load each strike table var count = reader.ReadInt32BE(); if (count > MaxBitmapStrikes) { throw new InvalidFontException("Too many bitmap strikes in font."); } var sizeTableHeaders = new BitmapSizeTable[count]; for (int i = 0; i < count; i++) { sizeTableHeaders[i].SubTableOffset = reader.ReadUInt32BE(); sizeTableHeaders[i].SubTableSize = reader.ReadUInt32BE(); sizeTableHeaders[i].SubTableCount = reader.ReadUInt32BE(); // skip colorRef, metrics entries, start and end glyph indices reader.Skip(sizeof(uint) + sizeof(ushort) * 2 + 12 * 2); sizeTableHeaders[i].PpemX = reader.ReadByte(); sizeTableHeaders[i].PpemY = reader.ReadByte(); sizeTableHeaders[i].BitDepth = reader.ReadByte(); sizeTableHeaders[i].Flags = (BitmapSizeFlags)reader.ReadByte(); } // read index subtables var indexSubTables = new IndexSubTable[count]; for (int i = 0; i < count; i++) { reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset); indexSubTables[i] = new IndexSubTable { FirstGlyph = reader.ReadUInt16BE(), LastGlyph = reader.ReadUInt16BE(), Offset = reader.ReadUInt32BE() }; } // read the actual data for each strike table for (int i = 0; i < count; i++) { // read the subtable header reader.Seek(baseOffset + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset); var indexFormat = reader.ReadUInt16BE(); var imageFormat = reader.ReadUInt16BE(); var imageDataOffset = reader.ReadUInt32BE(); } return(null); }
protected override void ReadContentFrom(BinaryReader reader) { // load each strike table int beginPos = (int)reader.BaseStream.Position; // ushort versionMajor = reader.ReadUInt16(); ushort versionMinor = reader.ReadUInt16(); uint numSizes = reader.ReadUInt32(); if (numSizes > MaxBitmapStrikes) { throw new Exception("Too many bitmap strikes in font."); } //---------------- var sizeTableHeaders = new BitmapSizeTable[numSizes]; //int skipLen = sizeof(uint) + sizeof(ushort) * 2 + 12 * 2; for (int i = 0; i < numSizes; i++) { //bitmapSizeTable //Type Name Description //Offset32 indexSubTableArrayOffset offset to index subtable from beginning of EBLC. //uint32 indexTablesSize number of bytes in corresponding index subtables and array //uint32 numberOfIndexSubTables an index subtable for each range or format change //uint32 colorRef not used; set to 0. //sbitLineMetrics hori line metrics for text rendered horizontally //sbitLineMetrics vert line metrics for text rendered vertically //uint16 startGlyphIndex lowest glyph index for this size //uint16 endGlyphIndex highest glyph index for this size //uint8 ppemX horizontal pixels per Em //uint8 ppemY vertical pixels per Em //uint8 bitDepth the Microsoft rasterizer v.1.7 or greater supports the following bitDepth values, as described below: 1, 2, 4, and 8. //int8 flags vertical or horizontal(see bitmapFlags) // //sbitLineMetrics (12 bytes) //Type Name //int8 ascender //int8 descender //uint8 widthMax //int8 caretSlopeNumerator //int8 caretSlopeDenominator //int8 caretOffset //int8 minOriginSB //int8 minAdvanceSB //int8 maxBeforeBL //int8 minAfterBL //int8 pad1 //int8 pad2 // BitmapSizeTable bmpsizeTable = new BitmapSizeTable(); bmpsizeTable.SubTableOffset = reader.ReadUInt32(); bmpsizeTable.SubTableSize = reader.ReadUInt32(); bmpsizeTable.SubTableCount = reader.ReadUInt32(); reader.ReadUInt32();//not use, colorRef The colorRef and bitDepth fields are reserved for future enhancements // //metrics entries reader.BaseStream.Position += (12 * 2); //skip line matric // bmpsizeTable.startGlyph = reader.ReadUInt16(); bmpsizeTable.endGlyph = reader.ReadUInt16(); bmpsizeTable.PpemX = reader.ReadByte(); bmpsizeTable.PpemY = reader.ReadByte(); bmpsizeTable.BitDepth = reader.ReadByte(); //The colorRef and bitDepth fields are reserved for future enhancements. For monochrome bitmaps they should have the values colorRef=0 and bitDepth=1. // //The 'flags' byte contains two bits to indicate the direction of small glyph metrics: horizontal or vertical.The remaining bits are reserved. bmpsizeTable.Flags = (BitmapSizeFlags)reader.ReadByte(); sizeTableHeaders[i] = bmpsizeTable; //save } // read index subtables var indexSubTables = new IndexSubTable[numSizes]; for (int i = 0; i < numSizes; i++) { reader.BaseStream.Seek(beginPos + sizeTableHeaders[i].SubTableOffset, SeekOrigin.Begin); //-------------------------------------------- //indexSubTableArray //Type Name Description //uint16 firstGlyphIndex first glyph code of this range //uint16 lastGlyphIndex last glyph code of this range(inclusive) //Offset32 additionalOffsetToIndexSubtable add to indexSubTableArrayOffset to get offset from beginning of 'EBLC' //-------------------------------------------- indexSubTables[i] = new IndexSubTable { FirstGlyph = reader.ReadUInt16(), LastGlyph = reader.ReadUInt16(), Offset = reader.ReadUInt32() }; } // read the actual data for each strike table for (int i = 0; i < numSizes; i++) { // read the subtable header reader.BaseStream.Seek(beginPos + sizeTableHeaders[i].SubTableOffset + indexSubTables[i].Offset, SeekOrigin.Begin); //-------------------------------------------- //indexSubHeader //-------------------------------------------- //Type Name Description //uint16 indexFormat format of this indexSubTable //uint16 imageFormat format of 'EBDT' image data //Offset32 imageDataOffset offset to image data in 'EBDT' table ushort indexFormat = reader.ReadUInt16(); ushort imageFormat = reader.ReadUInt16(); uint imageDataOffset = reader.ReadUInt32(); //There are currently five different formats used for the indexSubTable, //depending upon the size and type of bitmap data in the glyph code range. //Apple 'bloc' tables support only formats 1 through 3. //The choice of which indexSubTable format to use is up to the font manufacturer, //but should be made with the aim of minimizing the size of the font file. //Ranges of glyphs with variable metrics -that is, where glyphs may differ from each other in bounding box height, //width, side bearings or advance - must use format 1, 3 or 4.Ranges of glyphs with constant metrics can save space by using format 2 or 5, which keep a single copy of the metrics information in the indexSubTable rather than a copy per glyph in the 'EBDT' table.In some monospaced fonts it makes sense to store extra white space around some of the glyphs to keep all metrics identical, thus permitting the use of format 2 or 5. //Structures for each indexSubTable format are listed below. //TODO: impl this } }