Esempio n. 1
0
        public uint GetNumPadBytesAfterTable(OTTable t)
        {
            long TableFilePos = t.GetBuffer().GetFilePos();

            if (TableFilePos == -1)
            {
                // the table's file position is initialized to -1 if the table was not read from a file
                throw new ApplicationException("invalid file position");
            }

            uint TableLength = t.GetBuffer().GetLength();
            long PadFilePos  = TableFilePos + TableLength;

            long NextTablePos = m_fs.Length;

            // possible DSIG in TTC after all the tables
            if (IsCollection() && m_ttch.DsigTag != null && (string)m_ttch.DsigTag == "DSIG" && m_ttch.DsigOffset > 0 && m_ttch.DsigOffset < NextTablePos && (string)t.m_tag != "DSIG")
            {
                NextTablePos = m_ttch.DsigOffset;
            }

            for (uint iFont = 0; iFont < m_nFonts; iFont++)
            {
                if (IsCollection())
                {
                    uint offset = (uint)m_ttch.DirectoryOffsets[(int)iFont];
                    if (offset >= PadFilePos && offset < NextTablePos)
                    {
                        NextTablePos = offset;
                    }
                }

                OTFont f = GetFont(iFont);
                for (ushort iTable = 0; iTable < f.GetNumTables(); iTable++)
                {
                    DirectoryEntry de = f.GetDirectoryEntry(iTable);
                    if (de.offset >= PadFilePos && de.offset < NextTablePos)
                    {
                        NextTablePos = de.offset;
                    }
                }
            }

            return((uint)(NextTablePos - PadFilePos));
        }
Esempio n. 2
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);
        }
Esempio n. 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;
        }