static byte[] get_TTC_digest( OTFile f ) { TTCHeader ttc = f.GetTTCHeader(); uint back_shift = 12; //if ( ttc.version == 0x00020000 ) back_shift = 0; TTCHBuffer ttcb = new TTCHBuffer ( 12 + ttc.DirectoryCount * 4 + 12 - back_shift ); // write the TTC header ttcb.FillUint32MBO((uint) ttc.TTCTag); ttcb.FillUint32MBO(ttc.version); ttcb.FillUint32MBO(ttc.DirectoryCount); for (int i=0; i< f.GetNumFonts() ; i++) { ttcb.FillUint32MBO( (uint) ttc.DirectoryOffsets[i] - back_shift); } //if ( ttc.version == 0x00020000 ) { ttcb.FillUint32MBO( 0 ); ttcb.FillUint32MBO( 0 ); ttcb.FillUint32MBO( 0 ); } hash.TransformBlock ( ttcb.buffer, 0, ttcb.buffer.Length, ttcb.buffer, 0 ); // build an array of offset tables OffsetTable[] otArr = new OffsetTable[f.GetNumFonts()]; for (uint iFont=0; iFont<f.GetNumFonts(); iFont++) { otArr[iFont] = new OffsetTable(new OTFixed(1,0), f.GetFont(iFont).GetNumTables()); for (ushort i=0; i<f.GetFont(iFont).GetNumTables(); i++) { DirectoryEntry old = f.GetFont(iFont).GetDirectoryEntry(i); DirectoryEntry de = new DirectoryEntry(old); de.offset -= back_shift; otArr[iFont].DirectoryEntries.Add(de); } } if ( (uint) ttc.DirectoryOffsets[(int)f.GetNumFonts()-1] < f.GetFont(0).GetDirectoryEntry(0).offset ) { // assume directory-contiguous for (uint iFont=0; iFont<f.GetNumFonts(); iFont++) { // write the offset table hash.TransformBlock (otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(), otArr[iFont].m_buf.GetBuffer(), 0); // write the directory entries for (int i=0; i<f.GetFont(iFont).GetNumTables(); i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; hash.TransformBlock (de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(), de.m_buf.GetBuffer(), 0 ); } } } // write out each font uint PrevPos = 0; for (uint iFont=0; iFont<f.GetNumFonts(); iFont++) { ushort numTables = f.GetFont(iFont).GetNumTables(); if ( (uint) ttc.DirectoryOffsets[(int)f.GetNumFonts()-1] > f.GetFont(0).GetDirectoryEntry(0).offset ) { // assume font-contiguous // write the offset table hash.TransformBlock (otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(), otArr[iFont].m_buf.GetBuffer(), 0 ); // write the directory entries for (int i=0; i<numTables; i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; hash.TransformBlock (de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(), de.m_buf.GetBuffer(), 0 ); } } // write out each table unless a shared version has been written for (ushort i=0; i<numTables; i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; if (PrevPos < de.offset) //crude { OTTable table = f.GetFont(iFont).GetTable(de.tag); hash.TransformBlock (table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength(), table.m_bufTable.GetBuffer(), 0 ); PrevPos = de.offset; } } } byte[] usFlag = {0, 1}; hash.TransformFinalBlock(usFlag, 0,2); return hash.Hash; }
static byte[] get_TTC_digest(OTFile f) { TTCHeader ttc = f.GetTTCHeader(); uint back_shift = 12; //if ( ttc.version == 0x00020000 ) back_shift = 0; TTCHBuffer ttcb = new TTCHBuffer(12 + ttc.DirectoryCount * 4 + 12 - back_shift); // write the TTC header ttcb.FillUint32MBO((uint)ttc.TTCTag); ttcb.FillUint32MBO(ttc.version); ttcb.FillUint32MBO(ttc.DirectoryCount); for (int i = 0; i < f.GetNumFonts(); i++) { ttcb.FillUint32MBO((uint)ttc.DirectoryOffsets[i] - back_shift); } //if ( ttc.version == 0x00020000 ) { ttcb.FillUint32MBO(0); ttcb.FillUint32MBO(0); ttcb.FillUint32MBO(0); } uint Position = (uint)ttcb.buffer.Length; hash.TransformBlock(ttcb.buffer, 0, ttcb.buffer.Length, ttcb.buffer, 0); // build an array of offset tables OffsetTable[] otArr = new OffsetTable[f.GetNumFonts()]; for (uint iFont = 0; iFont < f.GetNumFonts(); iFont++) { otArr[iFont] = new OffsetTable(new OTFixed(1, 0), f.GetFont(iFont).GetNumTables()); for (ushort i = 0; i < f.GetFont(iFont).GetNumTables(); i++) { DirectoryEntry old = f.GetFont(iFont).GetDirectoryEntry(i); DirectoryEntry de = new DirectoryEntry(old); de.offset -= back_shift; otArr[iFont].DirectoryEntries.Add(de); } } if ((uint)ttc.DirectoryOffsets[(int)f.GetNumFonts() - 1] < f.GetFont(0).GetDirectoryEntry(0).offset) { // assume directory-contiguous for (uint iFont = 0; iFont < f.GetNumFonts(); iFont++) { // write the offset table hash.TransformBlock(otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(), otArr[iFont].m_buf.GetBuffer(), 0); Position += otArr[iFont].m_buf.GetLength(); // write the directory entries for (int i = 0; i < f.GetFont(iFont).GetNumTables(); i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; hash.TransformBlock(de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(), de.m_buf.GetBuffer(), 0); Position += de.m_buf.GetLength(); } } } // write out each font uint max_offset = 0; uint max_padded_length = 0; uint PrevPos = 0; for (uint iFont = 0; iFont < f.GetNumFonts(); iFont++) { ushort numTables = f.GetFont(iFont).GetNumTables(); if ((uint)ttc.DirectoryOffsets[(int)f.GetNumFonts() - 1] > f.GetFont(0).GetDirectoryEntry(0).offset) { // assume font-contiguous // write the offset table hash.TransformBlock(otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(), otArr[iFont].m_buf.GetBuffer(), 0); Position += otArr[iFont].m_buf.GetLength(); // write the directory entries for (int i = 0; i < numTables; i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; hash.TransformBlock(de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(), de.m_buf.GetBuffer(), 0); Position += de.m_buf.GetLength(); } } // write out each table unless a shared version has been written for (ushort i = 0; i < numTables; i++) { DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i]; if (de.offset > max_offset) { max_offset = de.offset; max_padded_length = f.GetFont(iFont).GetTable(de.tag).GetBuffer().GetPaddedLength(); } if (PrevPos < de.offset) //crude { OTTable table = f.GetFont(iFont).GetTable(de.tag); hash.TransformBlock(table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength(), table.m_bufTable.GetBuffer(), 0); Position += table.GetBuffer().GetPaddedLength(); PrevPos = de.offset; } } } if (max_offset + max_padded_length - Position != 0) { throw new NotImplementedException("Unusual TTC Directory Layout"); } byte[] usFlag = { 0, 1 }; hash.TransformFinalBlock(usFlag, 0, 2); return(hash.Hash); }