Пример #1
0
        /************************
         * public methods
         */


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

            if (v.PerformTest(T.maxp_TableVersion))
            {
                uint val = TableVersionNumber.GetUint();

                Table_CFF  CFFTable  = (Table_CFF)  fontOwner.GetTable("CFF ");
                Table_glyf glyfTable = (Table_glyf) fontOwner.GetTable("glyf");

                if (val == 0x00005000)
                {
                    if (CFFTable != null && glyfTable == null)
                    {
                        v.Pass(T.maxp_TableVersion, P.maxp_P_VERSION_0_5, m_tag);
                    }
                    else if (CFFTable == null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_0_5_NOCFF, m_tag);
                        bRet = false;
                    }
                    else if (glyfTable != null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_0_5_glyf, m_tag);
                        bRet = false;
                    }
                }
                else if (val == 0x00010000)
                {
                    if (CFFTable == null && glyfTable != null)
                    {
                        v.Pass(T.maxp_TableVersion, P.maxp_P_VERSION_1_0, m_tag);
                    }
                    else if (glyfTable == null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_1_0_NOglyf, m_tag);
                        bRet = false;
                    }
                    else if (CFFTable != null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_1_0_CFF, m_tag);
                        bRet = false;
                    }
                }
                else
                {
                    v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_INVALID, m_tag, "0x"+val.ToString("x8"));
                    bRet = false;
                }
            }

            if (v.PerformTest(T.maxp_TableLength))
            {
                uint val = TableVersionNumber.GetUint();

                if (val == 0x00005000)
                {
                    if (m_bufTable.GetLength() == 6)
                    {
                        v.Pass(T.maxp_TableLength, P.maxp_P_LENGTH_0_5, m_tag);
                    }
                    else
                    {
                        v.Error(T.maxp_TableLength, E.maxp_E_LENGTH_0_5, m_tag, m_bufTable.GetLength().ToString());
                        bRet = false;
                    }
                }
                else if (val == 0x00010000)
                {
                    if (m_bufTable.GetLength() == 32)
                    {
                        v.Pass(T.maxp_TableLength, P.maxp_P_LENGTH_1_0, m_tag);
                    }
                    else
                    {
                        v.Error(T.maxp_TableLength, E.maxp_E_LENGTH_1_0, m_tag, m_bufTable.GetLength().ToString());
                        bRet = false;
                    }
                }
            }

            if (v.PerformTest(T.maxp_NumGlyphsMatchLoca))
            {
                if (TableVersionNumber.GetUint() == 0x00010000)
                {
                    Table_loca locaTable = (Table_loca)fontOwner.GetTable("loca");
                    if (locaTable != null)
                    {
                        // locaTable.NumEntry returns (-1) on failure
                        if (locaTable.NumEntry(fontOwner) == NumGlyphs+1)
                        {
                            v.Pass(T.maxp_NumGlyphsMatchLoca, P.maxp_P_NumGlyphsMatchLoca, m_tag, "numGlyphs = " + NumGlyphs);
                        }
                        else
                        {
                            v.Error(T.maxp_NumGlyphsMatchLoca, E.maxp_E_NumGlyphsMatchLoca, m_tag, "numGlyphs = " + NumGlyphs);
                            bRet = false;
                        }
                    }
                    else
                    {
                        v.Error(T.maxp_NumGlyphsMatchLoca, E._TEST_E_TableMissing, m_tag, "loca");
						bRet = false;
                    }
                }
                else
                {
                    v.Info(T.maxp_NumGlyphsMatchLoca, I._TEST_I_TableVersion, m_tag, "test = maxp_NumGlyphsMatchLoca");
                }
            }

            if (v.PerformTest(T.maxp_GlyphStats))
            {
                if (TableVersionNumber.GetUint() == 0x00010000)
                {
                    Table_glyf glyfTable = (Table_glyf) fontOwner.GetTable("glyf");

                    if (glyfTable == null)
                    {
                        v.Error(T.maxp_GlyphStats, E._TEST_E_TableMissing, m_tag, "glyf");
						bRet = false;
                    }
                    else
                    {

                        bool bGlyphStatsOk = true;

                        if (ComputeMaxpStats(glyfTable, fontOwner))
                        {

                            if (maxPoints != maxPointsCalc)
                            {
                                String sDetails = "maxPoints = " + maxPoints + ", calculated = " + maxPointsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxContours != maxContoursCalc)
                            {
                                String sDetails = "maxContours = " + maxContours + ", calculated = " + maxContoursCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxCompositePoints != maxCompositePointsCalc)
                            {
                                String sDetails = "maxCompositePoints = " + maxCompositePoints + ", calculated = " + maxCompositePointsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxCompositeContours != maxCompositeContoursCalc)
                            {
                                String sDetails = "maxCompositeContours = " + maxCompositeContours + ", calculated = " + maxCompositeContoursCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            // Bug 2168.
                            // Case 1: Same as max size from glyf table. Info.
                            // Case 2: Same as max size from glyf table + 
                            //         size(fpgm) + size(prep). Info message.
                            // Case 3: Smaller than max size from glyf table. 
                            //         Error
                            // Case 4: Neither 1 nor 2. Warning.
                            DirectoryEntry dePrep = 
                                fontOwner.GetDirectoryEntry("prep" );
                            uint prepLength = 0;
                            if ( null != dePrep ) {
                                prepLength = dePrep.length;
                            }
                            DirectoryEntry deFpgm = 
                                fontOwner.GetDirectoryEntry("fpgm" );
                            uint fpgmLength = 0;
                            if ( null != deFpgm ) {
                                fpgmLength = deFpgm.length;
                            }

                            if ( maxSizeOfInstructions == 
                                 maxSizeOfInstructionsCalc ) {
                                // Case 1:
                                String sDetails = "maxSizeOfInstructions=" +
                                    maxSizeOfInstructions + ", computed " +
                                    "from the glyf table";
                                v.Info( T.maxp_GlyphStats,
                                        I.maxp_I_Calculation_Method1,
                                        m_tag, sDetails);
                            }
                            else if ( maxSizeOfInstructions ==  
                                      ( maxSizeOfInstructionsCalc + 
                                        prepLength + fpgmLength ) ) {
                                // Case 2:
                                String sDetails = 
                                    "maxp maxSizeOfInstructions is " + 
                                    maxSizeOfInstructions + ", which is " +
                                    "glyf maxSizeOfInstructions (" + 
                                    maxSizeOfInstructionsCalc + 
                                    ") + prep size (" + prepLength + 
                                    ") + fpgm size (" + fpgmLength + ")";
                                v.Info( T.maxp_GlyphStats, 
                                        I.maxp_I_Calculation_Method2, 
                                        m_tag, sDetails);
                            }
                            else if ( maxSizeOfInstructions < 
                                      maxSizeOfInstructionsCalc ) {
                                // Case 3
                                String sDetails = 
                                    "maxp maxSizeOfInstructions is " + 
                                    maxSizeOfInstructions + 
                                    ", which is smaller than the " + 
                                    "size of instuctions (" + 
                                    maxSizeOfInstructionsCalc + ") found" +
                                    " for some glyph in the glyf table.";
                                v.Error( T.maxp_GlyphStats, 
                                         E.maxp_E_Calculation, m_tag, 
                                         sDetails);
                                bRet = false;
                            }
                            else {
                                // Case 4
                                String sDetails = 
                                    "glyf maxSizeOfInstructions=" + 
                                    maxSizeOfInstructionsCalc + 
                                    ", prep size=" + prepLength + 
                                    ", fpgm size=" + fpgmLength + 
                                    ", whereas maxp maxSizeOfInstruction " +
                                    "is " + maxSizeOfInstructions;
                                v.Warning(T.maxp_GlyphStats, 
                                          W.maxp_W_Calculation_Unclear, 
                                          m_tag, 
                                          sDetails);
                                bGlyphStatsOk = false;
                            }

                            if (maxComponentElements != maxComponentElementsCalc)
                            {
                                String sDetails = "maxComponentElements = " + maxComponentElements + ", calculated = " + maxComponentElementsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxComponentDepth != maxComponentDepthCalc)
                            {
                                String sDetails = "maxComponentDepth = " + maxComponentDepth + ", calculated = " + maxComponentDepthCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet = false;
                                bGlyphStatsOk = false;
                            }

                            if (bGlyphStatsOk)
                            {
                                v.Pass(T.maxp_GlyphStats, P.maxp_P_Calculation, m_tag);
                            }
                        }
                        else
                        {
                            v.Warning(T.maxp_GlyphStats, W._TEST_W_ErrorInAnotherTable, m_tag, "Errors in the glyf table are preventing validation of maxPoints, maxContours, maxCompositePoints, maxCompositeContours, maxSizeofInstructions, maxComponentElements, and maxComponentDepth");
                        }
                    }
                }
                else
                {
                    v.Info(T.maxp_GlyphStats, I._TEST_I_TableVersion, m_tag, "test = maxp_GlyphStats");
                }
            }

            return bRet;
        }
Пример #2
0
        public bool Validate(Validator validator, OTFontVal fontOwner)
        {
            bool bRet = true;

            if (!validator.PerformTest(T.glyf_ValidateAll))
            {
                return(true);
            }

            if (fontOwner.GetFile().IsCollection())
            {
                if (fontOwner.GetFontIndexInFile() > 0)
                {
                    // checksum not matching data is covered by check elsewhere. Assume they match.
                    DirectoryEntry de_glyf = fontOwner.GetDirectoryEntry("glyf");
                    for (uint i = 0; i < fontOwner.GetFontIndexInFile(); i++)
                    {
                        if (fontOwner.GetFile().GetFont(i).GetDirectoryEntry("glyf").checkSum
                            == de_glyf.checkSum)
                        {
                            validator.Info(T.T_NULL, I.glyf_I_IDENTICAL_GLYF_TABLES_IN_TTC, m_tag);
                            return(true);
                        }
                    }
                }
            }

            this.m_diaValidate = validator.DIA;
            this.m_cnts        = new int[this.m_namesInfoCnt.Length];
            for (int iCnt = 0; iCnt < this.m_cnts.Length; iCnt++)
            {
                this.m_cnts[iCnt] = 0;
            }

            I_IOGlyphsFile i_IOGlyphs = new I_IOGlyphsFile();

            if (!i_IOGlyphs.Initialize(fontOwner, validator))
            {
                return(false); // the error is already reported
            }

            DIAction diaFilter =
                DIActionBuilder.DIA(this, "DIAFunc_Filter");
            FManager fm       = new FManager(i_IOGlyphs, null, null);
            int      numGlyph = fm.FNumGlyph;
            int      indGlyph;

            for (indGlyph = 0; indGlyph < numGlyph; indGlyph++)
            {
                try
                {
                    if ((indGlyph % 100) == 0)
                    {
                        validator.OnTableProgress("Validating glyph with index " + indGlyph + " (out of " + numGlyph + " glyphs)");
                    }
                    Glyph glyph = fm.GGet(indGlyph);
                    glyph.GValidate();
                    bRet &= fm.GErrGetInformed(indGlyph, diaFilter);
                    fm.ClearManagementStructs();
                }
                catch
                {
                    validator.Error(T.T_NULL, E.glyf_E_ExceptionUnhandeled, (OTTag)"glyf",
                                    "Glyph index " + indGlyph);
                }
                if (validator.CancelFlag)
                {
                    break;
                }
            }
            i_IOGlyphs.Clear();
            fm.ClearDestroy();
            fm = null;

/*
 *          I_ProgressUpdater i_ProgressUpdater=new ValidationCancel(validator);
 *
 *          FManager fm=new FManager(i_IOGlyphs, null, null);
 *          DIAction diaFilter=
 *              DIActionBuilder.DIA(this,"DIAFunc_Filter");
 *
 *          fm.GErrActionAdd(diaFilter,
 *              FManager.TypeActionOnErr.onAdd);
 *
 *
 *          fm.FValidate(GConsts.IND_UNINITIALIZED,
 *              GConsts.IND_UNINITIALIZED);
 *
 *          i_IOGlyphs.Clear();
 *          i_ProgressUpdater.Clear();
 *          fm.ClearDestroy();
 *          fm=null;
 */
            for (int iCnt = 0; iCnt < this.m_cnts.Length; iCnt++)
            {
                if (this.m_cnts[iCnt] > 0)
                {
                    bool   isGErr         = this.m_namesInfoCnt[iCnt].StartsWith("GERR_");
                    string nameFileErr    = isGErr? GErrConsts.FILE_RES_GERR_STRINGS: GErrConsts.FILE_RES_OTFFERR_STRINGS;
                    string nameAsmFileErr = isGErr? GErrConsts.ASM_RES_GERR_STRINGS: GErrConsts.ASM_RES_OTFFERR_STRINGS;
                    string strDetails     = "Number of glyphs with the warning = " + this.m_cnts[iCnt];
                    if (validator.CancelFlag)
                    {
                        strDetails += " (Validation cancelled)";
                    }
                    ValInfoBasic info = new ValInfoBasic(
                        ValInfoBasic.ValInfoType.Warning,
                        this.m_namesInfoCnt[iCnt],
                        strDetails,
                        nameFileErr,
                        nameAsmFileErr,
                        "glyf",
                        null);
                    validator.DIA(info);
                }
            }

            this.m_cnts = null;
            return(bRet);
        }
Пример #3
0
        /************************
         * public methods
         */


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

            if (fontOwner.GetFile().IsCollection())
            {
                if (fontOwner.GetFontIndexInFile() > 0)
                {
                    // checksum not matching data is covered by check elsewhere. Assume they match.
                    DirectoryEntry de_EBDT = fontOwner.GetDirectoryEntry("EBDT");
                    for (uint i = 0; i < fontOwner.GetFontIndexInFile(); i++)
                    {
                        if (fontOwner.GetFile().GetFont(i).GetDirectoryEntry("EBDT").checkSum
                            == de_EBDT.checkSum)
                        {
                            v.Info(T.T_NULL, I.glyf_I_IDENTICAL_GLYF_TABLES_IN_TTC, m_tag);
                            return(true);
                        }
                    }
                }
            }

            m_nCachedMaxpNumGlyphs = fontOwner.GetMaxpNumGlyphs();


            if (v.PerformTest(T.EBDT_version))
            {
                if (version.GetUint() == 0x00020000 || version.GetUint() == 0x00030000)
                {
                    v.Pass(T.EBDT_version, P.EBDT_P_version, m_tag);
                }
                else
                {
                    v.Error(T.EBDT_version, E.EBDT_E_version, m_tag, "version = 0x" + version.GetUint().ToString("x8") + ", unable to continue validation");
                    return(false);
                }
            }
            //TODO: check tag for EBDT v3, CBDT v2, bdat

            if (v.PerformTest(T.EBDT_TableDependency))
            {
                Table_EBLC EBLCTable = (Table_EBLC)fontOwner.GetTable("EBLC");
                if (EBLCTable != null)
                {
                    v.Pass(T.EBDT_TableDependency, P.EBDT_P_TableDependency, m_tag);
                }
                else
                {
                    v.Error(T.EBDT_TableDependency, E.EBDT_E_TableDependency, m_tag);
                    bRet = false;
                }
            }

            // T.EBDT_GlyphImageData depends on T.EBDT_TableDependency passing.
            if (v.PerformTest(T.EBDT_GlyphImageData))
            {
                bool bGlyphImageDataOk = true;

                Table_EBLC EBLCTable = (Table_EBLC)fontOwner.GetTable("EBLC");
                if (EBLCTable == null)
                {
                    return(bRet); //failed the last test, not going on.
                }
                // for each bitmap size
                for (uint i = 0; i < EBLCTable.numSizes; i++)
                {
                    Table_EBLC.bitmapSizeTable bst = EBLCTable.GetBitmapSizeTable(i);
                    string sSize = "bitmapsize[" + i + "], ppemX=" + bst.ppemX + ", ppemY=" + bst.ppemY;

                    if (true)
                    {
                        for (uint j = 0; j < bst.numberOfIndexSubTables; j++)
                        {
                            Table_EBLC.indexSubTable      ist    = null;
                            Table_EBLC.indexSubTableArray ista_j = EBLCTable.GetIndexSubTableArray(bst, j);
                            if (ista_j != null)
                            {
                                ist = bst.GetIndexSubTable(ista_j);
                            }

                            if (ist != null)
                            {
                                string sID = sSize + ", indexSubTable[" + j + "](index fmt " + ist.header.indexFormat +
                                             ", image fmt " + ist.header.imageFormat + ")";

                                switch (ist.header.imageFormat)
                                {
                                case 1:
                                    if (!Validate_Format1(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 2:
                                    if (!Validate_Format2(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 3:
                                    if (!Validate_Format3(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 4:
                                    if (!Validate_Format4(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 5:
                                    if (!Validate_Format5(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 6:
                                    if (!Validate_Format6(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 7:
                                    if (!Validate_Format7(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 8:
                                    if (!Validate_Format8(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 9:
                                    if (!Validate_Format9(v, sID, ist))
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    break;

                                case 17:
                                    if (version.GetUint() != 0x00030000)
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    // TODO: adding 3 checks
                                    break;

                                case 18:
                                    if (version.GetUint() != 0x00030000)
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    // TODO: adding 3 checks
                                    break;

                                case 19:
                                    if (version.GetUint() != 0x00030000)
                                    {
                                        bGlyphImageDataOk = false;
                                        bRet = false;
                                    }
                                    // TODO: adding 3 checks
                                    break;

                                default:
                                    // TODO: emit Unknown
                                    break;
                                }
                            }
                        }
                    }
                }

                if (bGlyphImageDataOk)
                {
                    v.Pass(T.EBDT_GlyphImageData, P.EBDT_P_GlyphImageData, m_tag);
                }
            }

            return(bRet);
        }
Пример #4
0
        /************************
         * public methods
         */


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

            if (v.PerformTest(T.maxp_TableVersion))
            {
                uint val = TableVersionNumber.GetUint();

                Table_CFF  CFFTable  = (Table_CFF)fontOwner.GetTable("CFF ");
                Table_glyf glyfTable = (Table_glyf)fontOwner.GetTable("glyf");

                if (val == 0x00005000)
                {
                    if (CFFTable != null && glyfTable == null)
                    {
                        v.Pass(T.maxp_TableVersion, P.maxp_P_VERSION_0_5, m_tag);
                    }
                    else if (CFFTable == null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_0_5_NOCFF, m_tag);
                        bRet = false;
                    }
                    else if (glyfTable != null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_0_5_glyf, m_tag);
                        bRet = false;
                    }
                }
                else if (val == 0x00010000)
                {
                    if (CFFTable == null && glyfTable != null)
                    {
                        v.Pass(T.maxp_TableVersion, P.maxp_P_VERSION_1_0, m_tag);
                    }
                    else if (glyfTable == null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_1_0_NOglyf, m_tag);
                        bRet = false;
                    }
                    else if (CFFTable != null)
                    {
                        v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_1_0_CFF, m_tag);
                        bRet = false;
                    }
                }
                else
                {
                    v.Error(T.maxp_TableVersion, E.maxp_E_VERSION_INVALID, m_tag, "0x" + val.ToString("x8"));
                    bRet = false;
                }
            }

            if (v.PerformTest(T.maxp_TableLength))
            {
                uint val = TableVersionNumber.GetUint();

                if (val == 0x00005000)
                {
                    if (m_bufTable.GetLength() == 6)
                    {
                        v.Pass(T.maxp_TableLength, P.maxp_P_LENGTH_0_5, m_tag);
                    }
                    else
                    {
                        v.Error(T.maxp_TableLength, E.maxp_E_LENGTH_0_5, m_tag, m_bufTable.GetLength().ToString());
                        bRet = false;
                    }
                }
                else if (val == 0x00010000)
                {
                    if (m_bufTable.GetLength() == 32)
                    {
                        v.Pass(T.maxp_TableLength, P.maxp_P_LENGTH_1_0, m_tag);
                    }
                    else
                    {
                        v.Error(T.maxp_TableLength, E.maxp_E_LENGTH_1_0, m_tag, m_bufTable.GetLength().ToString());
                        bRet = false;
                    }
                }
            }

            if (v.PerformTest(T.maxp_NumGlyphsMatchLoca))
            {
                if (TableVersionNumber.GetUint() == 0x00010000)
                {
                    Table_loca locaTable = (Table_loca)fontOwner.GetTable("loca");
                    if (locaTable != null)
                    {
                        // locaTable.NumEntry returns (-1) on failure
                        if (locaTable.NumEntry(fontOwner) == NumGlyphs + 1)
                        {
                            v.Pass(T.maxp_NumGlyphsMatchLoca, P.maxp_P_NumGlyphsMatchLoca, m_tag, "numGlyphs = " + NumGlyphs);
                        }
                        else
                        {
                            v.Error(T.maxp_NumGlyphsMatchLoca, E.maxp_E_NumGlyphsMatchLoca, m_tag, "numGlyphs = " + NumGlyphs);
                            bRet = false;
                        }
                    }
                    else
                    {
                        v.Error(T.maxp_NumGlyphsMatchLoca, E._TEST_E_TableMissing, m_tag, "loca");
                        bRet = false;
                    }
                }
                else
                {
                    v.Info(T.maxp_NumGlyphsMatchLoca, I._TEST_I_TableVersion, m_tag, "test = maxp_NumGlyphsMatchLoca");
                }
            }

            if (v.PerformTest(T.maxp_GlyphStats))
            {
                if (TableVersionNumber.GetUint() == 0x00010000)
                {
                    Table_glyf glyfTable = (Table_glyf)fontOwner.GetTable("glyf");

                    if (glyfTable == null)
                    {
                        v.Error(T.maxp_GlyphStats, E._TEST_E_TableMissing, m_tag, "glyf");
                        bRet = false;
                    }
                    else
                    {
                        bool bGlyphStatsOk = true;

                        if (ComputeMaxpStats(glyfTable, fontOwner))
                        {
                            if (maxPoints != maxPointsCalc)
                            {
                                String sDetails = "maxPoints = " + maxPoints + ", calculated = " + maxPointsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxContours != maxContoursCalc)
                            {
                                String sDetails = "maxContours = " + maxContours + ", calculated = " + maxContoursCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxCompositePoints != maxCompositePointsCalc)
                            {
                                String sDetails = "maxCompositePoints = " + maxCompositePoints + ", calculated = " + maxCompositePointsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxCompositeContours != maxCompositeContoursCalc)
                            {
                                String sDetails = "maxCompositeContours = " + maxCompositeContours + ", calculated = " + maxCompositeContoursCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            // Bug 2168.
                            // Case 1: Same as max size from glyf table. Info.
                            // Case 2: Same as max size from glyf table +
                            //         size(fpgm) + size(prep). Info message.
                            // Case 3: Smaller than max size from glyf table.
                            //         Error
                            // Case 4: Neither 1 nor 2. Warning.
                            DirectoryEntry dePrep =
                                fontOwner.GetDirectoryEntry("prep");
                            uint prepLength = 0;
                            if (null != dePrep)
                            {
                                prepLength = dePrep.length;
                            }
                            DirectoryEntry deFpgm =
                                fontOwner.GetDirectoryEntry("fpgm");
                            uint fpgmLength = 0;
                            if (null != deFpgm)
                            {
                                fpgmLength = deFpgm.length;
                            }

                            if (maxSizeOfInstructions ==
                                maxSizeOfInstructionsCalc)
                            {
                                // Case 1:
                                String sDetails = "maxSizeOfInstructions=" +
                                                  maxSizeOfInstructions + ", computed " +
                                                  "from the glyf table";
                                v.Info(T.maxp_GlyphStats,
                                       I.maxp_I_Calculation_Method1,
                                       m_tag, sDetails);
                            }
                            else if (maxSizeOfInstructions ==
                                     (maxSizeOfInstructionsCalc +
                                      prepLength + fpgmLength))
                            {
                                // Case 2:
                                String sDetails =
                                    "maxp maxSizeOfInstructions is " +
                                    maxSizeOfInstructions + ", which is " +
                                    "glyf maxSizeOfInstructions (" +
                                    maxSizeOfInstructionsCalc +
                                    ") + prep size (" + prepLength +
                                    ") + fpgm size (" + fpgmLength + ")";
                                v.Info(T.maxp_GlyphStats,
                                       I.maxp_I_Calculation_Method2,
                                       m_tag, sDetails);
                            }
                            else if (maxSizeOfInstructions <
                                     maxSizeOfInstructionsCalc)
                            {
                                // Case 3
                                String sDetails =
                                    "maxp maxSizeOfInstructions is " +
                                    maxSizeOfInstructions +
                                    ", which is smaller than the " +
                                    "size of instuctions (" +
                                    maxSizeOfInstructionsCalc + ") found" +
                                    " for some glyph in the glyf table.";
                                v.Error(T.maxp_GlyphStats,
                                        E.maxp_E_Calculation, m_tag,
                                        sDetails);
                                bRet = false;
                            }
                            else
                            {
                                // Case 4
                                String sDetails =
                                    "glyf maxSizeOfInstructions=" +
                                    maxSizeOfInstructionsCalc +
                                    ", prep size=" + prepLength +
                                    ", fpgm size=" + fpgmLength +
                                    ", whereas maxp maxSizeOfInstruction " +
                                    "is " + maxSizeOfInstructions;
                                v.Warning(T.maxp_GlyphStats,
                                          W.maxp_W_Calculation_Unclear,
                                          m_tag,
                                          sDetails);
                                bGlyphStatsOk = false;
                            }

                            if (maxComponentElements != maxComponentElementsCalc)
                            {
                                String sDetails = "maxComponentElements = " + maxComponentElements + ", calculated = " + maxComponentElementsCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            if (maxComponentDepth != maxComponentDepthCalc)
                            {
                                String sDetails = "maxComponentDepth = " + maxComponentDepth + ", calculated = " + maxComponentDepthCalc;
                                v.Error(T.maxp_GlyphStats, E.maxp_E_Calculation, m_tag, sDetails);
                                bRet          = false;
                                bGlyphStatsOk = false;
                            }

                            if (bGlyphStatsOk)
                            {
                                v.Pass(T.maxp_GlyphStats, P.maxp_P_Calculation, m_tag);
                            }
                        }
                        else
                        {
                            v.Warning(T.maxp_GlyphStats, W._TEST_W_ErrorInAnotherTable, m_tag, "Errors in the glyf table are preventing validation of maxPoints, maxContours, maxCompositePoints, maxCompositeContours, maxSizeofInstructions, maxComponentElements, and maxComponentDepth");
                        }
                    }
                }
                else
                {
                    v.Info(T.maxp_GlyphStats, I._TEST_I_TableVersion, m_tag, "test = maxp_GlyphStats");
                }
            }

            return(bRet);
        }