Пример #1
0
        /// <summary>Write a single OTF to a disk file, with tables in
        /// proper order, checksums set, etc.
        /// </summary>
        public static bool WriteSfntFile(FileStream fs, OTFont font)
        {
            bool bRet = true;


            OTFixed     sfntVersion = new OTFixed(1, 0);
            ushort      numTables   = font.GetNumTables();
            OffsetTable ot          = new OffsetTable(sfntVersion, numTables);


            // order tables in fastfont order

            string [] arrOrderedNames = null;
            string [] ttNames         =
            {
                "head", "hhea", "maxp", "OS/2", "hmtx", "LTSH", "VDMX", "hdmx", "cmap", "fpgm",
                "prep", "cvt ", "loca", "glyf", "kern", "name", "post", "gasp", "PCLT"
            };
            string [] psNames =
            {
                "head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF "
            };

            if (font.ContainsTrueTypeOutlines())
            {
                arrOrderedNames = ttNames;
            }
            else if (font.ContainsPostScriptOutlines())
            {
                arrOrderedNames = psNames;
            }

            OTTable[] OrderedTables = new OTTable[numTables];
            for (ushort i = 0; i < numTables; i++)
            {
                OrderedTables[i] = font.GetTable(i);
            }

            if (arrOrderedNames != null)
            {
                ushort curpos = 0;
                for (int iName = 0; iName < arrOrderedNames.Length; iName++)
                {
                    for (ushort i = curpos; i < numTables; i++)
                    {
                        if (arrOrderedNames[iName] == (string)OrderedTables[i].m_tag)
                        {
                            OTTable temp = OrderedTables[curpos];
                            OrderedTables[curpos] = OrderedTables[i];
                            OrderedTables[i]      = temp;
                            curpos++;
                            break;
                        }
                    }
                }
            }


            // update the modified date in the head table

            for (int i = 0; i < OrderedTables.Length; i++)
            {
                if ((string)OrderedTables[i].m_tag == "head")
                {
                    // get the cache
                    Table_head            headTable = (Table_head)OrderedTables[i];
                    Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

                    // set the 'modified' field to the current date and time
                    DateTime dt = DateTime.Now;
                    headCache.modified = headTable.DateTimeToSecondsSince1904(dt);

                    // generate a new table and replace the head table in the list of ordered tables
                    Table_head newHead = (Table_head)headCache.GenerateTable();
                    OrderedTables[i] = newHead;

                    break;
                }
            }


            // build a list of directory entries

            long TableFilePos = 12 + numTables * 16;

            for (ushort i = 0; i < numTables; i++)
            {
                OTTable table = OrderedTables[i];
                OTTag   tag   = table.m_tag;

                // build a new directory entry
                DirectoryEntry de = new DirectoryEntry();
                de.tag      = new OTTag(tag.GetBytes());
                de.checkSum = table.CalcChecksum();
                de.offset   = (uint)TableFilePos;
                de.length   = table.GetLength();

                ot.DirectoryEntries.Add(de);

                TableFilePos += table.GetBuffer().GetPaddedLength();
            }


            // sort the directory entries

            if (numTables > 1)
            {
                for (int i = 0; i < numTables - 1; i++)
                {
                    for (int j = i + 1; j < numTables; j++)
                    {
                        if (((DirectoryEntry)(ot.DirectoryEntries[i])).tag > ((DirectoryEntry)(ot.DirectoryEntries[j])).tag)
                        {
                            DirectoryEntry temp = (DirectoryEntry)ot.DirectoryEntries[i];
                            ot.DirectoryEntries[i] = (DirectoryEntry)ot.DirectoryEntries[j];
                            ot.DirectoryEntries[j] = temp;
                        }
                    }
                }
            }


            // update the font checksum in the head table

            for (int i = 0; i < OrderedTables.Length; i++)
            {
                if ((string)OrderedTables[i].m_tag == "head")
                {
                    // calculate the checksum
                    uint sum = 0;
                    sum += ot.CalcOffsetTableChecksum();
                    sum += ot.CalcDirectoryEntriesChecksum();
                    for (int j = 0; j < OrderedTables.Length; j++)
                    {
                        sum += OrderedTables[j].CalcChecksum();
                    }

                    // get the cache
                    Table_head            headTable = (Table_head)OrderedTables[i];
                    Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

                    // set the checkSumAdujustment field
                    headCache.checkSumAdjustment = 0xb1b0afba - sum;

                    // generate a new table and replace the head table in the list of ordered tables
                    Table_head newHead = (Table_head)headCache.GenerateTable();
                    OrderedTables[i] = newHead;

                    break;
                }
            }


            // write the offset table

            fs.Write(ot.m_buf.GetBuffer(), 0, (int)ot.m_buf.GetLength());


            // write the directory entries

            for (int i = 0; i < numTables; i++)
            {
                DirectoryEntry de = (DirectoryEntry)ot.DirectoryEntries[i];
                fs.Write(de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength());
            }


            // write the tables

            for (ushort i = 0; i < numTables; i++)
            {
                OTTable table = OrderedTables[i];

                fs.Write(table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength());
            }


            return(bRet);
        }
Пример #2
0
        static byte[] get_TTF_digest( OTFile f )
        {
            OTFont fn = f.GetFont(0);
            Table_DSIG tDSIG = (Table_DSIG) fn.GetTable("DSIG");
            DirectoryEntry deDSIG = null;
            // sort table by offset
            Dictionary<uint, int> offsetlookup = new Dictionary<uint, int>();
            var list = new List<uint>();
            for (ushort i=0; i<fn.GetNumTables(); i++) {
                DirectoryEntry de = fn.GetDirectoryEntry(i);
                offsetlookup.Add(de.offset, i);
                list.Add( de.offset );
                if ((string) de.tag == "DSIG" )
                    deDSIG = de;
            }
            list.Sort();

            // New offset table
            var old_ot = fn.GetOffsetTable();
            OffsetTable ot = new OffsetTable (old_ot.sfntVersion, (ushort) ( old_ot.numTables - 1) );

            for (ushort i=0; i<fn.GetNumTables(); i++) {
                DirectoryEntry oldde = fn.GetDirectoryEntry(i);
                if ( (string) oldde.tag != "DSIG" )
                {
                    DirectoryEntry de = new DirectoryEntry(oldde);
                    de.offset -=16; // one less entry
                    if ( de.offset > deDSIG.offset )
                        de.offset -= tDSIG.GetBuffer().GetPaddedLength();
                    ot.DirectoryEntries.Add(de);
                }
            }
            hash.TransformBlock (ot.m_buf.GetBuffer(), 0, (int)ot.m_buf.GetLength(), ot.m_buf.GetBuffer(), 0);

            for (int i=0; i< ot.DirectoryEntries.Count ; i++)
            {
                DirectoryEntry de = (DirectoryEntry)ot.DirectoryEntries[i];
                hash.TransformBlock (de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(), de.m_buf.GetBuffer(), 0);
            }

            Table_head headTable = (Table_head) fn.GetTable("head");

            // calculate the checksum
            uint sum = 0;
            sum += ot.CalcOffsetTableChecksum();
            sum += ot.CalcDirectoryEntriesChecksum();
            foreach (var key in list) {
                OTTable table = fn.GetTable((ushort)offsetlookup[key]);

                if ( (string) table.GetTag() != "DSIG")
                    sum += table.CalcChecksum();
            }

            Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

            // set the checkSumAdujustment field
            headCache.checkSumAdjustment = 0xb1b0afba - sum;
            Table_head newHead = (Table_head)headCache.GenerateTable();

            foreach (var key in list) {
                OTTable table = fn.GetTable((ushort)offsetlookup[key]);

                if ( (string) table.GetTag() == "head" )
                    table = newHead;

                if ( (string) table.GetTag() != "DSIG" ) {
                    hash.TransformBlock (table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength(),
                                         table.m_bufTable.GetBuffer(), 0);
                }
            }

            byte[] usFlag = {0, 1};
            hash.TransformFinalBlock(usFlag, 0,2);
            return hash.Hash;
        }
Пример #3
0
        /// <summary>Write a single OTF to a disk file, with tables in
        /// proper order, checksums set, etc.
        /// </summary>
        public static bool WriteSfntFile(FileStream fs, OTFont font)
        {
            bool bRet = true;

            OTFixed sfntVersion = new OTFixed(1,0);
            ushort numTables = font.GetNumTables();
            OffsetTable ot = new OffsetTable(sfntVersion, numTables);

            // order tables in fastfont order

            string [] arrOrderedNames = null;
            string [] ttNames =
                {
                    "head", "hhea", "maxp", "OS/2", "hmtx", "LTSH", "VDMX", "hdmx", "cmap", "fpgm",
                    "prep", "cvt ", "loca", "glyf", "kern", "name", "post", "gasp", "PCLT"
                };
            string [] psNames =
                {
                    "head", "hhea", "maxp", "OS/2", "name", "cmap", "post", "CFF "
                };

            if (font.ContainsTrueTypeOutlines())
            {
                arrOrderedNames = ttNames;
            }
            else if (font.ContainsPostScriptOutlines())
            {
                arrOrderedNames = psNames;
            }

            OTTable[] OrderedTables = new OTTable[numTables];
            for (ushort i=0; i<numTables; i++)
            {
                OrderedTables[i] = font.GetTable(i);
            }

            if (arrOrderedNames != null)
            {
                ushort curpos = 0;
                for (int iName=0; iName<arrOrderedNames.Length; iName++)
                {
                    for (ushort i=curpos; i<numTables; i++)
                    {
                        if (arrOrderedNames[iName] == (string)OrderedTables[i].m_tag)
                        {
                            OTTable temp = OrderedTables[curpos];
                            OrderedTables[curpos] = OrderedTables[i];
                            OrderedTables[i] = temp;
                            curpos++;
                            break;
                        }
                    }
                }
            }

            // update the modified date in the head table

            for (int i=0; i<OrderedTables.Length; i++)
            {
                if ((string)OrderedTables[i].m_tag == "head")
                {
                    // get the cache
                    Table_head headTable = (Table_head)OrderedTables[i];
                    Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

                    // set the 'modified' field to the current date and time
                    DateTime dt = DateTime.Now;
                    headCache.modified = headTable.DateTimeToSecondsSince1904(dt);

                    // generate a new table and replace the head table in the list of ordered tables
                    Table_head newHead = (Table_head)headCache.GenerateTable();
                    OrderedTables[i] = newHead;

                    break;
                }
            }

            // build a list of directory entries

            long TableFilePos = 12 + numTables*16;

            for (ushort i=0; i<numTables; i++)
            {
                OTTable table = OrderedTables[i];
                OTTag tag = table.m_tag;

                // build a new directory entry
                DirectoryEntry de = new DirectoryEntry();
                de.tag = new OTTag(tag.GetBytes());
                de.checkSum = table.CalcChecksum();
                de.offset = (uint)TableFilePos;
                de.length = table.GetLength();

                ot.DirectoryEntries.Add(de);

                TableFilePos += table.GetBuffer().GetPaddedLength();
            }

            // sort the directory entries

            if (numTables > 1)
            {
                for (int i=0; i<numTables-1; i++)
                {
                    for (int j=i+1; j<numTables; j++)
                    {
                        if (((DirectoryEntry)(ot.DirectoryEntries[i])).tag > ((DirectoryEntry)(ot.DirectoryEntries[j])).tag)
                        {
                            DirectoryEntry temp = (DirectoryEntry)ot.DirectoryEntries[i];
                            ot.DirectoryEntries[i] = (DirectoryEntry)ot.DirectoryEntries[j];
                            ot.DirectoryEntries[j] = temp;
                        }
                    }
                }
            }

            // update the font checksum in the head table

            for (int i=0; i<OrderedTables.Length; i++)
            {
                if ((string)OrderedTables[i].m_tag == "head")
                {
                    // calculate the checksum
                    uint sum = 0;
                    sum += ot.CalcOffsetTableChecksum();
                    sum += ot.CalcDirectoryEntriesChecksum();
                    for (int j=0; j<OrderedTables.Length; j++)
                    {
                        sum += OrderedTables[j].CalcChecksum();
                    }

                    // get the cache
                    Table_head headTable = (Table_head)OrderedTables[i];
                    Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

                    // set the checkSumAdujustment field
                    headCache.checkSumAdjustment = 0xb1b0afba - sum;

                    // generate a new table and replace the head table in the list of ordered tables
                    Table_head newHead = (Table_head)headCache.GenerateTable();
                    OrderedTables[i] = newHead;

                    break;
                }
            }

            // write the offset table

            fs.Write(ot.m_buf.GetBuffer(), 0, (int)ot.m_buf.GetLength());

            // write the directory entries

            for (int i=0; i<numTables; i++)
            {
                DirectoryEntry de = (DirectoryEntry)ot.DirectoryEntries[i];
                fs.Write(de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength());
            }

            // write the tables

            for (ushort i=0; i<numTables; i++)
            {
                OTTable table = OrderedTables[i];

                fs.Write(table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength());
            }

            return bRet;
        }