/************************ * 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 methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.DSIG_Formats)) { bool bFormatsOk = true; for (uint i = 0; i < usNumSigs; i++) { SigFormatOffset sfo; try { sfo = GetSigFormatOffset(i); if (sfo.ulFormat != 1) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", format = " + sfo.ulFormat); bFormatsOk = false; bRet = false; } } catch (IndexOutOfRangeException e) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", " + e); bFormatsOk = false; bRet = false; break; // No point continuing } } if (bFormatsOk) { v.Pass(T.DSIG_Formats, P.DSIG_P_Formats, m_tag); } } if (v.PerformTest(T.DSIG_Reserved)) { bool bReservedOk = true; for (uint i = 0; i < usNumSigs; i++) { SignatureBlock sb; try { sb = GetSignatureBlock(i); if (sb.usReserved1 != 0 || sb.usReserved2 != 0) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; } } catch (IndexOutOfRangeException) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; break; // No point continuing } } if (bReservedOk) { v.Pass(T.DSIG_Reserved, P.DSIG_P_Reserved, m_tag); } } if (v.PerformTest(T.DSIG_VerifySignature)) { OTFile file = fontOwner.GetFile(); System.IO.FileStream fs = file.GetFileStream(); String sFilename = fs.Name; try { WinVerifyTrustWrapper wvt = new WinVerifyTrustWrapper(); if (wvt.WinVerifyTrustFile(sFilename)) { if (wvt.usNumSigs > 0) { if (wvt.Warn_TTCv1 || wvt.Warn_DSIG_in_memFonts) { v.Warning(T.DSIG_VerifySignature, W.DSIG_W_VerifySignature_Generic, m_tag, (wvt.Warn_TTCv1 ? "TTC with v1 header;":"") + (wvt.Warn_DSIG_in_memFonts ? "DSIG tables detected in member fonts;":"")); } v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag, wvt.Signer); } else { v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag); } } else { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag); bRet = false; } } catch (Exception e) { if (e is NotImplementedException) { v.ApplicationError(T.DSIG_VerifySignature, E.DSIG_A_UNUSUAL_TTC_TABLE_LAYOUT, m_tag, e.Message); } else { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag, e.Message); } bRet = false; } } return(bRet); }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; ushort numGlyphs = GetNumGlyphs(fontOwner); if (v.PerformTest(T.hdmx_Version)) { if (TableVersionNumber == 0) { v.Pass(T.hdmx_Version, P.hdmx_P_Version, m_tag); } else { v.Error(T.hdmx_Version, E.hdmx_E_Version, m_tag, TableVersionNumber.ToString()); bRet = false; } } bool bNumDeviceRecordsOk = true; if (v.PerformTest(T.hdmx_NumDeviceRecords)) { if (NumberDeviceRecords >= 0) { v.Pass(T.hdmx_NumDeviceRecords, P.hdmx_P_NumDeviceRecords, m_tag, NumberDeviceRecords.ToString()); } else { v.Error(T.hdmx_NumDeviceRecords, E.hdmx_E_NumDeviceRecords_neg, m_tag, NumberDeviceRecords.ToString()); bNumDeviceRecordsOk = false; bRet = false; } } bool bSizeOk = true; if (v.PerformTest(T.hdmx_SizeofDeviceRecord)) { if ((SizeofDeviceRecord & 3) != 0) { v.Error(T.hdmx_SizeofDeviceRecord, E.hdmx_E_SizeofDeviceRecord_alignment, m_tag, SizeofDeviceRecord.ToString()); bSizeOk = false; bRet = false; } uint CalculatedSizeofDeviceRecord = CalculateSizeofDeviceRecord(numGlyphs); if (SizeofDeviceRecord != CalculatedSizeofDeviceRecord) { string s = "actual = " + SizeofDeviceRecord + ", calc = " + CalculatedSizeofDeviceRecord; v.Error(T.hdmx_SizeofDeviceRecord, E.hdmx_E_SizeofDeviceRecord_numGlyphs, m_tag, s); bSizeOk = false; bRet = false; } if (bSizeOk) { v.Pass(T.hdmx_SizeofDeviceRecord, P.hdmx_P_SizeofDeviceRecord, m_tag, SizeofDeviceRecord.ToString()); } } bool bLengthOk = true; if (v.PerformTest(T.hdmx_TableLength)) { if (bNumDeviceRecordsOk) { uint CalculatedTableLength = 8 + (uint)NumberDeviceRecords * CalculateSizeofDeviceRecord(numGlyphs); if (GetLength() == CalculatedTableLength) { v.Pass(T.hdmx_TableLength, P.hdmx_P_TableLength, m_tag); } else { string s = "actual: " + GetLength() + ", calc: " + CalculatedTableLength; v.Error(T.hdmx_TableLength, E.hdmx_E_TableLength, m_tag, s); bLengthOk = false; bRet = false; } } else { v.Warning(T.hdmx_TableLength, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate table length"); } } if (v.PerformTest(T.hdmx_DeviceRecordPadBytesZero)) { if (bSizeOk && bLengthOk & bNumDeviceRecordsOk) { uint unpaddedLength = (uint)numGlyphs + 2; if ((unpaddedLength & 3) == 0) { v.Pass(T.hdmx_DeviceRecordPadBytesZero, P.hdmx_P_DeviceRecordPadBytes_none, m_tag); } else { bool bPadOk = true; if (NumberDeviceRecords > 1) { for (uint i=0; i<NumberDeviceRecords; i++) { DeviceRecord dr = GetDeviceRecord(i, numGlyphs); for (uint j=0; j<dr.GetNumPadBytes(); j++) { if (dr.GetPadByte(j) != 0) { bPadOk = false; break; } } } } if (bPadOk) { v.Pass(T.hdmx_DeviceRecordPadBytesZero, P.hdmx_P_DeviceRecordPadBytes_zero, m_tag); } else { v.Error(T.hdmx_DeviceRecordPadBytesZero, E.hdmx_E_DeviceRecordPadBytes_nonzero, m_tag); bRet = false; } } } else { v.Warning(T.hdmx_DeviceRecordPadBytesZero, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that device record padding bytes are zero"); } } if (v.PerformTest(T.hdmx_SortedOrder)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bSortOk = true; if (NumberDeviceRecords > 1) { DeviceRecord drCurr = GetDeviceRecord(0, numGlyphs); DeviceRecord drNext = null; for (uint i=1; i<NumberDeviceRecords; i++) { drNext = GetDeviceRecord(i, numGlyphs); if (drCurr.PixelSize >= drNext.PixelSize) { bSortOk = false; break; } drCurr = drNext; } } if (bSortOk) { v.Pass(T.hdmx_SortedOrder, P.hdmx_P_SortedOrder, m_tag); } else { v.Error(T.hdmx_SortedOrder, E.hdmx_E_SortedOrder, m_tag); bRet = false; } } else { v.Warning(T.hdmx_SortedOrder, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that device records are in sorted order"); } } if (v.PerformTest(T.hdmx_DuplicateDeviceRecords)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bNoDup = true; if (NumberDeviceRecords > 1) { for (uint i=0; i<NumberDeviceRecords-1; i++) { DeviceRecord dr1 = GetDeviceRecord(i, numGlyphs); for (uint j=i+1; j<NumberDeviceRecords; j++) { DeviceRecord dr2 = GetDeviceRecord(j, numGlyphs); if (dr1.PixelSize == dr2.PixelSize) { bNoDup = false; break; } } } } if (bNoDup) { v.Pass(T.hdmx_DuplicateDeviceRecords, P.hdmx_P_DuplicateDeviceRecords, m_tag); } else { v.Error(T.hdmx_DuplicateDeviceRecords, E.hdmx_E_DuplicateDeviceRecords, m_tag); bRet = false; } } else { v.Warning(T.hdmx_DuplicateDeviceRecords, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that there are no duplicate device records"); } } if (v.PerformTest(T.hdmx_Widths)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bWidthsOk = true; RasterInterf.DevMetricsData dmd = null; try { Version ver = fontOwner.GetFile().GetRasterizer().FTVersion; if ( ver.CompareTo(new Version(2,6,1)) < 0 ) v.Warning(T.hdmx_Widths, W.hdmx_W_Need_Newer_FreeType, m_tag, "Using FreeType Version " + ver + " may not get correct results for HDMX"); dmd = fontOwner.GetCalculatedDevMetrics(); } catch (Exception e) { v.ApplicationError(T.hdmx_Widths, E._Table_E_Exception, m_tag, e.Message); bRet = false; } if (dmd != null) { for (uint i=0; i<NumberDeviceRecords; i++) { DeviceRecord dr = GetDeviceRecord(i, numGlyphs); for (uint iGlyph=0; iGlyph<numGlyphs; iGlyph++) { if (dr.GetWidth(iGlyph) != dmd.hdmxData.Records[i].Widths[iGlyph]) { String sDetails = "rec " + i + ", PixelSize " + dr.PixelSize + ", glyph# " + iGlyph + ", width = " + dr.GetWidth(iGlyph) + ", calc = " + dmd.hdmxData.Records[i].Widths[iGlyph]; v.Error(T.hdmx_Widths, E.hdmx_E_Widths, m_tag, sDetails); bWidthsOk = false; bRet = false; } } } if (bWidthsOk) { v.Pass(T.hdmx_Widths, P.hdmx_P_Widths, m_tag); } } else { // if user didn't cancel, then check for error message if (!v.CancelFlag) { String sDetails = null; try { sDetails = fontOwner.GetDevMetricsDataError(); } catch (Exception e) { v.ApplicationError(T.hdmx_Widths, E._Table_E_Exception, m_tag, e.Message); } Debug.Assert(sDetails != null); v.Error(T.hdmx_Widths, E.hdmx_E_Rasterizer, m_tag, sDetails); bRet = false; } } } else { v.Warning(T.hdmx_Widths, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that the widths are correct"); } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.DSIG_Formats)) { bool bFormatsOk = true; for (uint i=0; i<usNumSigs; i++) { SigFormatOffset sfo; try { sfo = GetSigFormatOffset(i); if (sfo.ulFormat != 1) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", format = " + sfo.ulFormat); bFormatsOk = false; bRet = false; } } catch (IndexOutOfRangeException e) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", " + e); bFormatsOk = false; bRet = false; break; // No point continuing } } if (bFormatsOk) { v.Pass(T.DSIG_Formats, P.DSIG_P_Formats, m_tag); } } if (v.PerformTest(T.DSIG_Reserved)) { bool bReservedOk = true; for (uint i=0; i<usNumSigs; i++) { SignatureBlock sb; try { sb = GetSignatureBlock(i); if (sb.usReserved1 != 0 || sb.usReserved2 != 0) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; } } catch (IndexOutOfRangeException) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; break; // No point continuing } } if (bReservedOk) { v.Pass(T.DSIG_Reserved, P.DSIG_P_Reserved, m_tag); } } if (v.PerformTest(T.DSIG_VerifySignature)) { OTFile file = fontOwner.GetFile(); System.IO.FileStream fs = file.GetFileStream(); String sFilename = fs.Name; try { WinVerifyTrustWrapper wvt = new WinVerifyTrustWrapper(); if (wvt.WinVerifyTrustFile(sFilename)) { if (wvt.usNumSigs > 0) { if (wvt.Warn_TTCv1 || wvt.Warn_DSIG_in_memFonts) v.Warning(T.DSIG_VerifySignature, W.DSIG_W_VerifySignature_Generic, m_tag, ( wvt.Warn_TTCv1 ? "TTC with v1 header;":"") + (wvt.Warn_DSIG_in_memFonts ? "DSIG tables detected in member fonts;":"") ); v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag, wvt.Signer); } else v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag); } else { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag); bRet = false; } } catch (Exception e) { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag, e.Message); bRet = false; } } 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 methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (fontOwner.GetFile().IsCollection()) { if (fontOwner.GetFontIndexInFile() > 0) { // checksum not matching data is covered by check elsewhere. Assume they match. DirectoryEntry de_EBDT = fontOwner.GetDirectoryEntry("EBDT"); for (uint i = 0; i < fontOwner.GetFontIndexInFile(); i++) { if (fontOwner.GetFile().GetFont(i).GetDirectoryEntry("EBDT").checkSum == de_EBDT.checkSum) { v.Info(T.T_NULL, I.glyf_I_IDENTICAL_GLYF_TABLES_IN_TTC, m_tag); return(true); } } } } m_nCachedMaxpNumGlyphs = fontOwner.GetMaxpNumGlyphs(); if (v.PerformTest(T.EBDT_version)) { if (version.GetUint() == 0x00020000 || version.GetUint() == 0x00030000) { v.Pass(T.EBDT_version, P.EBDT_P_version, m_tag); } else { v.Error(T.EBDT_version, E.EBDT_E_version, m_tag, "version = 0x" + version.GetUint().ToString("x8") + ", unable to continue validation"); return(false); } } //TODO: check tag for EBDT v3, CBDT v2, bdat if (v.PerformTest(T.EBDT_TableDependency)) { Table_EBLC EBLCTable = (Table_EBLC)fontOwner.GetTable("EBLC"); if (EBLCTable != null) { v.Pass(T.EBDT_TableDependency, P.EBDT_P_TableDependency, m_tag); } else { v.Error(T.EBDT_TableDependency, E.EBDT_E_TableDependency, m_tag); bRet = false; } } // T.EBDT_GlyphImageData depends on T.EBDT_TableDependency passing. if (v.PerformTest(T.EBDT_GlyphImageData)) { bool bGlyphImageDataOk = true; Table_EBLC EBLCTable = (Table_EBLC)fontOwner.GetTable("EBLC"); if (EBLCTable == null) { return(bRet); //failed the last test, not going on. } // for each bitmap size for (uint i = 0; i < EBLCTable.numSizes; i++) { Table_EBLC.bitmapSizeTable bst = EBLCTable.GetBitmapSizeTable(i); string sSize = "bitmapsize[" + i + "], ppemX=" + bst.ppemX + ", ppemY=" + bst.ppemY; if (true) { for (uint j = 0; j < bst.numberOfIndexSubTables; j++) { Table_EBLC.indexSubTable ist = null; Table_EBLC.indexSubTableArray ista_j = EBLCTable.GetIndexSubTableArray(bst, j); if (ista_j != null) { ist = bst.GetIndexSubTable(ista_j); } if (ist != null) { string sID = sSize + ", indexSubTable[" + j + "](index fmt " + ist.header.indexFormat + ", image fmt " + ist.header.imageFormat + ")"; switch (ist.header.imageFormat) { case 1: if (!Validate_Format1(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 2: if (!Validate_Format2(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 3: if (!Validate_Format3(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 4: if (!Validate_Format4(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 5: if (!Validate_Format5(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 6: if (!Validate_Format6(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 7: if (!Validate_Format7(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 8: if (!Validate_Format8(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 9: if (!Validate_Format9(v, sID, ist)) { bGlyphImageDataOk = false; bRet = false; } break; case 17: if (version.GetUint() != 0x00030000) { bGlyphImageDataOk = false; bRet = false; } // TODO: adding 3 checks break; case 18: if (version.GetUint() != 0x00030000) { bGlyphImageDataOk = false; bRet = false; } // TODO: adding 3 checks break; case 19: if (version.GetUint() != 0x00030000) { bGlyphImageDataOk = false; bRet = false; } // TODO: adding 3 checks break; default: // TODO: emit Unknown break; } } } } } if (bGlyphImageDataOk) { v.Pass(T.EBDT_GlyphImageData, P.EBDT_P_GlyphImageData, m_tag); } } return(bRet); }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.LTSH_version)) { if (version == 0) { v.Pass(T.LTSH_version, P.LTSH_P_version, m_tag); } else { v.Error(T.LTSH_version, E.LTSH_E_version, m_tag, version.ToString()); bRet = false; } } 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.LTSH_numGlyphs)) { if (numGlyphs == fontOwner.GetMaxpNumGlyphs()) { v.Pass(T.LTSH_numGlyphs, P.LTSH_P_numGlyphs, m_tag); } else { string s = "LTSH.numGlyphs = " + numGlyphs + ", maxp.numGlyphs = " + fontOwner.GetMaxpNumGlyphs(); v.Error(T.LTSH_numGlyphs, E.LTSH_E_numGlyphs, m_tag, s); bRet = false; } } if (v.PerformTest(T.LTSH_TableLength)) { uint CalcLength = (uint)FieldOffsets.yPels + numGlyphs; if (GetLength() == CalcLength) { v.Pass(T.LTSH_TableLength, P.LTSH_P_TableLength, m_tag); } else { string s = "calc length = " + CalcLength + ", actual length = " + GetLength(); v.Error(T.LTSH_TableLength, E.LTSH_E_TableLength, m_tag, s); bRet = false; } } if (v.PerformTest(T.LTSH_yPels)) { bool bYPelsOk = true; RasterInterf.DevMetricsData dmd = null; try { Version ver = fontOwner.GetFile().GetRasterizer().FTVersion; if (ver.CompareTo(new Version(2, 6, 1)) < 0) { v.Warning(T.LTSH_yPels, W.LTSH_W_Need_Newer_FreeType, m_tag, "Using FreeType Version " + ver + " may not get correct results for LTSH"); } dmd = fontOwner.GetCalculatedDevMetrics(); } catch (Exception e) { v.ApplicationError(T.LTSH_yPels, E._Table_E_Exception, m_tag, e.Message); bRet = false; } if (dmd != null) { for (uint iGlyphIndex = 0; iGlyphIndex < numGlyphs; iGlyphIndex++) { if (iGlyphIndex >= fontOwner.GetMaxpNumGlyphs()) { // JJF. Figure out what to do v.Warning(T.LTSH_yPels, W._TEST_W_OtherErrorsInTable, m_tag, "can't test all yPel values, LTSH.numGlyphs does not equal maxp.numGlyphs"); bRet = false; bYPelsOk = false; break; } if (GetYPel(iGlyphIndex) != dmd.ltshData.yPels[iGlyphIndex]) { String sDetails = "glyph# = " + iGlyphIndex + ", value = " + GetYPel(iGlyphIndex) + ", calculated value = " + dmd.ltshData.yPels[iGlyphIndex]; v.Error(T.LTSH_yPels, E.LTSH_E_yPels, m_tag, sDetails); bRet = false; bYPelsOk = false; } /* * else * { * String sDetails = "glyph# = " + iGlyphIndex + ", value = " + GetYPel(iGlyphIndex); * v.DebugMsg("yPel value OK! " + sDetails, m_tag); * } */ if (GetYPel(iGlyphIndex) == 0) { String sDetails = "glyph# = " + iGlyphIndex; v.Warning(T.LTSH_yPels, W.LTSH_W_yPels_zero, m_tag, sDetails); } } if (bYPelsOk) { v.Pass(T.LTSH_yPels, P.LTSH_P_yPels, m_tag); } } else { // if user didn't cancel, then check for error message if (!v.CancelFlag) { String sDetails = null; try { sDetails = fontOwner.GetDevMetricsDataError(); } catch (Exception e) { v.ApplicationError(T.LTSH_yPels, E._Table_E_Exception, m_tag, e.Message); } Debug.Assert(sDetails != null); v.Error(T.LTSH_yPels, E.LTSH_E_Rasterizer, m_tag, sDetails); bRet = false; } } } return(bRet); }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.LTSH_version)) { if (version == 0) { v.Pass(T.LTSH_version, P.LTSH_P_version, m_tag); } else { v.Error(T.LTSH_version, E.LTSH_E_version, m_tag, version.ToString()); bRet = false; } } 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.LTSH_numGlyphs)) { if (numGlyphs == fontOwner.GetMaxpNumGlyphs()) { v.Pass(T.LTSH_numGlyphs, P.LTSH_P_numGlyphs, m_tag); } else { string s = "LTSH.numGlyphs = " + numGlyphs + ", maxp.numGlyphs = " + fontOwner.GetMaxpNumGlyphs(); v.Error(T.LTSH_numGlyphs, E.LTSH_E_numGlyphs, m_tag, s); bRet = false; } } if (v.PerformTest(T.LTSH_TableLength)) { uint CalcLength = (uint)FieldOffsets.yPels + numGlyphs; if (GetLength() == CalcLength) { v.Pass(T.LTSH_TableLength, P.LTSH_P_TableLength, m_tag); } else { string s = "calc length = " + CalcLength + ", actual length = " + GetLength(); v.Error(T.LTSH_TableLength, E.LTSH_E_TableLength, m_tag, s); bRet = false; } } if (v.PerformTest(T.LTSH_yPels)) { bool bYPelsOk = true; RasterInterf.DevMetricsData dmd = null; try { Version ver = fontOwner.GetFile().GetRasterizer().FTVersion; if ( ver.CompareTo(new Version(2,6,1)) < 0 ) v.Warning(T.LTSH_yPels, W.LTSH_W_Need_Newer_FreeType, m_tag, "Using FreeType Version " + ver + " may not get correct results for LTSH"); dmd = fontOwner.GetCalculatedDevMetrics(); } catch (Exception e) { v.ApplicationError(T.LTSH_yPels, E._Table_E_Exception, m_tag, e.Message); bRet = false; } if (dmd != null) { for( uint iGlyphIndex = 0; iGlyphIndex < numGlyphs; iGlyphIndex++ ) { if (iGlyphIndex >= fontOwner.GetMaxpNumGlyphs()) { // JJF. Figure out what to do v.Warning(T.LTSH_yPels, W._TEST_W_OtherErrorsInTable, m_tag, "can't test all yPel values, LTSH.numGlyphs does not equal maxp.numGlyphs"); bRet = false; bYPelsOk = false; break; } if( GetYPel(iGlyphIndex) != dmd.ltshData.yPels[iGlyphIndex] ) { String sDetails = "glyph# = " + iGlyphIndex + ", value = " + GetYPel(iGlyphIndex) + ", calculated value = " + dmd.ltshData.yPels[iGlyphIndex]; v.Error(T.LTSH_yPels, E.LTSH_E_yPels, m_tag, sDetails); bRet = false; bYPelsOk = false; } /* else { String sDetails = "glyph# = " + iGlyphIndex + ", value = " + GetYPel(iGlyphIndex); v.DebugMsg("yPel value OK! " + sDetails, m_tag); } */ if (GetYPel(iGlyphIndex) == 0) { String sDetails = "glyph# = " + iGlyphIndex; v.Warning(T.LTSH_yPels, W.LTSH_W_yPels_zero, m_tag, sDetails); } } if (bYPelsOk) { v.Pass(T.LTSH_yPels, P.LTSH_P_yPels, m_tag); } } else { // if user didn't cancel, then check for error message if (!v.CancelFlag) { String sDetails = null; try { sDetails = fontOwner.GetDevMetricsDataError(); } catch (Exception e) { v.ApplicationError(T.LTSH_yPels, E._Table_E_Exception, m_tag, e.Message); } Debug.Assert(sDetails != null); v.Error(T.LTSH_yPels, E.LTSH_E_Rasterizer, m_tag, sDetails); bRet = false; } } } return bRet; }
public bool Validate(Validator validator, OTFontVal fontOwner) { bool bRet = true; if (!validator.PerformTest(T.glyf_ValidateAll)) { return(true); } if (fontOwner.GetFile().IsCollection()) { if (fontOwner.GetFontIndexInFile() > 0) { // checksum not matching data is covered by check elsewhere. Assume they match. DirectoryEntry de_glyf = fontOwner.GetDirectoryEntry("glyf"); for (uint i = 0; i < fontOwner.GetFontIndexInFile(); i++) { if (fontOwner.GetFile().GetFont(i).GetDirectoryEntry("glyf").checkSum == de_glyf.checkSum) { validator.Info(T.T_NULL, I.glyf_I_IDENTICAL_GLYF_TABLES_IN_TTC, m_tag); return(true); } } } } this.m_diaValidate = validator.DIA; this.m_cnts = new int[this.m_namesInfoCnt.Length]; for (int iCnt = 0; iCnt < this.m_cnts.Length; iCnt++) { this.m_cnts[iCnt] = 0; } I_IOGlyphsFile i_IOGlyphs = new I_IOGlyphsFile(); if (!i_IOGlyphs.Initialize(fontOwner, validator)) { return(false); // the error is already reported } DIAction diaFilter = DIActionBuilder.DIA(this, "DIAFunc_Filter"); FManager fm = new FManager(i_IOGlyphs, null, null); int numGlyph = fm.FNumGlyph; int indGlyph; for (indGlyph = 0; indGlyph < numGlyph; indGlyph++) { try { if ((indGlyph % 100) == 0) { validator.OnTableProgress("Validating glyph with index " + indGlyph + " (out of " + numGlyph + " glyphs)"); } Glyph glyph = fm.GGet(indGlyph); glyph.GValidate(); bRet &= fm.GErrGetInformed(indGlyph, diaFilter); fm.ClearManagementStructs(); } catch { validator.Error(T.T_NULL, E.glyf_E_ExceptionUnhandeled, (OTTag)"glyf", "Glyph index " + indGlyph); } if (validator.CancelFlag) { break; } } i_IOGlyphs.Clear(); fm.ClearDestroy(); fm = null; /* * I_ProgressUpdater i_ProgressUpdater=new ValidationCancel(validator); * * FManager fm=new FManager(i_IOGlyphs, null, null); * DIAction diaFilter= * DIActionBuilder.DIA(this,"DIAFunc_Filter"); * * fm.GErrActionAdd(diaFilter, * FManager.TypeActionOnErr.onAdd); * * * fm.FValidate(GConsts.IND_UNINITIALIZED, * GConsts.IND_UNINITIALIZED); * * i_IOGlyphs.Clear(); * i_ProgressUpdater.Clear(); * fm.ClearDestroy(); * fm=null; */ for (int iCnt = 0; iCnt < this.m_cnts.Length; iCnt++) { if (this.m_cnts[iCnt] > 0) { bool isGErr = this.m_namesInfoCnt[iCnt].StartsWith("GERR_"); string nameFileErr = isGErr? GErrConsts.FILE_RES_GERR_STRINGS: GErrConsts.FILE_RES_OTFFERR_STRINGS; string nameAsmFileErr = isGErr? GErrConsts.ASM_RES_GERR_STRINGS: GErrConsts.ASM_RES_OTFFERR_STRINGS; string strDetails = "Number of glyphs with the warning = " + this.m_cnts[iCnt]; if (validator.CancelFlag) { strDetails += " (Validation cancelled)"; } ValInfoBasic info = new ValInfoBasic( ValInfoBasic.ValInfoType.Warning, this.m_namesInfoCnt[iCnt], strDetails, nameFileErr, nameAsmFileErr, "glyf", null); validator.DIA(info); } } this.m_cnts = null; return(bRet); }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.DSIG_Formats)) { bool bFormatsOk = true; for (uint i=0; i<usNumSigs; i++) { SigFormatOffset sfo = GetSigFormatOffset(i); if (sfo.ulFormat != 1) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", format = " + sfo.ulFormat); bFormatsOk = false; bRet = false; } } if (bFormatsOk) { v.Pass(T.DSIG_Formats, P.DSIG_P_Formats, m_tag); } } if (v.PerformTest(T.DSIG_Reserved)) { bool bReservedOk = true; for (uint i=0; i<usNumSigs; i++) { SignatureBlock sb = GetSignatureBlock(i); if (sb.usReserved1 != 0 || sb.usReserved2 != 0) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; } } if (bReservedOk) { v.Pass(T.DSIG_Reserved, P.DSIG_P_Reserved, m_tag); } } if (v.PerformTest(T.DSIG_VerifySignature)) { OTFile file = fontOwner.GetFile(); System.IO.FileStream fs = file.GetFileStream(); String sFilename = fs.Name; try { WinVerifyTrustWrapper wvt = new WinVerifyTrustWrapper(); if (wvt.WinVerifyTrustFile(sFilename)) { v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag); } else { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag); bRet = false; } } catch (Exception e) { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag, e.Message); bRet = false; } } return bRet; }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; if (v.PerformTest(T.DSIG_Formats)) { bool bFormatsOk = true; for (uint i = 0; i < usNumSigs; i++) { SigFormatOffset sfo = GetSigFormatOffset(i); if (sfo.ulFormat != 1) { v.Error(T.DSIG_Formats, E.DSIG_E_Formats, m_tag, "block " + i + ", format = " + sfo.ulFormat); bFormatsOk = false; bRet = false; } } if (bFormatsOk) { v.Pass(T.DSIG_Formats, P.DSIG_P_Formats, m_tag); } } if (v.PerformTest(T.DSIG_Reserved)) { bool bReservedOk = true; for (uint i = 0; i < usNumSigs; i++) { SignatureBlock sb = GetSignatureBlock(i); if (sb.usReserved1 != 0 || sb.usReserved2 != 0) { v.Error(T.DSIG_Reserved, E.DSIG_E_Reserved, m_tag, "block " + i); bReservedOk = false; bRet = false; } } if (bReservedOk) { v.Pass(T.DSIG_Reserved, P.DSIG_P_Reserved, m_tag); } } if (v.PerformTest(T.DSIG_VerifySignature)) { OTFile file = fontOwner.GetFile(); System.IO.FileStream fs = file.GetFileStream(); String sFilename = fs.Name; try { WinVerifyTrustWrapper wvt = new WinVerifyTrustWrapper(); if (wvt.WinVerifyTrustFile(sFilename)) { v.Pass(T.DSIG_VerifySignature, P.DSIG_P_VerifySignature, m_tag); } else { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag); bRet = false; } } catch (Exception e) { v.Error(T.DSIG_VerifySignature, E.DSIG_E_VerifySignature, m_tag, e.Message); bRet = false; } } return(bRet); }
/************************ * public methods */ public bool Validate(Validator v, OTFontVal fontOwner) { bool bRet = true; ushort numGlyphs = GetNumGlyphs(fontOwner); if (v.PerformTest(T.hdmx_Version)) { if (TableVersionNumber == 0) { v.Pass(T.hdmx_Version, P.hdmx_P_Version, m_tag); } else { v.Error(T.hdmx_Version, E.hdmx_E_Version, m_tag, TableVersionNumber.ToString()); bRet = false; } } bool bNumDeviceRecordsOk = true; if (v.PerformTest(T.hdmx_NumDeviceRecords)) { if (NumberDeviceRecords >= 0) { v.Pass(T.hdmx_NumDeviceRecords, P.hdmx_P_NumDeviceRecords, m_tag, NumberDeviceRecords.ToString()); } else { v.Error(T.hdmx_NumDeviceRecords, E.hdmx_E_NumDeviceRecords_neg, m_tag, NumberDeviceRecords.ToString()); bNumDeviceRecordsOk = false; bRet = false; } } bool bSizeOk = true; if (v.PerformTest(T.hdmx_SizeofDeviceRecord)) { if ((SizeofDeviceRecord & 3) != 0) { v.Error(T.hdmx_SizeofDeviceRecord, E.hdmx_E_SizeofDeviceRecord_alignment, m_tag, SizeofDeviceRecord.ToString()); bSizeOk = false; bRet = false; } uint CalculatedSizeofDeviceRecord = CalculateSizeofDeviceRecord(numGlyphs); if (SizeofDeviceRecord != CalculatedSizeofDeviceRecord) { string s = "actual = " + SizeofDeviceRecord + ", calc = " + CalculatedSizeofDeviceRecord; v.Error(T.hdmx_SizeofDeviceRecord, E.hdmx_E_SizeofDeviceRecord_numGlyphs, m_tag, s); bSizeOk = false; bRet = false; } if (bSizeOk) { v.Pass(T.hdmx_SizeofDeviceRecord, P.hdmx_P_SizeofDeviceRecord, m_tag, SizeofDeviceRecord.ToString()); } } bool bLengthOk = true; if (v.PerformTest(T.hdmx_TableLength)) { if (bNumDeviceRecordsOk) { uint CalculatedTableLength = 8 + (uint)NumberDeviceRecords * CalculateSizeofDeviceRecord(numGlyphs); if (GetLength() == CalculatedTableLength) { v.Pass(T.hdmx_TableLength, P.hdmx_P_TableLength, m_tag); } else { string s = "actual: " + GetLength() + ", calc: " + CalculatedTableLength; v.Error(T.hdmx_TableLength, E.hdmx_E_TableLength, m_tag, s); bLengthOk = false; bRet = false; } } else { v.Warning(T.hdmx_TableLength, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate table length"); } } if (v.PerformTest(T.hdmx_DeviceRecordPadBytesZero)) { if (bSizeOk && bLengthOk & bNumDeviceRecordsOk) { uint unpaddedLength = (uint)numGlyphs + 2; if ((unpaddedLength & 3) == 0) { v.Pass(T.hdmx_DeviceRecordPadBytesZero, P.hdmx_P_DeviceRecordPadBytes_none, m_tag); } else { bool bPadOk = true; if (NumberDeviceRecords > 1) { for (uint i = 0; i < NumberDeviceRecords; i++) { DeviceRecord dr = GetDeviceRecord(i, numGlyphs); for (uint j = 0; j < dr.GetNumPadBytes(); j++) { if (dr.GetPadByte(j) != 0) { bPadOk = false; break; } } } } if (bPadOk) { v.Pass(T.hdmx_DeviceRecordPadBytesZero, P.hdmx_P_DeviceRecordPadBytes_zero, m_tag); } else { v.Error(T.hdmx_DeviceRecordPadBytesZero, E.hdmx_E_DeviceRecordPadBytes_nonzero, m_tag); bRet = false; } } } else { v.Warning(T.hdmx_DeviceRecordPadBytesZero, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that device record padding bytes are zero"); } } if (v.PerformTest(T.hdmx_SortedOrder)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bSortOk = true; if (NumberDeviceRecords > 1) { DeviceRecord drCurr = GetDeviceRecord(0, numGlyphs); DeviceRecord drNext = null; for (uint i = 1; i < NumberDeviceRecords; i++) { drNext = GetDeviceRecord(i, numGlyphs); if (drCurr.PixelSize >= drNext.PixelSize) { bSortOk = false; break; } drCurr = drNext; } } if (bSortOk) { v.Pass(T.hdmx_SortedOrder, P.hdmx_P_SortedOrder, m_tag); } else { v.Error(T.hdmx_SortedOrder, E.hdmx_E_SortedOrder, m_tag); bRet = false; } } else { v.Warning(T.hdmx_SortedOrder, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that device records are in sorted order"); } } if (v.PerformTest(T.hdmx_DuplicateDeviceRecords)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bNoDup = true; if (NumberDeviceRecords > 1) { for (uint i = 0; i < NumberDeviceRecords - 1; i++) { DeviceRecord dr1 = GetDeviceRecord(i, numGlyphs); for (uint j = i + 1; j < NumberDeviceRecords; j++) { DeviceRecord dr2 = GetDeviceRecord(j, numGlyphs); if (dr1.PixelSize == dr2.PixelSize) { bNoDup = false; break; } } } } if (bNoDup) { v.Pass(T.hdmx_DuplicateDeviceRecords, P.hdmx_P_DuplicateDeviceRecords, m_tag); } else { v.Error(T.hdmx_DuplicateDeviceRecords, E.hdmx_E_DuplicateDeviceRecords, m_tag); bRet = false; } } else { v.Warning(T.hdmx_DuplicateDeviceRecords, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that there are no duplicate device records"); } } if (v.PerformTest(T.hdmx_Widths)) { if (bSizeOk && bLengthOk && bNumDeviceRecordsOk) { bool bWidthsOk = true; RasterInterf.DevMetricsData dmd = null; try { Version ver = fontOwner.GetFile().GetRasterizer().FTVersion; if (ver.CompareTo(new Version(2, 6, 1)) < 0) { v.Warning(T.hdmx_Widths, W.hdmx_W_Need_Newer_FreeType, m_tag, "Using FreeType Version " + ver + " may not get correct results for HDMX"); } dmd = fontOwner.GetCalculatedDevMetrics(); } catch (Exception e) { v.ApplicationError(T.hdmx_Widths, E._Table_E_Exception, m_tag, e.Message); bRet = false; } if (dmd != null) { for (uint i = 0; i < NumberDeviceRecords; i++) { DeviceRecord dr = GetDeviceRecord(i, numGlyphs); for (uint iGlyph = 0; iGlyph < numGlyphs; iGlyph++) { if (dr.GetWidth(iGlyph) != dmd.hdmxData.Records[i].Widths[iGlyph]) { String sDetails = "rec " + i + ", PixelSize " + dr.PixelSize + ", glyph# " + iGlyph + ", width = " + dr.GetWidth(iGlyph) + ", calc = " + dmd.hdmxData.Records[i].Widths[iGlyph]; v.Error(T.hdmx_Widths, E.hdmx_E_Widths, m_tag, sDetails); bWidthsOk = false; bRet = false; } } } if (bWidthsOk) { v.Pass(T.hdmx_Widths, P.hdmx_P_Widths, m_tag); } } else { // if user didn't cancel, then check for error message if (!v.CancelFlag) { String sDetails = null; try { sDetails = fontOwner.GetDevMetricsDataError(); } catch (Exception e) { v.ApplicationError(T.hdmx_Widths, E._Table_E_Exception, m_tag, e.Message); } Debug.Assert(sDetails != null); v.Error(T.hdmx_Widths, E.hdmx_E_Rasterizer, m_tag, sDetails); bRet = false; } } } else { v.Warning(T.hdmx_Widths, W._TEST_W_OtherErrorsInTable, m_tag, "unable to validate that the widths are correct"); } } return(bRet); }