Exemple #1
0
        public uint FastMapUnicodeToGlyphID(char c)
        {
            // this routine caches the windows unicode cmap for better performance
            // but uses 256K of heap

            uint glyphID = 0xffffffff;

            if (m_arrUnicodeToGlyph_3_1 == null)
            {
                m_arrUnicodeToGlyph_3_1 = new uint[0x00010000];
                for (uint i = 0; i <= 0xffff; i++)
                {
                    m_arrUnicodeToGlyph_3_1[i] = 0;
                }

                Table_cmap cmapTable = (Table_cmap)GetTable("cmap");
                if (cmapTable != null)
                {
                    Table_cmap.EncodingTableEntry eteUni = cmapTable.GetEncodingTableEntry(3, 1);
                    if (eteUni != null)
                    {
                        Table_cmap.Subtable st = cmapTable.GetSubtable(eteUni);

                        if (st != null)
                        {
                            byte [] buf = new byte[2];
                            for (ushort i = 0; i < 0xffff; i++)
                            {
                                buf[0] = (byte)i;
                                buf[1] = (byte)(i >> 8);

                                uint g = st.MapCharToGlyph(buf, 0);
                                if (g != 0)
                                {
                                    // BEWARE: Some bad fonts have the glyph ID greater than # of glyphs
                                    // and we're not throwing it out here!
                                    m_arrUnicodeToGlyph_3_1[i] = g;
                                }
                            }
                        }
                    }
                }
            }

            Debug.Assert(m_arrUnicodeToGlyph_3_1 != null);
            if (m_arrUnicodeToGlyph_3_1 != null)
            {
                glyphID = m_arrUnicodeToGlyph_3_1[c];
            }

            return(glyphID);
        }
Exemple #2
0
        // TODO: rewrite
        public void ReadFontMetrics(out int descendMin,
                                    out int ascendMax,
                                    out int lsbMin,
                                    out int rsbMax,
                                    DIAction dia)
        {
            descendMin = -700;
            ascendMax  = 2100;
            lsbMin     = -1000;
            rsbMax     = 3500;

            try
            {
                BoxD bboxRes = new BoxD();

                Table_cmap tableCmap = (Table_cmap)this.m_font.GetTable("cmap");
                if (tableCmap == null)
                {
                    return;
                }
                Table_cmap.EncodingTableEntry eteUni =
                    tableCmap.GetEncodingTableEntry(3, 1);
                if (eteUni == null)
                {
                    return;
                }
                Table_cmap.Subtable subtableCmap = tableCmap.GetSubtable(eteUni);
                char[] samples = { 'A', 'W', 'p' };
                for (int iSample = 0; iSample < samples.Length; iSample++)
                {
                    byte[] charbuf = new byte[2];
                    charbuf[0] = (byte)'A';
                    charbuf[1] = 0;
                    int indGlyph             = (int)subtableCmap.MapCharToGlyph(charbuf, 0);
                    Table_glyf.header header = this.m_tableGlyf.GetGlyphHeader((uint)indGlyph, this.m_font);
                    if (header == null)
                    {
                        return;
                    }
                    BoxD bboxCur = new BoxD(header.xMin, header.yMin,
                                            header.xMax, header.yMax);
                    bboxRes.Unite(bboxCur);
                }
                descendMin = (int)bboxRes.VecMin.Y;
                ascendMax  = (int)bboxRes.VecMax.Y;
                lsbMin     = (int)bboxRes.VecMin.X;
                rsbMax     = (int)bboxRes.VecMax.X;
            }
            catch
            {
            }
        }
Exemple #3
0
        public bool ContainsMsSymbolEncodedCmap()
        {
            if (!bCheckedForSymbolCmap)
            {
                Table_cmap cmapTable = (Table_cmap)GetTable("cmap");
                if (cmapTable != null)
                {
                    Table_cmap.EncodingTableEntry eteUni = cmapTable.GetEncodingTableEntry(3, 0);
                    if (eteUni != null)
                    {
                        m_bContainsMsSymbolEncodedCmap = true;
                    }
                }
                bCheckedForSymbolCmap = true;
            }

            return(m_bContainsMsSymbolEncodedCmap);
        }
Exemple #4
0
        /************************
         * public methods
         */


        public bool Validate(Validator v, OTFontVal fontOwner)
        {
            bool bRet = true;

            if (v.PerformTest(T.kern_TableVersion))
            {
                if (version == 0)
                {
                    v.Pass(T.kern_TableVersion, P.kern_P_TableVersion, m_tag);
                }
                else
                {
                    v.Error(T.kern_TableVersion, E.kern_E_TableVersion, m_tag, "version = " + version.ToString() + ", unrecognized version #, no further tests can be performed");
                    return(false);
                }
            }



            if (v.PerformTest(T.kern_NumSubtables))
            {
                if (nTables != 0)
                {
                    v.Pass(T.kern_NumSubtables, P.kern_P_NumSubTables, m_tag, nTables.ToString());
                }
                else
                {
                    v.Error(T.kern_NumSubtables, E.kern_E_NumSubTables, m_tag);
                    bRet = false;
                }
            }


            if (v.PerformTest(T.kern_SubtableFormats))
            {
                bool bFormatsOk = true;

                for (uint i = 0; i < nTables; i++)
                {
                    SubTableHeader sth = GetSubTableHeader(i);
                    if (sth != null)
                    {
                        if (sth.GetFormat() != 0 && sth.GetFormat() != 2)
                        {
                            v.Error(T.kern_SubtableFormats, E.kern_E_SubtableFormats, m_tag, "subtable #" + i + ", format " + sth.GetFormat());
                            bFormatsOk = false;
                            bRet       = false;
                        }
                    }
                    else
                    {
                        v.Error(T.kern_SubtableFormats, E.kern_E_SubTableExtendsPastEOT, m_tag, "subtable #" + i);
                        bFormatsOk = false;
                        bRet       = false;
                        break;
                    }
                }
                if (bFormatsOk)
                {
                    v.Pass(T.kern_SubtableFormats, P.kern_P_SubtableFormats, m_tag);
                }
            }

            if (!bRet)
            {
                v.Warning(T.kern_SubtableFormats, W._TEST_W_OtherErrorsInTable, m_tag, "kern table appears to be corrupt.  No further tests will be performed.");
                return(bRet);
            }

            if (v.PerformTest(T.kern_SubtableLength))
            {
                bool bLengthsOk = true;

                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if (st.length != st.CalculatedLength())
                    {
                        v.Error(T.kern_SubtableLength, E.kern_E_SubtableLength, m_tag, "subtable #" + i + ", length = " + st.length + ", calculated length = " + st.CalculatedLength());
                        bLengthsOk = false;
                        bRet       = false;
                    }
                }
                if (bLengthsOk)
                {
                    v.Pass(T.kern_SubtableLength, P.kern_P_SubtableLengths, m_tag);
                }
            }

            if (v.PerformTest(T.kern_CoverageReservedBits))
            {
                bool bReservedOk = true;

                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if ((st.coverage & 0xf0) != 0)
                    {
                        bReservedOk = false;
                        v.Error(T.kern_CoverageReservedBits, E.kern_E_ReservedCoverageBits, m_tag, "subtable #" + i);
                        bRet = false;
                        break;
                    }
                }
                if (bReservedOk)
                {
                    v.Pass(T.kern_CoverageReservedBits, P.kern_P_ReservedCoverageBits, m_tag);
                }
            }

            if (v.PerformTest(T.kern_Format0_SearchFields))
            {
                bool bBinaryFieldsOk = true;

                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if (st.version == 0)
                    {
                        SubTableFormat0 stf0        = (SubTableFormat0)st;
                        ushort          nPairs      = stf0.nPairs;
                        ushort          sizeofEntry = 6;

                        if (nPairs != 0)
                        {
                            ushort CalculatedSearchRange   = (ushort)(util.MaxPower2LE(nPairs) * sizeofEntry);
                            ushort CalculatedEntrySelector = util.Log2(util.MaxPower2LE(nPairs));
                            ushort CalculatedRangeShift    = (ushort)((nPairs - util.MaxPower2LE(nPairs)) * sizeofEntry);

                            if (stf0.searchRange != CalculatedSearchRange)
                            {
                                string s = "subtable #" + i
                                           + ", calc = " + CalculatedSearchRange
                                           + ", actual = " + stf0.searchRange;
                                v.Error(T.kern_Format0_SearchFields, E.kern_E_Format0_searchRange, m_tag, s);
                                bBinaryFieldsOk = false;
                                bRet            = false;
                            }
                            if (stf0.entrySelector != CalculatedEntrySelector)
                            {
                                string s = "subtable #" + i
                                           + ", calc = " + CalculatedEntrySelector
                                           + ", actual = " + stf0.entrySelector;
                                v.Error(T.kern_Format0_SearchFields, E.kern_E_Format0_entrySelector, m_tag, s);
                                bBinaryFieldsOk = false;
                                bRet            = false;
                            }
                            if (stf0.rangeShift != CalculatedRangeShift)
                            {
                                string s = "subtable #" + i
                                           + ", calc = " + CalculatedRangeShift
                                           + ", actual = " + stf0.rangeShift;
                                v.Error(T.kern_Format0_SearchFields, E.kern_E_Format0_rangeShift, m_tag, s);
                                bBinaryFieldsOk = false;
                                bRet            = false;
                            }
                        }
                        else
                        {
                            // cannot validate fields since they are undefined when nPairs is zero
                            v.Warning(T.kern_Format0_SearchFields, W.kern_W_Format0_SearchFields, m_tag, "subtable #" + i + ", nPairs = " + stf0.nPairs);
                            bBinaryFieldsOk = false;
                        }
                    }
                }

                if (bBinaryFieldsOk)
                {
                    v.Pass(T.kern_Format0_SearchFields, P.kern_P_Format0_SearchFields, m_tag);
                }
            }

            if (v.PerformTest(T.kern_Format0_GlyphIDs))
            {
                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if (st.version == 0)
                    {
                        bool bGlyphIDsOk = true;

                        SubTableFormat0 stf0 = (SubTableFormat0)st;

                        for (int iPair = 0; iPair < stf0.nPairs; iPair++)
                        {
                            ushort left = 0, right = 0;
                            short  kernvalue = 0;

                            stf0.GetKerningPairAndValue(iPair, ref left, ref right, ref kernvalue);

                            ushort numGlyphs = fontOwner.GetMaxpNumGlyphs();
                            if (left >= numGlyphs)
                            {
                                v.Error(T.kern_Format0_GlyphIDs, E.kern_E_Format0_GlyphIDs, m_tag, "kern pair[" + iPair + "]: left = " + left);
                                bGlyphIDsOk = false;
                                bRet        = false;
                            }
                            if (right >= numGlyphs)
                            {
                                v.Error(T.kern_Format0_GlyphIDs, E.kern_E_Format0_GlyphIDs, m_tag, "kern pair[" + iPair + "]: right = " + right);
                                bGlyphIDsOk = false;
                                bRet        = false;
                            }
                        }

                        if (bGlyphIDsOk)
                        {
                            v.Pass(T.kern_Format0_GlyphIDs, P.kern_P_Format0_GlyphIDs, m_tag);
                        }
                    }
                }
            }

            if (v.PerformTest(T.kern_Format0_Values))
            {
                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if (st.version == 0)
                    {
                        SubTableFormat0 stf0 = (SubTableFormat0)st;

                        Table_hmtx hmtxTable = (Table_hmtx)fontOwner.GetTable("hmtx");
                        if (hmtxTable != null)
                        {
                            bool bValuesOk = true;

                            for (int iPair = 0; iPair < stf0.nPairs; iPair++)
                            {
                                ushort left = 0, right = 0;
                                short  kernvalue = 0;

                                stf0.GetKerningPairAndValue(iPair, ref left, ref right, ref kernvalue);
                                short absKernValue = Math.Abs(kernvalue);

                                Table_hmtx.longHorMetric lhmLeft  = null;
                                Table_hmtx.longHorMetric lhmRight = null;
                                try {
                                    lhmLeft  = hmtxTable.GetOrMakeHMetric(left, fontOwner);
                                    lhmRight = hmtxTable.GetOrMakeHMetric(right, fontOwner);
                                }
                                catch (Exception e)
                                {
                                    v.ApplicationError(T.kern_Format0_Values, E._Table_E_Exception, m_tag, "GetOrMakeHMetric:" + e.Message);
                                    bValuesOk = false;
                                    bRet      = false;
                                    break;
                                }

                                if (lhmLeft == null || lhmRight == null)
                                {
                                    v.ApplicationError(T.kern_Format0_Values, E._Table_E_Exception, m_tag, "hmtx Left or Right null");
                                    bValuesOk = false;
                                    bRet      = false;
                                    break;
                                }

                                if (absKernValue > lhmLeft.advanceWidth && absKernValue > lhmRight.advanceWidth)
                                {
                                    v.Error(T.kern_Format0_Values, E.kern_E_Format0_Values, m_tag, "kern pair[" + iPair + "]: left id = " + left + ", right id = " + right + ", value = " + kernvalue);
                                    bValuesOk = false;
                                    bRet      = false;
                                }
                            }

                            if (bValuesOk)
                            {
                                v.Pass(T.kern_Format0_Values, P.kern_P_Format0_Values, m_tag);
                            }
                        }
                    }
                }
            }

            if (v.PerformTest("kern_Format0_IDsInCmap"))
            {
                for (uint i = 0; i < nTables; i++)
                {
                    SubTable st = this.GetSubTable(i);
                    if (st.version == 0)
                    {
                        SubTableFormat0 stf0 = (SubTableFormat0)st;

                        Table_cmap cmapTable = (Table_cmap)fontOwner.GetTable("cmap");
                        if (cmapTable != null)
                        {
                            Table_cmap.Subtable cmapSubtable = cmapTable.GetSubtable(3, 10);
                            if (cmapSubtable == null)
                            {
                                cmapSubtable = cmapTable.GetSubtable(3, 1);
                            }
                            if (cmapSubtable == null)
                            {
                                Table_cmap.EncodingTableEntry ete = cmapTable.GetEncodingTableEntry(0);
                                cmapSubtable = cmapTable.GetSubtable(ete);
                            }

                            if (cmapSubtable != null)
                            {
                                uint [] map = cmapSubtable.GetMap();

                                bool bAllIDsInCmap = true;

                                for (int iPair = 0; iPair < stf0.nPairs; iPair++)
                                {
                                    ushort left = 0, right = 0;
                                    short  kernvalue = 0;

                                    stf0.GetKerningPairAndValue(iPair, ref left, ref right, ref kernvalue);

                                    bool bFoundLeft  = false;
                                    bool bFoundRight = false;

                                    for (int j = 0; j < map.Length; j++)
                                    {
                                        if (left == map[j])
                                        {
                                            bFoundLeft = true;
                                            break;
                                        }
                                    }

                                    for (int j = 0; j < map.Length; j++)
                                    {
                                        if (right == map[j])
                                        {
                                            bFoundRight = true;
                                            break;
                                        }
                                    }

                                    if (bFoundLeft == false)
                                    {
                                        v.Error(T.kern_Format0_IDsInCmap, E.kern_E_Format0_GlyphIdInCmap, m_tag, "kern pair[" + iPair + "]: left id = " + left);
                                        bAllIDsInCmap = false;
                                        bRet          = false;
                                    }
                                    if (bFoundRight == false)
                                    {
                                        v.Error(T.kern_Format0_IDsInCmap, E.kern_E_Format0_GlyphIdInCmap, m_tag, "kern pair[" + iPair + "]: right id = " + right);
                                        bAllIDsInCmap = false;
                                        bRet          = false;
                                    }
                                }

                                if (bAllIDsInCmap)
                                {
                                    v.Pass(T.kern_Format0_IDsInCmap, P.kern_P_Format0_GlyphIdInCmap, m_tag);
                                }
                            }
                        }
                    }
                }
            }

            return(bRet);
        }