public int DoIt( ) { Validator v = new Validator(); m_vp.SetupValidator( v ); OTFontFileVal.Driver driver = new OTFontFileVal.Driver( this ); return driver.RunValidation( v, m_sFiles ); }
public bool ValidateNumEntries(Validator validator, OTFont fontOwner) { int numGlyph=this.NumGlyph(fontOwner); int numEntry=this.NumEntry(fontOwner); if ((numGlyph==Table_loca.ValueInvalid)|| (numEntry==Table_loca.ValueInvalid)|| (numEntry!=numGlyph+1)) { if (validator!=null) { validator.Error(T.T_NULL, E.loca_E_NumEntries, m_tag, "number of entries="+numEntry+" number of glyphs="+numGlyph); } return false; } else { if (validator!=null) { validator.Pass(P.loca_P_NumEntries, m_tag); } return true; } }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp"); if (maxpTable == null) { v.Error(T.T_NULL, E._TEST_E_TableMissing, m_tag, "Unable to test this table, maxp table is invalid or missing"); return false; } if (v.PerformTest(T.vmtx_TableLength)) { uint CalcTableLength = GetNumOfLongVerMetrics(fontOwner)*4 + (fontOwner.GetMaxpNumGlyphs() - GetNumOfLongVerMetrics(fontOwner))*2; if (CalcTableLength == GetLength()) { v.Pass(T.vmtx_TableLength, P.vmtx_P_TableLength, m_tag); } else { v.Error(T.vmtx_TableLength, E.vmtx_E_TableLength, m_tag); bRet = false; } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.VORG_CFF_Font)) { if (fontOwner.ContainsPostScriptOutlines()) { v.Pass(T.VORG_CFF_Font, P.VORG_P_CFF_Font, m_tag); } else { v.Error(T.VORG_CFF_Font, E.VORG_E_CFF_Font, m_tag); bRet = false; } } if (v.PerformTest(T.VORG_Version)) { if (majorVersion == 1 && minorVersion == 0) { v.Pass(T.VORG_Version, P.VORG_P_Version, m_tag); } else { v.Error(T.VORG_Version, E.VORG_E_Version, m_tag); bRet = false; } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; v.Info(I.fpgm_I_NotValidated, m_tag); return bRet; }
/* * CONSTRUCTORS */ public I_IOGlyphsFile() { this.m_font=null; this.m_tableLoca=null; this.m_tableGlyf=null; this.m_validator=null; this.m_numGlyph=GConsts.IND_UNINITIALIZED; this.m_toCloseFileOnClear=false; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; v.Info(T.T_NULL, I.CFF_I_Version, m_tag, major + "." + minor); v.Info(I.CFF_I_NotValidated, m_tag); return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable tableOwner) { bool bOk = true; // ??? // ??? are there any values that are invalid ??? // ??? return bOk; }
/*************** * constructors */ public OTFileVal(Validator v) { if (v == null) { throw new ArgumentNullException(); } m_TableManager = new TableManagerVal(this); m_Validator = v; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.vhea_version)) { if (version.GetUint() == 0x00010000 || version.GetUint() == 0x00011000) { v.Pass(T.vhea_version, P.vhea_P_version, m_tag, "0x" + version.GetUint().ToString("x8")); } else { v.Error(T.vhea_version, E.vhea_E_version, m_tag, "0x" + version.GetUint().ToString("x8")); bRet = false; } } if (v.PerformTest(T.vhea_ReservedFields)) { if (reserved1 == 0 && reserved2 == 0 && reserved3 == 0 && reserved4 == 0) { v.Pass(T.vhea_ReservedFields, P.vhea_P_ReservedFields, m_tag); } else { v.Error(T.vhea_ReservedFields, E.vhea_E_ReservedFields, m_tag); bRet = false; } } if (v.PerformTest(T.vhea_metricDataFormat)) { if (metricDataFormat == 0) { v.Pass(T.vhea_metricDataFormat, P.vhea_P_metricDataFormat, m_tag); } else { v.Error(T.vhea_metricDataFormat, E.vhea_E_metricDataFormat, m_tag, metricDataFormat.ToString()); bRet = false; } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.cvt_length)) { if ((m_bufTable.GetLength() & 1) != 0) { v.Error(T.cvt_length, E.cvt_E_length_odd, m_tag); bRet = false; } else { v.Pass(T.cvt_length, P.cvt_P_length_even, m_tag); } } return bRet; }
/* * VALIDATION FUNCTIONS */ public bool ValidateFormat(Validator validator, OTFont fontOwner) { int format=this.Format(fontOwner); if ((format!=0)&&(format!=1)) { if (validator!=null) { validator.Error(E.loca_E_Format, m_tag); } return false; } else { if (validator!=null) { validator.Pass(P.loca_P_Format, m_tag); } return true; } }
public Progress( Form1 formParent, Validator v, string [] sFilenames, ReportFileDestination rfd, bool bOpenReportFiles, string sReportFixedDir ) { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // m_Validator = v; m_sFiles = sFilenames; m_formParent = formParent; m_bValidationInProgress = false; m_ReportFileDestination = rfd; m_bOpenReportFiles = bOpenReportFiles; m_sReportFixedDir = sReportFixedDir; }
public bool Validate(Validator v, OTTable table, ushort numGlyphs, String sIdentity) { bool bRet = true; // warn if not encoding id 10 if (m_ete.encodingID != 10) { v.Warning(T.T_NULL, W.cmap_W_f12_EncID, table.m_tag, sIdentity); } // check that groups are sorted by ascending startCharCodes if (nGroups > 1) { for (uint i=0; i<nGroups-1; i++) { Group gCurr = GetGroup(i); Group gNext = GetGroup(i+1); if (gCurr.startCharCode >= gNext.startCharCode) { v.Error(T.T_NULL, E.cmap_E_f12_SortOrder, table.m_tag, sIdentity); bRet = false; break; } } } // check each start code is less than or equal to the end code for (uint i=0; i<nGroups; i++) { Group g = GetGroup(i); if (g.startCharCode > g.endCharCode) { String sDetails = ", group[" + i + "], startCharCode = 0x" + g.startCharCode.ToString("X8") + ", endCharCode = 0x" + g.endCharCode.ToString("X8"); v.Error(T.T_NULL, E.cmap_E_f12_StartCode_GT_EndCode, table.m_tag, sIdentity + sDetails); bRet = false; } } // check the mapping for (uint i=0; i<nGroups; i++) { Group g = GetGroup(i); uint c = g.endCharCode; uint nGlyphID = g.startGlyphID + (c - g.startCharCode); if (nGlyphID >= numGlyphs) { v.Error(T.T_NULL, E.cmap_E_Mapping, table.m_tag, sIdentity + ", char = 0x" + ((uint)c).ToString("X4") + ", glyphID = " + nGlyphID); bRet = false; } } // if encoding id 10, then check that the greatest character // is not greater than 0x10ffff if (m_ete.encodingID == 10) { if (nGroups > 0) { Group lastgroup = GetGroup(nGroups-1); if (lastgroup.endCharCode > 0x10ffff) { v.Error(T.T_NULL, E.cmap_E_f12_EndCode_GT_10FFFF, table.m_tag, sIdentity + ", last endCharCode = 0x" + lastgroup.endCharCode.ToString("X8")); bRet = false; } } } return bRet; }
/************************ * 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; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.head_TableLength)) { if (m_bufTable.GetLength() == 54) { v.Pass(T.head_TableLength, P.head_P_TableLength, m_tag); } else { v.Error(T.head_TableLength, E.head_E_TableLength, m_tag, m_bufTable.GetLength().ToString()); bRet = false; } } if (v.PerformTest(T.head_TableVersion)) { if (TableVersionNumber.GetUint() == 0x00010000) { v.Pass(T.head_TableVersion, P.head_P_TableVersion, m_tag); } else { v.Error(T.head_TableVersion, E.head_E_TableVersion, m_tag, "0x"+TableVersionNumber.GetUint().ToString("x8")); bRet = false; } } if (v.PerformTest(T.head_fontRevision)) { string sVersion = fontOwner.GetFontVersion(); if (sVersion != null) { if (sVersion.Length >= 11 && sVersion.StartsWith("Version ") && Char.IsDigit(sVersion, 8)) { string sVersionNum = sVersion.Substring(8); bool bFoundDecPt = false; int nLastDigitPos = 0; for (int i=0; i<sVersionNum.Length; i++) { if (Char.IsDigit(sVersionNum, i)) { nLastDigitPos = i; } else if (sVersionNum[i] == '.') { if (!bFoundDecPt) { bFoundDecPt = true; } else { break; } } else { break; } } double fVersion = Double.Parse(sVersionNum.Substring(0, nLastDigitPos+1)); double fRevision = fontRevision.GetDouble(); if (Math.Round(fVersion, 3) == Math.Round(fRevision, 3)) { v.Pass(T.head_fontRevision, P.head_P_fontRevision, m_tag, fRevision.ToString("f3")); } else { string s = "revision: " + fRevision.ToString("f3") + ", version: " + sVersionNum; v.Warning(T.head_fontRevision, W.head_W_fontRevision, m_tag, s); } } } } if (v.PerformTest(T.head_ChecksumAdjustment)) { if (checkSumAdjustment == 0xb1b0afba - fontOwner.CalcChecksum()) { v.Pass(T.head_ChecksumAdjustment, P.head_P_FontChecksum, m_tag, "0x"+checkSumAdjustment.ToString("x8")); } else { v.Error(T.head_ChecksumAdjustment, E.head_E_FontChecksum, m_tag, "0x"+checkSumAdjustment.ToString("x8")); bRet = false; } } if (v.PerformTest(T.head_MagicNumber)) { if (magicNumber == 0x5f0f3cf5) { v.Pass(T.head_MagicNumber, P.head_P_MagicNumber, m_tag); } else { v.Error(T.head_MagicNumber, E.head_E_MagicNumber, m_tag, "0x"+magicNumber.ToString("x8")); bRet = false; } } if (v.PerformTest(T.head_FlagTests)) { ushort val = flags; // bit 0 indicates baseline for font at y=0 // bit 1 indicates left sidebearing point at x=0 // bit 2 indicates instructions may depend on point size // bit 3 indicates forcing ppem to integer values instead of fractional values // bit 4 indicates non-linear scaling - if set allows presence of LTSH and/or hdmx tables Table_hdmx hdmxTable = (Table_hdmx)fontOwner.GetTable("hdmx"); Table_LTSH LTSHTable = (Table_LTSH)fontOwner.GetTable("LTSH"); if ((val & 0x0010) == 0) { if (hdmxTable == null) { v.Pass(T.head_FlagTests, P.head_P_flags_bit4_0_hdmx, m_tag); } else { v.Error(T.head_FlagTests, E.head_E_flags_bit4_0_hdmx, m_tag); } if (LTSHTable == null) { v.Pass(T.head_FlagTests, P.head_P_flags_bit4_0_LTSH, m_tag); } else { v.Error(T.head_FlagTests, E.head_E_flags_bit4_0_LTSH, m_tag); } } else { if (hdmxTable != null) { v.Pass(T.head_FlagTests, P.head_P_flags_bit4_1_hdmx, m_tag); } else { v.Warning(T.head_FlagTests, W.head_W_flags_bit4_1_hdmx, m_tag); } if (LTSHTable != null) { v.Pass(T.head_FlagTests, P.head_P_flags_bit4_1_LTSH, m_tag); } else { v.Warning(T.head_FlagTests, W.head_W_flags_bit4_1_LTSH, m_tag); } } // bits 5 - 10 are used by apple and ignored by windows // bit 11 indicates font data is 'lossless' as a result of having been compressed/decompressed // bit 12 indicates a converted font // bit 13 indicates optimized for cleartype // bit 14 reserved if ((val & 0x4000) == 0) { v.Pass(T.head_FlagTests, P.head_P_flags_bit14, m_tag); } else { v.Error(T.head_FlagTests, E.head_E_flags_bit14, m_tag, val.ToString()); bRet = false; } // bit 15 reserved if ((val & 0x8000) == 0) { v.Pass(T.head_FlagTests, P.head_P_flags_bit15, m_tag); } else { v.Error(T.head_FlagTests, E.head_E_flags_bit15, m_tag, val.ToString()); bRet = false; } } if (v.PerformTest(T.head_UnitsPerEmValues)) { ushort val = unitsPerEm; bool bInRange = false; if (val < 16) // opentype spec says min value is 16 { v.Error(T.head_UnitsPerEmValues, E.head_E_unitsPerEm_LT16, m_tag, val.ToString()); bRet = false; } else if (val < 64) // apple spec says min value is 64 { v.Warning(T.head_UnitsPerEmValues, W.head_W_unitsPerEM_LT64, m_tag, val.ToString()); } else if (val > 16384) { v.Error(T.head_UnitsPerEmValues, E.head_E_unitsPerEM_GT16384, m_tag, val.ToString()); bRet = false; } else { bInRange = true; } // apple spec says unitsPerEm must be power of two // but don't check if it's a CFF font if (!fontOwner.ContainsPostScriptOutlines()) { bool bPowerOfTwo = false; for (int i=0; i<16; i++) { ushort nPow2 = (ushort)(1<<i); if (val == nPow2) { bPowerOfTwo = true; break; } } if (bPowerOfTwo) { if (bInRange) { v.Pass(T.head_UnitsPerEmValues, P.head_P_unitsPerEm, m_tag, val.ToString()); } } else { v.Warning(T.head_UnitsPerEmValues, W.head_W_unitsPerEm_Pow2, m_tag, val.ToString()); } } } if (v.PerformTest(T.head_Dates)) { DateTime dtBeforeTrueType = new DateTime(1985, 1, 1); if ((created >> 32) == 0) { DateTime dtCreated = this.GetCreatedDateTime(); if (created == 0) { v.Warning(T.head_Dates, W.head_W_created_0, m_tag); } else if (dtCreated < dtBeforeTrueType || dtCreated > DateTime.Now) { string sDetails = "created = " + created + " (" + dtCreated.ToString("f", null) + ")"; v.Warning(T.head_Dates, W.head_W_created_unlikely, m_tag, sDetails); } else { v.Pass(T.head_Dates, P.head_P_created_0, m_tag); } } else { string sDetails = "created = 0x" + created.ToString("x16"); v.Error(T.head_Dates, E.head_E_created_invalid, m_tag, sDetails); bRet = false; } if ((modified >> 32) == 0) { DateTime dtModified = this.GetModifiedDateTime(); if (modified == 0) { v.Warning(T.head_Dates, W.head_W_modified_0, m_tag); } else if (dtModified < dtBeforeTrueType || dtModified > DateTime.Now) { string sDetails = "modified = " + modified + " (" + dtModified.ToString("f", null) + ")"; v.Warning(T.head_Dates, W.head_W_modified_unlikely, m_tag, sDetails); } else { v.Pass(T.head_Dates, P.head_P_modified_0, m_tag); } } else { string sDetails = "modified = 0x" + modified.ToString("x16"); v.Error(T.head_Dates, E.head_E_modified_invalid, m_tag, sDetails); bRet = false; } } if (v.PerformTest(T.head_MinMaxValues)) { if (fontOwner.ContainsTrueTypeOutlines()) { if (xMin > xMax) { v.Error(T.head_MinMaxValues, E.head_E_xMin_GT_xMax, m_tag); bRet = false; } if (yMin > yMax) { v.Error(T.head_MinMaxValues, E.head_E_yMin_GT_yMax, m_tag); bRet = false; } short xMinExpected = 32767; short xMaxExpected = -32768; short yMinExpected = 32767; short yMaxExpected = -32768; Table_glyf glyfTable = (Table_glyf)fontOwner.GetTable("glyf"); if (glyfTable != null) { Table_maxp maxp = (Table_maxp)fontOwner.GetTable("maxp"); if (maxp != null) { for (uint i=0; i<fontOwner.GetMaxpNumGlyphs(); i++) { Table_glyf.header h = glyfTable.GetGlyphHeader(i, fontOwner); if (h != null) { if (xMinExpected > h.xMin) xMinExpected = h.xMin; if (xMaxExpected < h.xMax) xMaxExpected = h.xMax; if (yMinExpected > h.yMin) yMinExpected = h.yMin; if (yMaxExpected < h.yMax) yMaxExpected = h.yMax; } } if (xMin == xMinExpected) { String s = "xMin = " + xMin; v.Pass(T.head_MinMaxValues, P.head_P_xMin_glyf, m_tag, s); } else { string s = "actual: " + xMin + ", expected: " + xMinExpected; v.Error(T.head_MinMaxValues, E.head_E_xMin_glyf, m_tag, s); bRet = false; } if (yMin == yMinExpected) { String s = "yMin = " + yMin; v.Pass(T.head_MinMaxValues, P.head_P_yMin_glyf, m_tag, s); } else { string s = "actual: " + yMin + ", expected: " + yMinExpected; v.Error(T.head_MinMaxValues, E.head_E_yMin_glyf, m_tag, s); bRet = false; } if (xMax == xMaxExpected) { String s = "xMax = " + xMax; v.Pass(T.head_MinMaxValues, P.head_P_xMax_glyf, m_tag, s); } else { string s = "actual: " + xMax + ", expected: " + xMaxExpected; v.Error(T.head_MinMaxValues, E.head_E_xMax_glyf, m_tag, s); bRet = false; } if (yMax == yMaxExpected) { String s = "yMax = " + yMax; v.Pass(T.head_MinMaxValues, P.head_P_yMax_glyf, m_tag, s); } else { string s = "actual: " + yMax + ", expected: " + yMaxExpected; v.Error(T.head_MinMaxValues, E.head_E_yMax_glyf, m_tag, s); bRet = false; } } else { v.Error(T.head_MinMaxValues, E._TEST_E_TableMissing, m_tag, "maxp"); } } else { v.Error(T.head_MinMaxValues, E._TEST_E_TableMissing, m_tag, "glyf"); } } else { v.Info(T.head_MinMaxValues, I._TEST_I_NotForCFF, m_tag, "test = head_MinMaxValues"); } } if (v.PerformTest(T.head_MacStyleBits)) { bool bMacBold = ((macStyle & 0x0001) != 0); bool bMacItal = ((macStyle & 0x0002) != 0); // subfamily (style) string Table_name nameTable = (Table_name)fontOwner.GetTable("name"); string sStyle = null; string sStyleLower = null; if (nameTable != null) { sStyle = nameTable.GetStyleString(); if (sStyle != null) { sStyleLower = sStyle.ToLower(); } } if (sStyleLower != null) { if (bMacBold && sStyleLower.IndexOf("bold") == -1) { v.Error(T.head_MacStyleBits, E.head_E_macStyleBold_subfamily, m_tag, "macStyle bold bit is set, but subfamily is " + sStyle); bRet = false; } else if (!bMacBold && sStyleLower.IndexOf("bold") != -1) { v.Error(T.head_MacStyleBits, E.head_E_macStyleBold_subfamily, m_tag, "macStyle bold bit is clear, but subfamily is " + sStyle); bRet = false; } else { v.Pass(T.head_MacStyleBits, P.head_P_macStyleBold_subfamily, m_tag); } if (bMacItal && sStyleLower.IndexOf("italic") == -1 && sStyleLower.IndexOf("oblique") == -1) { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal_subfamily, m_tag, "macStyle italic bit is set, but subfamily is " + sStyle); bRet = false; } else if (!bMacItal && (sStyleLower.IndexOf("italic") != -1 || sStyleLower.IndexOf("oblique") != -1)) { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal_subfamily, m_tag, "macStyle italic bit is clear, but subfamily is " + sStyle); bRet = false; } else { v.Pass(T.head_MacStyleBits, P.head_P_macStyleItal_subfamily, m_tag); } } Table_OS2 OS2Table = (Table_OS2)fontOwner.GetTable("OS/2"); if (OS2Table != null) { // fsSelection bool bOS2Bold = ((OS2Table.fsSelection & 0x0020) != 0); bool bOS2Ital = ((OS2Table.fsSelection & 0x0001) != 0); if (bMacBold == bOS2Bold) { v.Pass(T.head_MacStyleBits, P.head_P_macStyleBold_OS2, m_tag); } else if (bMacBold) { v.Error(T.head_MacStyleBits, E.head_E_macStyleBold1_OS2, m_tag); bRet = false; } else { v.Error(T.head_MacStyleBits, E.head_E_macStyleBold0_OS2, m_tag); bRet = false; } if (bMacItal == bOS2Ital) { v.Pass(T.head_MacStyleBits, P.head_P_macStyleItal_OS2, m_tag); } else if (bMacItal) { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal1_OS2, m_tag); bRet = false; } else { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal0_OS2, m_tag); bRet = false; } } Table_post postTable = (Table_post)fontOwner.GetTable("post"); if (postTable != null) { bool bPostItal = (postTable.italicAngle.GetUint() != 0); if (bMacItal == bPostItal) { v.Pass(T.head_MacStyleBits, P.head_P_macStyleItal_post, m_tag); } else if (bMacItal) { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal1_post, m_tag); bRet = false; } else { v.Error(T.head_MacStyleBits, E.head_E_macStyleItal0_post, m_tag); bRet = false; } } } if (v.PerformTest(T.head_LowestRecSize)) { if (lowestRecPPEM == 0) { v.Error(T.head_LowestRecSize, E.head_E_lowestRecPPEM_zero, m_tag); bRet = false; } else if (lowestRecPPEM >= 1 && lowestRecPPEM <= 6) { v.Warning(T.head_LowestRecSize, W.head_W_lowestRecPPEM_small, m_tag, "lowestRecPPEM = " + lowestRecPPEM.ToString()); } else if (lowestRecPPEM >= 36) { v.Warning(T.head_LowestRecSize, W.head_W_lowestRecPPEM_large, m_tag, "lowestRecPPEM = " + lowestRecPPEM.ToString()); } else { v.Pass(T.head_LowestRecSize, P.head_P_lowestRecPPEM, m_tag); } } if (v.PerformTest(T.head_FontDirectionHint)) { if (fontDirectionHint >= -2 && fontDirectionHint <= 2) { v.Pass(T.head_FontDirectionHint, P.head_P_fontDirectionHint, m_tag, fontDirectionHint.ToString()); } else { v.Error(T.head_FontDirectionHint, E.head_E_fontDirectionHint, m_tag, fontDirectionHint.ToString()); bRet = false; } } if (v.PerformTest(T.head_IndexToLocFormat)) { if (fontOwner.ContainsPostScriptOutlines()) { v.Pass(T.head_IndexToLocFormat, P.head_P_indexToLocFormat_ignore, m_tag, "indexToLocFormat = " + indexToLocFormat); } else { if (indexToLocFormat == 0 || indexToLocFormat == 1) { v.Pass(T.head_IndexToLocFormat, P.head_P_indexToLocFormat_range, m_tag, indexToLocFormat.ToString()); } else { v.Error(T.head_IndexToLocFormat, E.head_E_indexToLocFormat_range, m_tag, indexToLocFormat.ToString()); bRet = false; } if (indexToLocFormat == 0 || indexToLocFormat == 1) { Table_loca locaTable = (Table_loca)fontOwner.GetTable("loca"); if (locaTable != null) { Table_maxp maxpTable = (Table_maxp)fontOwner.GetTable("maxp"); if (maxpTable != null) { uint locaTableElementSize = 0; if (indexToLocFormat == 0) locaTableElementSize = 2; else if (indexToLocFormat == 1) locaTableElementSize = 4; uint CalcLocaLength = (uint)(maxpTable.NumGlyphs + 1) * locaTableElementSize; if (CalcLocaLength == locaTable.GetLength()) { v.Pass(T.head_IndexToLocFormat, P.head_P_indexToLocFormat_match, m_tag, indexToLocFormat.ToString()); } else { v.Error(T.head_IndexToLocFormat, E.head_E_indexToLocFormat_match, m_tag, indexToLocFormat.ToString()); bRet = false; } } else { v.Error(T.head_IndexToLocFormat, E._TEST_E_TableMissing, m_tag, "maxp"); } } else { v.Error(T.head_IndexToLocFormat, E._TEST_E_TableMissing, m_tag, "loca"); } } } } if (v.PerformTest(T.head_GlyphDataFormat)) { if (glyphDataFormat == 0) { v.Pass(T.head_GlyphDataFormat, P.head_P_glyphDataFormat, m_tag); } else { v.Error(T.head_GlyphDataFormat, E.head_E_glyphDataFormat, m_tag); bRet = false; } } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; bool bScriptTableOk = true; // check the DefaultLangSys offset if (DefaultLangSysOffset != 0) { if (m_offsetScriptTable + DefaultLangSysOffset > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_ScriptTable_E_DefaultLangSysOffset, table.m_tag, sIdentity); bScriptTableOk = false; bRet = false; } else { // check the DefaultLangSys table LangSysTable_val lst = GetDefaultLangSysTable_val(); bRet &= lst.Validate(v, sIdentity + ", DefaultLangSysTable", table); } } // check the LansgSysRecord array length if (m_offsetScriptTable + (uint)FieldOffsets.LangSysRecord + LangSysCount * 6 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_ScriptTable_E_LangSysRecordArray_pastEOT, table.m_tag, sIdentity); bScriptTableOk = false; bRet = false; } // check that the LangSysRecord array is sorted alphabetically if (LangSysCount > 1) { for (uint i=0; i<LangSysCount-1; i++) { LangSysRecord ThisLsr = GetLangSysRecord(i); LangSysRecord NextLsr = GetLangSysRecord(i+1); if (ThisLsr.LangSysTag >= NextLsr.LangSysTag) { v.Error(T.T_NULL, E._OTL_ScriptTable_E_LangSysRecordArray_order, table.m_tag, sIdentity); bScriptTableOk = false; bRet = false; } } } // check each LangSysRecord for (uint i=0; i<LangSysCount; i++) { LangSysRecord lsr = GetLangSysRecord(i); // check the tag if (!lsr.LangSysTag.IsValid()) { v.Error(T.T_NULL, E._OTL_ScriptTable_E_LangSysRecord_tag, table.m_tag, sIdentity + ", LangSysRecord[" + i + "]"); bScriptTableOk = false; bRet = false; } // check the offset if (m_offsetScriptTable + lsr.LangSysOffset > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_ScriptTable_E_LangSysRecord_offset, table.m_tag, sIdentity + ", LangSysRecord[" + i + "]"); bScriptTableOk = false; bRet = false; } // validate the langsys table LangSysTable_val lst = GetLangSysTable_val(lsr); bRet &= lst.Validate(v, sIdentity + ", LangSysRecord[" + i + "], LangSysTable", table); } if (bScriptTableOk) { v.Pass(T.T_NULL, P._OTL_ScriptTable_P_valid, table.m_tag, sIdentity); } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; // check StartSize for unreasonable values if (StartSize > 16384) { v.Warning(T.T_NULL, W._OTL_DeviceTable_W_StartSize, table.m_tag, sIdentity + ", StartSize = " + StartSize); } // check EndSize for unreasonable values if (EndSize > 16384) { v.Warning(T.T_NULL, W._OTL_DeviceTable_W_EndSize, table.m_tag, sIdentity + ", EndSize = " + EndSize); } // check that StartSize <= EndSize if (StartSize > EndSize) { v.Error(T.T_NULL, E._OTL_DeviceTable_E_sizes, table.m_tag, sIdentity); bRet = false; } // check DeltaFormat is 1, 2, or 3 if (DeltaFormat < 1 || DeltaFormat > 3) { v.Error(T.T_NULL, E._OTL_DeviceTable_E_DeltaFormat, table.m_tag, sIdentity + ", DeltaFormat = " + DeltaFormat); bRet = false; } else { // check that DeltaValue array doesn't extend past the end of the table int nSizes = EndSize - StartSize + 1; int nValuesPerUint = 16 >> DeltaFormat; int nUints = nSizes / nValuesPerUint; if (nSizes % nValuesPerUint != 0) nUints++; if (m_offsetDeviceTable + (uint)FieldOffsets.DeltaValueArray + nUints > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_DeviceTable_E_DeltaValueArray_pastEOT, table.m_tag, sIdentity); bRet = false; } } // way too many device tables to justify this pass message //if (bRet) //{ // v.Pass("_OTL_DeviceTable_P_valid", table.m_tag, sIdentity); //} return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; // check that ClassRangeRecord array doesn't extend past end of table if (m_offsetClassDefFormat2 + (uint)FieldOffsets.ClassRangeRecordArray + ClassRangeCount*6 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_ClassDefinitionTable_E_RangeRecordArrayPastEOT, table.m_tag, sIdentity); bRet = false; } // check that ClassRangeRecord array is in sorted order if (ClassRangeCount > 1) { for (uint i=0; i<ClassRangeCount-1; i++) { ClassRangeRecord ThisCrr = GetClassRangeRecord(i); ClassRangeRecord NextCrr = GetClassRangeRecord(i+1); if (ThisCrr.Start >= NextCrr.Start) { v.Error(T.T_NULL, E._OTL_ClassDefinitionTable_E_RangeRecordArray_order, table.m_tag, sIdentity); bRet = false; // temporary debug code /* v.DebugMsg("ClassRangeCount = " + ClassRangeCount, tag); for (uint j=0; j<ClassRangeCount; j++) { ClassRangeRecord crr = GetClassRangeRecord(j); v.DebugMsg("ClassRangeRecord[" + j + "].Start = " + crr.Start, tag); } */ break; } } } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; if (m_offsetClassDefFormat1 + (uint)FieldOffsets.ClassValueArray + GlyphCount*2 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_ClassDefinitionTable_E_GlyphArrayPastEOT, table.m_tag, sIdentity); bRet = false; } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; if (ClassFormat == 1) { ClassDefFormat1_val cdf1 = GetClassDefFormat1_val(); bRet &= cdf1.Validate(v, sIdentity + "(Fmt1)", table); } else if (ClassFormat == 2) { ClassDefFormat2_val cdf2 = GetClassDefFormat2_val(); bRet &= cdf2.Validate(v, sIdentity + "(Fmt2)", table); } else { v.Error(T.T_NULL, E._OTL_ClassDefinitionTable_E_Format, table.m_tag, sIdentity + ", format = " + ClassFormat.ToString()); bRet = false; } // way too many ClassDefTables to justify this pass message //if (bRet) //{ // v.Pass("_OTL_ClassDefinitionTable_P_valid", table.m_tag, sIdentity); //} return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.GDEF_Version)) { if (Version.GetUint() == 0x00010000) { v.Pass(T.GDEF_Version, P.GDEF_P_Version, m_tag); } else { v.Error(T.GDEF_Version, E.GDEF_E_Version, m_tag, "0x" + Version.GetUint().ToString("x8")); } } if (v.PerformTest(T.GDEF_HeaderOffsets)) { bool bOffsetsOk = true; if (GlyphClassDefOffset != 0) { if (GlyphClassDefOffset > m_bufTable.GetLength()) { v.Error(T.GDEF_HeaderOffsets, E.GDEF_E_HeaderOffset, m_tag, "GlyphClassDef"); bOffsetsOk = false; bRet = false; } } if (AttachListOffset != 0) { if (AttachListOffset > m_bufTable.GetLength()) { v.Error(T.GDEF_HeaderOffsets, E.GDEF_E_HeaderOffset, m_tag, "AttachList"); bOffsetsOk = false; bRet = false; } } if (LigCaretListOffset != 0) { if (LigCaretListOffset > m_bufTable.GetLength()) { v.Error(T.GDEF_HeaderOffsets, E.GDEF_E_HeaderOffset, m_tag, "LigCaretList"); bOffsetsOk = false; bRet = false; } } if (MarkAttachClassDefOffset != 0) { if (MarkAttachClassDefOffset > m_bufTable.GetLength()) { v.Error(T.GDEF_HeaderOffsets, E.GDEF_E_HeaderOffset, m_tag, "MarkAttachClassDef"); bOffsetsOk = false; bRet = false; } } if (bOffsetsOk == true) { v.Pass(T.GDEF_HeaderOffsets, P.GDEF_P_HeaderOffsets, m_tag); } } if (v.PerformTest(T.GDEF_Subtables)) { if (GlyphClassDefOffset != 0) { ClassDefTable_val cdt = GetGlyphClassDefTable_val(); cdt.Validate(v, "GlyphClassDef", this); } if (AttachListOffset != 0) { AttachListTable_val alt = GetAttachListTable_val(); alt.Validate(v, "AttachList", this); } if (LigCaretListOffset != 0) { LigCaretListTable_val lclt = GetLigCaretListTable_val(); lclt.Validate(v, "LigCaretList", this); } if (MarkAttachClassDefOffset != 0) { ClassDefTable_val macdt = GetMarkAttachClassDefTable_val(); macdt.Validate(v, "MarkAttachClassDef", this); } } return(bRet); }
public bool Validate(Validator v, OTTable table, ushort numGlyphs, String sIdentity) { bool bRet = true; // check that segCountX2 is even if ((segCountX2 & 1) == 1) { v.Error(T.T_NULL, E.cmap_E_f4_segCountX2, table.m_tag, sIdentity + ", segCountX2 = " + segCountX2); bRet = false; } // check searchRange ushort segCount = (ushort)(segCountX2 / 2); ushort CalculatedSearchRange = (ushort)(2 * util.MaxPower2LE(segCount)); if (searchRange != CalculatedSearchRange) { v.Error(T.T_NULL, E.cmap_E_f4_searchRange, table.m_tag, sIdentity + ", searchRange = " + searchRange + ", calc = " + CalculatedSearchRange); bRet = false; } // check entrySelector ushort CalculatedEntrySelector = util.Log2((ushort)(CalculatedSearchRange/2)); if (entrySelector != CalculatedEntrySelector) { v.Error(T.T_NULL, E.cmap_E_f4_entrySelector, table.m_tag, sIdentity + ", entrySelector = " + entrySelector + ", calc = " + CalculatedEntrySelector); bRet = false; } // check rangeShift ushort CalculatedRangeShift = (ushort)(2 * segCount - CalculatedSearchRange); if (rangeShift != CalculatedRangeShift) { v.Error(T.T_NULL, E.cmap_E_f4_rangeShift, table.m_tag, sIdentity + ", rangeShift = " + rangeShift + ", calc = " + CalculatedRangeShift); bRet = false; } // check that final endCode value is 0xffff if (GetEndCode((uint)segCount-1) != 0xffff) { v.Error(T.T_NULL, E.cmap_E_f4_FinalEndCode, table.m_tag, sIdentity + ", endCode[" + (segCount-1) + "] = " + GetEndCode((uint)segCount-1)); bRet = false; } // check that end character codes are in ascending order if (segCount > 1) { for (uint i=0; i<segCount-1; i++) { if (GetEndCode(i) >= GetEndCode(i+1)) { v.Error(T.T_NULL, E.cmap_E_f4_EndCodeOrder, table.m_tag, sIdentity); bRet = false; break; } } } // check that the reservedPad is zero if ( m_ete.offset + (uint)FieldOffsets.endCode + segCountX2 < m_bufTable.GetLength() && reservedPad != 0) { v.Error(T.T_NULL, E.cmap_E_f4_reservedPad, table.m_tag, sIdentity); bRet = false; } // check that each start character code is not greater than // the corresponding end character code for (uint i=0; i<segCount; i++) { if (GetStartCode(i) > GetEndCode(i)) { String sDetails = ", startCode[" + i + "] = " + GetStartCode(i) + " , endCode[" + i + "] = " + GetEndCode(i); v.Error(T.T_NULL, E.cmap_E_f4_StartCode_GT_EndCode, table.m_tag, sIdentity + sDetails); bRet = false; } } // check that each delta value (where idRangeOffset == 0) // added to the start code is not negative for (uint i=0; i<segCount; i++) { if (GetIdRangeOffset(i) == 0) { if (GetIdDelta(i) + GetStartCode(i) < 0) { String sDetails = ", idDelta[" + i + "] = " + GetIdDelta(i) + ", startCode[" + i + "] = " + GetStartCode(i); v.Error(T.T_NULL, E.cmap_E_f4_idDeltaNeg, table.m_tag, sIdentity + sDetails); bRet = false; } } } // check range offsets for (uint i=0; i<segCount; i++) { ushort idRangeOffset = GetIdRangeOffset(i); ushort endCode = GetEndCode(i); ushort startCode = GetStartCode(i); if (idRangeOffset != 0) { uint AddressOfIdRangeOffset = (uint)FieldOffsets.endCode + segCountX2*3u + 2 + i*2; uint obscureIndex = (uint) (idRangeOffset + (endCode - startCode)*2 + AddressOfIdRangeOffset); if (obscureIndex > length) { v.Error(T.T_NULL, E.cmap_E_f4_idRangeOffset, table.m_tag, sIdentity + ", idRangeOffset[" + i + "] = " + idRangeOffset); bRet = false; } } } // check that glyph ids are less than numGlyphs for (uint i=0; i<segCount; i++) { int nGlyphMappingErrors = 0; // Report the first 10 errors and // a count of errors after that. int nMaxMappingErrors = 10; ushort idRangeOffset = GetIdRangeOffset(i); ushort endCode = GetEndCode(i); ushort startCode = GetStartCode(i); short idDelta = GetIdDelta(i); ushort nGlyph; for (uint j=startCode; j<= endCode; j++) { ushort c = (ushort)j; nGlyph = 0; if (idRangeOffset == 0) { nGlyph = (ushort)(c + idDelta); } else { uint AddressOfIdRangeOffset = (uint) FieldOffsets.endCode + segCountX2*3u + 2 + i*2; uint obscureIndex = (uint) (idRangeOffset + (c-startCode)*2 + AddressOfIdRangeOffset); // throw out invalid indexes for this test // (they should have already been reported) if (obscureIndex < length && (m_ete.offset + obscureIndex < m_bufTable.GetLength())) { nGlyph = m_bufTable.GetUshort(m_ete.offset + obscureIndex); } if (nGlyph !=0 ) { nGlyph = (ushort)(nGlyph + idDelta); } } if (nGlyph > numGlyphs) { // it is possible that an entire segment is bad. // That causes a hang like behavior and a // bloated error file // that cannot be opened because it is so huge. if (nGlyphMappingErrors < nMaxMappingErrors) { v.Error(T.T_NULL, E.cmap_E_Mapping, table.m_tag, sIdentity + ", char = 0x" + c.ToString("X4") + ", glyphID = " + nGlyph); } nGlyphMappingErrors++; } } if (nGlyphMappingErrors >= nMaxMappingErrors) { string sDetails = sIdentity + ", segment = " + i + " has " + nGlyphMappingErrors + " glyphs mapped out of range"; v.Error(T.T_NULL, E.cmap_E_Mapping, table.m_tag, sDetails); bRet = false; } } return bRet; }
public bool Validate(Validator v, OTTable table, ushort numGlyphs, String sIdentity) { bool bRet = true; // check the length if (length != 262) { v.Error(T.T_NULL, E.cmap_E_f0_length, table.m_tag, sIdentity); bRet = false; } // check the mapping for (char c = (char)0; c<256; c++) { ushort nGlyphID = GetGlyphID(c); if (nGlyphID >= numGlyphs) { v.Error(T.T_NULL, E.cmap_E_Mapping, table.m_tag, sIdentity + ", char = 0x" + ((uint)c).ToString("X4") + ", glyphID = " + nGlyphID); bRet = false; } } return bRet; }
public bool Validate( Validator v, OTTable table, ushort numGlyphs, String sIdentity ) { bool bRet = true; m_v = v; m_table = table; m_sIdentity = sIdentity; m_numGlyphs = numGlyphs; List<VarSelectorRecord> recs = new List<VarSelectorRecord>(); // Find the offset of the start of the Default and // Non-Default UVS tables to make sure that // everything the offsets point to is within the table // area. const uint f14HeaderLength = 10; // USHORT, ULONG, ULONG const uint varSelRecLength = 11; // UINT24, ULONG, ULONG uint dataStart = f14HeaderLength + ( NumVarSelectorRecs * varSelRecLength ); // Fill in recs while we are at it. bool bLengthsOk = CheckLengths( dataStart, recs ); bRet = bLengthsOk; if ( !bLengthsOk ) { string unable = "Unable to perform more tests"; // Is the 2nd arg correct? v.Warning( T.T_NULL, W._TEST_W_OtherErrorsInTable, m_table.m_tag, unable + SDetails() ); goto Finish; } // We now know that all the tables are within the data area, // that is, from dataStart to the end of the subtable. Now // we about overlapping and non-packed tables. bool bOverlapsOk = CheckOverlaps( dataStart, recs ); if ( !bOverlapsOk ) { bRet = false; string unable = "Unable to perform more tests"; // Is the 2nd arg correct? v.Warning( T.T_NULL, W._TEST_W_OtherErrorsInTable, m_table.m_tag, unable + SDetails() ); goto Finish; } // Check that all values in offset tables are legal bRet = CheckLegalValues( recs ); Finish: return bRet; }
public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.cmap_Version)) { if (TableVersionNumber == 0) { v.Pass(T.cmap_Version, P.cmap_P_version, m_tag); } else { v.Error(T.cmap_Version, E.cmap_E_version, m_tag, TableVersionNumber.ToString()); bRet = false; } } // Check that the number of encoding records seems to // agree with the numTables field, and that each offset // is greater than 0 and less than the length of the cmap // table. bool bOffsetsOk = true; if (v.PerformTest(T.cmap_SubtableOffset)) { for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); if (ete != null) { if (ete.offset == 0) { v.Error(T.cmap_SubtableOffset, E.cmap_E_SubtableOffset_zero, m_tag, "encoding table entry index = " + i.ToString() + ", platformID = " + ete.platformID + ", encodingID = " + ete.encodingID); bRet = false; bOffsetsOk = false; } if (ete.offset > m_bufTable.GetLength()) { v.Error(T.cmap_SubtableOffset, E.cmap_E_SubtableOffset_eot, m_tag, "encoding table entry index = " + i.ToString() + ", platformID = " + ete.platformID + ", encodingID = " + ete.encodingID); bRet = false; bOffsetsOk = false; } } else { v.Warning(T.cmap_SubtableOffset, W._TEST_W_OtherErrorsInTable, m_tag, "cmap table appears to be corrupt. " + " No further tests will be performed."); return bRet; } } if (bOffsetsOk) { v.Pass(T.cmap_SubtableOffset, P.cmap_P_SubtableOffset, m_tag); } } // Check that each subtable can be retrieved from the font // and that its offset + length lies within the cmap. bool bLengthsOk = true; if (v.PerformTest(T.cmap_SubtableLength)) { for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); Subtable st = GetSubtable(ete); if (st != null) { if (st.length == 0) { v.Error(T.cmap_SubtableLength, E.cmap_E_SubtableLength_zero, m_tag, i.ToString()); bRet = false; bLengthsOk = false; } if (ete.offset + st.length > m_bufTable.GetLength()) { v.Error(T.cmap_SubtableLength, E.cmap_E_SubtableLength_eot, m_tag, i.ToString()); bRet = false; bLengthsOk = false; } } else { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID; v.Warning(T.cmap_SubtableLength, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate the length of subtable - " + sDetails); bLengthsOk = false; } } if (bLengthsOk) { v.Pass(T.cmap_SubtableLength, P.cmap_P_SubtableLength, m_tag); } } // Assuming previous tests ok, check that sort order is by // 1. increasing platformID // 2. increasing encodingID // 3. increasing language if (v.PerformTest(T.cmap_SubtableSortOrder)) { if (bOffsetsOk && bLengthsOk) { bool bOrderOk = true; if (NumberOfEncodingTables > 1) { EncodingTableEntry etePrev = GetEncodingTableEntry(0); for (uint i=1; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); if (etePrev.platformID == ete.platformID) { if (etePrev.encodingID == ete.encodingID) { Subtable stPrev = GetSubtable(etePrev); Subtable st = GetSubtable(ete); if (stPrev.language > st.language) { bOrderOk = false; } } else if (etePrev.encodingID > ete.encodingID) { bOrderOk = false; } } else if (etePrev.platformID > ete.platformID) { bOrderOk = false; } etePrev = ete; } } if (bOrderOk) { v.Pass(T.cmap_SubtableSortOrder, P.cmap_P_SubtableSortOrder, m_tag); } else { v.Error(T.cmap_SubtableSortOrder, E.cmap_E_SubtableSortOrder, m_tag); bRet = false; } } else { v.Warning(T.cmap_SubtableSortOrder, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate sort order"); } } // Check that no encoding record has the same // (platformID,encodingID,language) // as the previous one. if (v.PerformTest(T.cmap_DuplicateSubtables)) { if (bOffsetsOk && bLengthsOk) { bool bNoDuplicates = true; if (NumberOfEncodingTables > 1) { EncodingTableEntry etePrev = GetEncodingTableEntry(0); for (uint i=1; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); if (etePrev.platformID == ete.platformID) { if (etePrev.encodingID == ete.encodingID) { Subtable stPrev = GetSubtable(etePrev); Subtable st = GetSubtable(ete); if (stPrev.language == st.language) { bNoDuplicates = false; } } } etePrev = ete; } } if (bNoDuplicates) { v.Pass(T.cmap_DuplicateSubtables, P.cmap_P_DuplicateSubtables, m_tag); } else { v.Error(T.cmap_DuplicateSubtables, E.cmap_E_DuplicateSubtables, m_tag); bRet = false; } } else { string unable = "unable to validate that there are " + "no duplicate subtables"; v.Warning(T.cmap_DuplicateSubtables, W._TEST_W_OtherErrorsInTable, m_tag, unable ); } } // Check that no subtable overlaps and subtable following it, // in other words, check for the beginning of one subtable // falling within the bounds of a subtable that follows it. if (v.PerformTest(T.cmap_SubtableOverlap)) { if (bOffsetsOk && bLengthsOk) { bool bNoOverlap = true; if (NumberOfEncodingTables > 1) { for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete1 = GetEncodingTableEntry(i); Subtable st1 = GetSubtable(ete1); for (uint j=i+1; j<NumberOfEncodingTables; j++) { EncodingTableEntry ete2 = GetEncodingTableEntry(j); Subtable st2 = GetSubtable(ete2); if ( (ete1.offset > ete2.offset && ete1.offset < ete2.offset + st2.length) || (ete2.offset > ete1.offset && ete2.offset < ete1.offset + st1.length) ) { v.Error(T.cmap_SubtableOverlap, E.cmap_E_SubtableOverlap, m_tag, i.ToString() + " " + j.ToString()); bRet = false; bNoOverlap = true; } } } } if (bNoOverlap) { v.Pass(T.cmap_SubtableOverlap, P.cmap_P_SubtableOverlap, m_tag); } } else { v.Warning(T.cmap_SubtableOverlap, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that no subtables overlap"); } } // Check that all subtable formats (First USHORT in the subtable) // is an even number between 0 and 14, inclusive. if (v.PerformTest(T.cmap_ValidFormat)) { bool bAllFormatsValid = true; for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); if (ete.offset < m_bufTable.GetLength()-1) { // the format of the subtable is the first uint16 ushort format = m_bufTable.GetUshort(ete.offset); if (format > HIGHEST_FORMAT || ((format&1)==1)) { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID + ", Fmt = " + format; v.Error(T.cmap_ValidFormat, E.cmap_E_SubtableValidFormat, m_tag, sDetails); bRet = false; bAllFormatsValid = false; } } else { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID; string unable = "unable to validate format number for subtable - "; v.Warning(T.cmap_ValidFormat, W._TEST_W_OtherErrorsInTable, m_tag, unable + sDetails); bAllFormatsValid = false; } } if (bAllFormatsValid) { v.Pass(T.cmap_ValidFormat, P.cmap_P_SubtableValidFormat, m_tag); } } // Assuming maxp is present, get the number of glyphs from maxp, // and for each subtable, run its validate routine. if (v.PerformTest(T.cmap_SubtableInternalFormat)) { if (fontOwner.GetTable("maxp") == null) { string cant = "can't check subtable internal formats - " + "maxp table inaccessible"; v.Warning(T.cmap_SubtableInternalFormat, W._TEST_W_ErrorInAnotherTable, m_tag, cant ); } else { for (uint i=0; i<NumberOfEncodingTables; i++) { bool bInternalFormatOk = true; EncodingTableEntry ete = GetEncodingTableEntry(i); Subtable st = GetSubtable(ete); if (st != null) { ushort numGlyphs = fontOwner.GetMaxpNumGlyphs(); string sIdentity = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID + ", Fmt = " + st.format; ISubtableValidate valSubtable = (ISubtableValidate)st; bInternalFormatOk = valSubtable.Validate(v, this, numGlyphs, sIdentity); bRet &= bInternalFormatOk; if (bInternalFormatOk) { v.Pass(T.cmap_SubtableInternalFormat, P.cmap_P_InternalFormat, m_tag, sIdentity); } } else { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID; v.Warning(T.cmap_SubtableInternalFormat, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate internal format " + "for subtable - " + sDetails); } } } } // Pass if there is at least one subtable with platformID == 1 and // one subtable with platformID == 3. // Warn if either is missing. if (v.PerformTest(T.cmap_AppleMSSupport)) { bool bFoundApple = false; bool bFoundMS = false; for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); if (ete.platformID == 1) { bFoundApple = true; } else if (ete.platformID == 3) { bFoundMS = true; } } if (bFoundApple && bFoundMS) { v.Pass(T.cmap_AppleMSSupport, P.cmap_P_AppleMSSupport, m_tag); } else if (!bFoundApple) { v.Warning(T.cmap_AppleMSSupport, W.cmap_W_AppleMSSupport_A, m_tag); } else if (!bFoundMS) { v.Warning(T.cmap_AppleMSSupport, W.cmap_W_AppleMSSupport_M, m_tag); } } // Find encoding table with platformID==1, encodingID==0 // i.e., Macintosh. Make sure that the Apple Logo, code point 240, // is mapped to glyphID 0, a legal requirement for Microsoft fonts // developed for use on Apple platforms. if (v.PerformTest(T.cmap_AppleLogo)) { EncodingTableEntry ete = GetEncodingTableEntry(1,0); if (ete != null) { Subtable st = GetSubtable(ete); if (st != null) { byte[] charbuf = new byte[2]; charbuf[0] = 240; charbuf[1] = 0; uint glyph = st.MapCharToGlyph(charbuf, 0); if (glyph == 0) { v.Pass(T.cmap_AppleLogo, P.cmap_P_AppleLogo, m_tag); } else { v.Warning(T.cmap_AppleLogo, W.cmap_W_AppleLogo, m_tag); } } else { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID; string unable = "unable to validate apple logo for subtable - "; v.Warning(T.cmap_AppleLogo, W._TEST_W_OtherErrorsInTable, m_tag, unable + sDetails); } } else { v.Warning(T.cmap_AppleLogo, W.cmap_W_AppleLogo_NoMap, m_tag); } } // Euro symbol. // Unless there is a Microsoft Symbol encoding cmap (3,0): // * Make sure that any apple cmap(1,0) contains a glyph U+00db // * Make sure that any Microsoft Unicode cmap (3,1) contains // a glyph U+20AC. if (v.PerformTest(T.cmap_EuroGlyph)) { EncodingTableEntry eteSym = GetEncodingTableEntry(3,0); if (eteSym == null) { EncodingTableEntry eteMac = GetEncodingTableEntry(1,0); if (eteMac != null) { Subtable st = GetSubtable(eteMac); if (st != null) { byte[] charbuf = new byte[2]; charbuf[0] = 0xdb; charbuf[1] = 0; uint glyph = st.MapCharToGlyph(charbuf, 0); if (glyph != 0) { v.Pass(T.cmap_EuroGlyph, P.cmap_P_EuroGlyph_Mac, m_tag); } else { v.Warning(T.cmap_EuroGlyph, W.cmap_W_EuroGlyph_Mac, m_tag); } } else { string sDetails = "PlatID = " + eteMac.platformID + ", EncID = " + eteMac.encodingID; string unable = "unable to validate if euro glyph " + "is present for subtable - "; v.Warning(T.cmap_EuroGlyph, W._TEST_W_OtherErrorsInTable, m_tag, unable + sDetails); } } EncodingTableEntry eteUni = GetEncodingTableEntry(3,1); if (eteUni != null) { Subtable st = GetSubtable(eteUni); if (st != null) { byte[] charbuf = new byte[2]; charbuf[0] = 0xac; charbuf[1] = 0x20; uint glyph = st.MapCharToGlyph(charbuf, 0); if (glyph != 0) { v.Pass(T.cmap_EuroGlyph, P.cmap_P_EuroGlyph_Uni, m_tag); } else { v.Warning(T.cmap_EuroGlyph, W.cmap_W_EuroGlyph_Uni, m_tag); } } else { string sDetails = "PlatID = " + eteMac.platformID + ", EncID = " + eteMac.encodingID; string unable = "unable to validate if euro glyph" + " is present for subtable - "; v.Warning(T.cmap_EuroGlyph, W._TEST_W_OtherErrorsInTable, m_tag, unable + sDetails); } } } } // Make sure that no glyphs, other than "fi" and "fl" ligatures, // are mapped from the "private use area", that is, // 0xE000 - 0xF8FF. The above ligatures may only be a the // prescribed places. // // Checks that 0xf001 and 0xfb01 map to the same place, and // Checks that 0xf002 and 0xfb02 map to the same place. // // Only warn if a problem. if (v.PerformTest(T.cmap_PrivateUse)) { EncodingTableEntry eteUni = GetEncodingTableEntry(3,1); if (eteUni != null) { Subtable st = GetSubtable(eteUni); if (st != null) { bool bFoundGlyph = false; bool bFoundLigChar = false; byte[] charbuf = new byte[2]; for (char c='\xe000'; c<'\xf8ff'; c++) { uint glyph = fontOwner.FastMapUnicodeToGlyphID(c); if (glyph != 0) { if (c == '\xf001') { // check to see if this is the 'fi' ligature uint glyph2 = fontOwner. FastMapUnicodeToGlyphID('\xfb01'); if (glyph == glyph2) { bFoundLigChar = true; } else { bFoundGlyph = true; break; } } else if (c == '\xf002') { // check to see if this is the 'fl' ligature uint glyph2 = fontOwner. FastMapUnicodeToGlyphID('\xfb02'); if (glyph == glyph2) { bFoundLigChar = true; } else { bFoundGlyph = true; break; } } else { bFoundGlyph = true; break; } } } if (bFoundGlyph) { v.Warning(T.cmap_PrivateUse, W.cmap_W_UnicodePrivateUse, m_tag); } else if (bFoundLigChar) { v.Pass(T.cmap_PrivateUse, P.cmap_P_UnicodePrivateUse_lig, m_tag); } else { v.Pass(T.cmap_PrivateUse, P.cmap_P_UnicodePrivateUse, m_tag); } } else { string sDetails = "PlatID = " + eteUni.platformID + ", EncID = " + eteUni.encodingID; v.Warning(T.cmap_PrivateUse, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate Private Use Area " + "for subtable - " + sDetails); } } } // Check that subtable language field is zero if not mac platform if (v.PerformTest(T.cmap_NonMacSubtableLanguage)) { bool bOk = true; for (uint i=0; i<NumberOfEncodingTables; i++) { EncodingTableEntry ete = GetEncodingTableEntry(i); Subtable st = GetSubtable(ete); if (st != null) { if (ete.platformID != 1) // not mac { if (st.language != 0) { string sDetails = "PlatID = " + ete.platformID + ", EncID = " + ete.encodingID + ", Language = " + st.language; v.Error(T.cmap_SubtableLanguage, E.cmap_E_NonMacSubtableLanguage, m_tag, sDetails); bOk = false; } } } } if (bOk) { v.Pass(T.cmap_SubtableLanguage, P.cmap_P_NonMacSubtableLanguage, m_tag); } } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; bool bLookupListOk = true; // check that the Lookup array doesn't extend past end of table if (m_offsetLookupListTable + (uint)FieldOffsets.LookupArray + LookupCount * 2 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_LookupListTable_E_LookupArray_pastEOT, table.m_tag, sIdentity); bLookupListOk = false; bRet = false; } // check that each offset is within the table for (uint i=0; i<LookupCount; i++) { if (m_offsetLookupListTable + GetLookupOffset(i) > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_LookupListTable_E_Lookup_offset, table.m_tag, sIdentity + ", Lookup[" + i + "]"); bLookupListOk = false; bRet = false; } } // validate each lookup table for (uint i=0; i<LookupCount; i++) { LookupTable_val lt = GetLookupTable_val(i); if (lt != null) { bRet &= lt.Validate(v, sIdentity + ", Lookup[" + i + "]", table); } else { bLookupListOk = false; bRet = false; } } if (bLookupListOk) { v.Pass(T.T_NULL, P._OTL_LookupListTable_P_valid, table.m_tag, sIdentity); } return bRet; }
public bool Validate(Validator v, OTTable table, ushort numGlyphs, String sIdentity) { bool bRet = true; // check the mapping byte [] charbuf = new byte[2]; for (uint i = 0; i<=65535; i++) { char c = (char)i; charbuf[0] = (byte)c; charbuf[1] = (byte)(c>>8); uint nGlyphID = MapCharToGlyph(charbuf, 0); if (nGlyphID >= numGlyphs) { v.Error(T.T_NULL, E.cmap_E_Mapping, table.m_tag, sIdentity + ", char = 0x" + ((uint)c).ToString("X4") + ", glyphID = " + nGlyphID); bRet = false; } } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; // check the LookupType if (((string)table.m_tag == "GPOS") && LookupType > 9 || ((string)table.m_tag == "GSUB" && LookupType > 8)) { v.Error(T.T_NULL, E._OTL_LookupTable_E_LookupType, table.m_tag, sIdentity + ", LookupType = " + LookupType); bRet = false; } // check LookupFlag reserved bits are clear if ((LookupFlag & 0x00f0) != 0) { v.Error(T.T_NULL, E._OTL_LookupTable_E_LookupFlag_reserved, table.m_tag, sIdentity); bRet = false; } // check Subtable offset array doesn't extend past end of table if (m_offsetLookupTable + (uint)FieldOffsets.SubTableOffsetArray + SubTableCount*2 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_LookupTable_E_SubtableArray_pastEOT, table.m_tag, sIdentity); bRet = false; } // check Subtable offsets don't point past end of table for (uint i=0; i<SubTableCount; i++) { // verify that the subtable offset is accessible, if not error was already reported if (m_offsetLookupTable + (uint)FieldOffsets.SubTableOffsetArray + i*2 + 2 <= m_bufTable.GetLength()) { if (m_offsetLookupTable + GetSubTableOffset(i) > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_LookupTable_E_SubtableArray_offset, table.m_tag, sIdentity + ", SubTable[" + i + "]"); bRet = false; } } } // way too many lookup tables to justify this pass message //if (bRet) //{ // v.Pass("_OTL_LookupTable_P_valid", table.m_tag, sIdentity); //} // validate each subtable for (uint i=0; i<SubTableCount; i++) { // verify that the subtable offset is accessible, if not error was already reported if (m_offsetLookupTable + (uint)FieldOffsets.SubTableOffsetArray + i*2 + 2 <= m_bufTable.GetLength()) { // verify subtable offset is valid if (m_offsetLookupTable + GetSubTableOffset(i) <= m_bufTable.GetLength()) { SubTable st = GetSubTable(i); if (st != null) { I_OTLValidate iv = (I_OTLValidate)st; bRet &= iv.Validate(v, sIdentity + ", SubTable[" + i + "]", table); } else { v.Warning(T.T_NULL, W._TEST_W_OtherErrorsInTable, table.m_tag, "unable to validate subtable: " + sIdentity + ", SubTable[" + i + "]"); } } else { v.Warning(T.T_NULL, W._TEST_W_OtherErrorsInTable, table.m_tag, "unable to validate subtable: " + sIdentity + ", SubTable[" + i + "]"); } } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.VDMX_Version)) { if (version == 0 || version == 1) { v.Pass(T.VDMX_Version, P.VDMX_P_Version, m_tag, version.ToString()); } else { v.Error(T.VDMX_Version, E.VDMX_E_Version, m_tag, version.ToString()); bRet = false; } } if (v.PerformTest(T.VDMX_Offsets)) { bool bOffsetsOk = true; ushort minPossibleOffset = (ushort)((ushort)FieldOffsets.ratRange + numRatios * 4 + numRatios*2); ushort maxPossibleOffset = (ushort)GetLength(); for (uint i=0; i<numRatios; i++) { ushort offset = GetVdmxGroupOffset(i); if (offset < minPossibleOffset || offset > maxPossibleOffset) { v.Error(T.VDMX_Offsets, E.VDMX_E_InvalidOffset, m_tag, "#" + i + " offset = " + offset); bOffsetsOk = false; bRet = false; } } if (bOffsetsOk) { v.Pass(T.VDMX_Offsets, P.VDMX_P_Offsets, m_tag); } } if (v.PerformTest(T.VDMX_GroupsInTable)) { bool bGroupsOk = true; for (uint i=0; i<numRatios; i++) { Vdmx vdmx = GetVdmxGroup(i); uint EndOffset = (uint)GetVdmxGroupOffset(i) + 4 + (uint)vdmx.recs*6; if (EndOffset > GetLength()) { v.Error(T.VDMX_GroupsInTable, E.VDMX_E_GroupsInTable, m_tag, "group# " + i); bGroupsOk = false; bRet = false; } } if (bGroupsOk) { v.Pass(T.VDMX_GroupsInTable, P.VDMX_P_GroupsInTable, m_tag); } } if (v.PerformTest(T.VDMX_CompareToCalcData)) { bool bDataOk = true; bool needtol = false; RasterInterf.DevMetricsData dmd = null; try { Version ver = fontOwner.GetFile().GetRasterizer().FTVersion; if ( ver.CompareTo(new Version(2,6,1)) < 0 ) v.Warning(T.VDMX_CompareToCalcData, W.VDMX_W_Need_Newer_FreeType, m_tag, "Using FreeType Version " + ver + " may not get correct results for VDMX"); dmd = fontOwner.GetCalculatedDevMetrics(); } catch (InvalidOperationException e) { // JJF Figure out what to do. Changed to warning v.Warning(T.VDMX_CompareToCalcData, W._TEST_W_ErrorInAnotherTable, m_tag, e.Message); } catch(Exception e) { v.ApplicationError(T.VDMX_CompareToCalcData, E._Table_E_Exception, m_tag, e.Message); bRet = false; } if (dmd != null) { for (uint iRatio=0; iRatio<numRatios; iRatio++) { Ratios ratio = GetRatioRange(iRatio); Vdmx group = GetVdmxGroup(iRatio); for (uint iEntry=0; iEntry<group.recs; iEntry++) { Vdmx.vTable vTableEntry = group.GetEntry(iEntry); if (vTableEntry.yPelHeight <= 255) { if (vTableEntry.yPelHeight == dmd.vdmxData.groups[iRatio].entry[vTableEntry.yPelHeight - group.startsz].yPelHeight) { if (vTableEntry.yMin != dmd.vdmxData.groups[iRatio].entry[iEntry].yMin || vTableEntry.yMax != dmd.vdmxData.groups[iRatio].entry[iEntry].yMax){ int dif = dmd.vdmxData.groups[iRatio].entry[iEntry].yMax - dmd.vdmxData.groups[iRatio].entry[iEntry].yMin; if (!TestTolerance(dmd.vdmxData.groups[iRatio].entry[iEntry].yMin, vTableEntry.yMin, dif) || !TestTolerance(dmd.vdmxData.groups[iRatio].entry[iEntry].yMax, vTableEntry.yMax, dif)) { String sDetails = "group[" + iRatio + "], entry[" + iEntry + "], yPelHeight = " + vTableEntry.yPelHeight + ", yMin,yMax = " + vTableEntry.yMin + "," + vTableEntry.yMax + ", calculated yMin,yMax = " + dmd.vdmxData.groups[iRatio].entry[iEntry].yMin + "," + dmd.vdmxData.groups[iRatio].entry[iEntry].yMax; v.Error(T.VDMX_CompareToCalcData, E.VDMX_E_CalcData, m_tag, sDetails); bDataOk = false; } else { needtol = true; } } /* else { String s = "group[" + iRatio + "], yPelHeight = " + vTableEntry.yPelHeight + ", entry OK"; v.DebugMsg(s, m_tag); } */ } else { Debug.Assert(false); } } else { String sDetails = "group[" + iRatio + "], entry[" + iEntry + "], yPelHeight = " + vTableEntry.yPelHeight; v.Error(T.VDMX_CompareToCalcData, E.VDMX_E_yPelHeight_illegal, m_tag, sDetails); bDataOk = false; } } } if (bDataOk) { if (needtol) { String sDetails = "The differences were smaller than the tolerance, so they may well be valid if the VDMX was hand-tuned"; v.Warning(T.VDMX_CompareToCalcData, W.VDMX_W_CalcData, m_tag, sDetails); } else { v.Pass(T.VDMX_CompareToCalcData, P.VDMX_P_CalcData, m_tag); } } else { //v.Error(T.VDMX_CompareToCalcData, E.VDMX_E_CalcData, m_tag); bRet = false; } } else { // Rasterization could not occur for various reasons. string s = "Unable to get calculated device metrics."; v.Error(T.VDMX_CompareToCalcData, E.VDMX_E_CalcData, m_tag, s); bDataOk = false; bRet = false; } } return bRet; }
public bool Validate(Validator v, string sIdentity, OTTable table) { bool bRet = true; if (CoverageFormat == 1) { if (m_offsetCoverageTable + (uint)FieldOffsets1.GlyphArray + F1GlyphCount*2 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_CoverageTable_E_GlyphArrayPastEOT, table.m_tag, sIdentity); bRet = false; } } else if (CoverageFormat == 2) { if (m_offsetCoverageTable + (uint)FieldOffsets2.RangeRecordArray + F2RangeCount*6 > m_bufTable.GetLength()) { v.Error(T.T_NULL, E._OTL_CoverageTable_E_RangeRecordArrayPastEOT, table.m_tag, sIdentity); bRet = false; } } else { v.Error(T.T_NULL, E._OTL_CoverageTable_E_Format, table.m_tag, sIdentity + ", format = " + CoverageFormat.ToString()); bRet = false; } // way too many coverage tables to justify this pass message //if (bRet) //{ // v.Pass("_OTL_CoverageTable_P_valid", table.m_tag, sIdentity); //} return bRet; }