Exemplo n.º 1
0
        /************************
         * public methods
         */
        
        
        public OTTable GetTable(OTFont fontOwner, DirectoryEntry de)
        {
            // first try getting it from the table cache
            OTTable table = GetTableFromCache(de);

            if (table == null)
            {
                if (   de.length != 0 
                    && de.offset != 0 
                    && de.offset < m_file.GetFileLength()
                    && de.offset + de.length <= m_file.GetFileLength())
                {
                    // read the table from the file
                    MBOBuffer buf = m_file.ReadPaddedBuffer(de.offset, de.length);

                    if (buf != null)
                    {
                        // put the buffer into a table object
                        table = CreateTableObject(de.tag, buf);

                        // add the table to the cache
                        CachedTables.Add(table);
                    }
                }
            }

            return table;
        }
Exemplo n.º 2
0
        /// <summary>Return <c>true</c> iff <c>de</c> is for a 
        /// <c>DirectoryEntry</c> for a table equal to this one in
        /// tag, checksum, file offset and length.
        /// </summary>
        public bool MatchDirectoryEntry(DirectoryEntry de)
        {
            bool bRet = true;

            if (de.tag != m_tag)
            {
                bRet = false;
            }

            if (de.checkSum != CalcChecksum())
            {
                bRet = false;
            }

            if (!MatchFileOffsetLength(de.offset, de.length))
            {
                bRet = false;
            }

            return bRet;
        }
Exemplo n.º 3
0
        /************************
         * protected methods
         */

        protected OTTable GetTableFromCache(DirectoryEntry de)
        {
            OTTable ot = null;

            for (int i=0; i<CachedTables.Count; i++)
            {
                OTTable temp = (OTTable)CachedTables[i];
                if (temp.MatchFileOffsetLength(de.offset, de.length))
                {
                    ot = temp;
                    break;
                }
            }

            return ot;
        }
Exemplo n.º 4
0
 /// <summary>Notify observer of TableBegin and TableEnd events</summary>
 public void OnTableValidationEvent(DirectoryEntry de, bool bBegin)
 {
     if (m_OnValidateEvent != null)
     {
         if (bBegin)
         {
             m_OnValidateEvent(EventTypes.TableBegin, de);
         }
         else
         {
             m_OnValidateEvent(EventTypes.TableEnd, de);
         }
     }
 }
Exemplo n.º 5
0
 public void OnBeginTableTest(DirectoryEntry de)
 {
     StdOut("Table Test: " + (string)de.tag);
 }
Exemplo n.º 6
0
        /// <summary>Write a TTC (TT Collection) to a disk file.</summary>
        public static bool WriteTTCFile(FileStream fs, OTFont[] fonts)
        {
            bool bRet = true;

            // build the TTC header

            OTTag TTCtag = (OTTag)"ttcf";
            uint version = 0x00020000;
            uint DirectoryCount = (uint)fonts.Length;
            uint [] TableDirectory = new uint[fonts.Length];
            uint ulDsigTag    = 0;
            uint ulDsigLength = 0;
            uint ulDsigOffset = 0;

            uint TTCHeaderLen = 12 + DirectoryCount * 4 + 12; // length of version 2.0 header

            // build an array of offset tables
            OffsetTable[] otArr = new OffsetTable[fonts.Length];
            for (int iFont=0; iFont<fonts.Length; iFont++)
            {
                otArr[iFont] = new OffsetTable(new OTFixed(1,0), fonts[iFont].GetNumTables());
            }

            // build an array of head tables that will contain the updated modified field and font checksum
            Table_head[] arrHeadTables = new Table_head[fonts.Length];
            for (int i=0; i<fonts.Length; i++)
            {
                // get the cache
                Table_head headTable = (Table_head)fonts[i].GetTable("head");
                Table_head.head_cache headCache = (Table_head.head_cache)headTable.GetCache();

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

                // generate a new table and add it to the array
                Table_head newHead = (Table_head)headCache.GenerateTable();
                arrHeadTables[i] = newHead;
            }

            // build a list of directory entries for each font

            long FilePos = TTCHeaderLen;

            for (int iFont = 0; iFont<fonts.Length; iFont++)
            {
                ushort numTables = fonts[iFont].GetNumTables();
                TableDirectory[iFont] = (uint)FilePos;
                FilePos += 12 + numTables*16;

                uint PrevFilePos = 0;
                for (ushort i=0; i<numTables; i++)
                {
                    OTTable table = fonts[iFont].GetTable(i);
                    OTTag tag = table.m_tag;

                    if ((string)tag == "head")
                    {
                        table = arrHeadTables[iFont];
                    }

                    // check if this table is a duplicate of a table in a previous font

                    PrevFilePos = 0;
                    if (iFont > 0)
                    {
                        for (int iPrevFont=0; iPrevFont<iFont; iPrevFont++)
                        {
                            for (int iTable=0; iTable<fonts[iPrevFont].GetNumTables(); iTable++)
                            {
                                OTTable PrevTable = fonts[iPrevFont].GetTable(table.m_tag);
                                if (PrevTable != null)
                                {
                                    if (MBOBuffer.BinaryEqual(table.m_bufTable, PrevTable.m_bufTable))
                                    {
                                        // get the file position for the previous table
                                        for (int iDe=0; iDe<otArr[iPrevFont].DirectoryEntries.Count; iDe++)
                                        {
                                            DirectoryEntry dePrev = (DirectoryEntry)otArr[iPrevFont].DirectoryEntries[iDe];
                                            if (dePrev.tag == table.m_tag)
                                            {
                                                PrevFilePos = dePrev.offset;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // build a new directory entry

                    DirectoryEntry de = new DirectoryEntry();
                    de.tag = new OTTag(tag.GetBytes());
                    de.checkSum = table.CalcChecksum();
                    de.length = table.GetLength();
                    if (PrevFilePos != 0)
                    {
                        de.offset = (uint)PrevFilePos;
                    }
                    else
                    {
                        de.offset = (uint)FilePos;
                        FilePos += table.GetBuffer().GetPaddedLength();
                    }

                    otArr[iFont].DirectoryEntries.Add(de);
                }

                // 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)otArr[iFont].DirectoryEntries[i]).tag > ((DirectoryEntry)otArr[iFont].DirectoryEntries[j]).tag)
                            {
                                DirectoryEntry temp = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                                otArr[iFont].DirectoryEntries[i] = (DirectoryEntry)otArr[iFont].DirectoryEntries[j];
                                otArr[iFont].DirectoryEntries[j] = temp;
                            }
                        }
                    }
                }
            }

            // update each font's checksum in the head table

            for (int iFont=0; iFont<fonts.Length; iFont++)
            {
                ushort numTables = fonts[iFont].GetNumTables();

                // calculate the checksum
                uint sum = 0;
                sum += otArr[iFont].CalcOffsetTableChecksum();
                sum += otArr[iFont].CalcDirectoryEntriesChecksum();
                for (ushort i=0; i<numTables; i++)
                {
                    DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                    OTTable table = fonts[iFont].GetTable(de.tag);
                    if ((string)de.tag == "head")
                    {
                        table = arrHeadTables[iFont];
                    }
                    sum += table.CalcChecksum();
                }

                // get the cache
                Table_head headTable = arrHeadTables[iFont];
                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 array of head tables
                Table_head newHead = (Table_head)headCache.GenerateTable();
                arrHeadTables[iFont] = newHead;

            }

            // write the TTC header

            WriteUint32MBO(fs, (uint)TTCtag);
            WriteUint32MBO(fs, version);
            WriteUint32MBO(fs, DirectoryCount);
            for (int i=0; i<fonts.Length; i++)
            {
                WriteUint32MBO(fs, TableDirectory[i]);
            }
            WriteUint32MBO(fs, ulDsigTag);
            WriteUint32MBO(fs, ulDsigLength);
            WriteUint32MBO(fs, ulDsigOffset);

            // write out each font

            for (int iFont=0; iFont<fonts.Length; iFont++)
            {
                ushort numTables = fonts[iFont].GetNumTables();

                // write the offset table

                fs.Write(otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength());

                // write the directory entries

                for (int i=0; i<numTables; i++)
                {
                    DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                    fs.Write(de.m_buf.GetBuffer(), 0, (int)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 (fs.Position == de.offset)
                    {
                        OTTable table = fonts[iFont].GetTable(de.tag);
                        if ((string)table.m_tag == "head")
                        {
                            table = arrHeadTables[iFont];
                        }
                        fs.Write(table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength());
                    }
                }

            }

            return bRet;
        }
Exemplo n.º 7
0
        /******************
         * protected methods
         */
        
        
        protected static OffsetTable ReadOffsetTable(OTFile file, uint filepos)
        {
            // read the Offset Table from the file

            const int SIZEOF_OFFSETTABLE = 12;

            OffsetTable ot = null;


            // read the offset table

            MBOBuffer buf = file.ReadPaddedBuffer(filepos, SIZEOF_OFFSETTABLE);

            if (buf != null)
            {
                if (OTFile.IsValidSfntVersion(buf.GetUint(0)))
                {
                    ot = new OffsetTable(buf);
                }
            }


            // now read the directory entries

            if (ot != null)
            {
                const int SIZEOF_DIRECTORYENTRY = 16;


                for (int i=0; i<ot.numTables; i++)
                {
                    uint dirFilePos = (uint)(filepos+SIZEOF_OFFSETTABLE+i*SIZEOF_DIRECTORYENTRY);
                    MBOBuffer DirEntBuf = file.ReadPaddedBuffer(dirFilePos, SIZEOF_DIRECTORYENTRY);

                    if (DirEntBuf != null)
                    {
                        DirectoryEntry de = new DirectoryEntry(DirEntBuf);
                        ot.DirectoryEntries.Add(de);                        
                    }
                    else
                    {
                        Debug.Assert(false);
                        break;
                    }
                }
            }

            return ot;
        }
Exemplo n.º 8
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;
        }
Exemplo n.º 9
0
 public void OnBeginTableTest( DirectoryEntry de )
 {
     string name = ( string )de.tag;
     if (m_verbose == true && m_vp.IsTestingTable(name))
         StdOut( "Table Test: " + name );
 }
Exemplo n.º 10
0
 public DirectoryEntry(DirectoryEntry obj)
 {
     if (m_buf == null)
         m_buf = new MBOBuffer(16);
     tag = new OTTag(obj.tag.GetBytes());
     checkSum = obj.checkSum;
     offset   = obj.offset;
     length   = obj.length;
 }
Exemplo n.º 11
0
 private void OnBeginTable( DirectoryEntry de )
 {
     m_xmlWriter.WriteStartElement("TableEntry");
     m_xmlWriter.WriteAttributeString("Tag", de.tag);
     m_xmlWriter.WriteAttributeString("Offset", 
                                      "0x"+de.offset.ToString("x8"));
     m_xmlWriter.WriteAttributeString("Length", 
                                      "0x"+de.length.ToString("x8"));
     m_xmlWriter.WriteAttributeString("Checksum", 
                                      "0x"+de.checkSum.ToString("x8"));
     m_xmlWriter.WriteAttributeString("CodeFriendlyTag", 
                                      MakeCodeFriendlyTag(de.tag));
     m_xmlWriter.WriteWhitespace("\r\n");
     
     m_callbacks.OnBeginTableTest( de );
 }
Exemplo n.º 12
0
        /*****************
        * protected methods
        */

        /*****************
         * public methods
         */

        //meant to avoid code repetition (is called from OTFontVal too)
        public bool ValidateTable(OTTable table, Validator v, DirectoryEntry de, OTFontVal fontOwner)
        {
            String tname = GetTableManager().GetUnaliasedTableName(de.tag);
            bool bRet = true;

            // verify the checksum value from the directory entry matches the checksum for the table
            if (!(tname == "DSIG" && IsCollection()))
            {
                uint calcChecksum = 0;
                if (table != null)
                {
                    calcChecksum = table.CalcChecksum();
                }

                if (de.checkSum != calcChecksum)
                {
                    string s = "table '" + de.tag + "', calc: 0x" + calcChecksum.ToString("x8") + ", font: 0x" + de.checkSum.ToString("x8");
                    v.Error(T.T_NULL, E._DE_E_ChecksumError, de.tag, s);
                    bRet = false;
                }
            }

            // verify that table has pad bytes set to zero
            if (table != null)
            {
                uint nBytes = GetNumPadBytesAfterTable(table);

                bool bPadBytesZero = true;

                if (nBytes != 0)
                {
                    long PadFilePos = table.GetBuffer().GetFilePos() + table.GetBuffer().GetLength();
                    byte[] padbuf = ReadBytes(PadFilePos, nBytes);
                    for (int iByte = 0; iByte < padbuf.Length; iByte++)
                    {
                        if (padbuf[iByte] != 0)
                        {
                            bPadBytesZero = false;
                            break;
                        }
                    }

                }

                if (bPadBytesZero == false)
                {
                    v.Warning(T.T_NULL, W._DE_W_PadBytesNotZero, de.tag, "after " + de.tag + " table");
                }
            }

            // ask the table object to validate its data
            if (!(tname == "DSIG" && IsCollection())) v.OnTableValidationEvent(de, true);
            if (table != null)
            {
                if (v.TestTable(de.tag)) // don't test deselected tables
                {
                    try
                    {
                        ITableValidate valtable = (ITableValidate)table;
                        bRet &= valtable.Validate(v, fontOwner);
                    }
                    catch (InvalidCastException e)
                    {
                        v.ApplicationError(T.T_NULL, E._Table_E_Exception, table.m_tag, e.ToString());
                        bRet = false;
                    }
                }
                else
                {
                    v.Info(I._Table_I_NotSelected, de.tag);
                }
            }
            else
            {
                if (de.length == 0)
                {
                    // check if it's a known OT table type since zero length private tables seem allowable
                    if (TableManager.IsKnownOTTableType(de.tag))
                    {
                        v.Error(T.T_NULL, E._Table_E_Invalid, de.tag, "The directory entry length is zero");
                        bRet = false;
                    }
                }
                else if (de.offset == 0)
                {
                    v.Error(T.T_NULL, E._Table_E_Invalid, de.tag, "The directory entry offset is zero");
                    bRet = false;
                }
                else if (de.offset > GetFileLength())
                {
                    v.Error(T.T_NULL, E._Table_E_Invalid, de.tag, "The table offset points past end of file");
                    bRet = false;
                }
                else if (de.offset + de.length > GetFileLength())
                {
                    v.Error(T.T_NULL, E._Table_E_Invalid, de.tag, "The table extends past end of file");
                    bRet = false;
                }
                else
                {
                    v.Error(E._Table_E_Invalid, de.tag);
                    bRet = false;
                }
            }
            if (!(tname == "DSIG" && IsCollection())) v.OnTableValidationEvent(de, false);

            return bRet;

        }
Exemplo n.º 13
0
        public bool Validate()
        {
            long StartTicks = DateTime.Now.Ticks;
			bool bRet = true;

            m_Validator.OnFileValidationEvent(this, true);

            for (uint i=0; i<m_nFonts; i++)
            {
                // check to see if user canceled validation
                if (m_Validator.CancelFlag)
                {
                	bRet = false;
                    break;
                }

                m_Validator.OnFontValidationEvent(i, true);

                OTFontVal f = GetFont(i);

                if (f != null)
                {
                    m_Validator.OnFontParsedEvent(f);

                    if(!f.Validate()) bRet = false;
                }

                m_Validator.OnFontValidationEvent(i, false);
            }

            // build the elapsed time string
            int nSeconds = (int)((DateTime.Now.Ticks-StartTicks)/(double)10000000);
            int nHours = nSeconds / 3600;
            nSeconds = nSeconds - nHours*3600;
            int nMins = nSeconds / 60;
            nSeconds = nSeconds - nMins*60;
            string sTime = nHours.ToString() + ":" + nMins.ToString("d2") + ":" + nSeconds.ToString("d2");

            m_Validator.Info(T.T_NULL, I._GEN_I_TotalValTime, null, sTime);

            //Let's try to validate the DSIG table in a TTC, if it exists
            if (IsCollection())
            {
                if (m_ttch.version >= 0x00020000 && GetTableManager().GetUnaliasedTableName(m_ttch.DsigTag) == "DSIG")
                {
                    MBOBuffer buf = this.ReadPaddedBuffer(m_ttch.DsigOffset, m_ttch.DsigLength);
                    OTTable table = GetTableManager().CreateTableObject(m_ttch.DsigTag, buf);
                    DirectoryEntry de = new DirectoryEntry();
                    de.tag = m_ttch.DsigTag;
                    de.offset = m_ttch.DsigOffset;
                    de.length = m_ttch.DsigLength;

                    OTFontVal fontOwner = new OTFontVal(this);
                    bRet &= ValidateTable(table, m_Validator, de, fontOwner);
                }
                else
                {
                    m_Validator.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "DSIG");
                }
            }

            m_Validator.OnFileValidationEvent(this, false);

            if (m_Validator.CancelFlag)
            {
                m_Validator.ApplicationError(T.T_NULL, E._GEN_E_UserCanceled, null, "");
				bRet = false;
            }

			return bRet;

        }
Exemplo n.º 14
0
	    public void OnBeginTableTest( DirectoryEntry de ){

	    }
Exemplo n.º 15
0
        /******************
         * protected methods
         */
        protected static OffsetTable ReadOffsetTable(OTFileVal file, uint filepos)
        {
            // read the Offset Table from the file

            Validator v = file.GetValidator();

            const int SIZEOF_OFFSETTABLE = 12;

            OffsetTable ot = null;

            // read the offset table

            MBOBuffer buf = file.ReadPaddedBuffer(filepos, SIZEOF_OFFSETTABLE);

            if (buf != null)
            {
                if (OTFile.IsValidSfntVersion(buf.GetUint(0)))
                {
                    ot = new OffsetTable(buf);
                }
                else
                {
                    v.Error(T.T_NULL, E._OFFSET_E_InvalidSFNT, null, "0x"+buf.GetUint(0).ToString("x8"));
                }
            }

            // now read the directory entries

            if (ot != null)
            {
                const int SIZEOF_DIRECTORYENTRY = 16;

                for (int i=0; i<ot.numTables; i++)
                {
                    uint dirFilePos = (uint)(filepos+SIZEOF_OFFSETTABLE+i*SIZEOF_DIRECTORYENTRY);
                    MBOBuffer DirEntBuf = file.ReadPaddedBuffer(dirFilePos, SIZEOF_DIRECTORYENTRY);

                    if (DirEntBuf != null)
                    {
                        DirectoryEntry de = new DirectoryEntry();

                        de.tag = new OTTag(DirEntBuf.GetBuffer());
                        de.checkSum = DirEntBuf.GetUint(4);
                        de.offset = DirEntBuf.GetUint(8);
                        de.length = DirEntBuf.GetUint(12);

                        ot.DirectoryEntries.Add(de);

                        if (de.offset > file.GetFileLength())
                        {
                            v.Error(T.T_NULL, E._DE_E_OffsetPastEOF, de.tag, "0x"+de.offset.ToString("x8"));
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return ot;
        }
Exemplo n.º 16
0
        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;
        }
Exemplo n.º 17
0
 public void OnBeginTableTest( DirectoryEntry de )
 {
     UpdateLabelText( labelTestname, "" + de.tag );
     UpdateLabelText( labelTestProgress, "" );
     UpdateLabelVisible( labelTestProgress, false );
 }
Exemplo n.º 18
0
        /// <summary>Add a new table to an non-file based table. Table cannot
        /// already exist in the font.
        /// </summary>
        public void AddTable(OTTable t)
        {
            if (m_File != null)
            {
                throw new ApplicationException("attempted to add a table to a file-based OTFont object");
            }

            if (GetDirectoryEntry(t.m_tag) != null)
            {
                throw new ArgumentException("the specified table already exists in the font");
            }

            // build a new directory entry
            DirectoryEntry de = new DirectoryEntry();
            de.tag = new OTTag(t.m_tag.GetBytes());
            de.checkSum = t.CalcChecksum();
            de.offset = 0;  // this value won't get fixed up until the font is written
            de.length = t.GetLength();

            // add the directory entry

            m_OffsetTable.DirectoryEntries.Add(de);    
            m_OffsetTable.numTables++;
            

            // add the table to the list of tables in memory

            MemBasedTables.Add(t);


            // special handling for certain tables

            string sTable = (string)t.m_tag;
            if (sTable == "CFF ")
            {
                m_OutlineType = OutlineType.OUTLINE_POSTSCRIPT;
            }
            else if (sTable == "glyf")
            {
                m_OutlineType = OutlineType.OUTLINE_TRUETYPE;
            }
        }
Exemplo n.º 19
0
 public DirectoryEntry(DirectoryEntry obj)
 {
     tag = new OTTag(obj.tag.GetBytes());
     checkSum = obj.checkSum;
     offset   = obj.offset;
     length   = obj.length;
 }
Exemplo n.º 20
0
        protected OTTable GetTable(DirectoryEntry de)
        {
            OTTable table = null;

            if (m_File != null)
            {
                // get the table from OTFile's table manager
                table = m_File.GetTableManager().GetTable(this, de);
            }
            else
            {
                // get the table from the list in memory
                for (int i=0; i<MemBasedTables.Count; i++)
                {
                    OTTable t = (OTTable)MemBasedTables[i];
                    if (de.tag == t.m_tag)
                    {
                        table = t;
                        break;
                    }
                }
            }

            return table;
        }
Exemplo n.º 21
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;
        }