Exemplo n.º 1
0
        protected bool CheckForRecommendedTables(Validator v)
        {
            bool bRet = true;

            bool bMissing = false;

            if (!IsPostScript())
            {
                if (GetDirectoryEntry("gasp") == null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "gasp");
                    bMissing = true;
                }

                Table_hmtx hmtxTable = (Table_hmtx)GetTable("hmtx");
                if (hmtxTable != null)
                {
                    if (!hmtxTable.IsMonospace(this) && !ContainsSymbolsOnly())
                    {
                        if (GetDirectoryEntry("kern") == null)
                        {
                            v.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "kern");
                            bMissing = true;
                        }

                        if (GetDirectoryEntry("hdmx") == null)
                        {
                            v.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "hdmx");
                            bMissing = true;
                        }
                    }
                }

                if (GetDirectoryEntry("VDMX") == null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "VDMX");
                    bMissing = true;
                }
            }

            if (GetDirectoryEntry("DSIG") == null && !GetFile().IsCollection())
            {
                v.Warning(T.T_NULL, W._FONT_W_MissingRecommendedTable, null, "DSIG");
                bMissing = true;
            }

            if (!bMissing)
            {
                v.Pass(P._FONT_P_MissingRecommendedTable, null);
            }

            return(bRet);
        }
Exemplo n.º 2
0
        protected bool CheckForNoUnnecessaryTables(Validator v)
        {
            bool bRet = true;

            bool bFoundUnnecessary = false;

            Table_hmtx hmtxTable = (Table_hmtx)GetTable("hmtx");

            if (hmtxTable != null)
            {
                if (hmtxTable.IsMonospace(this))
                {
                    if (GetDirectoryEntry("hdmx") != null)
                    {
                        v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "hdmx table not needed for monospaced font");
                        bFoundUnnecessary = true;
                    }

                    if (GetDirectoryEntry("LTSH") != null)
                    {
                        v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "LTSH table not needed for monospaced font");
                        bFoundUnnecessary = true;
                    }

                    if (GetDirectoryEntry("kern") != null)
                    {
                        v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "kern table not needed for monospaced font");
                        bFoundUnnecessary = true;
                    }
                }

                if (GetDirectoryEntry("CFF ") == null && GetDirectoryEntry("VORG") != null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "VORG table not needed, it may optionally be present for fonts with Postscript outlines");
                    bFoundUnnecessary = true;
                }

                if (GetDirectoryEntry("PCLT") != null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "PCLT table not needed, Microsoft no longer recommends including this table");
                    bFoundUnnecessary = true;
                }
            }

            if (GetDirectoryEntry("CFF ") != null)
            {
                string [] UnnecessaryTables = { "glyf", "fpgm", "cvt ", "loca", "prep" };

                for (int i = 0; i < UnnecessaryTables.Length; i++)
                {
                    if (GetDirectoryEntry(UnnecessaryTables[i]) != null)
                    {
                        v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, UnnecessaryTables[i] + " not needed since the font contains a 'CFF ' table");
                        bFoundUnnecessary = true;
                    }
                }
            }

            if (GetDirectoryEntry("glyf") != null)
            {
                if (GetDirectoryEntry("CFF ") != null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "CFF not needed since the font contains a 'CFF ' table");
                    bFoundUnnecessary = true;
                }
            }

            if (ContainsLatinOnly())
            {
                if (GetDirectoryEntry("vhea") != null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "vhea not needed since the font only contains Latin characters");
                    bFoundUnnecessary = true;
                }

                if (GetDirectoryEntry("vmtx") != null)
                {
                    v.Warning(T.T_NULL, W._FONT_W_UnnecessaryTable, null, "vmtx not needed since the font only contains Latin characters");
                    bFoundUnnecessary = true;
                }
            }


            if (!bFoundUnnecessary)
            {
                v.Pass(P._FONT_P_UnnecessaryTable, null);
            }

            return(bRet);
        }
Exemplo n.º 3
0
        /************************
         * public methods
         */


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

            if (v.PerformTest(T.hhea_version))
            {
                if (TableVersionNumber.GetUint() == 0x00010000)
                {
                    v.Pass(T.hhea_version, P.hhea_P_version, m_tag);
                }
                else
                {
                    v.Error(T.hhea_version, E.hhea_E_version, m_tag, "0x" + TableVersionNumber.GetUint().ToString("x8"));
                    bRet = false;
                }
            }

            if (v.PerformTest(T.hhea_AscenderPositive))
            {
                if (Ascender <= 0)
                {
                    string s = "Ascender = " + Ascender;
                    v.Error(T.hhea_AscenderPositive, E.hhea_E_AscenderPositive, m_tag, s);
                    bRet = false;
                }
                else
                {
                    v.Pass(T.hhea_AscenderPositive, P.hhea_P_AscenderPositive, m_tag);
                }
            }

            if (v.PerformTest(T.hhea_DescenderNegative))
            {
                if (Descender >= 0)
                {
                    string s = "Descender = " + Descender;
                    v.Error(T.hhea_DescenderNegative, E.hhea_E_DescenderNegative, m_tag, s);
                    bRet = false;
                }
                else
                {
                    v.Pass(T.hhea_DescenderNegative, P.hhea_P_DescenderNegative, m_tag);
                }
            }

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

            if (headTable != null)
            {
                if (v.PerformTest(T.hhea_Ascender_yMax))
                {
                    if (Ascender > headTable.yMax)
                    {
                        string s = "Ascender = " + Ascender + ", head.yMax = " + headTable.yMax;
                        v.Info(T.hhea_Ascender_yMax, I.hhea_I_Ascender_yMax, m_tag, s);
                        // bRet = false;
                    }
                    else
                    {
                        v.Pass(T.hhea_Ascender_yMax, P.hhea_P_Ascender_yMax, m_tag);
                    }
                }

                if (v.PerformTest(T.hhea_Descender_yMin))
                {
                    if (Descender < headTable.yMin)
                    {
                        string s = "Descender = " + Descender + ", head.yMin = " + headTable.yMin;
                        v.Info(T.hhea_Descender_yMin, I.hhea_I_Descender_yMin, m_tag, s);
                        // bRet = false;
                    }
                    else
                    {
                        v.Pass(T.hhea_Descender_yMin, P.hhea_P_Descender_yMin, m_tag);
                    }
                }
            }
            else
            {
                v.Error(T.hhea_Ascender_yMax, E._TEST_E_TableMissing, m_tag, "head");
                bRet = false;
            }

            if (v.PerformTest(T.hhea_LineGapPositive))
            {
                if (LineGap < 0)
                {
                    string s = "LineGap = " + LineGap;
                    v.Warning(T.hhea_LineGapPositive, W.hhea_W_LineGapPositive, m_tag, s);
                    //bRet = false;
                }
                else
                {
                    v.Pass(T.hhea_LineGapPositive, P.hhea_P_LineGapPositive, m_tag);
                }
            }

            Table_OS2 OS2Table = (Table_OS2)fontOwner.GetTable("OS/2");

            if (OS2Table != null)
            {
                if (v.PerformTest(T.hhea_Ascender_usWinAscent))
                {
                    if (OS2Table.usWinAscent != Ascender)
                    {
                        string s = "hhea.Ascender = " + Ascender + ", OS/2.usWinAscent = " + OS2Table.usWinAscent;
                        v.Warning(T.hhea_Ascender_usWinAscent, W.hhea_W_Ascender_usWinAscent, m_tag, s);
                    }
                    else
                    {
                        v.Pass(T.hhea_Ascender_usWinAscent, P.hhea_P_Ascender_usWinAscent, m_tag);
                    }
                }

                if (v.PerformTest(T.hhea_Descender_usWinDescent))
                {
                    if (OS2Table.usWinDescent != (Descender * -1))
                    {
                        string s = "hhea.Descender = " + Descender + ", OS/2.usWinDescent = " + OS2Table.usWinDescent;
                        v.Warning(T.hhea_Descender_usWinDescent, W.hhea_W_Descender_usWinDescent, m_tag, s);
                    }
                    else
                    {
                        v.Pass(T.hhea_Descender_usWinDescent, P.hhea_P_Descender_usWinDescent, m_tag);
                    }
                }

                // Microsoft is recommending that Ascender, Descender and LineGap be in line with OS2.winAscent, OS2.winDescent
                // and formulated value for LineGap to make sure font displays the same on Apple as it does no Windows.
                if (v.PerformTest(T.hhea_LineGap_minGap))
                {
                    int sMinGap = (OS2Table.usWinAscent + OS2Table.usWinDescent) - (Ascender - Descender);
                    if (LineGap < sMinGap)
                    {
                        string s = "LineGap = " + LineGap + ", recommended = " + sMinGap;
                        v.Warning(T.hhea_LineGap_minGap, W.hhea_W_LineGap_minGap, m_tag, s);
                        //bRet = false;
                    }
                    else
                    {
                        v.Pass(T.hhea_LineGap_minGap, P.hhea_P_LineGap_minGap, m_tag);
                    }
                }
                else
                {
                    v.Error(T.hhea_LineGap_minGap, E._TEST_E_TableMissing, m_tag, "OS/2");
                }
            }
            else
            {
                v.Error(T.hhea_Ascender_usWinAscent, E._TEST_E_TableMissing, m_tag, "OS/2");
                v.Error(T.hhea_Descender_usWinDescent, E._TEST_E_TableMissing, m_tag, "OS/2");
                v.Error(T.hhea_LineGap_minGap, E._TEST_E_TableMissing, m_tag, "OS/2");
                bRet = false;
            }

            if (v.PerformTest(T.hhea_MinMax))
            {
                if (fontOwner.ContainsTrueTypeOutlines())
                {
                    Table_hmtx hmtxTable = (Table_hmtx)fontOwner.GetTable("hmtx");
                    Table_glyf glyfTable = (Table_glyf)fontOwner.GetTable("glyf");
                    Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp");
                    if (hmtxTable == null)
                    {
                        v.Error(T.hhea_MinMax, E._TEST_E_TableMissing, m_tag, "hmtx");
                        bRet = false;
                    }
                    else if (glyfTable == null)
                    {
                        v.Error(T.hhea_MinMax, E._TEST_E_TableMissing, m_tag, "glyf");
                        bRet = false;
                    }
                    else if (maxpTable == null)
                    {
                        v.Error(T.hhea_MinMax, E._TEST_E_TableMissing, m_tag, "maxp");
                        bRet = false;
                    }
                    else
                    {
                        ushort numGlyphs = fontOwner.GetMaxpNumGlyphs();

                        ushort awMax  = 0;
                        short  minLSB = 32767;
                        short  minRSB = 32767;
                        short  xmaxEx = -32768;

                        Table_hmtx.longHorMetric hm = null;

                        for (uint iGlyph = 0; iGlyph < numGlyphs; iGlyph++)
                        {
                            hm = hmtxTable.GetOrMakeHMetric(iGlyph, fontOwner);
                            if (hm == null)
                            {
                                break;
                            }

                            if (awMax < hm.advanceWidth)
                            {
                                awMax = hm.advanceWidth;

                                // We want to give the user feedback to know what glyph id
                                // has the bad width assigned
                                if (awMax > advanceWidthMax)
                                {
                                    string s = "glyph ID = " + iGlyph + ", advance width = " + awMax;
                                    v.Error(T.hhea_MinMax, E.hhea_E_advanceWidthMax, m_tag, s);
                                    bRet = false;
                                }
                            }

                            Table_glyf.header gh = glyfTable.GetGlyphHeader(iGlyph, fontOwner);
                            // calculate for all non-zero contours...this includes composites
                            if (gh != null &&
                                gh.numberOfContours != 0)
                            {
                                if (minLSB > hm.lsb)
                                {
                                    minLSB = hm.lsb;
                                }

                                short rsb = (short)(hm.advanceWidth - hm.lsb - (gh.xMax - gh.xMin));
                                if (minRSB > rsb)
                                {
                                    minRSB = rsb;
                                }

                                short extent = (short)(hm.lsb + (gh.xMax - gh.xMin));
                                if (xmaxEx < extent)
                                {
                                    xmaxEx = extent;
                                }
                            }
                        }


                        if (hm != null)
                        {
                            if (advanceWidthMax == awMax)
                            {
                                v.Pass(T.hhea_MinMax, P.hhea_P_advanceWidthMax, m_tag);
                            }
                            else
                            {
                                string s = "actual = " + advanceWidthMax + ", calc = " + awMax;
                                v.Error(T.hhea_MinMax, E.hhea_E_advanceWidthMax, m_tag, s);
                                bRet = false;
                            }

                            if (minLeftSideBearing == minLSB)
                            {
                                v.Pass(T.hhea_MinMax, P.hhea_P_minLeftSideBearing, m_tag);
                            }
                            else
                            {
                                string s = "actual = " + minLeftSideBearing + ", calc = " + minLSB;
                                v.Error(T.hhea_MinMax, E.hhea_E_minLeftSideBearing, m_tag, s);
                                bRet = false;
                            }

                            if (minRightSideBearing == minRSB)
                            {
                                v.Pass(T.hhea_MinMax, P.hhea_P_minRightSideBearing, m_tag);
                            }
                            else
                            {
                                string s = "actual = " + minRightSideBearing + ", calc = " + minRSB;
                                v.Error(T.hhea_MinMax, E.hhea_E_minRightSideBearing, m_tag, s);
                                bRet = false;
                            }

                            if (xMaxExtent == xmaxEx)
                            {
                                v.Pass(T.hhea_MinMax, P.hhea_P_xMaxExtent, m_tag);
                            }
                            else
                            {
                                string s = "actual = " + xMaxExtent + ", calc = " + xmaxEx;
                                v.Error(T.hhea_MinMax, E.hhea_E_xMaxExtent, m_tag, s);
                                bRet = false;
                            }
                        }
                        else
                        {
                            v.Warning(T.hhea_MinMax, W.hhea_W_hmtx_invalid, m_tag, "unable to parse hmtx table");
                        }
                    }
                }
                else
                {
                    v.Info(T.hhea_MinMax, I._TEST_I_NotForCFF, m_tag, "test = hhea_MinMax");
                }
            }

            if (v.PerformTest(T.hhea_reserved))
            {
                if (reserved1 != 0)
                {
                    v.Error(T.hhea_reserved, E.hhea_E_reserved1, m_tag, reserved1.ToString());
                    bRet = false;
                }
                else if (reserved2 != 0)
                {
                    v.Error(T.hhea_reserved, E.hhea_E_reserved2, m_tag, reserved2.ToString());
                    bRet = false;
                }
                else if (reserved3 != 0)
                {
                    v.Error(T.hhea_reserved, E.hhea_E_reserved3, m_tag, reserved3.ToString());
                    bRet = false;
                }
                else if (reserved4 != 0)
                {
                    v.Error(T.hhea_reserved, E.hhea_E_reserved4, m_tag, reserved4.ToString());
                    bRet = false;
                }
                else
                {
                    v.Pass(T.hhea_reserved, P.hhea_P_reserved, m_tag);
                }
            }

            if (v.PerformTest(T.hhea_metricDataFormat))
            {
                if (metricDataFormat == 0)
                {
                    v.Pass(T.hhea_metricDataFormat, P.hhea_P_metricDataFormat, m_tag);
                }
                else
                {
                    v.Error(T.hhea_metricDataFormat, E.hhea_E_metricDataFormat, m_tag, metricDataFormat.ToString());
                    bRet = false;
                }
            }

            if (v.PerformTest(T.hhea_numberOfHMetrics))
            {
                Table_hmtx hmtxTable = (Table_hmtx)fontOwner.GetTable("hmtx");
                Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp");
                if (hmtxTable == null)
                {
                    v.Error(T.hhea_numberOfHMetrics, E._TEST_E_TableMissing, m_tag, "hmtx");
                    bRet = false;
                }
                else if (maxpTable == null)
                {
                    v.Error(T.hhea_numberOfHMetrics, E._TEST_E_TableMissing, m_tag, "maxp");
                    bRet = false;
                }
                else
                {
                    ushort numGlyphs = fontOwner.GetMaxpNumGlyphs();
                    if (numberOfHMetrics * 4 + (numGlyphs - numberOfHMetrics) * 2 == hmtxTable.GetLength())
                    {
                        v.Pass(T.hhea_numberOfHMetrics, P.hhea_P_numberOfHMetrics, m_tag);
                    }
                    else
                    {
                        v.Error(T.hhea_numberOfHMetrics, E.hhea_E_numberOfHMetrics, m_tag);
                        bRet = false;
                    }
                }
            }

            if (v.PerformTest(T.hhea_caretSlope))
            {
                bool bSlopeOk = true;

                Table_post postTable = (Table_post)fontOwner.GetTable("post");

                if (postTable != null)
                {
                    uint   ia           = postTable.italicAngle.GetUint();
                    double dItalicAngle = postTable.italicAngle.GetDouble();

                    if (ia == 0)
                    {
                        if (caretSlopeRun != 0)
                        {
                            v.Error(T.hhea_caretSlope, E.hhea_E_caretSlopeRunNonZero_italicAngle, m_tag);
                            bSlopeOk = false;
                            bRet     = false;
                        }
                    }
                    else
                    {
                        if (caretSlopeRun == 0)
                        {
                            v.Error(T.hhea_caretSlope, E.hhea_E_caretSlopeRunZero_italicAngle, m_tag);
                            bSlopeOk = false;
                            bRet     = false;
                        }
                        else
                        {
                            double dActualAngle = 90.0 + postTable.italicAngle.GetDouble();
                            double dhheaAngle   = (Math.Atan2(caretSlopeRise, caretSlopeRun)) * (180.0 / Math.PI);
                            if (Math.Abs(dActualAngle - dhheaAngle) >= 1.0)
                            {
                                string sDetails = "caretSlope Rise:Run = " + caretSlopeRise + ":" + caretSlopeRun +
                                                  " (" + (dhheaAngle - 90.0) + " degrees)" +
                                                  ", post.italicAngle = 0x" + ia.ToString("x8") +
                                                  " (" + postTable.italicAngle.GetDouble() + " degrees)";
                                v.Error(T.hhea_caretSlope, E.hhea_E_caretSlopeAngle_italicAngle, m_tag, sDetails);
                                bSlopeOk = false;
                                bRet     = false;
                            }
                        }
                    }
                }
                else
                {
                    v.Error(T.hhea_caretSlope, E._TEST_E_TableMissing, m_tag, "post table missing, can't compare caret slope to italicAngle");
                    bSlopeOk = false;
                    bRet     = false;
                }


                if (bSlopeOk)
                {
                    v.Pass(T.hhea_caretSlope, P.hhea_P_caretSlopeAngle_italicAngle, m_tag);
                }
            }

            return(bRet);
        }
Exemplo n.º 4
0
        /************************
         * public methods
         */


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

            if (v.PerformTest(T.post_TableLength))
            {
                bool bLenOk = true;

                if (Version.GetUint() == 0x00010000 ||
                    Version.GetUint() == 0x00030000)
                {
                    if (GetLength() != 32)
                    {
                        v.Error(T.post_TableLength, E.post_E_TableLenNot32, m_tag);
                        bLenOk = false;
                        bRet   = false;
                    }
                }
                if (Version.GetUint() == 0x00020000)
                {
                    if (GetLength() < 34)
                    {
                        v.Error(T.post_TableLength, E.post_E_InvalidTableLen, m_tag);
                        bLenOk = false;
                        bRet   = false;
                    }
                }

                if (bLenOk)
                {
                    v.Pass(T.post_TableLength, P.post_P_TableLength, m_tag);
                }
            }

            if (v.PerformTest(T.post_Version))
            {
                uint ver = Version.GetUint();
                if (ver == 0x00025000)
                {
                    v.Warning(T.post_Version, W.post_W_Version_2_5, m_tag);
                }
                else if (ver == 0x00010000 || ver == 0x00020000)
                {
                    v.Pass(T.post_Version, P.post_P_Version, m_tag);
                }
                else if (ver == 0x00030000)
                {
                    v.Warning(T.post_Version, W.post_W_Version_3_Apple, m_tag);
                }
                else if (ver == 0x00040000)
                {
                    v.Warning(T.post_Version, W.post_W_Version_4_Apple, m_tag);
                }
                else
                {
                    v.Error(T.post_Version, E.post_E_Version, m_tag, "0x" + ver.ToString("x8"));
                }
            }

            if (v.PerformTest(T.post_italicAngle))
            {
                bool bItalOk = true;

                uint   ia           = italicAngle.GetUint();
                double dItalicAngle = italicAngle.GetDouble();

                if (dItalicAngle < -30.0 || dItalicAngle > 360.0 || (dItalicAngle > 0.0 && dItalicAngle < 330.0))
                {
                    v.Warning(T.post_italicAngle, W.post_W_italicAngle_unlikely, m_tag, "0x" + ia.ToString("x8"));
                    bItalOk = false;
                }

                Table_head headTable = (Table_head)fontOwner.GetTable("head");
                if (headTable != null)
                {
                    if ((headTable.macStyle & 0x0002) != 0)
                    {
                        if (ia == 0)
                        {
                            v.Error(T.post_italicAngle, E.post_E_italicAngleZero_macStyle, m_tag);
                            bItalOk = false;
                            bRet    = false;
                        }
                    }
                    else
                    {
                        if (ia != 0)
                        {
                            v.Error(T.post_italicAngle, E.post_E_italicAngleNonzero_macStyle, m_tag);
                            bItalOk = false;
                            bRet    = false;
                        }
                    }
                }
                else
                {
                    v.Error(T.post_italicAngle, E._TEST_E_TableMissing, m_tag, "head table missing, can't compare italicAngle to head.macStyle");
                    bItalOk = false;
                }

                Table_hhea hheaTable = (Table_hhea)fontOwner.GetTable("hhea");
                if (hheaTable != null)
                {
                    if (ia == 0)
                    {
                        if (hheaTable.caretSlopeRun != 0)
                        {
                            v.Error(T.post_italicAngle, E.post_E_italicAngleZero_caretSlopeRun, m_tag);
                            bItalOk = false;
                            bRet    = false;
                        }
                    }
                    else
                    {
                        if (hheaTable.caretSlopeRun == 0)
                        {
                            v.Error(T.post_italicAngle, E.post_E_italicAngleNonzero_caretSlopeRun, m_tag);
                            bItalOk = false;
                            bRet    = false;
                        }
                        else
                        {
                            double dActualAngle = 90.0 + italicAngle.GetDouble();
                            double dhheaAngle   = (Math.Atan2(hheaTable.caretSlopeRise, hheaTable.caretSlopeRun)) * (180.0 / Math.PI);
                            if (Math.Abs(dActualAngle - dhheaAngle) >= 1.0)
                            {
                                string sDetails = "italicAngle = 0x" + ia.ToString("x8") +
                                                  " (" + italicAngle.GetDouble() + " degrees)" +
                                                  ",caretSlope Rise:Run = " + hheaTable.caretSlopeRise + ":" + hheaTable.caretSlopeRun +
                                                  " (" + (dhheaAngle - 90.0) + " degrees)";
                                v.Error(T.post_italicAngle, E.post_E_italicAngleNonzero_hheaAngle, m_tag, sDetails);
                                bItalOk = false;
                                bRet    = false;
                            }
                        }
                    }
                }
                else
                {
                    v.Error(T.post_italicAngle, E._TEST_E_TableMissing, m_tag, "hhea table missing, can't compare italicAngle to hhea.caretSlopeRun");
                    bItalOk = false;
                    bRet    = false;
                }

                if (bItalOk)
                {
                    v.Pass(T.post_italicAngle, P.post_P_italicAngle, m_tag);
                }
            }

            if (v.PerformTest(T.post_underlinePosition))
            {
                Table_hhea hheaTable = (Table_hhea)fontOwner.GetTable("hhea");
                if (hheaTable != null)
                {
                    if (underlinePosition >= hheaTable.Descender)
                    {
                        v.Pass(T.post_underlinePosition, P.post_P_underlinePosition, m_tag);
                    }
                    else
                    {
                        v.Warning(T.post_underlinePosition, W.post_W_underlinePos_LT_descender, m_tag);
                        //bRet = false;
                    }
                }
                else
                {
                    v.Error(T.post_underlinePosition, E._TEST_E_TableMissing, m_tag, "hhea table missing, can't compare underlinePosition to hhea.Descender");
                }
            }

            if (v.PerformTest(T.post_underlineThickness))
            {
                Table_head headTable = (Table_head)fontOwner.GetTable("head");
                if (headTable != null)
                {
                    if (underlineThickness >= 0 && underlineThickness < headTable.unitsPerEm / 2)
                    {
                        v.Pass(T.post_underlineThickness, P.post_P_underlineThickness, m_tag);
                    }
                    else
                    {
                        v.Warning(T.post_underlineThickness, W.post_W_underlineThickness, m_tag, underlineThickness.ToString());
                    }
                }
                else
                {
                    v.Error(T.post_underlineThickness, E._TEST_E_TableMissing, m_tag, "head table missing, can't compare underlineThickness to head.unitsPerEm");
                    bRet = false;
                }
            }

            if (v.PerformTest(T.post_isFixedPitch))
            {
                bool bFixedPitchOk = true;

                Table_hmtx hmtxTable = (Table_hmtx)fontOwner.GetTable("hmtx");
                if (hmtxTable != null)
                {
                    uint numberOfHMetrics = 0;

                    Table_hhea hheaTable = (Table_hhea)fontOwner.GetTable("hhea");
                    if (hheaTable != null)
                    {
                        numberOfHMetrics = hheaTable.numberOfHMetrics;
                    }
                    else
                    {
                        v.Error(T.post_isFixedPitch, E._TEST_E_TableMissing, m_tag, "hhea table missing, can't compare isFixedPitch to horizontal metrics");
                        bRet = false;
                    }

                    bool bHmtxMono = hmtxTable.IsMonospace(fontOwner);

                    if (isFixedPitch == 0 && bHmtxMono)
                    {
                        v.Error(T.post_isFixedPitch, E.post_E_isFixedPitchZero_hmtx, m_tag);
                        bFixedPitchOk = false;
                        bRet          = false;
                    }
                    else if (isFixedPitch != 0 && !bHmtxMono)
                    {
                        v.Error(T.post_isFixedPitch, E.post_E_isFixedPitchNonzero_hmtx, m_tag);
                        bFixedPitchOk = false;
                        bRet          = false;
                    }
                }
                else
                {
                    v.Error(T.post_isFixedPitch, E._TEST_E_TableMissing, m_tag, "hmtx table missing, can't compare isFixedPitch to horizontal metrics");
                    bRet = false;
                }

                Table_OS2 OS2Table = (Table_OS2)fontOwner.GetTable("OS/2");
                if (OS2Table != null)
                {
                    if (OS2Table.panose_byte1 == 2)                          // PANOSE family kind == LatinText
                    {
                        if (isFixedPitch == 0 && OS2Table.panose_byte4 == 9) // PANOSE proportion == monospaced
                        {
                            v.Error(T.post_isFixedPitch, E.post_E_isFixedPitchZero_OS_2, m_tag);
                            bFixedPitchOk = false;
                            bRet          = false;
                        }
                        else if (isFixedPitch != 0 && OS2Table.panose_byte4 != 9)
                        {
                            v.Error(T.post_isFixedPitch, E.post_E_isFixedPitchNonzero_OS_2, m_tag);
                            bFixedPitchOk = false;
                            bRet          = false;
                        }
                    }
                }
                else
                {
                    v.Error(T.post_isFixedPitch, E._TEST_E_TableMissing,
                            m_tag, "OS/2 table is missing, can't compare isFixedPitch to OS/2 PANOSE");
                    bRet = false;
                }

                if (bFixedPitchOk && hmtxTable != null && OS2Table != null)
                {
                    v.Pass(T.post_isFixedPitch, P.post_P_isFixedPitch, m_tag, "matches the hmtx and OS/2 tables");
                }
                else if (bFixedPitchOk && hmtxTable == null && OS2Table != null)
                {
                    v.Pass(T.post_isFixedPitch, P.post_P_isFixedPitch, m_tag, "matches the OS/2 table");
                }
                else if (bFixedPitchOk && hmtxTable != null && OS2Table == null)
                {
                    v.Pass(T.post_isFixedPitch, P.post_P_isFixedPitch, m_tag, "matches the hmtx table");
                }
            }

            if (v.PerformTest(T.post_v2_numberOfGlyphs))
            {
                if (Version.GetUint() == 0x00020000)
                {
                    Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp");
                    if (maxpTable == null)
                    {
                        v.Error(T.post_v2_numberOfGlyphs, E._TEST_E_TableMissing, m_tag, "maxp table is missing");
                        bRet = false;
                    }
                    else
                    {
                        if (numberOfGlyphs == fontOwner.GetMaxpNumGlyphs())
                        {
                            v.Pass(T.post_v2_numberOfGlyphs, P.post_P_v2_numberOfGlyphs, m_tag);
                        }
                        else
                        {
                            v.Error(T.post_v2_numberOfGlyphs, E.post_E_v2_numberOfGlyphs,
                                    m_tag, "numberOfGlyphs = " + numberOfGlyphs +
                                    ", maxp.numGlyphs = " + fontOwner.GetMaxpNumGlyphs());
                            bRet = false;
                        }
                    }
                }
                else
                {
                    v.Info(T.post_v2_numberOfGlyphs, I.post_I_v2_numberOfGlyphs_notv2, m_tag);
                }
            }

            if (v.PerformTest(T.post_v2_glyphNameIndex))
            {
                if (Version.GetUint() == 0x00020000 && GetLength() >= 34)
                {
                    bool bIndexOk = true;

                    for (uint i = 0; i < numberOfGlyphs; i++)
                    {
                        if ((uint)FieldOffsetsVer2.glyphNameIndex + i * 2 + 2 <= m_bufTable.GetLength())
                        {
                            ushort index = GetGlyphNameIndex((ushort)i);
                            if (index - 258 >= m_nameOffsets.Length)
                            {
                                string s = "glyphNameIndex[" + i + "] = " +
                                           index + ", # names = " + m_nameOffsets.Length;
                                v.Error(T.post_v2_glyphNameIndex, E.post_E_glyphNameIndex_range, m_tag, s);
                                bIndexOk = false;
                                bRet     = false;
                            }
                        }
                        else
                        {
                            v.Warning(T.post_v2_glyphNameIndex,
                                      W._TEST_W_OtherErrorsInTable, m_tag,
                                      "unable to validate any more glyph indexes, index  " +
                                      i + " is past end of table");
                            bIndexOk = false;
                            break;
                        }
                    }

                    if (bIndexOk)
                    {
                        v.Pass(T.post_v2_glyphNameIndex, P.post_P_glyphNameIndex, m_tag);
                    }
                }
                else
                {
                    v.Info(T.post_v2_glyphNameIndex, I.post_I_v2_glyphNameIndex_notv2, m_tag);
                }
            }

            if (v.PerformTest(T.post_v2_names))
            {
                if (Version.GetUint() == 0x00020000)
                {
                    PostNames pn = new PostNames();

                    bool bNamesOk = true;

                    byte [] buf = new byte[2];

                    for (uint iGlyph = 0; iGlyph < numberOfGlyphs; iGlyph++)
                    {
                        if ((uint)FieldOffsetsVer2.glyphNameIndex + iGlyph * 2 + 2
                            <= m_bufTable.GetLength())
                        {
                            uint index = GetGlyphNameIndex((ushort)iGlyph);
                            if (index >= 258 && index - 258 < m_nameOffsets.Length)
                            {
                                if (m_nameOffsets[index - 258] >= GetLength())
                                {
                                    string s = "name index = " + index;
                                    v.Error(T.post_v2_names,
                                            E.post_E_v2_NameOffsetInvalid,
                                            m_tag, s);
                                    bNamesOk = false;
                                    bRet     = false;
                                }
                                else
                                {
                                    uint length =
                                        m_bufTable.GetByte(m_nameOffsets[index - 258]);
                                    if (m_nameOffsets[index - 258] + length < GetLength())
                                    {
                                        bNamesOk = CheckNames(v, fontOwner, pn, iGlyph, index);
                                    }
                                    else
                                    {
                                        string s = "name index = " + index;
                                        v.Error(T.post_v2_names, E.post_E_v2_NameLengthInvalid, m_tag, s);
                                        bNamesOk = false;
                                        bRet     = false;
                                    }
                                }
                            }
                        }
                        else
                        {
                            v.Warning(T.post_v2_names, W._TEST_W_OtherErrorsInTable, m_tag,
                                      "unable to validate any more names, index " +
                                      iGlyph + " is past end of table");
                            bNamesOk = false;
                            break;
                        }
                    }

                    if (bNamesOk)
                    {
                        v.Pass(T.post_v2_names, P.post_P_names, m_tag);
                    }
                }
                else
                {
                    v.Info(T.post_v2_names, I.post_I_v2_names_notv2, m_tag);
                }
            }

            return(bRet);
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        /************************
         * public methods
         */


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

            if (v.PerformTest(T.PCLT_TableLength))
            {
                if (GetLength() == 54)
                {
                    v.Pass(T.PCLT_TableLength, P.PCLT_P_TableLength, m_tag);
                }
                else
                {
                    v.Error(T.PCLT_TableLength, E.PCLT_E_TableLength, m_tag, GetLength().ToString());
                    bRet = false;
                }
            }

            if (v.PerformTest(T.PCLT_Version))
            {
                if (Version.GetUint() == 0x00010000)
                {
                    v.Pass(T.PCLT_Version, P.PCLT_P_Version, m_tag);
                }
                else
                {
                    v.Error(T.PCLT_Version, E.PCLT_E_Version, m_tag, "0x" + Version.GetUint().ToString("x8"));
                    bRet = false;
                }
            }

            if (v.PerformTest(T.PCLT_Pitch))
            {
                Table_hmtx hmtxTable = (Table_hmtx)fontOwner.GetTable("hmtx");
                Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp");
                if (hmtxTable == null)
                {
                    v.Error(T.PCLT_Pitch, E._TEST_E_TableMissing, m_tag, "hmtx");
                    bRet = false;
                }
                else if (maxpTable == null)
                {
                    v.Error(T.PCLT_Pitch, E._TEST_E_TableMissing, m_tag, "maxp");
                    bRet = false;
                }
                else
                {
                    uint iSpaceGlyph = fontOwner.FastMapUnicodeToGlyphID(' ');

                    if (iSpaceGlyph < fontOwner.GetMaxpNumGlyphs())
                    {
                        Table_hmtx.longHorMetric hmSpace = hmtxTable.GetOrMakeHMetric(iSpaceGlyph, fontOwner);
                        if (hmSpace != null)
                        {
                            if (Pitch == hmSpace.advanceWidth)
                            {
                                v.Pass(T.PCLT_Pitch, P.PCLT_P_Pitch, m_tag);
                            }
                            else
                            {
                                string s = "actual = " + Pitch + ", expected = " + hmSpace.advanceWidth;
                                v.Error(T.PCLT_Pitch, E.PCLT_E_Pitch, m_tag, s);
                                bRet = false;
                            }
                        }
                    }
                    else
                    {
                        // JJF Figure out what to do
                        v.Warning(T.PCLT_Pitch, W._TEST_W_ErrorInAnotherTable, m_tag, "can't validate Pitch field, error getting the space glyph");
                        bRet = false;
                    }
                }
            }

            if (v.PerformTest(T.PCLT_Style))
            {
                ushort Posture   = (ushort)(Style & 0x0003);
                ushort Width     = (ushort)((Style >> 2) & 0x0007);
                ushort Structure = (ushort)((Style >> 5) & 0x001f);
                ushort Reserved  = (ushort)(Style >> 10);

                bool bBitsOk = true;

                if (Posture == 3)
                {
                    v.Error(T.PCLT_Style, E.PCLT_E_Style_Posture, m_tag, "0x" + Style.ToString("x4"));
                    bBitsOk = false;
                    bRet    = false;
                }
                if (Width == 5)
                {
                    v.Error(T.PCLT_Style, E.PCLT_E_Style_Width, m_tag, "0x" + Style.ToString("x4"));
                    bBitsOk = false;
                    bRet    = false;
                }
                if (Structure > 17)
                {
                    v.Error(T.PCLT_Style, E.PCLT_E_Style_Structure, m_tag, "0x" + Style.ToString("x4"));
                    bBitsOk = false;
                    bRet    = false;
                }
                if (Reserved != 0)
                {
                    v.Error(T.PCLT_Style, E.PCLT_E_Style_Reserved, m_tag, "0x" + Style.ToString("x4"));
                    bBitsOk = false;
                    bRet    = false;
                }

                if (bBitsOk)
                {
                    v.Pass(T.PCLT_Style, P.PCLT_P_Style, m_tag);
                }
            }

            if (v.PerformTest(T.PCLT_StrokeWeight))
            {
                if (StrokeWeight >= -7 && StrokeWeight <= 7)
                {
                    v.Pass(T.PCLT_StrokeWeight, P.PCLT_P_StrokeWeight, m_tag, StrokeWeight.ToString());
                }
                else
                {
                    v.Error(T.PCLT_StrokeWeight, E.PCLT_E_StrokeWeight, m_tag, StrokeWeight.ToString());
                    bRet = false;
                }
            }

            if (v.PerformTest(T.PCLT_WidthType))
            {
                if (WidthType >= -5 && WidthType <= 5)
                {
                    v.Pass(T.PCLT_WidthType, P.PCLT_P_WidthType, m_tag, WidthType.ToString());
                }
                else
                {
                    v.Error(T.PCLT_WidthType, E.PCLT_E_WidthType, m_tag, WidthType.ToString());
                    bRet = false;
                }
            }

            if (v.PerformTest(T.PCLT_SerifStyle))
            {
                uint bot6 = (uint)SerifStyle & 0x3f;
                uint top2 = (uint)SerifStyle >> 6;

                bool bBitsOk = true;

                if (bot6 > 12)
                {
                    v.Error(T.PCLT_SerifStyle, E.PCLT_E_Bottom6, m_tag, "0x" + SerifStyle.ToString("x2"));
                    bBitsOk = false;
                    bRet    = false;
                }
                if (top2 == 0 || top2 == 3)
                {
                    v.Error(T.PCLT_SerifStyle, E.PCLT_E_Top2, m_tag);
                    bBitsOk = false;
                    bRet    = false;
                }

                if (bBitsOk)
                {
                    v.Pass(T.PCLT_SerifStyle, P.PCLT_P_SerifStyle, m_tag);
                }
            }

            if (v.PerformTest(T.PCLT_Reserved))
            {
                if (Reserved == 0)
                {
                    v.Pass(T.PCLT_Reserved, P.PCLT_P_Reserved, m_tag);
                }
                else
                {
                    v.Error(T.PCLT_Reserved, E.PCLT_E_Reserved, m_tag, Reserved.ToString());
                    bRet = false;
                }
            }

            return(bRet);
        }