public byte [,] GetBitmapImage(Table_EBLC.bitmapSizeTable bst, ushort glyphID) { byte [,] bits = null; Table_EBLC.indexSubTableArray ista = bst.FindIndexSubTableArray(glyphID); if (ista != null) { Table_EBLC.indexSubTable ist = bst.GetIndexSubTable(ista); if (ist.header.imageFormat < 8) { // simple bitmap byte [] encodedDataBuf = GetImageData(ist, glyphID, ista.firstGlyphIndex); byte width=0, height=0; switch (ist.header.imageFormat) { case 0: throw new ApplicationException("illegal image format: 0"); //break; case 1: case 2: smallGlyphMetrics sgm = this.GetSmallMetrics(ist, glyphID, ista.firstGlyphIndex); width = sgm.width; height = sgm.height; break; case 3: case 4: throw new ApplicationException("illegal image format: " + ist.header.imageFormat); //break; case 5: switch (ist.header.indexFormat) { case 2: Table_EBLC.indexSubTable2 ist2 = (Table_EBLC.indexSubTable2)ist; width = ist2.bigMetrics.width; height = ist2.bigMetrics.height; break; case 5: Table_EBLC.indexSubTable5 ist5 = (Table_EBLC.indexSubTable5)ist; width = ist5.bigMetrics.width; height = ist5.bigMetrics.height; break; } break; case 6: case 7: bigGlyphMetrics bgm = this.GetBigMetrics(ist, glyphID, ista.firstGlyphIndex); width = bgm.width; height = bgm.height; break; } if (encodedDataBuf != null) { bits = DecodeImageData(ist, width, height, bst.bitDepth, encodedDataBuf); } else { //Debug.Assert(false); } } else if (ist.header.imageFormat <10) { // composite bitmap throw new ApplicationException("TODO: impelement bitmap composites"); } else { Debug.Assert(false, "illegal image format"); } } return bits; }
private uint getImageFormatOffset( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex ) { int nIndexFormat = cIndexSubTable.header.indexFormat; uint nGlyphImageDataOffset = 0; switch( nIndexFormat ) { case 1: { nGlyphImageDataOffset = cIndexSubTable.header.imageDataOffset + ((Table_EBLC.indexSubTable1)cIndexSubTable).GetOffset( (uint)(nGlyphIndex - nStartGlyphIndex)); break; } case 2: { nGlyphImageDataOffset = cIndexSubTable.header.imageDataOffset + 4 + bigGlyphMetrics.bufSize; nGlyphImageDataOffset += (uint)(((Table_EBLC.indexSubTable2)cIndexSubTable).imageSize * (nGlyphIndex - nStartGlyphIndex)); break; } case 3: { nGlyphImageDataOffset = cIndexSubTable.header.imageDataOffset + ((Table_EBLC.indexSubTable3)cIndexSubTable).GetOffset( (uint)(nGlyphIndex - nStartGlyphIndex)); break; } case 4: { Table_EBLC.indexSubTable4 ist = (Table_EBLC.indexSubTable4)cIndexSubTable; for( uint i = 0; i < ist.numGlyphs; i++ ) { if( ist.GetCodeOffsetPair( i ).glyphCode == nGlyphIndex ) { nGlyphImageDataOffset = ist.header.imageDataOffset + ist.GetCodeOffsetPair( i ).offset; break; } } break; } case 5: { for( uint i = 0; i < ((Table_EBLC.indexSubTable5)cIndexSubTable).numGlyphs; i++ ) { if( ((Table_EBLC.indexSubTable5)cIndexSubTable).GetGlyphCode( i ) == nGlyphIndex ) { nGlyphImageDataOffset = cIndexSubTable.header.imageDataOffset + 4 + bigGlyphMetrics.bufSize + 4; nGlyphImageDataOffset += (uint)(((Table_EBLC.indexSubTable5)cIndexSubTable).numGlyphs * 2); nGlyphImageDataOffset += (uint)(i * ((Table_EBLC.indexSubTable5)cIndexSubTable).imageSize); break; } } break; } } return nGlyphImageDataOffset; }
public uint getImageLength( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex, uint nImageOffset ) { int nIndexFormat = cIndexSubTable.header.indexFormat; uint nImageLength = 0; switch( nIndexFormat ) { case 1: { nImageLength = cIndexSubTable.header.imageDataOffset + ((Table_EBLC.indexSubTable1)cIndexSubTable).GetOffset( (uint)((nGlyphIndex + 1) - nStartGlyphIndex)); nImageLength -= nImageOffset; break; } case 2: { nImageLength = ((Table_EBLC.indexSubTable2)cIndexSubTable).imageSize; break; } case 3: { nImageLength = cIndexSubTable.header.imageDataOffset + ((Table_EBLC.indexSubTable3)cIndexSubTable).GetOffset( (uint)((nGlyphIndex + 1) - nStartGlyphIndex)); nImageLength -= nImageOffset; break; } case 4: { Table_EBLC.indexSubTable4 ist = (Table_EBLC.indexSubTable4)cIndexSubTable; for( uint i = 0; i < ist.numGlyphs; i++ ) { if( ist.GetCodeOffsetPair( i ).glyphCode == nGlyphIndex ) { nImageLength = ist.header.imageDataOffset + ist.GetCodeOffsetPair( i + 1 ).offset; nImageLength -= nImageOffset; } } break; } case 5: { nImageLength = ((Table_EBLC.indexSubTable5)cIndexSubTable).imageSize; break; } } return nImageLength; }
public ebdtComponent GetComponent( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex, uint nComponent ) { ebdtComponent ebdtc = null; int nIndexFormat = cIndexSubTable.header.indexFormat; int nImageFormat = cIndexSubTable.header.imageFormat; Debug.Assert( nIndexFormat != 2 && nIndexFormat != 5 ); // These images all have the same metrics as described in the indexSubTable so should have the proper image format Debug.Assert( nIndexFormat != 3 && nIndexFormat != 5 ); if (nImageFormat == 8 || nImageFormat == 9) { if( nGlyphIndex >= nStartGlyphIndex ) { uint nImageFormatOffset = getImageFormatOffset( cIndexSubTable, nGlyphIndex, nStartGlyphIndex ); if( nImageFormatOffset != 0 ) { ebdtc = new ebdtComponent(); if( nImageFormat == 8 ) { nImageFormatOffset += smallGlyphMetrics.bufSize + 3 + (nComponent * ebdtComponent.bufSize); } else // nImageFormat = 9 { nImageFormatOffset += smallGlyphMetrics.bufSize + 2 + (nComponent * ebdtComponent.bufSize); } ebdtc.glyphCode = m_bufTable.GetUshort( nImageFormatOffset + (uint)ebdtComponent.FieldOffsets.glyphCode ); ebdtc.xOffset = m_bufTable.GetSbyte( nImageFormatOffset + (uint)ebdtComponent.FieldOffsets.xOffset ); ebdtc.yOffset = m_bufTable.GetSbyte( nImageFormatOffset + (uint)ebdtComponent.FieldOffsets.yOffset ); } } } return ebdtc; }
public byte[] GetImageData( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex ) { int nIndexFormat = cIndexSubTable.header.indexFormat; int nImageFormat = cIndexSubTable.header.imageFormat; byte[] bufImageData = null; // 8 and 9 are composites so their image data should be retrieved through the composite glyphs Debug.Assert( nImageFormat != 8 && nImageFormat != 9 ); if( nGlyphIndex >= nStartGlyphIndex ) { uint nImageFormatOffset = getImageFormatOffset( cIndexSubTable, nGlyphIndex, nStartGlyphIndex ); if( nImageFormatOffset > 0 ) { uint nImageLength = 0; if( nImageFormat == 1 || nImageFormat == 2 ) { nImageFormatOffset += smallGlyphMetrics.bufSize; } else if( nImageFormat == 5 ) { } else if( nImageFormat == 6 || nImageFormat == 7 ) { nImageFormatOffset += bigGlyphMetrics.bufSize; } nImageLength = getImageLength( cIndexSubTable, nGlyphIndex, nStartGlyphIndex, nImageFormatOffset ); if( nImageLength > 0 ) { bufImageData = new byte[nImageLength]; System.Buffer.BlockCopy( m_bufTable.GetBuffer(), (int)nImageFormatOffset, bufImageData, 0, (int)nImageLength ); } } } return bufImageData; }
public bool Validate_Format5(Validator v, string sIdentity, Table_EBLC.indexSubTable ist) { bool bOk = true; Table_EBLC.indexSubTableArray ista = ist.GetIndexSubTableArray(); for (ushort idGlyph=ista.firstGlyphIndex; idGlyph <= ista.lastGlyphIndex; idGlyph++) { // no metrics in format 5 // validate image data // - this is just bitmap data, any values should be valid } return bOk; }
public ushort GetNumComponents( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex ) { ushort nNumComponents = 0; int nIndexFormat = cIndexSubTable.header.indexFormat; int nImageFormat = cIndexSubTable.header.imageFormat; Debug.Assert(nImageFormat == 8 || nImageFormat == 9); // These images all have the same metrics as described in the indexSubTable so should have the proper image format // Debug.Assert( nIndexFormat != 2 && nIndexFormat != 5 ); // commented out the above assert because batang.ttc violates this too much if (nImageFormat == 8 || nImageFormat == 9) { if( nGlyphIndex >= nStartGlyphIndex ) { uint nImageFormatOffset = getImageFormatOffset( cIndexSubTable, nGlyphIndex, nStartGlyphIndex ); if( nImageFormatOffset != 0 ) { if( nImageFormat == 8 ) { nNumComponents = m_bufTable.GetUshort( (uint)(nImageFormatOffset + smallGlyphMetrics.bufSize + 1)); } else // nImageFormat = 9 { nNumComponents = m_bufTable.GetUshort( (uint)(nImageFormatOffset + bigGlyphMetrics.bufSize)); } } } } return nNumComponents; }
public override OTTable GenerateTable() { uint nBufSize = (uint)Table_EBLC.FieldOffsets.FirstbitmapSizeTable; for( ushort i = 0; i < m_numSizes; i++ ) { bitmapSizeTableCache bstc = (bitmapSizeTableCache)m_bitmapSizeTables[i]; nBufSize += bitmapSizeTable.bufSize; nBufSize += bstc.indexSubTablesSize; } // create a Motorola Byte Order buffer for the new table MBOBuffer newbuf = new MBOBuffer( nBufSize ); // Determine the size of the EBDTTable and create its buffer uint nEBDTBufSize = (uint)Table_EBDT.FieldOffsets.StartOfData; for( ushort i = 0; i < m_numSizes; i++ ) { bitmapSizeTableCache bstc = (bitmapSizeTableCache)m_bitmapSizeTables[i]; for( int ii = 0; ii < bstc.numberOfIndexSubTables; ii++ ) { indexSubTableArrayCache istac = bstc.getIndexSubTableArrayCache( ii ); nEBDTBufSize += istac.indexSubTable.imageDataSize(); } } // create a Motorola Byte Order buffer for the EBDT table MBOBuffer bufEBDT = new MBOBuffer( nEBDTBufSize ); newbuf.SetFixed( m_version, (uint)Table_EBLC.FieldOffsets.version ); newbuf.SetUint( m_numSizes, (uint)Table_EBLC.FieldOffsets.numSizes ); //Set up initial offsets uint idxArrOffset = (uint)Table_EBLC.FieldOffsets.FirstbitmapSizeTable + (bitmapSizeTable.bufSize * m_numSizes); uint imageDataOffset = (uint)Table_EBDT.FieldOffsets.StartOfData; //EBDTTable for( ushort i = 0; i < m_numSizes; i++ ) { bitmapSizeTableCache bstc = (bitmapSizeTableCache)m_bitmapSizeTables[i]; //Set the offset to the bitmapSizeTable uint bstOffset = (uint)(Table_EBLC.FieldOffsets.FirstbitmapSizeTable + (i * bitmapSizeTable.bufSize)); newbuf.SetUint( idxArrOffset, bstOffset ); newbuf.SetUint( bstc.indexSubTablesSize, bstOffset + (uint)bitmapSizeTable.FieldOffsets.indexTablesSize ); newbuf.SetUint( bstc.numberOfIndexSubTables, bstOffset + (uint)bitmapSizeTable.FieldOffsets.numberOfIndexSubTables ); newbuf.SetUint( bstc.colorRef, bstOffset + (uint)bitmapSizeTable.FieldOffsets.colorRef ); // hori newbuf.SetSbyte( bstc.hori.ascender, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.ascender ); newbuf.SetSbyte( bstc.hori.descender, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.descender ); newbuf.SetByte( bstc.hori.widthMax, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.widthMax ); newbuf.SetSbyte( bstc.hori.caretSlopeNumerator, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretSlopeNumerator ); newbuf.SetSbyte( bstc.hori.caretSlopeDenominator, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretSlopeDenominator ); newbuf.SetSbyte( bstc.hori.caretOffset, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretOffset ); newbuf.SetSbyte( bstc.hori.minOriginSB, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minOriginSB ); newbuf.SetSbyte( bstc.hori.minAdvanceSB, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minAdvanceSB ); newbuf.SetSbyte( bstc.hori.maxBeforeBL, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.maxBeforeBL ); newbuf.SetSbyte( bstc.hori.minAfterBL, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minAfterBL ); newbuf.SetSbyte( bstc.hori.pad1, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.pad1 ); newbuf.SetSbyte( bstc.hori.pad2, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.pad2 ); //vert newbuf.SetSbyte( bstc.vert.ascender, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.ascender ); newbuf.SetSbyte( bstc.vert.descender, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.descender ); newbuf.SetByte( bstc.vert.widthMax, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.widthMax ); newbuf.SetSbyte( bstc.vert.caretSlopeNumerator, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretSlopeNumerator ); newbuf.SetSbyte( bstc.vert.caretSlopeDenominator, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretSlopeDenominator ); newbuf.SetSbyte( bstc.vert.caretOffset, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.caretOffset ); newbuf.SetSbyte( bstc.vert.minOriginSB, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minOriginSB ); newbuf.SetSbyte( bstc.vert.minAdvanceSB, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minAdvanceSB ); newbuf.SetSbyte( bstc.vert.maxBeforeBL, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.maxBeforeBL ); newbuf.SetSbyte( bstc.vert.minAfterBL, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.minAfterBL ); newbuf.SetSbyte( bstc.vert.pad1, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.pad1 ); newbuf.SetSbyte( bstc.vert.pad2, bstOffset + (uint)bitmapSizeTable.FieldOffsets.hori + (uint)sbitLineMetrics.FieldOffsets.pad2 ); newbuf.SetUshort( bstc.startGlyphIndex, bstOffset + (uint)bitmapSizeTable.FieldOffsets.startGlyphIndex ); newbuf.SetUshort( bstc.endGlyphIndex, bstOffset + (uint)bitmapSizeTable.FieldOffsets.endGlyphIndex ); newbuf.SetByte( bstc.ppemX, bstOffset + (uint)bitmapSizeTable.FieldOffsets.ppemX ); newbuf.SetByte( bstc.ppemY, bstOffset + (uint)bitmapSizeTable.FieldOffsets.ppemY ); newbuf.SetByte( bstc.bitDepth, bstOffset + (uint)bitmapSizeTable.FieldOffsets.bitDepth ); newbuf.SetSbyte( bstc.flags, bstOffset + (uint)bitmapSizeTable.FieldOffsets.flags ); uint idxSubTableOffset = idxArrOffset + (bstc.numberOfIndexSubTables * indexSubTableArray.bufSize); // Write this bitmapSizeTable indexSubTableArray and indexSubTable for( int ii = 0; ii < bstc.numberOfIndexSubTables; ii++ ) { // Write out the indexSubTableArray indexSubTableArrayCache istac = bstc.getIndexSubTableArrayCache( ii ); newbuf.SetUshort( istac.firstGlyphIndex, idxArrOffset + (uint)indexSubTableArray.FieldOffsets.firstGlyphIndex + (uint)(ii * indexSubTableArray.bufSize)); newbuf.SetUshort( istac.lastGlyphIndex, idxArrOffset + (uint)indexSubTableArray.FieldOffsets.lastGlyphIndex + (uint)(ii * indexSubTableArray.bufSize)); newbuf.SetUint( (idxSubTableOffset - idxArrOffset), idxArrOffset + (uint)indexSubTableArray.FieldOffsets.additionalOffsetToIndexSubtable + (uint)(ii * indexSubTableArray.bufSize)); // Write out the indexSubTable, The header is the same for all indexFormats newbuf.SetUshort( istac.indexSubTable.indexFormat, idxSubTableOffset + (uint)indexSubHeader.FieldOffsets.indexFormat ); newbuf.SetUshort( istac.indexSubTable.imageFormat, idxSubTableOffset + (uint)indexSubHeader.FieldOffsets.imageFormat ); newbuf.SetUint( imageDataOffset, idxSubTableOffset + (uint)indexSubHeader.FieldOffsets.imageDataOffset ); uint imageOffset = 0; switch( istac.indexSubTable.indexFormat ) { case 1: { indexSubTableCache1 istc = (indexSubTableCache1)istac.indexSubTable; for( ushort iii = istac.firstGlyphIndex; iii <= istac.lastGlyphIndex; iii++ ) { ushort nIndex = (ushort)(iii - istac.firstGlyphIndex); // offset + header length + (uint)offsetArray[iii] newbuf.SetUint( imageOffset, idxSubTableOffset + indexSubTable.headerLength + (uint)(nIndex * 4)); // Write image data for this indexSubTable to EBDT buffer imageCache ic = istc.getImageCache( iii, istac.firstGlyphIndex ); writeEBDTBuffer( bufEBDT, (imageDataOffset + imageOffset), ic, istac.indexSubTable.imageFormat ); imageOffset += ic.imageDataSize(); } // Add the last one so size can be determined newbuf.SetUint( imageOffset, idxSubTableOffset + indexSubTable.headerLength + ((uint)(istac.lastGlyphIndex - istac.firstGlyphIndex + 1) * 4)); break; } case 2: { indexSubTableCache2 istc = (indexSubTableCache2)istac.indexSubTable; // offset + header length newbuf.SetUint( istc.imageSize, idxSubTableOffset + indexSubTable.headerLength ); //BigMetrics, + 12 = indexSubTable.headerLength + (uint)imageSize newbuf.SetByte( istc.bigMetrics.height, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.height ); newbuf.SetByte( istc.bigMetrics.width, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.width ); newbuf.SetSbyte( istc.bigMetrics.horiBearingX, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiBearingX ); newbuf.SetSbyte( istc.bigMetrics.horiBearingY, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiBearingY ); newbuf.SetByte( istc.bigMetrics.horiAdvance, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiAdvance ); newbuf.SetSbyte( istc.bigMetrics.vertBearingX, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertBearingX ); newbuf.SetSbyte( istc.bigMetrics.vertBearingY, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertBearingY ); newbuf.SetByte( istc.bigMetrics.vertAdvance, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertAdvance ); for( ushort iii = istac.firstGlyphIndex; iii <= istac.lastGlyphIndex; iii++ ) { // Write image data for this indexSubTable to EBDT buffer imageCache ic = istc.getImageCache( iii, istac.firstGlyphIndex ); writeEBDTBuffer( bufEBDT, (imageDataOffset + imageOffset), ic, istac.indexSubTable.imageFormat ); imageOffset += ic.imageDataSize(); } break; } case 3: { indexSubTableCache3 istc = (indexSubTableCache3)istac.indexSubTable; for( ushort iii = istac.firstGlyphIndex; iii <= istac.lastGlyphIndex; iii++ ) { ushort nIndex = (ushort)(iii - istac.firstGlyphIndex); // offset + header length + ushort offsetArray[iii] newbuf.SetUshort( (ushort)imageOffset, idxSubTableOffset + indexSubTable.headerLength + (uint)(nIndex * 2 )); // Write image data for this indexSubTable to EBDT buffer imageCache ic = istc.getImageCache( iii, istac.firstGlyphIndex ); writeEBDTBuffer( bufEBDT, (imageDataOffset + imageOffset), ic, istac.indexSubTable.imageFormat ); imageOffset += ic.imageDataSize(); } // Add the last one so size can be determined newbuf.SetUshort( (ushort)imageOffset, idxSubTableOffset + indexSubTable.headerLength + ((uint)(istac.lastGlyphIndex - istac.firstGlyphIndex + 1) * 2 )); break; } case 4: { indexSubTableCache4 istc = (indexSubTableCache4)istac.indexSubTable; // offset + header length newbuf.SetUint( istc.numGlyphs, idxSubTableOffset + indexSubTable.headerLength ); for( ushort iii = 0; iii < istc.numGlyphs; iii++ ) { // offset + header length + (uint)numGlyphs + (4)codeOffsetPair[iii] newbuf.SetUshort( istc.getGlyphCode(iii), idxSubTableOffset + 12 + (uint)(iii * 4)); newbuf.SetUshort( (ushort)imageOffset, idxSubTableOffset + 12 + (uint)(iii * 4) + 2 ); // Write image data for this indexSubTable to EBDT buffer imageCache ic = istc.getImageCache( istc.getGlyphCode(iii)); writeEBDTBuffer( bufEBDT, (imageDataOffset + imageOffset), ic, istac.indexSubTable.imageFormat ); imageOffset += ic.imageDataSize(); } // Add the last codeOffsetPair so size can be determined newbuf.SetUshort( 0, idxSubTableOffset + 12 + (uint)(istc.numGlyphs * 4 )); newbuf.SetUshort( (ushort)imageOffset, idxSubTableOffset + 12 + (uint)(istc.numGlyphs * 4 ) + 2 ); break; } case 5: { indexSubTableCache5 istc = (indexSubTableCache5)istac.indexSubTable; // offset + header length newbuf.SetUint( istc.imageSize, idxSubTableOffset + indexSubTable.headerLength ); //BigMetrics, + 12 = indexSubTable.headerLength + (uint)imageSize newbuf.SetByte( istc.bigMetrics.height, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.height ); newbuf.SetByte( istc.bigMetrics.width, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.width ); newbuf.SetSbyte( istc.bigMetrics.horiBearingX, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiBearingX ); newbuf.SetSbyte( istc.bigMetrics.horiBearingY, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiBearingY ); newbuf.SetByte( istc.bigMetrics.horiAdvance, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.horiAdvance ); newbuf.SetSbyte( istc.bigMetrics.vertBearingX, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertBearingX ); newbuf.SetSbyte( istc.bigMetrics.vertBearingY, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertBearingY ); newbuf.SetByte( istc.bigMetrics.vertAdvance, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.FieldOffsets.vertAdvance ); newbuf.SetUint( istc.numGlyphs, idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.bufSize ); for( ushort iii = 0; iii < istc.numGlyphs; iii++ ) { // offset + header length + (uint)imageSize + bigGlyphMetrics.bufSize + big(uint)numGlyphs + (ushort)glyphCodeArray[iii} newbuf.SetUshort( istc.getGlyphCode(iii), idxSubTableOffset + 12 + (uint)Table_EBDT.bigGlyphMetrics.bufSize + 4 + (uint)(iii * 2 )); // Write image data for this indexSubTable to EBDT buffer imageCache ic = istc.getImageCache( istc.getGlyphCode(iii)); writeEBDTBuffer( bufEBDT, (imageDataOffset + imageOffset), ic, istac.indexSubTable.imageFormat ); imageOffset += ic.imageDataSize(); } break; } } // update imageDataOffset for the next SubTable imageDataOffset += imageOffset; // This will take care of any byte boundaries pads required by some indexSubTables idxSubTableOffset += istac.indexSubTable.indexSubTableSize(); } idxArrOffset += bstc.indexSubTablesSize; } // Put the EBDT buf to that table Table_EBDT.EBDT_cache EBDTCache = (Table_EBDT.EBDT_cache)m_tableEBDT.GetCache(); EBDTCache.setCache( bufEBDT ); // put the buffer into a Table_EBLC object and return it Table_EBLC EBLCTable = new Table_EBLC( "EBLC", newbuf ); return EBLCTable; }
public smallGlyphMetrics GetSmallMetrics( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex ) { smallGlyphMetrics sgm = null; int nIndexFormat = cIndexSubTable.header.indexFormat; int nImageFormat = cIndexSubTable.header.imageFormat; Debug.Assert( nImageFormat == 1 || nImageFormat == 2 || nImageFormat == 8); // These images all have the same metrics as described in the indexSubTable so should have the proper image format // Debug.Assert( nIndexFormat != 2 && nIndexFormat != 5 ); // commented out the above assert because batang.ttc violates this too much if (nImageFormat == 1 || nImageFormat == 2 || nImageFormat == 8) { if( nGlyphIndex >= nStartGlyphIndex ) { //EBDT table starts off with a version data so it would never be possible for this to be set to 0 uint nImageFormatOffset = getImageFormatOffset( cIndexSubTable, nGlyphIndex, nStartGlyphIndex ); if( nImageFormatOffset != 0 ) { // All of the supported image formats start with this data first sgm = new smallGlyphMetrics(); sgm.height = m_bufTable.GetByte( nImageFormatOffset + (uint)smallGlyphMetrics.FieldOffsets.height ); sgm.width = m_bufTable.GetByte( nImageFormatOffset + (uint)smallGlyphMetrics.FieldOffsets.width ); sgm.BearingX = m_bufTable.GetSbyte( nImageFormatOffset + (uint)smallGlyphMetrics.FieldOffsets.BearingX ); sgm.BearingY = m_bufTable.GetSbyte( nImageFormatOffset + (uint)smallGlyphMetrics.FieldOffsets.BearingY ); sgm.Advance = m_bufTable.GetByte( nImageFormatOffset + (uint)smallGlyphMetrics.FieldOffsets.Advance ); } } } return sgm; }
private indexSubTableCache getEBLCIndexSubTable( Table_EBLC OwnerTable, bitmapSizeTable bst, indexSubTableArray ista ) { indexSubTable ist = bst.GetIndexSubTable(ista); Table_EBDT tableEDBT = OwnerTable.getTableEDBT(); indexSubTableCache istc = null; switch( ist.header.indexFormat ) { case 1: { ArrayList cImageCache = new ArrayList(); for( uint i = ista.firstGlyphIndex; i <= ista.lastGlyphIndex; i++ ) { cImageCache.Add( getEBDTImageFormat( tableEDBT, ist, i, ista.firstGlyphIndex )); } istc = new indexSubTableCache1( ist.header.indexFormat, ist.header.imageFormat, cImageCache ); break; } case 2: { ArrayList cImageCache = new ArrayList(); for( uint i = ista.firstGlyphIndex; i <= ista.lastGlyphIndex; i++ ) { cImageCache.Add( getEBDTImageFormat( tableEDBT, ist, i, ista.firstGlyphIndex )); } uint nImageSize = ((indexSubTable2)ist).imageSize; Table_EBDT.bigGlyphMetrics bgm = ((indexSubTable2)ist).bigMetrics; istc = new indexSubTableCache2( ist.header.indexFormat, ist.header.imageFormat, cImageCache, nImageSize, bgm ); break; } case 3: { ArrayList cImageCache = new ArrayList(); for( uint i = ista.firstGlyphIndex; i <= ista.lastGlyphIndex; i++ ) { cImageCache.Add( getEBDTImageFormat( tableEDBT, ist, i, ista.firstGlyphIndex )); } istc = new indexSubTableCache3( ist.header.indexFormat, ist.header.imageFormat, cImageCache ); break; } case 4: { ArrayList cImageCache = new ArrayList(); ArrayList cGlyphCodes = new ArrayList(); for( uint i = 0; i < ((indexSubTable4)ist).numGlyphs; i++ ) { ushort nGlyphCode = ((indexSubTable4)ist).GetCodeOffsetPair( i ).glyphCode; cGlyphCodes.Add( nGlyphCode ); cImageCache.Add( getEBDTImageFormat( tableEDBT, ist, nGlyphCode, ista.firstGlyphIndex )); } istc = new indexSubTableCache4( ist.header.indexFormat, ist.header.imageFormat, cImageCache, cGlyphCodes ); break; } case 5: { ArrayList cImageCache = new ArrayList(); uint nImageSize = ((indexSubTable5)ist).imageSize; Table_EBDT.bigGlyphMetrics bgm = ((indexSubTable5)ist).bigMetrics; ArrayList cGlyphCodes = new ArrayList(); for( uint i = 0; i < ((indexSubTable5)ist).numGlyphs; i++ ) { ushort nGlyphCode = ((indexSubTable5)ist).GetGlyphCode( i ); cGlyphCodes.Add( nGlyphCode ); cImageCache.Add( getEBDTImageFormat( tableEDBT, ist, nGlyphCode, ista.firstGlyphIndex )); } istc = new indexSubTableCache5( ist.header.indexFormat, ist.header.imageFormat, cImageCache, nImageSize, bgm, cGlyphCodes ); break; } default: { Debug.Assert( false, "unsupported index format" ); break; } } return istc; }
// constructor public EBLC_cache( Table_EBLC OwnerTable ) { // copy the data from the owner table's MBOBuffer // and store it in the cache variables m_version = OwnerTable.version; m_numSizes = OwnerTable.numSizes; m_tableEBDT = OwnerTable.getTableEDBT(); m_bitmapSizeTables = new ArrayList( (int)m_numSizes ); for( uint i = 0; i < m_numSizes; i++ ) { bitmapSizeTable bst = OwnerTable.GetBitmapSizeTable( i ); m_bitmapSizeTables.Add( new bitmapSizeTableCache( OwnerTable, bst )); } }
public bitmapSizeTableCache( Table_EBLC OwnerTable, bitmapSizeTable bst ) { m_numberOfIndexSubTables = bst.numberOfIndexSubTables; m_indexSubTableArray = new ArrayList( (int)m_numberOfIndexSubTables ); indexSubTableArray[] ista = OwnerTable.GetIndexSubTableArray( bst ); for( int i = 0; i < m_numberOfIndexSubTables; i++ ) { indexSubTableCache istc = getEBLCIndexSubTable( OwnerTable, bst, ista[i] ); indexSubTableArrayCache istac = new indexSubTableArrayCache( ista[i].firstGlyphIndex, ista[i].lastGlyphIndex, istc ); m_indexSubTableArray.Add( istac ); indexSubTable ic = bst.GetIndexSubTable(ista[i]); //ista[i].additionalOffsetToIndexSubtable += bst.indexSubTableArrayOffset; } m_colorRef = bst.colorRef; hori = sbitLineMetricsCache.FromSbitLineMetrics(bst.hori); vert = sbitLineMetricsCache.FromSbitLineMetrics(bst.vert); m_startGlyphIndex = bst.startGlyphIndex; m_endGlyphIndex = bst.endGlyphIndex; ppemX = bst.ppemX; ppemY = bst.ppemY; bitDepth = bst.bitDepth; flags = bst.flags; }
public bool Validate_Format9(Validator v, string sIdentity, Table_EBLC.indexSubTable ist) { bool bOk = true; Table_EBLC.indexSubTableArray ista = ist.GetIndexSubTableArray(); for (ushort idGlyph=ista.firstGlyphIndex; idGlyph <= ista.lastGlyphIndex; idGlyph++) { // validate big metrics bigGlyphMetrics bgm = GetBigMetrics(ist, idGlyph, ista.firstGlyphIndex); if (bgm != null) { bigGlyphMetrics_val bgm_val = bigGlyphMetrics_val.CreateFromBigGlyphMetrics(bgm); if (!bgm_val.Validate(v, sIdentity + ", idGlyph=" + idGlyph, this)) { bOk = false; } ushort numComponents = this.GetNumComponents(ist, idGlyph, ista.firstGlyphIndex); // validate component array for (uint i=0; i<numComponents; i++) { ebdtComponent component = GetComponent(ist, idGlyph, ista.firstGlyphIndex, i); Debug.Assert(component!= null); // validate the ebdtComponent // verify that the component's glyph code is less than maxp numGlyphs if (component.glyphCode >= m_nCachedMaxpNumGlyphs) { string sDetails = sIdentity + ", idGlyph=" + idGlyph + ", component[" + i + "].glyphCode=" + component.glyphCode + ", maxp.numGlyphs = " + m_nCachedMaxpNumGlyphs; v.Error(T.EBDT_GlyphImageData, E.EBDT_E_GlyphImageData, m_tag, sDetails); bOk = false; } // verify that the component's glyph code isn't 0, which should be reserved as the empty glyph // (technically, someone could use the empty glyph as a component, but it's more likely to be an error) if (component.glyphCode == 0) { string sDetails = sIdentity + ", idGlyph=" + idGlyph + ", component[" + i + "].glyphCode=" + component.glyphCode; v.Error(T.EBDT_GlyphImageData, E.EBDT_E_GlyphImageData, m_tag, sDetails); bOk = false; } // verify that the component's glyph code isn't the glyph code of its parent if (component.glyphCode == idGlyph) { string sDetails = sIdentity + ", idGlyph=" + idGlyph + ", component[" + i + "].glyphCode=" + component.glyphCode + " (glyph can't use itself as a component)"; v.Error(T.EBDT_GlyphImageData, E.EBDT_E_GlyphImageData, m_tag, sDetails); bOk = false; } } } } return bOk; }
public bool Validate_Format7(Validator v, string sIdentity, Table_EBLC.indexSubTable ist) { bool bOk = true; Table_EBLC.indexSubTableArray ista = ist.GetIndexSubTableArray(); for (ushort idGlyph=ista.firstGlyphIndex; idGlyph <= ista.lastGlyphIndex; idGlyph++) { // validate big metrics bigGlyphMetrics bgm = GetBigMetrics(ist, idGlyph, ista.firstGlyphIndex); if (bgm != null) { bigGlyphMetrics_val bgm_val = bigGlyphMetrics_val.CreateFromBigGlyphMetrics(bgm); if (!bgm_val.Validate(v, sIdentity + ", idGlyph=" + idGlyph, this)) { bOk = false; } // validate image data // - this is just bitmap data, any values should be valid } } return bOk; }
protected byte[,] DecodeImageData(Table_EBLC.indexSubTable ist, byte width, byte height, byte bitDepth, byte[] databuf) { byte [,] bits = null; switch (ist.header.imageFormat) { case 0: throw new ApplicationException("illegal image format: 0"); //break; case 1: bits = DecodeImageDataFmt16(width, height, bitDepth, databuf); break; case 2: bits = DecodeImageDataFmt257(width, height, bitDepth, databuf); break; case 3: throw new ApplicationException("illegal image format: 3"); //break; case 4: throw new ApplicationException("illegal image format: 4"); //break; case 5: bits = DecodeImageDataFmt257(width, height, bitDepth, databuf); break; case 6: bits = DecodeImageDataFmt16(width, height, bitDepth, databuf); break; case 7: bits = DecodeImageDataFmt257(width, height, bitDepth, databuf); break; default: break; } return bits; }
public bigGlyphMetrics GetBigMetrics( Table_EBLC.indexSubTable cIndexSubTable, uint nGlyphIndex, uint nStartGlyphIndex ) { bigGlyphMetrics bgm = null; int nIndexFormat = cIndexSubTable.header.indexFormat; int nImageFormat = cIndexSubTable.header.imageFormat; Debug.Assert(nImageFormat == 6 || nImageFormat == 7 || nImageFormat == 9); // These images all have the same metrics as described in the indexSubTable so should have the proper image format //Debug.Assert( nIndexFormat != 2 && nIndexFormat != 5 ); if (nImageFormat == 6 || nImageFormat == 7 || nImageFormat == 9) { if( nGlyphIndex >= nStartGlyphIndex ) { try { uint nImageFormatOffset = getImageFormatOffset( cIndexSubTable, nGlyphIndex, nStartGlyphIndex ); if( nImageFormatOffset != 0 && nImageFormatOffset + bigGlyphMetrics.bufSize <= m_bufTable.GetLength()) { // All of the supported image formats start with this data first bgm = new bigGlyphMetrics(); bgm.height = m_bufTable.GetByte ( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.height ); bgm.width = m_bufTable.GetByte ( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.width ); bgm.horiBearingX = m_bufTable.GetSbyte( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.horiBearingX ); bgm.horiBearingY = m_bufTable.GetSbyte( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.horiBearingY ); bgm.horiAdvance = m_bufTable.GetByte ( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.horiAdvance ); bgm.vertBearingX = m_bufTable.GetSbyte( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.vertBearingX ); bgm.vertBearingY = m_bufTable.GetSbyte( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.vertBearingY ); bgm.vertAdvance = m_bufTable.GetByte ( nImageFormatOffset + (uint)bigGlyphMetrics.FieldOffsets.vertAdvance ); } } catch(Exception) { bgm = null; } } } return bgm; }
public virtual OTTable CreateTableObject(OTTag tag, MBOBuffer buf) { OTTable table = null; string sName = GetUnaliasedTableName(tag); switch (sName) { case "BASE": table = new Table_BASE(tag, buf); break; case "CFF ": table = new Table_CFF(tag, buf); break; case "cmap": table = new Table_cmap(tag, buf); break; case "cvt ": table = new Table_cvt(tag, buf); break; case "DSIG": table = new Table_DSIG(tag, buf); break; case "EBDT": table = new Table_EBDT(tag, buf); break; case "EBLC": table = new Table_EBLC(tag, buf); break; case "EBSC": table = new Table_EBSC(tag, buf); break; case "fpgm": table = new Table_fpgm(tag, buf); break; case "gasp": table = new Table_gasp(tag, buf); break; case "GDEF": table = new Table_GDEF(tag, buf); break; case "glyf": table = new Table_glyf(tag, buf); break; case "GPOS": table = new Table_GPOS(tag, buf); break; case "GSUB": table = new Table_GSUB(tag, buf); break; case "hdmx": table = new Table_hdmx(tag, buf); break; case "head": table = new Table_head(tag, buf); break; case "hhea": table = new Table_hhea(tag, buf); break; case "hmtx": table = new Table_hmtx(tag, buf); break; case "JSTF": table = new Table_JSTF(tag, buf); break; case "kern": table = new Table_kern(tag, buf); break; case "loca": table = new Table_loca(tag, buf); break; case "LTSH": table = new Table_LTSH(tag, buf); break; case "maxp": table = new Table_maxp(tag, buf); break; case "name": table = new Table_name(tag, buf); break; case "OS/2": table = new Table_OS2(tag, buf); break; case "PCLT": table = new Table_PCLT(tag, buf); break; case "post": table = new Table_post(tag, buf); break; case "prep": table = new Table_prep(tag, buf); break; case "VDMX": table = new Table_VDMX(tag, buf); break; case "vhea": table = new Table_vhea(tag, buf); break; case "vmtx": table = new Table_vmtx(tag, buf); break; case "VORG": table = new Table_VORG(tag, buf); break; //case "Zapf": table = new Table_Zapf(tag, buf); break; default: table = new Table__Unknown(tag, buf); break; } return table; }
public bool Validate_Format4(Validator v, string sIdentity, Table_EBLC.indexSubTable ist) { bool bOk = true; // this format is not supported! // - however the image format number is actually stored in the EBLC table // - and so any errors should get reported there return bOk; }