/************************ * 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); }
protected ArrayList m_groups; // VDMXGroupCache[] // constructor public VDMX_cache(Table_VDMX OwnerTable) { m_version = OwnerTable.version; m_numRecs = OwnerTable.numRecs; m_numRatios = OwnerTable.numRatios; m_ratRange = new ArrayList(m_numRatios); m_groups = new ArrayList(m_numRecs); // Used to detrmine which vdmx goes with which ratio ushort[] VDMXOffsets = new ushort[m_numRecs]; VDMXOffsets[0] = (ushort)(Table_VDMX.FieldOffsets.ratRange + (m_numRatios * 4) + (m_numRatios * 2)); // Fill in the VDMX groups for (ushort i = 0; i < m_numRecs; i++) { VDMXGroupCache vgc = new VDMXGroupCache(); vgc.recs = OwnerTable.GetVdmxGroup(i).recs; vgc.startsz = OwnerTable.GetVdmxGroup(i).startsz; vgc.endsz = OwnerTable.GetVdmxGroup(i).endsz; for (ushort ii = 0; ii < vgc.recs; ii++) { Vdmx.vTable vt = OwnerTable.GetVdmxGroup(i).GetEntry(ii); vgc.addVTableRecordCache(ii, vt.yPelHeight, vt.yMax, vt.yMin); } m_groups.Add(vgc); if (i < (m_numRecs - 1)) { VDMXOffsets[i + 1] = (ushort)(VDMXOffsets[i] + 4 + (vgc.recs * 6)); } } // Fill in the ratios for (ushort i = 0; i < m_numRatios; i++) { RatioCache rc = new RatioCache(); rc.bCharSet = OwnerTable.GetRatioRange(i).bCharSet; rc.xRatio = OwnerTable.GetRatioRange(i).xRatio; rc.yStartRatio = OwnerTable.GetRatioRange(i).yStartRatio; rc.yEndRatio = OwnerTable.GetRatioRange(i).yEndRatio; // Go through each of the offsets I saved above and match with this ratios offset // When we find the right one save this group to this ratio // later when we save the buffer we will redetermine these offsets for (ushort ii = 0; ii < m_numRatios; ii++) { if (VDMXOffsets[ii] == OwnerTable.GetVdmxGroupOffset(i)) { rc.VDMXGroupThisRatio = ii; break; } } m_ratRange.Add(rc); } }