diff options
Diffstat (limited to 'Build/source/libs/graphite/test/RegressionTest')
30 files changed, 5741 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/test/RegressionTest/GrJustifier.cpp b/Build/source/libs/graphite/test/RegressionTest/GrJustifier.cpp new file mode 100644 index 00000000000..566811c9907 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/GrJustifier.cpp @@ -0,0 +1,566 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2003 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: GrJustifier.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + A default justification agent for Graphite. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +//:>******************************************************************************************** +//:> Include files +//:>******************************************************************************************** +//#include "main.h" // This is used by clients, so main.h is not available + +#pragma hdrstop +// any other headers (not precompiled) +#include "GrClient.h" +#include "ITextSource.h" +#include "IGrJustifier.h" +#include "GraphiteProcess.h" +#include "GrDebug.h" + +#include "GrJustifier.h" + +#ifdef WIN32 +#include <string> +#endif + +#undef THIS_FILE +DEFINE_THIS_FILE + +//:>******************************************************************************************** +//:> Global constants +//:>******************************************************************************************** + +const int g_cnPrimes = 7; +static const int g_rgnPrimes[] = +{ + 2, 3, 5, 7, 11, 13, 17, // these primes will allow a range of weights up to 255 + // 19, 23, 31, 37, 41, 43, 47, 53, 59, 61 +}; + +//:>******************************************************************************************** +//:> Forward declarations +//:>******************************************************************************************** + +//:>******************************************************************************************** +//:> Methods +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Constructors. +----------------------------------------------------------------------------------------------*/ +GrJustifier::GrJustifier() +{ + m_cref = 1; // COM-like behavior +} + + +/*---------------------------------------------------------------------------------------------- + Destructor. +----------------------------------------------------------------------------------------------*/ +GrJustifier::~GrJustifier() +{ +} + +/*---------------------------------------------------------------------------------------------- + Determine how to adjust the widths of the glyphs to get a justified effect. + Return kresFalse if we can't achieve the desired width. +----------------------------------------------------------------------------------------------*/ +gr::GrResult GrJustifier::adjustGlyphWidths(gr::GraphiteProcess * pgje, + int iGlyphMin, int iGlyphLim, + float dxCurrentWidthArg, float dxDesiredWidthArg) +{ + if (dxCurrentWidthArg == dxDesiredWidthArg) + return gr::kresOk; // no stretch needed + + int dxCurrentWidth = (int)dxCurrentWidthArg; + int dxDesiredWidth = (int)dxDesiredWidthArg; + + bool fShrinking = (dxDesiredWidth < dxCurrentWidth); + + // First, get the relevant values for each glyph out of the Graphite engine. + + int dxsStretchAvail = 0; + std::vector<int> viGlyphs; + std::vector<int> vdxStretchLeft; + std::vector<int> vdxStep; + std::vector<int> vnWeight; + std::vector<int> vdxWidth; + std::vector<int> vdxStretchOrig; + bool fStep = false; + int nMaxWt = 1; + int cUnits = 0; // glyph-weight units + int cStretchable = 0; + for (int iGlyph = iGlyphMin; iGlyph < iGlyphLim; iGlyph++) + { + int dx; + pgje->getGlyphAttribute(iGlyph, + (fShrinking ? gr::kjgatShrink : gr::kjgatStretch), 1, &dx); + if (dx > 0) + { + int dxStep = 0; + pgje->getGlyphAttribute(iGlyph, gr::kjgatStep, 1, &dxStep); + if (fShrinking) + dxStep = (dxStep > 0) ? 0 : dxStep; // step is applicable if it is negative + else // stretching + dxStep = (dxStep < 0) ? 0 : dxStep; // step is applicable if it is positive + if (dxStep != 0) + { + // Get the actual number of steps allowed. This is more accurate than + // trying to calculate it, due to rounding when converting between + // font units and pixels. + int cSteps; + pgje->getGlyphAttribute(iGlyph, gr::kjgatStretchInSteps, 1, &cSteps); + dx = abs(dxStep * cSteps); + fStep = true; + } + dxStep = abs(dxStep); + + int nWt; + pgje->getGlyphAttribute(iGlyph, gr::kjgatWeight, 1, &nWt); + nWt = max(nWt, 0); + nMaxWt = max(nMaxWt, nWt); + + viGlyphs.push_back(iGlyph); + vdxStretchLeft.push_back(dx); + vdxStep.push_back(dxStep); + vnWeight.push_back(nWt); + vdxWidth.push_back(0); + vdxStretchOrig.push_back(dx); + + dxsStretchAvail += dx; + cUnits += nWt; + cStretchable++; + } + } + + int dxStretchNeeded = dxDesiredWidth - dxCurrentWidth; + if (fShrinking) + dxStretchNeeded *= -1; // always a positive number + int dxStretchAchieved = 0; + bool fIgnoreStepGlyphs = false; + int iiGlyph; + std::vector<int> vnMFactor; + + if (viGlyphs.size() > 0) + { + + // The way weights are handled is the following: we calculate the least common multiple + // of all the weights, and then scale each stretch value accordingly before distributing + // widths. In other words, we put the stretch values into an alternate "common" scaled + // system based on the LCM. "cUnits" represents the total number of stretch-units + // available, where each glyph contributes a number of units equal to its weight. + // To get into this scaled system, small-weight stretches are scaled by a large amount + // and large-weight stretches are scaled by a small amount. After assigning the width, + // we do the reverse scaling on that width. Since large-weight stretches are scaled + // back by less, this results in more width being assigned to glyphs with a large weight. + + int nLcm = 1; + if (nMaxWt > 1) + nLcm = Lcm(vnWeight, vnMFactor); + else + { + vnMFactor.push_back(1); // weight 0 - bogus + vnMFactor.push_back(1); // weight 1 + } + + // Loop over the glyphs until we have assigned all the available space. (If a small amount + // is left over it will be distributed using a special method.) + +LMainLoop: + + int dxStretchStillNeeded = dxStretchNeeded - dxStretchAchieved; + int dxNonStepMore = 0; + int dxNonStepLess = 0; + while (cUnits > 0 && dxStretchStillNeeded >= cStretchable) + // && dxStretchStillNeeded * nLcm >= cUnits) + { + // This is the scaled stretch per glyph, that is, in the scaled system of the LCM. + int dxwStretchPerGlyph = dxStretchStillNeeded * nLcm / cUnits; + + // Recalculate these for the next round: + cUnits = 0; + cStretchable = 0; + + for (iiGlyph = 0; iiGlyph < (signed)viGlyphs.size(); iiGlyph++) + { + if (vdxStep[iiGlyph] > 0 && fIgnoreStepGlyphs) + continue; // leave step-glyphs as they are + + int nWt = vnWeight[iiGlyph]; + int dxwThis = vdxStretchLeft[iiGlyph] * vnMFactor[nWt]; // weighted stretch + dxwThis = min(dxwStretchPerGlyph, dxwThis); + int dxThis = dxwThis / vnMFactor[nWt]; // scale back to unweighted stretch + vdxWidth[iiGlyph] += dxThis; + dxStretchAchieved += dxThis; + vdxStretchLeft[iiGlyph] -= dxThis; + if (vdxStretchLeft[iiGlyph] > 0) + { + cUnits += nWt; // can do some more on the next round + cStretchable++; + } + + // Keep track of how much we could adjust in either direction + // on the second round to handle steps. + if (vdxStep[iiGlyph] == 0) + { + dxNonStepMore += vdxStretchOrig[iiGlyph] - vdxWidth[iiGlyph]; + dxNonStepLess += vdxWidth[iiGlyph]; + } + } + dxStretchStillNeeded = dxStretchNeeded - dxStretchAchieved; + } + + Assert(dxStretchAchieved <= dxStretchNeeded); + + // Make adjustments so that the step values are honored. + + if (fStep // there are some step-glyphs + && !fIgnoreStepGlyphs) // and we didn't already do this + { + // First make some basic adjustments, alternating making more and fewer steps + // and see how much that buys us. + int dxAdjusted = 0; + int cNonStepUnits = 0; + int cStretchableNonStep = 0; + bool fReloop = false; + for (iiGlyph = 0; iiGlyph < (signed)viGlyphs.size(); iiGlyph++) + { + if (vdxStep[iiGlyph] > 1) + { + int dxRem = vdxWidth[iiGlyph] % vdxStep[iiGlyph]; + int dxFewer = vdxWidth[iiGlyph] - dxRem; // round down + int dxMore = dxFewer + vdxStep[iiGlyph]; // round up + int dxAdd = dxMore - vdxWidth[iiGlyph]; + if (dxRem == 0) + { // Step is okay; no adjustment needed. + } + else if ( + // this glyph has stretch available to make more steps: + (dxMore <= vdxStretchOrig[iiGlyph]) + // and we need at least this much extra: + && (dxAdd + dxStretchAchieved <= dxStretchNeeded) + // and we still have enough slack in the non-step-glyphs: + && (dxNonStepLess - dxAdjusted - dxAdd > 0) + // and we don't have to adjust much to get to the next step + // (we're 75% of the way there): + && ((dxRem > ((vdxStep[iiGlyph] * 3) << 2)) + // or this glyph has a high weight: + || (vnWeight[iiGlyph] > (nMaxWt >> 2)) + // or we've removed a fair amount already: + || (dxAdjusted < (dxAdd * -2)) + // or we don't have enough slack to remove more: + || (dxNonStepMore + dxAdjusted - dxRem < 0))) + { + // Use the next larger number of steps. + vdxWidth[iiGlyph] += dxAdd; + dxStretchAchieved += dxAdd; + dxAdjusted += dxAdd; + fReloop = true; + } + else + { + // Use the next smaller number of steps. + vdxWidth[iiGlyph] -= dxRem; + dxStretchAchieved -= dxRem; + dxAdjusted -= dxRem; + fReloop = true; + } + } + else if (vdxStep[iiGlyph] == 0) + { + cNonStepUnits += vnWeight[iiGlyph]; + cStretchableNonStep++; + } + } + + if (cNonStepUnits < cUnits || cStretchableNonStep < cStretchable) + { + // Even if no step-glyphs need to be adjusted, there is a different number + // of (non-step) glyphs to divide the space over. (The first time through + // there may not have been enough space per glyph to run the main loop, + // but now there may be.) + fReloop = true; + } + + // Any left over adjustments need to be made by adjusting the items with + // step = 1 (ie, the glyphs that allow fine-grained adjustments). + // Do the main loop again, but only adjust the non-step glyphs. + if (fReloop) + { + cUnits = cNonStepUnits; + cStretchable = cStretchableNonStep; + fIgnoreStepGlyphs = true; + goto LMainLoop; + } + } + + // Divide up any remainder that is due to rounding errors. + + int dxRemainder = dxStretchNeeded - dxStretchAchieved; + if (0 < dxRemainder && dxRemainder < cStretchable) + { + if (cStretchable < (signed)viGlyphs.size() || fStep) + { + // Make sub-lists using the glyphs that are still stretchable. + std::vector<int> vdxStretchRem; + std::vector<int> vdxWidthRem; + std::vector<int> viiGlyphsRem; + for (iiGlyph = 0; iiGlyph < (signed)viGlyphs.size(); iiGlyph++) + { + if (vdxStretchLeft[iiGlyph] > 0 && vdxStep[iiGlyph] == 0) + { + viiGlyphsRem.push_back(iiGlyph); + vdxStretchRem.push_back(vdxStretchLeft[iiGlyph]); + vdxWidthRem.push_back(vdxWidth[iiGlyph]); + } + } + Assert(viiGlyphsRem.size() == size_t(cStretchable)); + DistributeRemainder(vdxWidthRem, vdxStretchRem, dxRemainder, 0, vdxWidthRem.size(), + &dxStretchAchieved); + for (int iiiGlyph = 0; iiiGlyph < cStretchable; iiiGlyph++) + { + int iiGlyph = viiGlyphsRem[iiiGlyph]; + vdxStretchLeft[iiGlyph] = vdxStretchRem[iiiGlyph]; + vdxWidth[iiGlyph] = vdxWidthRem[iiiGlyph]; + } + } + else + { + // All glyphs are still stretchable. + DistributeRemainder(vdxWidth, vdxStretchLeft, dxRemainder, 0, vdxWidth.size(), + &dxStretchAchieved); + } + } + // otherwise we assume left-over is cannot be handled + + // Assign the widths to the glyphs. + + for (iiGlyph = 0; iiGlyph < (signed)viGlyphs.size(); iiGlyph++) + { + int dxThis = vdxWidth[iiGlyph] * ((fShrinking) ? -1 : 1); + if (vdxStep[iiGlyph] == 0) + pgje->setGlyphAttribute(viGlyphs[iiGlyph], gr::kjgatWidth, 1, dxThis); + else + { + // Set the actual number of steps allowed. This is more accurate than + // setting the pixels and then converting to font em-units. + Assert(int(dxThis) % vdxStep[iiGlyph] == 0); // width divides evenly into steps + int cSteps = dxThis/vdxStep[iiGlyph]; + pgje->setGlyphAttribute(viGlyphs[iiGlyph], gr::kjgatWidthInSteps, 1, cSteps); + } + } + } +//LLeave: + + if (dxStretchAchieved == dxStretchNeeded) + return gr::kresOk; + else + { +#ifdef WIN32 + wchar_t rgchw[20]; + std::fill_n(rgchw, 20, 0); + _itow(dxStretchNeeded - dxStretchAchieved, rgchw, 10); + std::wstring strTmp(L"justification failed by "); + strTmp += rgchw; + strTmp += L" units (width needed = "; + std::fill_n(rgchw, 10, 0); + _itow(dxDesiredWidth, rgchw, 10); + strTmp += rgchw; + strTmp += L")\n"; + OutputDebugString(strTmp.c_str()); +#else + Assert(fprintf(stderr, + "justification failed by %d units (width needed = %d)\n", + dxStretchNeeded - dxStretchAchieved, dxDesiredWidth)); +#endif + return gr::kresFalse; + } +} + +/*---------------------------------------------------------------------------------------------- + Distribute the remainder of the width evenly over the stretchable glyphs. +----------------------------------------------------------------------------------------------*/ +void GrJustifier::DistributeRemainder(std::vector<int> & vdxWidths, std::vector<int> & vdxStretch, + int dx, int iiMin, int iiLim, + int * pdxStretchAchieved) +{ + if (dx == 0) + return; + + Assert(dx <= iiLim - iiMin); + if (iiMin + 1 == iiLim) + { + int dxThis = min(dx, vdxStretch[iiMin]); + Assert(dxThis == 1); // we're never adjusting by more than 1, and the glyph should be + // adjustable by that much + vdxWidths[iiMin] += dxThis; + vdxStretch[iiMin] -= dxThis; + *pdxStretchAchieved += dxThis; + } + else + { + int iiMid = (iiLim + iiMin) / 2; + int dxHalf1 = dx / 2; + int dxHalf2 = dx - dxHalf1; + DistributeRemainder(vdxWidths, vdxStretch, dxHalf1, iiMin, iiMid, pdxStretchAchieved); + DistributeRemainder(vdxWidths, vdxStretch, dxHalf2, iiMid, iiLim, pdxStretchAchieved); + } +} + +/*---------------------------------------------------------------------------------------------- + Return the least common multiple of the given weights. Also return + a std::vector of multiplicative factors for each weight. +----------------------------------------------------------------------------------------------*/ +int GrJustifier::Lcm(std::vector<int> & vnWeights, std::vector<int> & vnMFactors) +{ + // The basic algorithm is to factor each weight into primes, counting how many times + // each prime occurs in the factorization. The LCM is the multiple of the primes + // with each prime raised to maximum power encountered within the factorizations. + // Example: weights = [2, 4, 5, 10] + // 2 = 2^1 + // 4 = 2^2 + // 5 = 5^1 + // 10 = 2^1 * 5^1 + // So the LCM = 2^2 * 5^1 = 20. + + std::vector<int> vnPowersForLcm; + int inPrime; + for (inPrime = 0; inPrime < g_cnPrimes; inPrime++) + vnPowersForLcm.push_back(0); + + std::vector<int> vnPowersPerPrime; + vnPowersPerPrime.resize(g_cnPrimes); + int nWtMax = 1; + for (int inWt = 0; inWt < (signed)vnWeights.size(); inWt++) + { + int inMax = PrimeFactors(vnWeights[inWt], vnPowersPerPrime); + for (inPrime = 0; inPrime <= inMax; inPrime++) + vnPowersForLcm[inPrime] = max(vnPowersForLcm[inPrime], vnPowersPerPrime[inPrime]); + nWtMax = max(nWtMax, vnWeights[inWt]); + } + + int nLcm = 1; + for (inPrime = 0; inPrime < g_cnPrimes; inPrime++) + nLcm = nLcm * NthPower(g_rgnPrimes[inPrime], vnPowersForLcm[inPrime]); + + // For each weight, calculate the multiplicative factor. This is the value by which + // to multiply stretch values of this weight in order to get them properly proportioned. + // Note that weights that are not used will have bogus factors. + vnMFactors.push_back(nLcm); // bogus, for weight 0 + for (int nWt = 1; nWt <= nWtMax; nWt++) + { + vnMFactors.push_back(nLcm / nWt); + } + return nLcm; +} + +/*---------------------------------------------------------------------------------------------- + Return a std::vector indicating the prime factors of n. The values of the std::vector correspond + to the primes in g_rgnPrimes: [2, 3, 5, 7, ...]; they are the powers to which each + prime should be raised. For instance, 20 = 2^2 * 5^1, so the result would contain + [2, 0, 1, 0, 0, ...]. + The returned int is index of the highest prime in the list that we found. +----------------------------------------------------------------------------------------------*/ +int GrJustifier::PrimeFactors(int n, std::vector<int> & vnPowersPerPrime) +{ + // Short-cut for common cases: + switch (n) + { + case 0: + case 1: + vnPowersPerPrime[0] = 0; + return 0; + case 2: + vnPowersPerPrime[0] = 1; // 2^1 + return 0; + case 3: + vnPowersPerPrime[0] = 0; + vnPowersPerPrime[1] = 1; // 3^1 + return 1; + case 4: + vnPowersPerPrime[0] = 2; // 2^2 + return 0; + case 5: + vnPowersPerPrime[0] = 0; + vnPowersPerPrime[1] = 0; + vnPowersPerPrime[2] = 1; // 5^1 + return 2; + case 6: + vnPowersPerPrime[0] = 1; // 2^1 + vnPowersPerPrime[1] = 1; // 3^1 + return 1; + case 7: + vnPowersPerPrime[0] = 0; + vnPowersPerPrime[1] = 0; + vnPowersPerPrime[2] = 0; + vnPowersPerPrime[3] = 1; // 7^1 + return 3; + case 8: + vnPowersPerPrime[0] = 3; // 2^3 + return 0; + case 9: + vnPowersPerPrime[0] = 0; + vnPowersPerPrime[1] = 2; // 3^2 + return 1; + case 10: + vnPowersPerPrime[0] = 1; // 2^1 + vnPowersPerPrime[1] = 0; + vnPowersPerPrime[2] = 1; // 5^1 + return 2; + default: + break; + } + + // Otherwise use the general algorithm: suck out prime numbers one by one, + // keeping track of how many we have of each. + + int inPrime; + for (inPrime = 0; inPrime < g_cnPrimes; inPrime++) + vnPowersPerPrime[inPrime] = 0; + + int nRem = n; + for (inPrime = 0; inPrime < g_cnPrimes; inPrime++) + { + while (nRem % g_rgnPrimes[inPrime] == 0) + { + vnPowersPerPrime[inPrime] += 1; + nRem = nRem / g_rgnPrimes[inPrime]; + } + if (nRem == 1) + break; + } + Assert(n > 255 || nRem == 1); + return inPrime; +} + +/*---------------------------------------------------------------------------------------------- + Return nX raised to the nY power. +----------------------------------------------------------------------------------------------*/ +int GrJustifier::NthPower(int nX, int nY) +{ + int nRet = 1; + for (int i = 0; i < nY; i++) + nRet *= nX; + return nRet; +} + +/*---------------------------------------------------------------------------------------------- + Determine how much shrinking is possible for low-end justification. +----------------------------------------------------------------------------------------------*/ +//GrResult GrJustifier::suggestShrinkAndBreak(GraphiteProcess * pgje, +// int iGlyphMin, int iGlyphLim, int dxsWidth, LgLineBreak lbPref, LgLineBreak lbMax, +// int * pdxShrink, LgLineBreak * plbToTry) +//{ +// *pdxShrink = 0; +// *plbToTry = lbPref; +// return kresOk; +//} + diff --git a/Build/source/libs/graphite/test/RegressionTest/GrJustifier.h b/Build/source/libs/graphite/test/RegressionTest/GrJustifier.h new file mode 100644 index 00000000000..ea5fc21bec9 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/GrJustifier.h @@ -0,0 +1,82 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2003 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: GrJustifier.h +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + A default justification agent for Graphite. +-------------------------------------------------------------------------------*//*:End Ignore*/ +#pragma once +#ifndef GRJUSTIFIER_INCLUDED +#define GRJUSTIFIER_INCLUDED + +/*---------------------------------------------------------------------------------------------- + Class: GrJustifier + This class provides a basic justification/layout algorithm for applications that use + Graphite. +----------------------------------------------------------------------------------------------*/ +class GrJustifier : public gr::IGrJustifier +{ +public: + // Constructor: + GrJustifier(); + ~GrJustifier(); + +/* + virtual long IncRefCount(void) + { + return InterlockedIncrement(&m_cref); + } + virtual long DecRefCount(void) + { + long cref = InterlockedDecrement(&m_cref); + if (cref == 0) { + m_cref = 1; + delete this; + } + return cref; + } +*/ + + virtual gr::GrResult adjustGlyphWidths(gr::GraphiteProcess * pfgje, + int iGlyphMin, int iGlyphLim, + float dxCurrWidth, float dxDesiredWidth); + + //virtual GrResult suggestShrinkAndBreak(GraphiteProcess * pfgjwe, + // int iGlyphMin, int iGlyphLim, int dxsWidth, LgLineBreak lbPref, LgLineBreak lbMax, + // int * pdxShrink, LgLineBreak * plbToTry); + + // Return a Graphite-compatible justifier that can be stored in a Graphite segment. + // TODO: remove + //virtual void JustifierObject(IGrJustifier ** ppgjus) + //{ + // *ppgjus = this; + //} + + // When a segment is being destroyed, there is nothing to do, since this is a pointer + // to an object that is allocated elsewhere. + // TODO: remove + //virtual void DeleteJustifierPtr() + //{ + //} + +protected: + long m_cref; + + gr::GraphiteProcess * m_pgreng; + + void DistributeRemainder(std::vector<int> & vdxWidths, std::vector<int> & vdxStretch, + int dx, int iiMin, int iiLim, + int * pdxStretchAchieved); + int Lcm(std::vector<int> & vnWeights, std::vector<int> & vnMFactors); + int PrimeFactors(int n, std::vector<int> & vnPowersPerPrime); + int NthPower(int nX, int nY); +}; + + +#endif // !GRJUSTIFIER_INCLUDED diff --git a/Build/source/libs/graphite/test/RegressionTest/Makefile.am b/Build/source/libs/graphite/test/RegressionTest/Makefile.am new file mode 100644 index 00000000000..fe59b65fbaa --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/Makefile.am @@ -0,0 +1,38 @@ +AUTOMAKE_OPTIONS = 1.6 + +EXTRA_DIST = \ + burmeseText.wpx \ + romanText.wpx \ + xlineText.wpx \ + grtest_arabic.ttf \ + grtest_badVersion.ttf \ + grtest_badCmap.ttf \ + grtest_burmese.ttf \ + grtest_roman.ttf \ + grtest_taiviet.ttf \ + grtest_xline.ttf \ + xline.gdl \ + Makefile.vc \ + makedebug.bat \ + readme.txt + +noinst_PROGRAMS = regression-test + +AM_CPPFLAGS = -I$(top_srcdir)/include/graphite + +regression_test_LDFLAGS = -L$(top_builddir)/src -lgraphite + +regression_test_SOURCES = \ + main.h \ + stdafx.cpp stdafx.h \ + RegressionTest.cpp \ + TestCase.cpp TestCase.h \ + RtTextSrc.h \ + SimpleTextSrc.cpp SimpleTextSrc.h \ + GrJustifier.cpp GrJustifier.h + +check-local: regression-test + $(top_builddir)/test/RegressionTest/regression-test -p $(srcdir) + +dist-hook: + rm -f grregtest.log tracelog.txt diff --git a/Build/source/libs/graphite/test/RegressionTest/Makefile.in b/Build/source/libs/graphite/test/RegressionTest/Makefile.in new file mode 100644 index 00000000000..547e7dfa408 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/Makefile.in @@ -0,0 +1,478 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = regression-test$(EXEEXT) +subdir = test/RegressionTest +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_regression_test_OBJECTS = stdafx.$(OBJEXT) RegressionTest.$(OBJEXT) \ + TestCase.$(OBJEXT) SimpleTextSrc.$(OBJEXT) \ + GrJustifier.$(OBJEXT) +regression_test_OBJECTS = $(am_regression_test_OBJECTS) +regression_test_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(regression_test_SOURCES) +DIST_SOURCES = $(regression_test_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LSB_RELEASE = @LSB_RELEASE@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +REL_CODENAME = @REL_CODENAME@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIZEOF_WCHAR_T = @SIZEOF_WCHAR_T@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +AUTOMAKE_OPTIONS = 1.6 +EXTRA_DIST = \ + burmeseText.wpx \ + romanText.wpx \ + xlineText.wpx \ + grtest_arabic.ttf \ + grtest_badVersion.ttf \ + grtest_badCmap.ttf \ + grtest_burmese.ttf \ + grtest_roman.ttf \ + grtest_xline.ttf \ + xline.gdl \ + Makefile.vc \ + makedebug.bat \ + readme.txt + +AM_CPPFLAGS = -I$(top_srcdir)/include/graphite +regression_test_LDFLAGS = -L$(top_builddir)/src -lgraphite +regression_test_SOURCES = \ + main.h \ + stdafx.cpp stdafx.h \ + RegressionTest.cpp \ + TestCase.cpp TestCase.h \ + RtTextSrc.h \ + SimpleTextSrc.cpp SimpleTextSrc.h \ + GrJustifier.cpp GrJustifier.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/RegressionTest/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/RegressionTest/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +regression-test$(EXEEXT): $(regression_test_OBJECTS) $(regression_test_DEPENDENCIES) + @rm -f regression-test$(EXEEXT) + $(CXXLINK) $(regression_test_LDFLAGS) $(regression_test_OBJECTS) $(regression_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GrJustifier.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegressionTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SimpleTextSrc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestCase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdafx.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + dist-hook distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am + + +check-local: regression-test + $(top_builddir)/test/RegressionTest/regression-test -p $(srcdir) + +dist-hook: + rm -f grregtest.log tracelog.txt +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Build/source/libs/graphite/test/RegressionTest/Makefile.vc b/Build/source/libs/graphite/test/RegressionTest/Makefile.vc new file mode 100644 index 00000000000..ff75d7e9e16 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/Makefile.vc @@ -0,0 +1,121 @@ +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +TARGET=RegressionTest +REGT_SRC=. +REGT_RES=. +REGT_APPLIB=..\..\..\examples\applib + + +!IF "$(CFG)" == "" +CFG=DEBUG +!ENDIF + +!IF "$(CFG)" == "RELEASE" + +OUTDIR=.\release +INTDIR=.\release_temp + +all : "$(OUTDIR)\$(TARGET).exe" + +clean : + @- rd /s/q $(INTDIR) + +realclean : clean + @- rd /s/q $(OUTDIR) + +CPP_PROJ=/nologo /MT /W3 /GR /GX /O2 /I "." /I "../../examples/applib" /I "../../include" /I "../../include/graphite" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /c +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\$(TARGET).res" /d "NDEBUG" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib graphite.lib /nologo /subsystem:console /incremental:no /machine:I386 /out:"$(OUTDIR)\$(TARGET).exe" /libpath:"..\..\release" +BSC32_FLAGS=/nologo /o"$(OUTDIR)\$(TARGET).bsc" + +!ELSEIF "$(CFG)" == "DEBUG" + +OUTDIR=.\debug +INTDIR=.\debug_temp + +all : "$(OUTDIR)\$(TARGET).exe" "$(OUTDIR)\$(TARGET).bsc" + +clean : + @- rd /s/q $(INTDIR) + +realclean : clean + @- rd /s/q $(OUTDIR) + +CPP_PROJ=/nologo /MTd /W3 /Gm /GR /GX /GZ /ZI /Od /I "." /I "../../examples/applib" /I "../../include" /I "../../include/graphite" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /c +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\$(TARGET).res" /d "_DEBUG" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib graphite.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\$(TARGET).pdb" /debug /machine:I386 /out:"$(OUTDIR)\$(TARGET).exe" /libpath:"..\..\debug" +BSC32_FLAGS=/nologo /o"$(OUTDIR)\$(TARGET).bsc" + +!ENDIF + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +{$(REGT_SRC)}.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +{$(REGT_SRC)}.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +{$(REGT_APPLIB)}.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +{$(REGT_APPLIB)}.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + + + +CPP=cl.exe +RSC=rc.exe +BSC32=bscmake.exe +LINK32=link.exe + +LINK32_OBJS= \ + "$(INTDIR)\RegressionTest.obj" \ + "$(INTDIR)\TestCase.obj" \ + "$(INTDIR)\GrJustifier.obj" \ + "$(INTDIR)\SimpleTextSrc.obj" \ + +# "$(INTDIR)\RegressionTest.res" + +"$(OUTDIR)\$(TARGET).exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +BSC32_SBRS= \ + "$(INTDIR)\RegressionTest.sbr" \ + "$(INTDIR)\TestCase.sbr" \ + "$(INTDIR)\GrJustifier.sbr" \ + "$(INTDIR)\SimpleTextSrc.sbr" \ +# + +"$(OUTDIR)\$(TARGET).bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +"$(INTDIR)\RegressionTest.obj" "$(INTDIR)\RegressionTest.sbr" : "$(REGT_SRC)\RegressionTest.cpp" "$(INTDIR)" +"$(INTDIR)\TestCase.obj" "$(INTDIR)\TestCase.sbr" : "$(REGT_SRC)\TestCase.cpp" "$(INTDIR)" +"$(INTDIR)\GrJustifier.obj" "$(INTDIR)\GrJustifier.sbr" : "$(REGT_APPLIB)\GrJustifier.cpp" "$(INTDIR)" +"$(INTDIR)\SimpleTextSrc.obj" "$(INTDIR)\SimpleTextSrc.sbr" : "$(REGT_APPLIB)\SimpleTextSrc.cpp" "$(INTDIR)" + + +"$(INTDIR)\$(TARGET).res" : "$(REGT_RES)\$(TARGET).rc" "$(INTDIR)" + $(RSC) $(RSC_PROJ) "$(REGT_RES)\$(TARGET).rc" + diff --git a/Build/source/libs/graphite/test/RegressionTest/RegressionTest.cpp b/Build/source/libs/graphite/test/RegressionTest/RegressionTest.cpp new file mode 100644 index 00000000000..1d361a4f3cd --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/RegressionTest.cpp @@ -0,0 +1,748 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2004 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: RegressionTest.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Main file for the Graphite regression test program. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +#include "main.h" +#include "MemoryUsage.h" +#include <cstring> + +//:>******************************************************************************************** +//:> Global variables +//:>******************************************************************************************** +std::ofstream g_strmLog; // log file output stream +std::ofstream g_strmTrace; // debugger trace for selected tests +std::ofstream g_strmMemUsage; + +int g_errorCount; + +// HDC g_hdc; // device-context for bogus window on which to do drawing + +bool g_debugMode = false; +bool g_silentMode = false; + +int g_itcaseStart = 0; // adjust to skip to a certain test + +SegmentMemoryUsage g_smu; +FontMemoryUsage g_fmu; + +std::string g_fontPath = "."; +#ifdef _WIN32 +#define PATH_SEP "\\" +#else +#define PATH_SEP "/" +#endif + +// Forward defintions. +int WriteLog(int); +void CopyWstringToUtf16(std::wstring textStr, gr::utf16 * utf16Buf, int bufSize); + +//:>******************************************************************************************** +//:> Functions +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Main function. +----------------------------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ +#ifdef _WIN32 + _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); +#endif // WIN32 + + int iargc = 1; + while (iargc < argc) + { + if ((strcmp(argv[iargc], "/d") == 0) || (strcmp(argv[iargc], "-d") == 0)) + { + g_debugMode = true; + } + if ((strcmp(argv[iargc], "/s") == 0) || (strcmp(argv[iargc], "-s") == 0)) + { + g_silentMode = true; + } + if ((strcmp(argv[iargc], "/p") == 0) || (strcmp(argv[iargc], "-p") == 0)) + { + iargc++; + if (iargc < argc) + { + g_fontPath = argv[iargc]; + } + } + iargc++; + } + + if (!g_silentMode) + { + std::cout << "Graphite Regression Test\n"; + std::cout << "Files path is " << g_fontPath << "\n\n"; + if (g_debugMode) + std::cout << "In debug mode\n"; + } + + // Start a new log. + g_strmLog.open("grregtest.log"); + if (g_strmLog.fail()) + { + std::cout << "Unable to open log file."; + return -1; + } + + g_errorCount = 0; + +// g_hdc = ::GetDC(NULL); + + WriteToLog("Graphite Regression Test\n\n"); + + // Initialize the tracelog file. + g_strmTrace.open("tracelog.txt"); + g_strmTrace.close(); + + TestCase * ptcaseList = NULL; + int numberOfTests = TestCase::SetupTests(&ptcaseList); + + RunTests(numberOfTests, ptcaseList); + + WriteToLog("\n==============================================\n"); + g_strmLog << "\n\nTOTAL NUMBER OF ERRORS: " << g_errorCount << "\n"; + if (!g_silentMode) + std::cout << "\n\nTOTAL NUMBER OF ERRORS: " << g_errorCount << "\n"; + + g_strmLog.close(); + + ////EngineInstance::DeleteEngines(); + TestCase::DeleteTests(); + +// ::ReleaseDC(NULL, g_hdc); + + // Output segment memory usage information. + //g_strmMemUsage.open("SegMemoryUsage.log"); + //g_smu.prettyPrint(g_strmMemUsage); + //g_strmMemUsage.close(); + + return g_errorCount; +} + +/*---------------------------------------------------------------------------------------------- + Run the tests. +----------------------------------------------------------------------------------------------*/ +void RunTests(int numberOfTests, TestCase * ptcaseList) +{ + Segment * psegPrev = NULL; + RtTextSrc * ptsrcPrev = NULL; + Segment * psegRet = NULL; + RtTextSrc * ptsrcRet = NULL; + + for (int itcase = g_itcaseStart; itcase < numberOfTests; itcase++) + { + TestCase * ptcase = ptcaseList + itcase; + WriteToLog("\n----------------------------------------------\n"); + WriteToLog("Test: "); + + if (!g_silentMode) + std::cout << "Test " << ptcase->TestName() << "..."; + WriteToLog(ptcase->TestName()); + WriteToLog("\n"); + + RunOneTestCase(ptcase, psegPrev, &psegRet, &ptsrcRet); + + delete psegPrev; + delete ptsrcPrev; + psegPrev = psegRet; + ptsrcPrev = ptsrcRet; + psegRet = NULL; + ptsrcRet = NULL; + } + + delete psegPrev; + delete ptsrcPrev; +} + +/*---------------------------------------------------------------------------------------------- + Run a single test case. +----------------------------------------------------------------------------------------------*/ +int RunOneTestCase(TestCase * ptcase, Segment * psegPrev, Segment ** ppsegRet, RtTextSrc ** pptsrcRet) +{ + if (ptcase->Skip()) + { + std::cout << "\nskipped\n"; + g_strmLog << "skipping\n"; + *ppsegRet = NULL; + return 0; + } + +#ifdef _WIN32 + // Break into the debugger if requested. + if (ptcase->RunDebugger() && ::IsDebuggerPresent()) + { + ::DebugBreak(); + } +#endif + + int errorCount = 0; + + gr::utf16 text[1024]; + CopyWstringToUtf16(ptcase->Text(), text, 1024); + + *ppsegRet = NULL; + SegmentPainter * ppainter = NULL; + std::pair<GlyphIterator, GlyphIterator> iterPair; + GlyphIterator gitBegin; + GlyphIterator gitEnd; + + //LOGFONT lf; + //memset(&lf, '\0', sizeof(LOGFONT)); + //lf.lfCharSet = DEFAULT_CHARSET; + //lf.lfHeight = (signed(ptcase->FontSize()) * -96) / 72; // 96 = resolution, 72 = points per inch + //lf.lfWeight = 400; + //lf.lfItalic = FALSE; + //wcscpy(lf.lfFaceName, ptcase->FontName().data()); + //HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + //HFONT hfont = CreateFontIndirect(&lf); + //HFONT hfontOld = (HFONT)::SelectObject(hdc, hfont); // restore before destroying the DC. + //WinFont winfont(hdc); + + FileFont font(g_fontPath + PATH_SEP + ptcase->FontFile(), float(signed(ptcase->FontSize())), 96, 96); + + if (!font.isValid()) + { + OutputError(ptcase, std::string("ERROR: reading font file: \"") + ptcase->FontFile() + "\" at path \"" + g_fontPath + "\"; remaining tests skipped"); + *ppsegRet = NULL; + errorCount++; + return WriteLog(errorCount); + } + + // Set up the text source. + *pptsrcRet = new RtTextSrc(&(text[0])); + RtTextSrc * ptsrc = *pptsrcRet; + (*pptsrcRet)->setFeatures(ptcase->Features()); + (*pptsrcRet)->setRightToLeft(ptcase->Rtl()); + + // Generate a segment. + LayoutEnvironment layout; + layout.setDumbFallback(ptcase->DumbFallback()); + layout.setStartOfLine(true); + layout.setRightToLeft(ptcase->ParaRtl()); + if (ptcase->InitWithPrevSeg()) + layout.setPrevSegment(psegPrev); + + if (ptcase->TraceLog()) + { + g_strmTrace.open("tracelog.txt", std::ios::app); + g_strmTrace << "Test: " << ptcase->TestName() << "\n\n"; + layout.setLoggingStream(&g_strmTrace); + } + + try + { + if (ptcase->AvailWidth() < 10000) + { + layout.setBestBreak(ptcase->PrefBreak()); + layout.setWorstBreak(ptcase->WorstBreak()); + layout.setTrailingWs(ptcase->Twsh()); + *ppsegRet = new LineFillSegment(&font, ptsrc, &layout, + ptcase->FirstChar(), ptsrc->getLength(), + (float)ptcase->AvailWidth(), + ptcase->Backtrack()); + } + else + { + *ppsegRet = new RangeSegment(&font, ptsrc, &layout); + } + } + catch (...) + { + if (!ptcase->NoSegment()) + { + if (ptcase->BadFont() && !ptcase->DumbFallback()) + // Weird situation. + OutputError(ptcase, "ERROR: bad font with no fallback, yet a segment was expected???"); + else + OutputError(ptcase, "ERROR: generating segment; remaining tests skipped"); + errorCount++; + } + // else segment creation failed as expected + + // NB: failure to create a segment due to throwing an exception seems to result in a memory + // leak--the FontCache object FontFace::s_pFontCache does not get deleted. + + *ppsegRet = NULL; + return WriteLog(errorCount); + } + + if (ptcase->TraceLog()) + { + g_strmTrace << "\n\n*********************************************************************************************************************\n\n"; + g_strmTrace.close(); + } + + if ((*ppsegRet) && (*ppsegRet)->segmentTermination() == kestNothingFit) + { + delete *ppsegRet; + *ppsegRet = NULL; + } + + if ((*ppsegRet) == NULL && !ptcase->NoSegment()) + { + OutputError(ptcase, "ERROR: segment not created; remaining tests skipped"); + errorCount++; + return WriteLog(errorCount); + } + else if (ptcase->NoSegment()) + { + if (*ppsegRet) + { + OutputError(ptcase, "ERROR: segment created when none expected"); + errorCount++; + } + delete *ppsegRet; + *ppsegRet = NULL; + return WriteLog(errorCount); + } + + Segment * pseg = *ppsegRet; + + pseg->calculateMemoryUsage(g_smu); + + // Calculate and output font memory usage. + //g_fmu = Font::calculateMemoryUsage(); + //g_strmMemUsage.open("fontMemoryUsage.log"); + //g_fmu.prettyPrint(g_strmMemUsage); + //g_strmMemUsage.close(); + + // Test results. + int segMin = pseg->startCharacter(); + int segLim = pseg->stopCharacter(); + if ((segLim - segMin) != ptcase->CharCount()) + { + OutputErrorWithValues(ptcase, "ERROR: number of characters in segment", -1, + (segLim - segMin), ptcase->CharCount()); + errorCount++; + } + + int segWidth = (int)pseg->advanceWidth(); + if (segWidth != ptcase->SegWidth()) + { + OutputErrorWithValues(ptcase, "ERROR: width of segment", -1, + segWidth, ptcase->SegWidth()); + errorCount++; + } + + iterPair = pseg->glyphs(); + gitBegin = iterPair.first; + gitEnd = iterPair.second; + int cGlyphs = gitEnd - gitBegin; + if (cGlyphs != ptcase->GlyphCount()) + { + OutputErrorWithValues(ptcase, "ERROR: number of glyphs", -1, + cGlyphs, ptcase->GlyphCount()); + errorCount++; + } + else + { + GlyphIterator gitThis = gitBegin; + for (int iglyph = 0; gitThis != gitEnd; ++gitThis, iglyph++) + { + if ((*gitThis).glyphID() != ptcase->GlyphID(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph id ", iglyph, + (*gitThis).glyphID(), ptcase->GlyphID(iglyph)); + errorCount++; + } + if (int((*gitThis).origin()) != ptcase->XPos(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph x-position ", iglyph, + int((*gitThis).origin()), ptcase->XPos(iglyph)); + errorCount++; + } + if (int((*gitThis).yOffset()) != ptcase->YPos(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph y-position ", iglyph, + int((*gitThis).yOffset()), ptcase->YPos(iglyph)); + errorCount++; + } + if (int((*gitThis).advanceWidth()) != ptcase->AdvWidth(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: advance width ", iglyph, + int((*gitThis).advanceWidth()), ptcase->AdvWidth(iglyph)); + errorCount++; + } + if (ptcase->BbTests()) + { + gr::Rect rectBb = (*gitThis).bb(); + if (int(rectBb.left) != ptcase->BbLeft(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb left ", iglyph, + int(rectBb.left), ptcase->BbLeft(iglyph)); + errorCount++; + } + if (int(rectBb.right) != ptcase->BbRight(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb right ", iglyph, + int(rectBb.right), ptcase->BbRight(iglyph)); + errorCount++; + } + if (int(rectBb.top) != ptcase->BbTop(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb top ", iglyph, + int(rectBb.top), ptcase->BbTop(iglyph)); + errorCount++; + } + if (int(rectBb.bottom) != ptcase->BbBottom(iglyph)) + { + OutputErrorWithValues(ptcase, "ERROR: bb bottom ", iglyph, + int(rectBb.bottom), ptcase->BbBottom(iglyph)); + errorCount++; + } + } + } + } + + ppainter = new SegmentNonPainter(pseg); + + if (segLim == ptcase->CharCount()) + { + for (int ichar = 0; ichar < segLim; ichar++) + { + LgIpValidResult ipvr = ppainter->isValidInsertionPoint(ichar); + if ((ipvr == kipvrOK && !ptcase->InsPtFlag(ichar)) // TODO: handle kipvrUnknown + || (ipvr != kipvrOK && ptcase->InsPtFlag(ichar))) + { + OutputErrorWithValues(ptcase, "ERROR: valid insertion point ", ichar, + (ipvr == kipvrOK), ptcase->InsPtFlag(ichar)); + errorCount++; + } + } + } + + int c2gi = 0; + while (c2gi < ptcase->CharToGlyphCount()) + { + int ichar = ptcase->CharToGlyphItem(c2gi++); + int glyphCount = ptcase->CharToGlyphItem(c2gi++); + std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyphSet = pseg->charToGlyphs(ichar); + gr::GlyphSetIterator gitStart = glyphSet.first; + gr::GlyphSetIterator gitStop = glyphSet.second; + if ((gitStop - gitStart) != glyphCount) + { + OutputErrorWithValues(ptcase, "ERROR: number of glyphs for char ", ichar, + gitStop - gitStart, glyphCount); + errorCount++; + c2gi += glyphCount; + } + else + { + GlyphSetIterator glyphLp = glyphSet.first; + for (int ig = 0; ig < glyphCount; ig++) + { + if (static_cast<int>((*glyphLp).logicalIndex()) != ptcase->CharToGlyphItem(c2gi)) + { + OutputErrorWithValues(ptcase, "ERROR: glyph for char ", ichar, + (*glyphLp).logicalIndex(), ptcase->CharToGlyphItem(c2gi)); + errorCount++; + } + c2gi++; + glyphLp++; + } + } + } + + int att = 0; + while (att < ptcase->AttachedGlyphCount()) + { + int iglyph = ptcase->AttachedGlyphItem(att++); + if (iglyph > cGlyphs) + { + OutputError(ptcase, "ERROR: non-existent glyph in attachment test ", iglyph); + errorCount++; + att++; + att += ptcase->AttachedGlyphItem(att) + 1; + continue; + } + + GlyphIterator gitThis = gitBegin + iglyph; + GlyphIterator gitBase = gitThis->attachedClusterBase(); + int ibase = gitBase->logicalIndex(); + if (ibase != ptcase->AttachedGlyphItem(att)) + { + OutputErrorWithValues(ptcase, "ERROR: attachment base for glyph ", iglyph, + ibase, ptcase->AttachedGlyphItem(att)); + errorCount++; + } + att++; + std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyphSet = gitThis->attachedClusterGlyphs(); + gr::GlyphSetIterator gitStart = glyphSet.first; + gr::GlyphSetIterator gitStop = glyphSet.second; + int glyphCount = ptcase->AttachedGlyphItem(att++); + if ((gitStop - gitStart) != glyphCount) + { + OutputErrorWithValues(ptcase, "ERROR: number of attachments for glyph ", iglyph, + gitStop - gitStart, glyphCount); + errorCount++; + att += glyphCount; + } + else + { + GlyphSetIterator glyphLp = glyphSet.first; + for (int ig = 0; ig < glyphCount; ig++) + { + if (static_cast<int>((*glyphLp).logicalIndex()) != ptcase->AttachedGlyphItem(att)) + { + OutputErrorWithValues(ptcase, "ERROR: attachment for glyph ", iglyph, + (*glyphLp).logicalIndex(), ptcase->AttachedGlyphItem(att)); + errorCount++; + } + att++; + glyphLp++; + } + } + } + + for (int iclicktest = 0; iclicktest < ptcase->NumberOfClickTests(); iclicktest++) + { + gr::Point ptClick; + ptClick.x = static_cast<float>(ptcase->XClick(iclicktest)); + ptClick.y = static_cast<float>(ptcase->YClick(iclicktest)); + int charIndex; + bool assocPrev; + ppainter->pointToChar(ptClick, &charIndex, &assocPrev); + if (charIndex != ptcase->ClickCharIndex(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: char index from click ", iclicktest, + charIndex, ptcase->ClickCharIndex(iclicktest)); + errorCount++; + continue; + } + if (assocPrev != ptcase->ClickAssocPrev(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: assoc-prev from click ", iclicktest, + assocPrev, ptcase->ClickAssocPrev(iclicktest)); + errorCount++; + } + gr::Rect rect1, rect2; + ppainter->positionsOfIP(charIndex, assocPrev, + false, &rect1, &rect2); + if (ptcase->Sel1Top(iclicktest) == TestCase::kAbsent) + { + if (rect1.top != 0 || rect1.bottom != 0 || rect1.left != 0 || rect1.right != 0) + { + OutputError(ptcase, "ERROR: IP prim rect found ", iclicktest); + errorCount++; + } + } + else if (rect1.top == 0 && rect1.bottom == 0 && rect1.left == 0 && rect1.right == 0) + { + OutputError(ptcase, "ERROR: IP prim rect not found ", iclicktest); + errorCount++; + } + else + { + if ((int)rect1.top != ptcase->Sel1Top(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect top ", iclicktest, + int(rect1.top), ptcase->Sel1Top(iclicktest)); + errorCount++; + } + if ((int)rect1.bottom != ptcase->Sel1Bottom(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect bottom ", iclicktest, + int(rect1.bottom), ptcase->Sel1Bottom(iclicktest)); + errorCount++; + } + if ((int)rect1.left != ptcase->Sel1Left(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP prim rect left ", iclicktest, + int(rect1.left), ptcase->Sel1Left(iclicktest)); + errorCount++; + } + } + + if (ptcase->Sel2Top(iclicktest) == TestCase::kAbsent) + { + if (rect2.top != 0 || rect2.bottom != 0 || rect2.left != 0 || rect2.right != 0) + { + OutputError(ptcase, "ERROR: IP sec rect found when not expected ", iclicktest); + errorCount++; + } + } + else if (rect2.top == 0 && rect2.bottom == 0 && rect2.left == 0 && rect2.right == 0) + { + OutputError(ptcase, "ERROR: IP sec rect not found ", iclicktest); + errorCount++; + } + else + { + if ((int)rect2.top != ptcase->Sel2Top(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect top ", iclicktest, + int(rect2.top), ptcase->Sel2Top(iclicktest)); + errorCount++; + } + if ((int)rect2.bottom != ptcase->Sel2Bottom(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect bottom ", iclicktest, + int(rect2.bottom), ptcase->Sel2Bottom(iclicktest)); + errorCount++; + } + if ((int)rect2.left != ptcase->Sel2Left(iclicktest)) + { + OutputErrorWithValues(ptcase, "ERROR: IP sec rect left ", iclicktest, + int(rect2.left), ptcase->Sel2Left(iclicktest)); + errorCount++; + } + } + } + + ////if (contextBlockOut != ptcase->OutputContextBlockSize()) + ////{ + //// OutputErrorWithValues(ptcase, "ERROR: output context block size ", -1, + //// (int)contextBlockOut, (int)ptcase->OutputContextBlockSize()); + //// errorCount++; + ////} + ////else if (!ptcase->CompareContextBlock(pContextBlockOut)) + ////{ + //// OutputError(ptcase, "ERROR: output context block"); + //// errorCount++; + ////} + delete ppainter; + + return WriteLog(errorCount); +} + + +/*---------------------------------------------------------------------------------------------- + Write the error count to the log. +----------------------------------------------------------------------------------------------*/ +int WriteLog(int errorCount) +{ + WriteToLog("\nError count = "); + WriteToLog(errorCount); + WriteToLog("\n"); + + if (!g_silentMode) + { + if (errorCount == 0) + std::cout << "ok\n"; + else + std::cout << "FAILED\n"; + } + + + //delete pseg; // don't delete these; they are passed back to the calling method + //delete ptsrc; + + // Delete device context + //DeleteObject(SelectObject(hdc, hfontOld)); + //DeleteDC(hdc); + + g_errorCount += errorCount; + return errorCount; +} + +/*---------------------------------------------------------------------------------------------- + Copy a std::wstring (whose bytes can be of various sizes on different platforms) + to a buffer of UTF16. +----------------------------------------------------------------------------------------------*/ +void CopyWstringToUtf16(std::wstring textStr, gr::utf16 * utf16Buf, int bufSize) +{ + std::fill_n(utf16Buf, bufSize, 0); + int cc = textStr.length(); + for (int i = 0; i < cc; i++) + utf16Buf[i] = textStr[i]; +} + +/*---------------------------------------------------------------------------------------------- + Output information about an error. +----------------------------------------------------------------------------------------------*/ +void OutputError(TestCase * ptcase, std::string strErr, int i) +{ + OutputErrorAux(ptcase, strErr, i, false, 0, 0); +} + +void OutputErrorWithValues(TestCase * ptcase, std::string strErr, int i, + int valueFound, int valueExpected) +{ + OutputErrorAux(ptcase, strErr, i, true, valueFound, valueExpected); +} + +void OutputErrorAux(TestCase * ptcase, std::string strErr, int i, + bool showValues, int valueFound, int valueExpected) +{ +// if (g_debugMode) +// ::DebugBreak(); + + if (!g_silentMode) + { + //std::cout << ptcase->TestName() << ": "; + std::cout << strErr; + if (i > -1) + { + std::cout << "[" << i << "]"; + } + std::cout << "\n "; + } + + WriteToLog(strErr, i, showValues, valueFound, valueExpected); + + WriteToLog("\n"); +} + +/*---------------------------------------------------------------------------------------------- + Write some text to the log file. +----------------------------------------------------------------------------------------------*/ +bool WriteToLog(std::string str, int i) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << str; + if (i > -1) + g_strmLog << "[" << i << "]"; + g_strmLog.flush(); + return true; +} + +bool WriteToLog(std::string str, int i, + bool showValues, int valueFound, int valueExpected) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << str; + if (i > -1) + g_strmLog << "[" << i << "]"; + if (showValues) + { + g_strmLog << "; found " << valueFound << " not " << valueExpected; + } + g_strmLog.flush(); + return true; +} + + +bool WriteToLog(int n) +{ + if (g_strmLog.fail()) + { + std::cout << "Error opening log file."; + return false; + } + g_strmLog << n; + g_strmLog.flush(); + return true; +} + diff --git a/Build/source/libs/graphite/test/RegressionTest/RtTextSrc.h b/Build/source/libs/graphite/test/RegressionTest/RtTextSrc.h new file mode 100644 index 00000000000..cdbd51e90df --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/RtTextSrc.h @@ -0,0 +1,74 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence.
+Copyright (C) 1999, 2001 SIL International. All rights reserved.
+
+Distributable under the terms of either the Common Public License or the
+GNU Lesser General Public License, as specified in the LICENSING.txt file.
+
+File: RtTextSrc.h
+Responsibility: Sharon Correll
+Last reviewed: Not yet.
+
+Description:
+
+-------------------------------------------------------------------------------*//*:End Ignore*/
+#pragma once
+#ifndef RTTXTSRC_INCLUDED
+#define RTTXTSRC_INCLUDED
+
+#include <cstring>
+
+/*----------------------------------------------------------------------------------------------
+ Class: RtTextSrc
+ This class extends the SimpleTextSource to allow setting of features.
+----------------------------------------------------------------------------------------------*/
+class RtTextSrc : public SimpleTextSrc
+{
+public:
+ RtTextSrc(gr::utf16 * pszText) : SimpleTextSrc(pszText)
+ {
+ m_fRtl = false;
+ memset(m_fset, 0, MAXFEAT * sizeof(FeatureSetting));
+ }
+
+ void setFeatures(FeatureSetting * fset)
+ {
+ m_cFeats = 0;
+ for (int i = 0; i < MAXFEAT; i++)
+ {
+ if (fset[i].id > 0)
+ {
+ m_fset[i].id = fset[i].id;
+ m_fset[i].value = fset[i].value;
+ m_cFeats++;
+ }
+ }
+ }
+
+ virtual size_t getFontFeatures(toffset ich, FeatureSetting * prgfset)
+ {
+ // Note: size of prgfset buffer = gr::kMaxFeatures = 64
+ std::copy(m_fset, m_fset + MAXFEAT, prgfset);
+ return m_cFeats;
+ }
+
+ virtual bool getRightToLeft(toffset ich)
+ {
+ return m_fRtl;
+ }
+ virtual unsigned int getDirectionDepth(toffset ich)
+ {
+ return ((m_fRtl == 1) ? 1 : 0);
+ }
+ void setRightToLeft(bool f)
+ {
+ m_fRtl = f;
+ }
+
+protected:
+ bool m_fRtl;
+ int m_cFeats;
+ FeatureSetting m_fset[MAXFEAT];
+};
+
+
+#endif // !RTTXTSRC_INCLUDED
diff --git a/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.cpp b/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.cpp new file mode 100644 index 00000000000..c50799c96bc --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.cpp @@ -0,0 +1,93 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 1999, 2001 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: SimpleTextSrc.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + A simple text source that shows how to use this interface within Graphite. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +//:>******************************************************************************************** +//:> Include files +//:>******************************************************************************************** +#pragma hdrstop +// any other headers (not precompiled) + +#include "GrClient.h" +#include "GrDebug.h" +#include "ITextSource.h" +#include "SimpleTextSrc.h" + +#undef THIS_FILE +DEFINE_THIS_FILE + +//:>******************************************************************************************** +//:> Initialization and destruction +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Constructors. +----------------------------------------------------------------------------------------------*/ +SimpleTextSrc::SimpleTextSrc(gr::utf16 * pszText) +{ + m_cref = 1; // COM-like behavior + + //m_cchLength = wcslen(pszText); // don't use wcslen, it's not cross-platform + m_cchLength = 0; + for (gr::utf16 * pch = pszText; *pch != 0; pch++) + m_cchLength++; + m_prgchText = new gr::utf16[m_cchLength + 1]; + std::copy(pszText, pszText + m_cchLength, m_prgchText); + m_prgchText[m_cchLength] = 0; // zero-terminate +} + +/*---------------------------------------------------------------------------------------------- + Destructor. +----------------------------------------------------------------------------------------------*/ +SimpleTextSrc::~SimpleTextSrc() +{ + delete[] m_prgchText; +} + +//:>******************************************************************************************** +//:> Interface methods +//:>******************************************************************************************** +/*---------------------------------------------------------------------------------------------- + Get the specified range of text +----------------------------------------------------------------------------------------------*/ +size_t SimpleTextSrc::fetch(toffset ichMin, size_t cch, gr::utf16 * prgchwBuffer) +{ + size_t ichRet = min(cch, size_t(m_cchLength - ichMin)); + std::copy(m_prgchText + ichMin, m_prgchText+ichMin + ichRet, prgchwBuffer); + return ichRet; +} + +/*---------------------------------------------------------------------------------------------- + Return true if the text uses a right-to-left writing system. +----------------------------------------------------------------------------------------------*/ +bool SimpleTextSrc::getRightToLeft(toffset ich) +{ + return false; +} + +/*---------------------------------------------------------------------------------------------- + Return the depth of embedding of the writing system. +----------------------------------------------------------------------------------------------*/ +unsigned int SimpleTextSrc::getDirectionDepth(toffset ich) +{ + return 0; +} + +/*---------------------------------------------------------------------------------------------- + Return the vertical offset of the text. This simple implementation provides no + vertical offset. +----------------------------------------------------------------------------------------------*/ +float SimpleTextSrc::getVerticalOffset(toffset ich) +{ + return 0; +} diff --git a/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.h b/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.h new file mode 100644 index 00000000000..a5d191b4ac3 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/SimpleTextSrc.h @@ -0,0 +1,113 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 1999, 2001 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: SimpleTextSrc.h +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + A simple text source that shows how to use this interface within Graphite. +-------------------------------------------------------------------------------*//*:End Ignore*/ +#pragma once +#ifndef GRTXTSRC_INCLUDED +#define GRTXTSRC_INCLUDED + +using namespace gr; + +/*---------------------------------------------------------------------------------------------- + Class: SimpleTextSrc + This class provides a simple implementation for a text source for the Graphite engine. + There are no paragraph properties of interest and one set of character properties that + apply to the entire string. + + This class is a subclass of IColorTextSource so that it can be used by the + WinSegmentPainter class, which expects the getColors method to be defined. +----------------------------------------------------------------------------------------------*/ +class SimpleTextSrc : public IColorTextSource +{ +public: + // Constructor: + SimpleTextSrc(gr::utf16 * pszText); + ~SimpleTextSrc(); + +/* + virtual long IncRefCount(void) + { + return InterlockedIncrement(&m_cref); + } + virtual long DecRefCount(void) + { + long cref = InterlockedDecrement(&m_cref); + if (cref == 0) { + m_cref = 1; + delete this; + } + return cref; + } +*/ + // ------------------------------------------------------------------------------- + // Interface methods: + + virtual UtfType utfEncodingForm() + { + return kutf16; + } + virtual size_t getLength() + { + return m_cchLength; + } + virtual size_t fetch(toffset ichMin, size_t cch, utf32 * prgchBuffer) + { + throw; + } + virtual size_t fetch(toffset ichMin, size_t cch, gr::utf16 * prgchwBuffer); + virtual size_t fetch(toffset ichMin, size_t cch, utf8 * prgchsBuffer) + { + throw; + }; + + virtual bool getRightToLeft(toffset ich); + virtual unsigned int getDirectionDepth(toffset ich); + virtual float getVerticalOffset(toffset ich); + + virtual isocode getLanguage(toffset ich) + { + isocode ret; + ret.rgch[0] = 'e'; ret.rgch[1] = 'n'; ret.rgch[2] = 0; ret.rgch[3] = 0; + return ret; + } + + virtual std::pair<toffset, toffset> propertyRange(toffset ich) + { + std::pair<toffset, toffset> pairRet; + pairRet.first = 0; + pairRet.second = m_cchLength; + return pairRet; + } + + virtual size_t getFontFeatures(toffset ich, FeatureSetting * prgfset) + { + return 0; // no features in this simple implementation + } + virtual bool sameSegment(toffset ich1, toffset ich2) + { + return true; + } + + virtual void getColors(toffset ich, int * pclrFore, int * pclrBack) + { + *pclrFore = kclrBlack; + *pclrBack = kclrTransparent; + } + +protected: + long m_cref; + gr::utf16 * m_prgchText; + int m_cchLength; +}; + + +#endif // !GRTXTSRC_INCLUDED diff --git a/Build/source/libs/graphite/test/RegressionTest/TestCase.cpp b/Build/source/libs/graphite/test/RegressionTest/TestCase.cpp new file mode 100644 index 00000000000..c9696141c95 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/TestCase.cpp @@ -0,0 +1,1974 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2004 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: TestCase.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + File to set up test cases for the Graphite regression test program. + +How to add a test: + 1. Add the name of your test method to the class declaration in TestCase.h. + 2. Increment the g_numberOfTests constant in this file. + 3. Add a call to your test method in the SetupTests method in this file. + 4. Copy one of the existing test methods such as SetupSimpleTest and change the name + and data. + +Things that still need testing: + Ligatures (there is one small test of this) + Justification + Fake italic +-------------------------------------------------------------------------------*//*:End Ignore*/ + +#include "main.h" +#include <cstring> + +//:>******************************************************************************************** +//:> Test constants and methods +//:>******************************************************************************************** + +const int g_numberOfTests = 25; // *** increment as tests are added *** + +TestCase * g_ptcaseList; // list of test cases + +namespace gr { // and it was SC who got rid of the byte defn in GrPlatform.h! +typedef unsigned char byte; +} + + +/*---------------------------------------------------------------------------------------------- + Create the list of tests. +----------------------------------------------------------------------------------------------*/ +int TestCase::SetupTests(TestCase ** pptcaseList) +{ + g_ptcaseList = new TestCase[g_numberOfTests]; + int cptcase = 0; + + // The number of methods called here should equal g_numberOfTests above. + g_ptcaseList[0].SetupSimpleTest(); cptcase++; + g_ptcaseList[1].SetupSimpleBacktrackTest(); cptcase++; + g_ptcaseList[2].SetupSurrogateTest(); cptcase++; + g_ptcaseList[3].SetupBurmese1(); cptcase++; + g_ptcaseList[4].SetupBurmese2(); cptcase++; + g_ptcaseList[5].SetupBurmese3(); cptcase++; + g_ptcaseList[6].SetupBurmese4(); cptcase++; + g_ptcaseList[7].SetupRoman(); cptcase++; + g_ptcaseList[8].SetupRomanFeatures(); cptcase++; + g_ptcaseList[9].SetupStackingAndBridging(); cptcase++; + g_ptcaseList[10].SetupNoWhiteSpace(); cptcase++; + g_ptcaseList[11].SetupNoWhiteSpaceNoSeg(); cptcase++; + g_ptcaseList[12].SetupOnlyWhiteSpace(); cptcase++; + g_ptcaseList[13].SetupCrossLine1(); cptcase++; + g_ptcaseList[14].SetupCrossLine2(); cptcase++; + g_ptcaseList[15].SetupCrossLine3(); cptcase++; + g_ptcaseList[16].SetupCrossLine4(); cptcase++; + g_ptcaseList[17].SetupArabic1(); cptcase++; + g_ptcaseList[18].SetupArabic2(); cptcase++; + g_ptcaseList[19].SetupTaiViet1(); cptcase++; + g_ptcaseList[20].SetupTaiViet2(); cptcase++; + g_ptcaseList[21].SetupDumbFallback1(); cptcase++; + g_ptcaseList[22].SetupDumbFallback2(); cptcase++; + g_ptcaseList[23].SetupBadFont(); cptcase++; + g_ptcaseList[24].SetupBugTest(); cptcase++; + // *** Add more method calls here. *** + + assert(cptcase == g_numberOfTests); + + *pptcaseList = g_ptcaseList; + + return g_numberOfTests; +} + +/*---------------------------------------------------------------------------------------------- + Set up a simple test. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupSimpleTest() +{ + m_testName = "Simple"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L"This is a test."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + // Output: + m_segWidth = 86; // physical width of segment + + const int charCnt = 15; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true + }; + + const int glyphCnt = 15; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {55, 75, 76, 86, 3, 76, 86, 3, 68, 3, 87, 72, 86, 87, 17}; + int xPositions[] = { 0, 9, 17, 22, 28, 33, 37, 43, 48, 55, 60, 64, 71, 77, 82}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 9, 8, 4, 6, 4, 4, 6, 4, 7, 4, 4, 7, 6, 4, 4}; + + int bbLefts[] = { 0, 9, 18, 22, 28, 33, 38, 43, 48, 55, 60, 65, 72, 78, 83}; + int bbRights[] = { 9, 17, 21, 27, 33, 37, 43, 48, 55, 60, 64, 71, 77, 82, 85}; + int bbTops[] = {10, 11, 10, 7, 0, 10, 7, 0, 7, 0, 9, 7, 7, 9, 1}; + int bbBottoms[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + int charsToGlyphs[] = { + 1, 1, 1, 2, 1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5, 6, 1, 6, 7, 1, 7 + }; + int c2gCount = 21; + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 3; + int clickStuff[] = { + 11, 25, 1, false, 0, 24, 8, kAbsent, kAbsent, kAbsent, // below baseline + 42, 5, 7, true, 0, 24, 42, kAbsent, kAbsent, kAbsent, // near top of text + 90, 16, 15, true, 0, 24, 85, kAbsent, kAbsent, kAbsent // near baseline + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetCharsToGlyphs(charsToGlyphs, c2gCount); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + Set up a simple test with backtracking. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupSimpleBacktrackTest() +{ + m_testName = "Simple Backtrack"; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L"This is a test."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = true; + + // Output: + m_segWidth = 55; // physical width of segment + + const int charCnt = 10; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true + }; + + const int glyphCnt = 10; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {55, 75, 76, 86, 3, 76, 86, 3, 68, 3}; + int xPositions[] = { 0, 9, 17, 22, 28, 33, 37, 43, 48, 55}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 9, 8, 4, 6, 4, 4, 6, 4, 7, 4}; + + const int contextBlockOutSize = 10; + gr::byte contextBlockOut[] = { 15, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +/*---------------------------------------------------------------------------------------------- + Set up a test that includes surrogates. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupSurrogateTest() +{ + m_testName = "Surrogates"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L"abXXcdYYe"; // text to render + m_text[2] = 0xD835; + m_text[3] = 0xDD13; + m_text[6] = 0xD835; + m_text[7] = 0xDD10; + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + // Output: + m_segWidth = 65; // physical width of segment + + const int charCnt = 9; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, false, true, true, true, false, true + }; + + const int glyphCnt = 7; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {68, 69,1227, 70, 71,1015, 72}; + int xPositions[] = { 0, 7, 15, 27, 34, 42, 58}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 7, 8, 12, 7, 8, 15, 7}; + + int bbLefts[] = { 0, 7, 15, 28, 35, 43, 59}; + int bbRights[] = { 7, 14, 26, 34, 42, 57, 65}; + int bbTops[] = { 7, 11, 10, 7, 11, 10, 7}; + int bbBottoms[] = { 0, 0, -3, 0, 0, 0, 0}; + + int charsToGlyphs[] = { + 0, 1, 0, 1, 1, 1, 2, 1, 2, 3, 0, 4, 1, 3, 5, 1, 4, 6, 1, 5, 7, 0, + 8, 1, 6, + }; + int c2gCount = 25; + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 3; + int clickStuff[] = { + 17, 25, 2, false, 0, 24, 14, kAbsent, kAbsent, kAbsent, // below baseline + 25, 5, 4, true, 0, 24, 26, kAbsent, kAbsent, kAbsent, // near top of text + 55, 16, 8, true, 0, 24, 57, kAbsent, kAbsent, kAbsent // near baseline + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetCharsToGlyphs(charsToGlyphs, c2gCount); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + A set of tests using Burmese, to test complex positioning and non-white-space + linebreaking. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupBurmese1() +{ + m_testName = "Burmese 1"; + m_debug = false; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Burmese"; + m_fontFile = "grtest_burmese.ttf"; + m_text = BurmeseText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 300; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_segWidth = 281; // physical width of segment + + SetupBurmeseAux( + 64, // character count + 45, // glyph count + 5); // number of click-tests + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,0, 1,1,0, 2,2,2,3,4, 3,2,0, 4,2,0, 5,5,1,6, 6,5,0, 7,7,3,8,9,10, + 8,7,0, 9,7,0, 10,7,0, 11,11,0, 12,12,0, 13,13,0, 14,14,0, 15,15,0, + 16,16,1,17, 17,16,0, 18,18,1,19, 19,18,0, 20,20,1,21, 21,20,0, 22,22,1,23, + 23,22,0, 24,24,0, 25,25,0 + }; + int attCount = sizeof(attachments) / sizeof(int); + SetAttachedClusters(attachments, attCount); + + const int contextBlockOutSize = 11; + gr::byte contextBlockOut[] = { 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupBurmese2() +{ + m_testName = "Burmese 2"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Burmese"; + m_fontFile = "grtest_burmese.ttf"; + + m_text = BurmeseText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 275; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_segWidth = 215; // physical width of segment + + SetupBurmeseAux( + 47, // character count + 33, // glyph count + 3); // number of click-tests + + const int contextBlockOutSize = 11; + gr::byte contextBlockOut[] = { 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupBurmese3() +{ + m_testName = "Burmese 3"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Burmese"; + m_fontFile = "grtest_burmese.ttf"; + + m_text = BurmeseText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 75; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_segWidth = 73; // physical width of segment + + SetupBurmeseAux( + 19, // character count + 13, // glyph count + 2); // number of click-tests + + const int contextBlockOutSize = 11; + gr::byte contextBlockOut[] = { 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupBurmese4() +{ + m_testName = "Burmese 4"; + //m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Burmese"; + m_fontFile = "grtest_burmese.ttf"; + + m_text = BurmeseText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWsBreak; // preferred break-weight + m_worstBreak = klbHyphenBreak; // worst-case break-weight + m_availWidth = 30; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_noSegment = true; + m_segWidth = 0; // physical width of segment + + SetupBurmeseAux( + 0, // character count + 0, // glyph count + 0); // number of click-tests +} + +void TestCase::SetupBurmeseAux(int charCnt, int glyphCnt, int clickTestCnt) +{ + m_rtl = false; + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, false, false, false, true, false, false, false, false, // 0 - 9 + true, false, false, true, false, false, false, true, true, true, // 10 - 19 + true, false, true, true, false, false, true, false, false, false, // 20 - 29 + false, true, false, false, true, false, false, false, true, true, // 30 - 39 + true, true, true, true, true, true, true, true, true, false, // 40 - 49 + true, true, true, false, false, false, true, false, false, true, // 50 - 59 + false, false, false, true + }; + + // need glyphCnt elements in these arrays: + // 0 10 20 30 40 + gid16 glyphList[] = {105,174,158,202,231,162,231,148,223,219,229,248, 3,226,162,173,216,231,177,195,115,231,170,204,243, 3,197,216,172,216, 3,233, 3,226,179,162,216,170,204,158,202,115,231,229, 3}; + int xPositions[] = { 0, 17, 20, 22, 28, 29, 38, 40, 50, 55, 56, 57, 73, 79, 89, 99,102,109,110,111,120,129,130,131,140,143,149,167,174,191,198,205,215,222,232,234,245,252,253,262,264,271,280,278,281}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 17, 2, 9, 4, 0, 10, 0, 17, 2, 0, 0, 15, 6, 10, 10, 2, 7, 0, 10, 9, 9, 0, 10, 7, 2, 6, 17, 7, 17, 7, 6, 10, 6, 10, 2, 10, 7, 10, 7, 9, 4, 9, 0, 0, 6}; + + int bbLefts[] = { 0, 10, 21, 23, 23, 30, 33, 41, 51, 49, 53, 58, 73, 80, 90, 96,100,103,111,109,121,123,131,132,141,143,150,165,175,189,198,206,215,223,233,235,243,253,254,263,265,272,275,275,281}; + int bbRights[] = { 16, 19, 28, 25, 28, 39, 38, 56, 54, 55, 56, 72, 79, 88, 98,101,109,109,119,119,129,129,139,138,142,149,166,173,190,197,205,214,222,231,244,244,251,261,260,271,267,280,280,278,288}; + int bbTops[] = { 7, 7, 7, -1, 15, 7, 15, 7, -1, 15, -2, 15, 0, 7, 7, 7, 7, 15, 7, -1, 7, 15, 7, -1, 7, 0, 7, 7, 7, 7, 0, 7, 0, 7, 16, 7, 7, 7, -1, 7, -1, 7, 15, -2, 0}; + int bbBottoms[] = { 0, -7, -1, -7, 9, 0, 9, 0, -7, 9, -5, 0, 0, 0, 0, -7, 0, 9, -4, -7, 0, 9, 0, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, -7, -1, -7, 0, 9, -5, 0}; + + // Each group = char-index, number of glyphs, glyph-indices. + int charsToGlyphs[] = { + 0, 1, 0, 1, 1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1, 5, 1, 2, 6, 1, 3, 7, 1, 3, + 8, 1, 4, 9, 1, 4, 10, 1, 5, 11, 1, 6, 12, 1, 6, 13, 1, 7 + }; + int c2gCount = sizeof(charsToGlyphs) / sizeof(int); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + int clickStuff[] = { + 10, 25, 1, true, 0, 25, 16, kAbsent, kAbsent, kAbsent, + 40, 5, 13, false, 0, 25, 39, kAbsent, kAbsent, kAbsent, + 93, 40, 19, false, 0, 25, 88, 0, 25, 77, + 251, 5, 52, true, 0, 25,251, kAbsent, kAbsent, kAbsent, + 235, 30, 48, false, -1, 27,230, 7, 19,243, + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetCharsToGlyphs(charsToGlyphs, c2gCount); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); +} + +std::wstring TestCase::BurmeseText() +{ + std::wstring strRet; + wchar_t charData[] = { + 0x1000, 0x1039, 0x101a, 0x1039, 0x101d, 0x1014, 0x1039, 0x101f, 0x1039, 0x200c, + 0x1015, 0x1039, 0x200c, 0x1010, 0x102f, 0x102d, 0x1037, 0x104f, 0x0020, 0x1015, + 0x1039, 0x101a, 0x1031, 0x102c, 0x1039, 0x200c, 0x101b, 0x1039, 0x101d, 0x1039, + 0x101f, 0x1004, 0x1039, 0x200c, 0x1019, 0x1039, 0x101f, 0x102f, 0x104a, 0x0020, + 0x101e, 0x102c, 0x101a, 0x102c, 0x0020, 0x1040, 0x0020, 0x1015, 0x1039, 0x101b, + 0x1031, 0x102c, 0x1019, 0x1039, 0x101f, 0x102f, 0x1014, 0x1039, 0x101f, 0x1004, + 0x1039, 0x200c, 0x1037, 0x0020, 0x1021, 0x1031, 0x102c, 0x1004, 0x1039, 0x200c, + 0x1019, 0x1039, 0x101b, 0x1004, 0x1039, 0x200c, 0x1019, 0x1039, 0x101f, 0x102f, + 0x1010, 0x102f, 0x102d, 0x1037, 0x101e, 0x100a, 0x1039, 0x200c, 0x0020, 0x1000, + 0x1039, 0x101a, 0x1039, 0x101d, 0x1014, 0x102f, 0x1039, 0x200c, 0x1015, 0x1039, + 0x200c, 0x1010, 0x102f, 0x102d, 0x1037, 0x104f, 0x0000 + }; + strRet.assign(charData); + return strRet; +} + +/*---------------------------------------------------------------------------------------------- + A set of tests using Roman script, which tests stacking diacritics, many-to-one glyphs, + and features. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupRoman() +{ + m_testName = "Roman"; + m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = RomanText(); // text to render + m_fontSize = 36; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + // Output: + m_segWidth = 278; // physical width of segment + + const int charCnt = 26; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true + }; + + const int glyphCnt = 24; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + // 0 10 20 + gid16 glyphList[] = {72,1815,1768, 83,1789, 86, 74,1943,1956,1926,1061, 68,1777,1755,805,1815, 44,1815, 80,1833,1768,1855,1838,637}; + int xPositions[] = { 0, 23, 23, 21, 41, 45, 64, 88, 98, 112, 116,148, 171, 171,170, 188,183, 203, 199, 230, 230, 230, 230,236}; + int yPositions[] = { 0, 0, 10, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 20, 0}; + int advWidths[] = {21, 0, 0, 24, 0, 18, 24, 13, 13, 4, 31, 21, 0, 0, 13, 0, 15, 0, 37, 0, 0, 0, 0, 41}; + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,2,1,2, 1,0,0, 2,0,0, 3,3,0, 4,4,0, 5,5,0, 6,6,0, 7,7,2,8,9, + 8,7,0, 9,7,0, 10,10,0, 11,11,2,12,13, 12,11,0, 13,11,0, 14,14,1,15, 15,14,0, + 16,16,1,17, 17,16,0, 18,18,4,19,20,21,22, 19,18,0, 20,18,0, 21,18,0, 22,18,0, + 23,23,0 + }; + int attCount = sizeof(attachments) / sizeof(int); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 5; + int clickStuff[] = { + 10, 15, 2, false, 9, 21, 1, 20, 30, 18, + 61, 50, 6, true, 0, 72, 63, kAbsent, kAbsent, kAbsent, + 90, 40, 7, false, 0, 72, 87, kAbsent, kAbsent, kAbsent, + 260, 40, 25, true, 0, 73,263, kAbsent, kAbsent, kAbsent, // ligature + 267, 40, 25, false, 0, 73,263, kAbsent, kAbsent, kAbsent, // ligature + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetAttachedClusters(attachments, attCount); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); +} + +void TestCase::SetupRomanFeatures() +{ + m_testName = "Roman Features"; + m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = RomanText(); // text to render + m_fontSize = 36; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + m_fset[0].id = 1024; m_fset[0].value = 2; // capital eng with tail + m_fset[1].id = 1026; m_fset[1].value = 1; // tone numbers + m_fset[2].id = 1029; m_fset[2].value = 1; // vietnamese diacritics + m_fset[3].id = 1032; m_fset[3].value = 1; // literacy alternates + m_fset[4].id = 1034; m_fset[4].value = 1; // y-hook alternate (default) + m_fset[5].id = 1051; m_fset[5].value = 0; // diacritic selection + m_fset[6].id = 0; + + // Output: + m_segWidth = 307; // physical width of segment + + const int charCnt = 26; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, false, false, true, true, true, true, true, true, true, + true, true, false, false, true, false, true, false, true, false, + false, false, false, true, true, true + }; + + const int glyphCnt = 23; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + // 0 10 20 + gid16 glyphList[] = {72,1815,1768, 83,1789, 86,681,1659,1667,1662,1056,274,1778, 805,1815, 44,1815, 80,1833,1768,1855,1838,637}; + int xPositions[] = { 0, 23, 23, 21, 41, 45, 64, 87, 104, 121, 138,173, 174, 198, 217, 211, 231, 227, 258, 258, 258, 258,265}; + int yPositions[] = { 0, 0, 10, 0, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 20, 0}; + int advWidths[] = {21, 0, 0, 24, 0, 18, 23, 17, 17, 17, 34, 24, 24, 13, 0, 15, 0, 37, 0, 0, 0, 0, 41}; + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 3; + int clickStuff[] = { + 10, 15, 3, true, 0, 72, 20, kAbsent, kAbsent, kAbsent, + 116, 5, 9, true, 0, 72, 120, kAbsent, kAbsent, kAbsent, + 90, 40, 7, false, 0, 72, 86, kAbsent, kAbsent, kAbsent + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); +} + +std::wstring TestCase::RomanText() +{ + std::wstring strRet; + wchar_t charData[] = { + 0x0065, 0x0303, 0x0300, 0x0070, 0x0361, 0x0073, 0x0067, 0x02e8, 0x02e5, 0x02e7, + 0x014a, 0x0061, 0x0302, 0x0301, 0x0069, 0x0303, 0x0049, 0x0303, 0x006d, 0x033c, + 0x0300, 0x0308, 0x0304, 0x0066, 0x0066, 0x0069, 0x0000 + }; + strRet.assign(charData); + return strRet; +} + +/*---------------------------------------------------------------------------------------------- + A set of tests for handling complex diacritic stacking and bridging. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupStackingAndBridging() +{ + m_testName = "Roman Stacking and Bridging"; + //m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_fontSize = 36; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + // text to render + wchar_t charData[] = { + 0x0061,0x035d,0x0061,0x0020,0x0074,0x035d,0x0061,0x0020,0x0061,0x0300, + 0x0300,0x035d,0x0061,0x0020,0x0283,0x0300,0x0300,0x035d,0x0061,0x0020, + 0x0061,0x0316,0x0316,0xf176,0x0061,0x0020,0x0283,0x0300,0x0300,0xf176, + 0x0061,0x0020,0x0061,0x0316,0x0316,0xf176,0x0061,0x0020,0x0283,0x035d, + 0xf176,0x0061,0x0000 + }; + m_text.assign(charData); + + // Output: + m_segWidth = 414; // physical width of segment + + const int charCnt = 42; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, + }; + + const int glyphCnt = 42; // number of glyphs in the segment + + // 68 = a, 97 = t, 1305 = esh, 1768 = upper grave, 1765 = lower grave, 1802 = upper bridge, + // 1801 = lower bridge + + // need glyphCnt elements in these arrays: + // 0 10 20 30 40 + gid16 glyphList[] = {68,1802, 68, 3, 87,1802, 68, 3, 68,1768,1768,1802, 68, 3,1305,1768,1768,1802, 68, 3, 68,1765,1765,1801, 68, 3,1305,1768,1768,1801, 68, 3, 68,1765,1765,1801, 68, 3,1305,1802,1801, 68}; + int xPositions[] = { 0, 21, 21, 42, 56, 73, 69, 91, 105, 127, 127, 126, 126,147, 161, 181, 181, 178,177,199,212, 235, 235, 234,234,255, 269, 289, 289, 286,285,307,320, 343, 343, 342,342,363, 377, 393, 393,393}; + int yPositions[] = { 0, -7, 0, 0, 0, -1, 0, 0, 0, 0, 10, 12, 0, 0, 0, 10, 20, 23, 0, 0, 0, 0, -9, -17, 0, 0, 0, 10, 20, -6, 0, 0, 0, 0, -9, -17, 0, 0, 0, 3, -6, 0}; + int advWidths[] = {21, 0, 21, 13, 13, 0, 21, 13, 21, 0, 0, 0, 21, 13, 16, 0, 0, 0, 21, 13, 21, 0, 0, 0, 21, 13, 16, 0, 0, 0, 21, 13, 21, 0, 0, 0, 21, 13, 16, 0, 0, 21}; + + int bbLefts[] = { 1, 0, 23, 42, 56, 52, 71, 91, 106, 108, 108, 105, 128,147, 159, 162, 162, 157,179,199,214, 217, 217, 213,235,255, 267, 270, 270, 265,287,307,322, 325, 325, 321,343,363, 375, 373, 373,395}; + int bbRights[] = {21, 41, 42, 56, 69, 93, 91,105, 126, 119, 119, 146, 147,161, 178, 173, 173, 198,199,212,234, 228, 228, 254,255,269, 286, 281, 281, 306,306,320,342, 336, 336, 362,363,377, 394, 413, 414,414}; + int bbTops [] = {22, 33, 22, 0, 28, 40, 22, 0, 22, 32, 42, 54, 22, 0, 33, 42, 53, 64, 22, 0, 22, -3, -13, -26, 22, 0, 33, 42, 53, -15, 22, 0, 22, -3, -13, -26, 22, 0, 33, 44, -15, 22}; + int bbBottoms [] = { 0, 26, 0, 0, 0, 33, 0, 0, 0, 24, 34, 47, 0, 0, -10, 34, 44, 57, 0, 0, 0, -11, -21, -32, 0, 0, -10, 34, 44, -21, 0, 0, 0, -11, -21, -32, 0, 0, -10, 38, -21, 0}; + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,0, 1,1,0, 2,2,0, 3,3,0, 4,4,0, 5,5,0, 6,6,0, 7,7,0, + 8,8,2,9,10, 9,8,0, 10,8,0, 11,11,0, 12,12,0, 13,13,0, 14,14,2,15,16, + 15,14,0, 16,14,0, 17,17,0, 18,18,0, 19,19,0, 20,20,2,21,22, 21,20,0, + 22,20,0, 23,23,0, 24,24,0, 25,25,0, 26,26,2,27,28, 27,26,0, 28,26,0, + 29,29,0, 30,30,0, 31,31,0, 32,32,2,33,34, 33,32,0, 34,32,0, 35,35,0, + 36,36,0, 37,37,0, 38,38,0, 39,39,0, 40,40,0, 41,41,0 + }; + int attCount = sizeof(attachments) / sizeof(int); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 6; + int clickStuff[] = { + 109, 25, 9, false, 19, 32, 105, 30, 56, 125, // first grave on 4th a + 178, 26, 15, true, 19, 66, 176, 9, 21, 159, // top of 1st esh, right side + 220, 84, 23, false, 78, 89, 210, 65, 77, 228, // first lower bridge diac + 271, 40, 26, false, 0, 72, 266, kAbsent, kAbsent, kAbsent, // second esh, left side + 271, 65, 26, false, 0, 72, 266, kAbsent, kAbsent, kAbsent, // just below second esh, left side + 271, 68, 29, false, 67, 78, 262, 0, 11, 280 // lower bridge diac under esh, left side + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetAttachedClusters(attachments, attCount); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + A set of tests for handling trailing whitespace. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupNoWhiteSpace() +{ + m_testName = "No white space"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L"The quick brown fox."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 150; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_twsh = ktwshNoWs; + m_paraRtl = true; + + // Output: + m_segWidth = 115; // physical width of segment + + const int charCnt = 16; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true + }; + + const int glyphCnt = 16; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {55, 75, 72, 3, 3, 84, 88, 76, 70, 78, 3, 69, 85, 82, 90, 81}; + int xPositions[] = { 0, 9, 17, 24, 29, 34, 42, 50, 54, 61, 69, 74, 82, 87, 95,107}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 9, 8, 7, 4, 4, 8, 8, 4, 7, 8, 4, 8, 5, 8, 11, 8}; + + const int contextBlockOutSize = 10; + gr::byte contextBlockOut[] = { 15, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(0, NULL); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupNoWhiteSpaceNoSeg() +{ + m_testName = "No white space - no segment"; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L"The quick brown fox."; // text to render + m_firstChar = 15; // spaces after brown + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 2; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_twsh = ktwshNoWs; + m_paraRtl = true; + + // Output: + m_noSegment = true; + m_segWidth = 0; // physical width of segment + + const int charCnt = 0; // number of characters in the segment + + const int glyphCnt = 0; // number of glyphs in the segment + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); +} + +void TestCase::SetupOnlyWhiteSpace() +{ + m_testName = "Only white space"; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_roman.ttf"; + m_text = L" fox."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 2; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_twsh = ktwshOnlyWs; + m_paraRtl = true; + + // Output: + m_segWidth = 0; // physical width of segment - visible + + const int charCnt = 3; // number of characters in the segment + // need charCnt elements in this array: + bool insPtFlags[] = { true, true, true }; + + const int glyphCnt = 3; // number of glyphs in the segment + // need glyphCnt elements in these arrays: + gid16 glyphList[] = { 3, 3, 3 }; + int xPositions[] = { -4, -9,-13 }; + int yPositions[] = { 0, 0, 0 }; + int advWidths[] = { 4, 4, 4 }; + + // TODO: add click tests when the bug fix with upstream tr white space is integrated. + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 6; + int clickStuff[] = { + 2, 25, 0, false, 0, 24, -1, kAbsent, kAbsent, kAbsent, + -1, 5, 0, false, 0, 24, -1, kAbsent, kAbsent, kAbsent, + -6, -3, 1, false, 0, 24, -5, kAbsent, kAbsent, kAbsent, + -8, -3, 2, true, 0, 24, -10, kAbsent, kAbsent, kAbsent, + -13, 40, 3, true, 0, 24, -14, kAbsent, kAbsent, kAbsent, + -18, 0, 3, true, 0, 24, -14, kAbsent, kAbsent, kAbsent + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + A set of tests of cross-line contextualization. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupCrossLine1() +{ + m_testName = "Cross-line 1"; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test CrossLine"; + m_fontFile = "grtest_xline.ttf"; + m_text = CrossLineText(); // "abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww"; + m_fontSize = 30; // font size in points + m_prefBreak = klbHyphenBreak; // preferred break-weight + m_availWidth = 350; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + + // Output: + m_segWidth = 312; // physical width of segment + + const int charCnt = 10; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true + }; + + const int glyphCnt = 13; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {30, 67, 68, 69, 70, 70, 70, 70, 71, 72, 34, 90, 32 }; + int xPositions[] = { 0, 40, 58, 79, 97,118,139,160,180,199,213,251,272 }; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int advWidths[] = {40, 18, 20, 18, 20, 20, 20, 20, 18, 13, 38, 20, 40 }; + + // TODO: add click tests + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 0; + int * clickStuff = NULL; + //int clickStuff[] = ; + //{ + // 10, 25, 1, false, 0, 24, 9, kAbsent, kAbsent, kAbsent, + //}; + + const int contextBlockOutSize = 9; + gr::byte contextBlockOut[] = { 20, 1, 0, 2, 0, 0, 4, 0, 0, 0 }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupCrossLine2() +{ + m_testName = "Cross-line 2"; + //m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test CrossLine"; + m_fontFile = "grtest_xline.ttf"; + m_text = CrossLineText(); // "abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww"; + m_firstChar = 10; + m_fontSize = 30; // font size in points + m_prefBreak = klbHyphenBreak; // preferred break-weight + m_availWidth = 400; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_initWithPrev = true; + + const int contextBlockInSize = 9; // output from Cross-line 1 + gr::byte contextBlockIn[] = { 20, 1, 0, 2, 0, 0, 4, 0, 0, 0 }; + + // Output: + m_segWidth = 395; // physical width of segment + + const int charCnt = 13; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + false, true, true, true, true, true, true, true, true, true, true, true, true + }; + + const int glyphCnt = 15; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {30, 34, 73, 74, 75, 76, 77, 79, 79, 79, 79, 80, 6, 91, 32 }; + int xPositions[] = { 0, 40, 78, 99,119,131,143,163,196,228,260,293,314,334,355 }; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int advWidths[] = {40, 38, 20, 20, 11, 11, 20, 32, 32, 32, 32, 20, 20, 20, 40 }; + + // TODO: add click tests + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 0; + int * clickStuff = NULL; + //int clickStuff[] = ; + //{ + // 10, 25, 1, false, 0, 24, 9, kAbsent, kAbsent, kAbsent, + //}; + + const int contextBlockOutSize = 9; + gr::byte contextBlockOut[] = { 20, 1, 0, 3, 0, 0, 4, 0, 0, 0 }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); + SetInputContextBlock(contextBlockInSize, contextBlockIn); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupCrossLine3() +{ + m_testName = "Cross-line 3"; + m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test CrossLine"; + m_fontFile = "grtest_xline.ttf"; + m_text = CrossLineText(); // "abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww"; + m_firstChar = 23; + m_fontSize = 30; // font size in points + m_prefBreak = klbHyphenBreak; // preferred break-weight + m_availWidth = 400; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_initWithPrev = true; + + const int contextBlockInSize = 9; // output from Cross-line 2 + gr::byte contextBlockIn[] = { 20, 1, 0, 3, 0, 0, 4, 0, 0, 0 }; + + // Output: + m_segWidth = 358; // physical width of segment + + const int charCnt = 13; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, true, false, true + }; + + const int glyphCnt = 16; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {30, 81, 6, 82, 82, 82, 82, 82, 83, 84, 85, 85, 85, 34, 8, 92 }; + int xPositions[] = { 0, 40, 60, 81,102,123,144,164,185,206,220,236,253,269,307,339 }; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int advWidths[] = {40, 20, 20, 20, 20, 20, 20, 20, 20, 14, 16, 16, 16, 38, 32, 18 }; + + // TODO: add click tests + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 0; + int * clickStuff = NULL; + //int clickStuff[] = ; + //{ + // 10, 25, 1, false, 0, 24, 9, kAbsent, kAbsent, kAbsent, + //}; + + const int contextBlockOutSize = 9; + gr::byte contextBlockOut[] = { 20, 1, 0, 3, 0, 0, 4, 0, 0, 0 }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); + SetInputContextBlock(contextBlockInSize, contextBlockIn); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +void TestCase::SetupCrossLine4() +{ + m_testName = "Cross-line 4"; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test CrossLine"; + m_fontFile = "grtest_xline.ttf"; + m_text = CrossLineText(); // "abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww"; + m_firstChar = 36; + m_fontSize = 30; // font size in points + m_prefBreak = klbHyphenBreak; // preferred break-weight + m_availWidth = 400; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_initWithPrev = true; + + const int contextBlockInSize = 9; // output from Cross-line 3 + gr::byte contextBlockIn[] = { 20, 1, 0, 3, 0, 0, 4, 0, 0, 0 }; + + // Output: + m_segWidth = 248; // physical width of segment + + const int charCnt = 8; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + false, true, true, true, true, true, true, true + }; + + const int glyphCnt = 10; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + gid16 glyphList[] = { 8, 6, 86, 86, 86, 89, 89, 89, 89, 32 }; + int xPositions[] = { 0, 32, 53, 64, 76, 87,117,147,177,208 }; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int advWidths[] = {32, 20, 11, 11, 11, 30, 30, 30, 30, 40 }; + + // TODO: add click tests + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 0; + int * clickStuff = NULL; + //int clickStuff[] = ; + //{ + // 10, 25, 1, false, 0, 24, 9, kAbsent, kAbsent, kAbsent, + //}; + + const int contextBlockOutSize = 0; + gr::byte * contextBlockOut = NULL; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); + SetInputContextBlock(contextBlockInSize, contextBlockIn); + SetOutputContextBlock(contextBlockOutSize, contextBlockOut); +} + +std::wstring TestCase::CrossLineText() +{ + // The equivalent data is in the "xlineTest.wpx" file. + std::wstring strRet; + strRet.assign(L"abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww"); + return strRet; +} + +/*---------------------------------------------------------------------------------------------- + A set of tests using Arabic: RTL, bidi, and embedded direction codes. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupArabic1() +{ + m_testName = "Arabic 1"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Arabic"; + m_fontFile = "grtest_arabic.ttf"; + m_text = ArabicText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 1000; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_segWidth = 409; // physical width of segment + + SetupArabicAux( + 61, // character count + 61); // glyph count + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,0, 1,1,1,2, 2,1,0, 3,3,4,4,5,6,7, 4,3,0, 5,3,0, 6,3,0, 7,3,0, + 8,8,0, 9,9,4,10,11,12,13, 10,9,0, 11,9,0, 12,9,0, 13,9,0, 14,14,0, + 15,15,0, 16,16,1,17, 17,16,0, 18,18,1,19, 19,18,0 // etc + }; + int attCount = sizeof(attachments) / sizeof(int); + SetAttachedClusters(attachments, attCount); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + int clickStuff[] = { + 199, 13, 37, true, 0, 35,196, kAbsent, kAbsent, kAbsent, + 396, 13, 3, false, 8, 26,399, 10, 17, 397, + 396, 8, 6, true, 3, 11,391, 9, 22, 394, + 222, 5, 32, true, 0, 35,225, kAbsent, kAbsent, kAbsent, + 217, 5, 31, false, 0, 35,215, 0, 35, 246, + }; + SetClickTests(4, clickStuff); +} + +void TestCase::SetupArabic2() +{ + m_testName = "Arabic 2"; + m_debug = false; + //m_traceLog = false; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test Arabic"; + m_fontFile = "grtest_arabic.ttf"; + m_text = ArabicText(); + m_fontSize = 20; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 230; // width available for segment-break after number + m_bold = false; + m_italic = false; + m_backtrack = false; + + // Output: + m_segWidth = 193; // physical width of segment + + SetupArabicAux( + 35, // character count + 35); // glyph count + + // The x-positions are different for a shorter segment: + // 0 10 20 30 + int xPositions[] = {188,183,184,177,178,178,170,169,162,150,154,154,153,155,139,132,127,127,115,118,108,102, 84, 77, 77, 72, 65, 46, 46, 37, 31, 20, 10, 0, -6}; + SetXPositions(xPositions); +} + +void TestCase::SetupArabicAux(int charCnt, int glyphCnt) +{ + m_rtl = true; + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, // 0 - 9 + true, true, true, true, true, true, true, true, true, true, // 10 - 19 + true, true, true, true, true, true, true, true, true, true, // 20 - 29 + true, true, true, true, true, true, true, true, true, true, // 30 - 39 + true, true, true, true, true, true, true, true, true, true, // 40 - 49 + true, true, true, true, true, true, true, true, true, true, // 50 - 59 + true + }; + + // need glyphCnt elements in these arrays: + // 0 10 20 30 40 50 60 + gid16 glyphList[] = {785,658,907,1182,913,907,1192,907, 3,811,914,909,911,934,592, 3,785,909,621,911, 12, 3,321, 3,236,659,731,555,925,961, 3,992,991,990, 3,821,924,712,474,882,527, 3,411,924,950, 3,236,990,991,992,993,995,236, 3,821,769,455,290,839,620,961}; + int xPositions[] = {404,400,401, 393,394,394, 386,385,379,366,370,370,370,371,355,348,343,343,331,334,324,318,300,293,293,289,281,263,262,254,247,237,226,216,209,197,197,189,179,172,154,147,135,139,127,120,120,110, 99, 89, 79, 68, 68, 62, 50, 41, 36, 29, 19, 8, 0}; + int yPositions[] = { 0, 0, -5, 0, 0, 4, 0, 0, 0, 0, -5, -3, -2, 4, 0, 0, 0, 1, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 4, 4, 0, 6, 0, 0, 6, 0, 6, 12, 0, 0, 0, 0, 11, 6, 4, 0, 11, 0, 7, 6, 17, 6, 0, 4, 7, 18, 0, 8, 6, 10, 10, 10, 6, 11, 0, 7, 9, 7, 17, 6, 11, 0, 8, 6, 0, 10, 10, 10, 10, 10, 0, 6, 11, 9, 4, 6, 9, 11, 8}; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); +} + +std::wstring TestCase::ArabicText() +{ + std::wstring strRet; + wchar_t charData[] = { + 0x0628, 0x0628, 0x064e, 0x0644, 0x064e, 0x0654, 0x0627, 0x064e, 0x0020, 0x0686, + 0x0650, 0x0652, 0x0655, 0x06e0, 0x06a8, 0x0020, 0x0628, 0x0650, 0x06b9, 0x0652, + 0x0029, 0x0020, 0x0628, 0x0020, 0x200d, 0x062a, 0x06a8, 0x0633, 0x0670, 0x061b, + 0x0020, 0x06f1, 0x06f2, 0x06f3, 0x0020, 0x0633, 0x0670, 0x0639, 0x062f, 0x0645, + 0x067e, 0x0020, 0x0644, 0x0670, 0x060c, 0x0020, 0x202e, 0x06f1, 0x06f2, 0x06f3, + 0x06f4, 0x06f5, 0x202c, 0x0020, 0x0633, 0x0647, 0x0627, 0x0631, 0x0639, 0x0646, + 0x061b, 0x0000 + }; + strRet.assign(charData); + return strRet; +} + +/*---------------------------------------------------------------------------------------------- + A set of tests that uses Tai Viet script to test positioning. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupTaiViet1() +{ + m_testName = "Tai Viet Collisions"; + //m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test TaiViet"; + m_fontFile = "grtest_taiviet.ttf"; + m_fontSize = 36; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 2000; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_text = TaiVietText(); + + m_fset[0].id = 2001; m_fset[0].value = 2; // vowel position = final consonant + m_fset[1].id = 1051; m_fset[1].value = 0; // diacritic selection = off + m_fset[2].id = 2102; m_fset[2].value = 0; // collision avoidance = off + m_fset[3].id = 0; + + // Output: + m_segWidth = 946; // physical width of segment + + const int charCnt = 46; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, false, true, true, true, false, true, true, true, + false, false, true, true, false, true, true, false, false, true, + true, false, false, true, true, false, false, true, true, false, + false, true, true, false, true, true, false, false, true, true, + false, true, true, true, false, false + }; + + const int glyphCnt = 46; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + // 0 10 20 30 40 + gid16 glyphList[] = {59, 70, 71, 65, 59, 70, 71, 23, 32, 175, 70, 65, 55, 70, 73, 55, 175, 184,185, 55, 76, 184,185, 55, 77, 70, 185, 41, 77, 70, 23, 56,175, 65, 27, 93, 70,185, 53, 69, 81, 50, 27,175, 70, 23}; + int xPositions[] = { 0, 72, 47, 72,101, 174,149,174, 206, 281, 283, 251, 283,352, 316, 352, 418, 425,386,425,493, 495,458, 495,556,559, 528, 559, 623, 623,591,623,706, 676, 706, 776,777,738, 777, 836, 816,843,880,944,946,912}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 5, 13, 0, 0, 5, 22, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 19, 0, 0, 8, 0, 0, 0, 5, 21, 0}; + int advWidths[] = {47, 0, 24, 29, 47, 0, 24, 32, 44, 0, 0, 29, 33, 0, 36, 33, 0, 0, 26, 33, 0, 0, 26, 33, 0, 0, 26, 32, 0, 0, 32, 52, 0, 29, 32, 0, 0, 26, 39, 0, 26, 36, 32, 0, 0, 32}; + + int bbLefts[] = { 5, 45, 52, 73,106, 147,154,177, 209, 254, 257, 252, 286,326, 322, 355, 391, 414,390,428,463, 484, 462,498,540,532, 532, 562, 607, 597,594,627,679, 677, 709, 744,751,742, 784, 825, 820,849,883,917,919,915}; + int bbRights[] = {72, 72, 63, 97,174, 174,165,211, 277, 281, 283, 276, 349,352, 355, 419, 418, 422,409,491,494, 491, 481,561,553,559, 551, 621, 620, 623,628,681,706, 701, 756, 776,777,761, 835, 833, 840,882,930,944,946,949}; + int bbTops [] = {60, 50, 25, 25, 60, 50, 25, 41, 60, 49, 66, 25, 60, 50, 40, 60, 55, 65, 36, 60, 56, 74, 36, 60, -5, 55, 36, 60, -5, 50, 41, 40, 49, 25, 55, 56, 69, 36, 55, 61, 41, 40, 55, 55, 71, 41}; + int bbBottoms [] = { 0, 35, 0, 0, 0, 35, 0, 0, 0, 34, 50, 0, 0, 35, 0, 0, 39, 51, 0, 0, 40, 60, 0, 0,-27, 40, 0, 0, -27, 35, 0, 0, 34, 0, 0, 40, 54, 0, 0, 45, 0, 0, 0, 39, 56, 0}; + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,0, 1,2,0, 2,2,1,1, 3,3,0, 4,4,0, 5,6,0, 6,6,1,5, 7,7,0, + 8,8,0, 9,11,0, 10,11,0, 11,11,2,9,10, 12,12,0, 13,14,0, 14,14,1,13, + 15,15,0, 16,18,0, 17,18,0, 18,18,2,16,17, 19,19,0, 20,22,0, 21,22,0, + 22,22,2,20,21, 23,23,0, 24,26,0, 25,26,0, 26,26,2,24,25, 27,27,0, 28,30,0, + 29,30,0, 30,30,2,28,29, 31,31,0, 32,33,0, 33,33,1,32, 34,34,0, 35,37,0, + 36,37,0, 37,37,2,35,36, 38,38,0, 39,40,0, 40,40,1,39, 41,41,0, 42,42,0, + 43,45,0, 44,45,0, 45,45,2,43,44 + }; + int attCount = sizeof(attachments) / sizeof(int); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel Top, prim sel bottom, prim sel left, + // sec sel Top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 4; + int clickStuff[] = { + 55, 40, 1, true, 0,100, 46, kAbsent, kAbsent, kAbsent, + 65, 20, 1, false, 0,100, 46, kAbsent, kAbsent, kAbsent, // adjust to the left to get a valid IP? + 95, 84, 4, true, 0,100, 100, kAbsent, kAbsent, kAbsent, + 104, 40, 4, false, 0,100, 100, kAbsent, kAbsent, kAbsent + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetAttachedClusters(attachments, attCount); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + A set of tests that uses Tai Viet script to test positioning. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupTaiViet2() +{ + m_testName = "Tai Viet No Collisions"; + //m_traceLog = true; + //m_debug = true; + //m_skip = true; + + // Input: + m_fontName = L"Graphite Test TaiViet"; + m_fontFile = "grtest_taiviet.ttf"; + m_fontSize = 36; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 2000; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_text = TaiVietText(); + + m_fset[0].id = 2001; m_fset[0].value = 2; // vowel position = final consonant + m_fset[1].id = 1051; m_fset[1].value = 1; // diacritic selection = on + m_fset[2].id = 2102; m_fset[2].value = 1; // collision avoidance = off + m_fset[3].id = 0; + + // Output: + m_segWidth = 947; // physical width of segment + + const int charCnt = 46; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true + }; + + const int glyphCnt = 46; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + // 0 10 20 30 40 + gid16 glyphList[] = {59, 70, 71, 65, 59, 70, 71, 23, 32, 175, 70, 65, 55, 70, 73, 55, 175, 184,185, 55, 76, 184,185, 55, 77, 70, 185, 41, 77, 70, 23, 56,175, 65, 27, 93, 70,185, 53, 69, 81, 50, 27,175, 70, 23}; + int xPositions[] = { 0, 82, 47, 72,101, 184,149,174, 206, 281, 283, 251, 283,359, 316, 352, 418, 431,386,425,496, 508,458, 497,559,578, 530, 561, 626, 635,593,626,709, 678, 708, 778,780,740, 780, 853, 819,846,882,942,947,914}; + int yPositions[] = { 0, -3, 0, 0, 0, -3, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 9, 0, 0, 2, 20, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -4, 0, 0, 5, 25, 0, 0, 8, 0, 0, 0, 0, 23, 0}; + int advWidths[] = {47, 0, 24, 29, 47, 0, 24, 32, 44, 0, 0, 29, 33, 0, 36, 33, 0, 0, 26, 33, 0, 0, 26, 33, 0, 0, 26, 32, 0, 0, 32, 52, 0, 29, 32, 0, 0, 26, 39, 0, 26, 36, 32, 0, 0, 32}; + + int bbLefts[] = { 5, 56, 52, 73,106, 158,154,177, 209, 254, 257, 252, 286,333, 322, 355, 391, 420,390,428,466, 497, 462,500,542,552, 534, 564, 609, 609,597,629,682, 679, 711, 747,753,744, 786, 842, 823,851,885,916,921,918}; + int bbRights[] = {72, 82, 63, 97,174, 184,165,211, 277, 281, 283, 276, 349,359, 355, 419, 418, 427,409,491,496, 504, 481,564,555,578, 553, 624, 622, 635,630,684,709, 703, 758, 778,780,763, 837, 850, 842,885,932,942,947,951}; + int bbTops [] = {60, 46, 25, 25, 60, 46, 25, 41, 60, 49, 73, 25, 60, 50, 40, 60, 50, 60, 36, 60, 54, 72, 36, 60, -5, 52, 36, 60, -5, 50, 41, 40, 45, 25, 55, 56, 75, 36, 55, 61, 41, 40, 55, 50, 73, 41}; + int bbBottoms [] = { 0, 31, 0, 0, 0, 31, 0, 0, 0, 34, 57, 0, 0, 35, 0, 0, 34, 46, 0, 0, 37, 57, 0, 0,-27, 36, 0, 0, -27, 35, 0, 0, 29, 0, 0, 40, 60, 0, 0, 45, 0, 0, 0, 34, 58, 0}; + + // Each group = glyph-index, base, number of attached, glyphs, attached-glyph-indices + int attachments[] = { + 0,0,0, 1,2,0, 2,2,1,1, 3,3,0, 4,4,0, 5,6,0, 6,6,1,5, 7,7,0, + 8,8,0, 9,11,0, 10,11,0, 11,11,2,9,10, 12,12,0, 13,14,0, 14,14,1,13, + 15,15,0, 16,18,0, 17,18,0, 18,18,2,16,17, 19,19,0, 20,22,0, 21,22,0, + 22,22,2,20,21, 23,23,0, 24,26,0, 25,26,0, 26,26,2,24,25, 27,27,0, 28,30,0, + 29,30,0, 30,30,2,28,29, 31,31,0, 32,33,0, 33,33,1,32, 34,34,0, 35,37,0, + 36,37,0, 37,37,2,35,36, 38,38,0, 39,40,0, 40,40,1,39, 41,41,0, 42,42,0, + 43,45,0, 44,45,0, 45,45,2,43,44 + }; + int attCount = sizeof(attachments) / sizeof(int); + + // Each line in clickStuff represents one click test with the following items: + // click x-coord, click y-coord, char index, assoc-prev, + // prim sel top, prim sel bottom, prim sel left, + // sec sel top, sec sel bottom, sec sel left + // Y-coordinates are offsets from segment top; ie, (0,0) is segment top-left. + const int clickTestCnt = 4; + int clickStuff[] = { + 55, 40, 2, false, 35, 65, 49, 14, 33, 82, + 65, 20, 1, false, 0,100, 50, kAbsent, kAbsent, kAbsent, + 95, 84, 4, true, 0,100, 100, kAbsent, kAbsent, kAbsent, + 104, 40, 4, false, 0,100, 100, kAbsent, kAbsent, kAbsent + }; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); + SetAttachedClusters(attachments, attCount); + SetClickTests(clickTestCnt, clickStuff); +} + +std::wstring TestCase::TaiVietText() +{ + std::wstring strRet; + wchar_t charData[] = { + 0xe00f,0xe042,0xe031,0xe02b,0xe00f,0xe042,0xe031,0xe025,0xe021,0xe033, + 0xe042,0xe02b,0xe01c,0xe042,0xe03e,0xe01c,0xe033,0xe040,0xe009,0xe01c, + 0xe039,0xe040,0xe009,0xe01c,0xe035,0xe042,0xe009,0xe024,0xe035,0xe042, + 0xe025,0xe01b,0xe033,0xe02b,0xe00a,0xe030,0xe042,0xe009,0xe01e,0xe040, + 0xe03b,0xe019,0xe00a,0xe033,0xe042,0xe025,0x0000 + }; + strRet.assign(charData); + return strRet; +} + +/*---------------------------------------------------------------------------------------------- + Set up a test where the font is bad and we revert to dumb rendering +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupDumbFallback1() +{ + m_testName = "Dumb Fallback 1"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"GrErr BadVersion"; + m_fontFile = "grtest_badVersion.ttf"; + m_text = RomanText(); // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_dumbFallback = true; + + // Output: + m_badFont = true; + m_segWidth = 196; // physical width of segment + + const int charCnt = 26; // number of characters in the segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true + }; + + const int glyphCnt = 26; // number of glyphs in the segment + + // need glyphCnt elements in these arrays: + // 0 10 20 + gid16 glyphList[] = {71, 0, 0, 82, 0, 85, 73, 0, 0, 0, 0, 67, 0, 0, 75, 0, 43, 0, 79, 0, 0, 0, 0, 72, 72, 75}; + int xPositions[] = { 0, 7, 15, 23, 31, 39, 46, 54, 62, 70, 78, 86, 93,101,109,114,122,128,136,149,157,165,173,181,186,192}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 7, 8, 8, 8, 8, 6, 8, 8, 8, 8, 8, 7, 8, 8, 4, 8, 5, 8, 12, 8, 8, 8, 8, 5, 5, 4}; + + const int clickTestCnt = 0; + int * clickStuff = NULL; + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetBBs(NULL, NULL, NULL, NULL); + SetInsPtFlags(insPtFlags); + SetClickTests(clickTestCnt, clickStuff); +} + +/*---------------------------------------------------------------------------------------------- + Now make sure we will get a crash when we turn dumb rendering off for the same font. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupDumbFallback2() +{ + m_testName = "Dumb Fallback 2"; + //m_debug = true; + //m_traceLog = true; + //m_skip = true; + + // Input: + m_fontName = L"GrErr BadVersion"; + m_fontFile = "grtest_badVersion.ttf"; + m_text = L"This is a test."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_dumbFallback = false; + + // Output: + m_badFont = true; + m_noSegment = true; + m_segWidth = 0; // physical width of segment + + const int charCnt = 0; // number of characters in the segment + + const int glyphCnt = 0; // number of glyphs in the segment + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); +} + +/*---------------------------------------------------------------------------------------------- + Now make sure we will get a crash when we turn dumb rendering off for the same font. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetupBadFont() +{ + m_testName = "Bad Font"; + //m_debug = true; + //m_traceLog = true; + m_skip = true; + + // Input: + // The font has been corrupted so that the size of the cmap in the directory is invalid. + m_fontName = L"Graphite Test Roman"; + m_fontFile = "grtest_badCmap.ttf"; + m_text = L"This is a test."; // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_rtl = false; + m_backtrack = false; + m_dumbFallback = true; // wants to do dumb fall-back, but can't because the font is totally invalid + + // Output: + m_badFont = true; + m_noSegment = true; + m_segWidth = 0; // physical width of segment + + const int charCnt = 0; // number of characters in the segment + + const int glyphCnt = 0; // number of glyphs in the segment + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); +} +// *** Add more methods here. *** + + +//:>******************************************************************************************** +//:> Utility methods. +//:>******************************************************************************************** + +/*---------------------------------------------------------------------------------------------- + Delete the list of tests. +----------------------------------------------------------------------------------------------*/ +void TestCase::DeleteTests() +{ + delete[] g_ptcaseList; +} + +/*---------------------------------------------------------------------------------------------- + Constructor: initialize test case with default values. +----------------------------------------------------------------------------------------------*/ +TestCase::TestCase() +{ + m_testName = "Unknown"; + m_debug = false; + m_traceLog = false; + m_skip = false; + + m_fontName.erase(); + m_fontFile.erase(); + m_text.erase(); // text to render + m_fontSize = 12; // font size in points + m_prefBreak = klbWordBreak; // preferred break-weight + m_worstBreak = klbClipBreak; // worst-case break-weight + m_availWidth = 500; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + m_twsh = ktwshAll; + m_paraRtl = false; + m_firstChar = 0; + m_contextBlockInSize = 0; + m_contextBlockIn = NULL; + m_initWithPrev = false; + memset(m_fset, 0, MAXFEAT * sizeof(FeatureSetting)); + m_dumbFallback = true; + + m_badFont = false; + m_noSegment = false; // yes, a segment should be generated + m_charCount = 0; + m_glyphCount = 0; + m_glyphArray = NULL; + m_xPositions = NULL; + m_yPositions = NULL; + m_advWidths = NULL; + m_bbLefts = NULL; + m_bbRights = NULL; + m_bbTops = NULL; + m_bbBottoms = NULL; + m_insPointFlags = NULL; + m_charsToGlyphs = NULL; + m_c2gCount = 0; + m_attGlyphs = NULL; + m_attGCount = 0; + m_contextBlockOutSize = 0; + m_contextBlockOut = NULL; + + m_clickTestCount = 0; + m_clickTests = NULL; +} + +/*---------------------------------------------------------------------------------------------- + Destructor. +----------------------------------------------------------------------------------------------*/ +TestCase::~TestCase() +{ + delete[] m_glyphArray; + delete[] m_xPositions; + delete[] m_yPositions; + delete[] m_advWidths; + delete[] m_bbLefts; + delete[] m_bbRights; + delete[] m_bbTops; + delete[] m_bbBottoms; + delete[] m_insPointFlags; + delete[] m_charsToGlyphs; + delete[] m_attGlyphs; + delete[] m_clickTests; + delete[] m_contextBlockIn; + delete[] m_contextBlockOut; +} + +/*---------------------------------------------------------------------------------------------- + Setters. +----------------------------------------------------------------------------------------------*/ +void TestCase::SetCharCount(int charCount) +{ + m_charCount = charCount; + m_insPointFlags = new bool[charCount]; +} + +void TestCase::SetGlyphCount(int glyphCount) +{ + m_glyphCount = glyphCount; + m_glyphArray = new gid16[glyphCount]; + m_xPositions = new int[glyphCount]; + m_yPositions = new int[glyphCount]; + m_advWidths = new int[glyphCount]; + m_bbLefts = new int[glyphCount]; + m_bbRights = new int[glyphCount]; + m_bbTops = new int[glyphCount]; + m_bbBottoms = new int[glyphCount]; +} + +void TestCase::SetGlyphList(gid16 * glyphList) +{ + for (int i = 0; i < m_glyphCount; i++) + m_glyphArray[i] = glyphList[i]; +} + +void TestCase::SetXPositions(int * xPosList) +{ + for (int i = 0; i < m_glyphCount; i++) + m_xPositions[i] = xPosList[i]; +} + +void TestCase::SetYPositions(int * yPosList) +{ + for (int i = 0; i < m_glyphCount; i++) + m_yPositions[i] = yPosList[i]; +} + +void TestCase::SetAdvWidths(int * advWidths) +{ + for (int i = 0; i < m_glyphCount; i++) + m_advWidths[i] = advWidths[i]; +} + +void TestCase::SetBBs(int * bbLefts, int * bbRights, int * bbTops, int * bbBottoms) +{ + if (bbLefts == NULL) // no bb tests + { + delete[] m_bbLefts; + delete[] m_bbRights; + delete[] m_bbTops; + delete[] m_bbBottoms; + m_bbLefts = NULL; + m_bbRights = NULL; + m_bbTops = NULL; + m_bbBottoms = NULL; + return; + } + + for (int i = 0; i < m_glyphCount; i++) + { + m_bbLefts[i] = bbLefts[i]; + m_bbRights[i] = bbRights[i]; + m_bbTops[i] = bbTops[i]; + m_bbBottoms[i] = bbBottoms[i]; + } +} + +void TestCase::SetInsPtFlags(bool * flags) +{ + for (int i = 0; i < m_charCount; i++) + m_insPointFlags[i] = flags[i]; +} + +void TestCase::SetCharsToGlyphs(int * stuff, int count) +{ + m_c2gCount = count; + m_charsToGlyphs = new int[count]; + for (int i = 0; i < count; i++) + m_charsToGlyphs[i] = stuff[i]; +} + +void TestCase::SetAttachedClusters(int * stuff, int count) +{ + m_attGCount = count; + m_attGlyphs = new int[count]; + for (int i = 0; i < count; i++) + m_attGlyphs[i] = stuff[i]; +} + +void TestCase::SetClickTests(int clickTestCount, int * clickStuff) +{ + const int fc = ClickTest::fieldCnt; + + m_clickTestCount = clickTestCount; + m_clickTests = new ClickTest[clickTestCount]; + for (int i = 0; i < clickTestCount; i++) + { + m_clickTests[i].xClick = clickStuff[(i * fc) + 0]; + m_clickTests[i].yClick = clickStuff[(i * fc) + 1]; + m_clickTests[i].charIndex = clickStuff[(i * fc) + 2]; + m_clickTests[i].assocPrev = clickStuff[(i * fc) + 3]; + m_clickTests[i].sel1Top = clickStuff[(i * fc) + 4]; + m_clickTests[i].sel1Bottom = clickStuff[(i * fc) + 5]; + m_clickTests[i].sel1Left = clickStuff[(i * fc) + 6]; + m_clickTests[i].sel2Top = clickStuff[(i * fc) + 7]; + m_clickTests[i].sel2Bottom = clickStuff[(i * fc) + 8]; + m_clickTests[i].sel2Left = clickStuff[(i * fc) + 9]; + } +} + +void TestCase::SetInputContextBlock(int contextBlockInSize, gr::byte * pContextBlockIn) +{ + m_contextBlockInSize = contextBlockInSize; + if (contextBlockInSize == 0) + { + m_contextBlockIn = NULL; + } + else + { + m_contextBlockIn = new gr::byte[contextBlockInSize]; + std::copy(pContextBlockIn, pContextBlockIn + contextBlockInSize, m_contextBlockIn); + } +} + +void TestCase::SetOutputContextBlock(int contextBlockOutSize, gr::byte * pContextBlockOut) +{ + m_contextBlockOutSize = contextBlockOutSize; + m_contextBlockOut = new gr::byte[contextBlockOutSize]; + std::copy(pContextBlockOut, pContextBlockOut + contextBlockOutSize, m_contextBlockOut); +} + + + + +void TestCase::SetupBugTest() +{ + m_testName = "Bug Test"; + m_traceLog = true; + m_debug = true; + m_skip = true; + + // Input: + m_fontName = L"Padauk"; + m_fontFile = "grtest_infinity.ttf"; + + wchar_t charData[] = { 0x101e, 0x1032, 0x1015, 0x103c, 0x103d, 0x103e, 0x102d, 0x1038, 0x0000 }; + m_text.assign(charData); + int charCnt = 8; + + m_fontSize = 20; // font size in points + m_prefBreak = klbWsBreak; // preferred break-weight + m_worstBreak = klbHyphenBreak; // worst-case break-weight + m_availWidth = 1000; // width available for segment + m_bold = false; + m_italic = false; + m_backtrack = false; + m_rtl = false; + + // Output: + m_noSegment = false; + m_segWidth = 52; // physical width of segment + + // need charCnt elements in this array: + bool insPtFlags[] = { + true, false, true, true, false, false, false, true + }; + + int glyphCnt = 7; + // need glyphCnt elements in these arrays: + gid16 glyphList[] = {105,174,158,202,231,162,231}; + int xPositions[] = { 0, 17, 20, 22, 28, 29, 38}; + int yPositions[] = { 0, 0, 0, 0, 0, 0, 0}; + int advWidths[] = { 17, 2, 9, 4, 0, 10, 0}; + + int bbLefts[] = { 0, 10, 21, 23, 23, 30, 33}; + int bbRights[] = { 16, 19, 28, 25, 28, 39, 38}; + int bbTops[] = { 7, 7, 7, -1, 15, 7, 15}; + int bbBottoms[] = { 0, -7, -1, -7, 9, 0, 9}; + + // Each group = char-index, number of glyphs, glyph-indices. + int charsToGlyphs[] = { + 0, 1, 0, 1, 1, 1, 2, 1, 3, 3, 1, 2, 4, 1, 4, 5, 0, 6, 1, 5, 7, 1, 6 + }; + int c2gCount = sizeof(charsToGlyphs) / sizeof(int); + + // Finish setting up test case. + SetCharCount(charCnt); + SetGlyphCount(glyphCnt); + SetGlyphList(glyphList); + SetXPositions(xPositions); + SetYPositions(yPositions); + SetAdvWidths(advWidths); + SetCharsToGlyphs(charsToGlyphs, c2gCount); + SetBBs(bbLefts, bbRights, bbTops, bbBottoms); + SetInsPtFlags(insPtFlags); +} diff --git a/Build/source/libs/graphite/test/RegressionTest/TestCase.h b/Build/source/libs/graphite/test/RegressionTest/TestCase.h new file mode 100644 index 00000000000..68258929a1f --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/TestCase.h @@ -0,0 +1,245 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2004 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: TestCase.h +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Definition of TestCase class for Graphite regression test program. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +#ifdef _MSC_VER +#pragma once +#endif +#ifndef TESTCASE_H +#define TESTCASE_H 1 + +#define NO_EXCEPTIONS 1 + +class TestCase +{ +public: + // Methods to set up test cases. + void SetupSimpleTest(); + void SetupSimpleBacktrackTest(); + void SetupSurrogateTest(); // TODO: add a test for UTF-8 + void SetupBurmese1(); + void SetupBurmese2(); + void SetupBurmese3(); + void SetupBurmese4(); + void SetupRoman(); + void SetupRomanFeatures(); + void SetupStackingAndBridging(); + void SetupNoWhiteSpace(); + void SetupNoWhiteSpaceNoSeg(); + void SetupOnlyWhiteSpace(); + void SetupCrossLine1(); + void SetupCrossLine2(); + void SetupCrossLine3(); + void SetupCrossLine4(); + void SetupArabic1(); + void SetupArabic2(); + void SetupTaiViet1(); + void SetupTaiViet2(); + void SetupDumbFallback1(); + void SetupDumbFallback2(); + void SetupBadFont(); + void SetupBugTest(); + // *** Add more methods here. *** + +protected: + // Auxiliary functions to set up test cases. + void SetupBurmeseAux(int charCount, int glyphCount, int clickTestCount); + void SetupArabicAux(int charCount, int glyphCount); + std::wstring BurmeseText(); + std::wstring RomanText(); + std::wstring CrossLineText(); + std::wstring ArabicText(); + std::wstring TaiVietText(); + +public: + const static int kAbsent = -100; // not present in data + +public: + // constructor: + TestCase(); + // destructor: + ~TestCase(); + + static int SetupTests(TestCase **); + static void DeleteTests(); + + // Getters: + std::string TestName() { return m_testName; } + bool RunDebugger() { return m_debug; } + bool TraceLog() { return m_traceLog; } + bool Skip() { return m_skip; } + + std::wstring Text() { return m_text; } + std::wstring FontName() { return m_fontName; } + std::string FontFile() { return m_fontFile; } + size_t FontSize() { return m_fontSize; } + LineBrk PrefBreak() { return m_prefBreak; } + LineBrk WorstBreak() { return m_worstBreak; } + int FeatureID(int i) { return m_fset[i].id; } + int FeatureValue(int i) { return m_fset[i].value; } + FeatureSetting * Features() { return m_fset; } + int AvailWidth() { return m_availWidth; } + bool Backtrack() { return m_backtrack; } + TrWsHandling Twsh() { return m_twsh; } + bool Rtl() { return m_rtl; } + bool ParaRtl() { return m_paraRtl; } + size_t FirstChar() { return m_firstChar; } + bool DumbFallback() { return m_dumbFallback; } + size_t InputContextBlock(gr::byte ** ppContextBlock) + { + *ppContextBlock = m_contextBlockIn; + return m_contextBlockInSize; + } + + bool InitWithPrevSeg() { return m_initWithPrev; } + bool BadFont() { return m_badFont; } + bool NoSegment() { return m_noSegment; } + int SegWidth() { return m_segWidth; } + int CharCount() { return m_charCount; } + int GlyphCount() { return m_glyphCount; } + + int GlyphID(int i) { return m_glyphArray[i]; } + int XPos(int i) { return m_xPositions[i]; } + int YPos(int i) { return m_yPositions[i]; } + int AdvWidth(int i) { return m_advWidths[i]; } + int BbLeft(int i) { return m_bbLefts[i]; } + int BbRight(int i) { return m_bbRights[i]; } + int BbTop(int i) { return m_bbTops[i]; } + int BbBottom(int i) { return m_bbBottoms[i]; } + bool BbTests() { return (m_bbLefts != NULL); } + + int InsPtFlag(int i) { return m_insPointFlags[i]; } + + int CharToGlyphCount() { return m_c2gCount; } + int CharToGlyphItem(int i) { return m_charsToGlyphs[i]; } + int AttachedGlyphCount() { return m_attGCount; } // that is, the lenght of the data + int AttachedGlyphItem(int i) { return m_attGlyphs[i]; } + + int NumberOfClickTests() { return m_clickTestCount; } + int XClick(int i) { return m_clickTests[i].xClick; } + int YClick(int i) { return m_clickTests[i].yClick; } + int ClickCharIndex(int i) { return m_clickTests[i].charIndex; } + bool ClickAssocPrev(int i) { return (bool)m_clickTests[i].assocPrev; } + int Sel1Top(int i) { return m_clickTests[i].sel1Top; } + int Sel1Bottom(int i) { return m_clickTests[i].sel1Bottom; } + int Sel1Left(int i) { return m_clickTests[i].sel1Left; } + int Sel2Top(int i) { return m_clickTests[i].sel2Top; } + int Sel2Bottom(int i) { return m_clickTests[i].sel2Bottom; } + int Sel2Left(int i) { return m_clickTests[i].sel2Left; } + size_t OutputContextBlockSize() { return m_contextBlockOutSize; } + bool CompareContextBlock(gr::byte * pResult) + { + for (size_t i = 0; i < m_contextBlockOutSize; i++) + { + if (m_contextBlockOut[i] != pResult[i]) + return false; + } + return true; + } + + struct ClickTest + { + int xClick; + int yClick; + int charIndex; + int assocPrev; // boolean: 0 or 1 + int sel1Top; + int sel1Bottom; + int sel1Left; // we only need left or right, not both + int sel2Top; + int sel2Bottom; + int sel2Left; + + const static int fieldCnt = 10; + }; + +protected: + std::string m_testName; + bool m_debug; // break into the debugger when running this test + bool m_traceLog; // generate a logging file (tracelog.txt) for this test; if this is turned on for + // more than one test, the tests will be appended + bool m_skip; + +#define MAXFEAT 10 + + // Input parameters: + std::wstring m_text; // default: none + std::wstring m_fontName; // default: empty + std::string m_fontFile; // default: empty + size_t m_fontSize; // default: 12 + LineBrk m_prefBreak; // default: word-break + LineBrk m_worstBreak; // default: clip-break + FeatureSetting m_fset[MAXFEAT]; // default: none + int m_availWidth; // default: 100 + bool m_bold; // default: false + bool m_italic; // default: false + bool m_rtl; // default: false + bool m_backtrack; // default: false + TrWsHandling m_twsh; // default: ktwshAll + bool m_paraRtl; // default: false + size_t m_firstChar; // default: 0 + size_t m_contextBlockInSize; // default: 0 + gr::byte * m_contextBlockIn; // default: NULL -- DELETE + bool m_initWithPrev; // default: false + bool m_dumbFallback; // default: true + // start of line flag + // resolution + // justification + + // Output: + bool m_badFont; // default: false + bool m_noSegment; // no segment should be generated + int m_segWidth; + int m_charCount; + int m_glyphCount; + gid16 * m_glyphArray; + int * m_xPositions; + int * m_yPositions; + int * m_advWidths; + int * m_bbLefts; + int * m_bbRights; + int * m_bbTops; + int * m_bbBottoms; + bool * m_insPointFlags; + int * m_charsToGlyphs; // char-to-glyph mappings + int m_c2gCount; + int * m_attGlyphs; // attachment clusters + int m_attGCount; + int m_clickTestCount; + ClickTest * m_clickTests; + size_t m_contextBlockOutSize; + gr::byte * m_contextBlockOut; + // glyphs-to-chars + // pdichwContext + // arrow key behavior + // etc. + + // Setters: + void SetCharCount(int charCount); + void SetGlyphCount(int glyphCount); + void SetGlyphList(gid16 * glyphList); + void SetXPositions(int * posList); + void SetYPositions(int * posList); + void SetAdvWidths(int * advWidths); + void SetBBs(int * bbLefts, int * bbRights, int * bbTops, int * bbBottoms); + void SetInsPtFlags(bool * flags); + void SetCharsToGlyphs(int * stuff, int count); + void SetAttachedClusters(int * stuff, int count); + void SetClickTests(int clickTestCount, int * clickStuff); + void SetInputContextBlock(int contextBlockInSize, gr::byte * contextBlockIn); + void SetOutputContextBlock(int contextBlockOutSize, gr::byte * contextBlockIn); +}; + + +#endif // !TESTCASE_H + diff --git a/Build/source/libs/graphite/test/RegressionTest/arabicText.wpx b/Build/source/libs/graphite/test/RegressionTest/arabicText.wpx new file mode 100644 index 00000000000..62fee81be5b --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/arabicText.wpx @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd"> +<WpDoc wpxVersion="2.0"> + +<Languages> + <LgWritingSystem id="arb" language="arb" type="ISO-639-2"> + <Name24> + <AUni ws="en">Arabic, Standard</AUni> + </Name24> + <Abbr24> + <AUni ws="en">Ara</AUni> + </Abbr24> + <Locale24><Integer val="1033"/></Locale24> + <RightToLeft24><Boolean val="true"/></RightToLeft24> + <DefaultSerif24><Uni>Scheherazade Graphite Alpha</Uni></DefaultSerif24> + <DefaultSansSerif24><Uni>Scheherazade Graphite Alpha</Uni></DefaultSansSerif24> + <DefaultBodyFont24><Uni>Charis SIL</Uni></DefaultBodyFont24> + <DefaultMonospace24><Uni>Courier</Uni></DefaultMonospace24> + <ICULocale24><Uni>arb</Uni></ICULocale24> + <KeyboardType24><Uni>standard</Uni></KeyboardType24> + <KeymanKeyboard24><Uni>Arabic Demo</Uni></KeymanKeyboard24> + <Collations24> + <LgCollation> + <Name30> + <AUni ws="en">DefaultCollation</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30> + </LgCollation> + </Collations24> + </LgWritingSystem> +</Languages> + +<Styles> + <StStyle> + <Name17><Uni>Normal</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni></Uni></BasedOn17> + <Next17><Uni>Normal</Uni></Next17> + <Rules17> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Bulleted List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Bulleted List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 1</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 1</Uni></Next17> + <Rules17> + <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 2</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 2</Uni></Next17> + <Rules17> + <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 3</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 3</Uni></Next17> + <Rules17> + <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Numbered List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Numbered List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="10"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>External Link</Uni></Name17> + <Type17><Integer val="1"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>External Link</Uni></Next17> + <Rules17> + <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/> + </Rules17> + </StStyle> +</Styles> + +<Body docRightToLeft="false"> + <StTxtPara> + <StyleRules15> + <Prop spaceBefore="12000" spaceAfter="12000" rightToLeft="1" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="arb" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Arabic" fontVariations="1051=1,1030=0">ببَلَٔاَ چِْٕ۠ڨ بِڹْ) ب تڨسٰ؛ ۱۲۳ سٰعدمپ لٰ، ۱۲۳۴۵ سهارعن؛</Run> + </Str> + </Contents16> + </StTxtPara> +</Body> + +<PageSetup> + <PageInfo> + <TopMargin9999><Integer val="72000"/></TopMargin9999> + <BottomMargin9999><Integer val="72000"/></BottomMargin9999> + <LeftMargin9999><Integer val="90000"/></LeftMargin9999> + <RightMargin9999><Integer val="90000"/></RightMargin9999> + <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999> + <FooterMargin9999><Integer val="36000"/></FooterMargin9999> + <PageSize9999><Integer val="0"/></PageSize9999> + <PageHeight9999><Integer val="792000"/></PageHeight9999> + <PageWidth9999><Integer val="612000"/></PageWidth9999> + <PageOrientation9999><Integer val="0"/></PageOrientation9999> + <Header9999> + <Str> + <Run ws="en">arabicText.wpx</Run> + </Str> + </Header9999> + <Footer9999> + <Str> + <Run ws="en">&[page],&[date]</Run> + </Str> + </Footer9999> + </PageInfo> +</PageSetup> + +</WpDoc> diff --git a/Build/source/libs/graphite/test/RegressionTest/bridgingStackingText.wpx b/Build/source/libs/graphite/test/RegressionTest/bridgingStackingText.wpx new file mode 100644 index 00000000000..d91ecea8262 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/bridgingStackingText.wpx @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd"> +<WpDoc wpxVersion="2.0"> + +<Languages> + <LgWritingSystem id="en" language="en" type="ISO-639-1"> + <Name24> + <AUni ws="en">English</AUni> + </Name24> + <Abbr24> + <AUni ws="en">Eng</AUni> + </Abbr24> + <Description24> + <AStr ws="en"> + <Run ws="en">The standard alphabetic representation of English (United States style).</Run> + </AStr> + </Description24> + <Locale24><Integer val="1033"/></Locale24> + <RightToLeft24><Boolean val="false"/></RightToLeft24> + <DefaultSerif24><Uni>Times New Roman</Uni></DefaultSerif24> + <DefaultSansSerif24><Uni>Arial</Uni></DefaultSansSerif24> + <DefaultBodyFont24><Uni>Charis SIL</Uni></DefaultBodyFont24> + <DefaultMonospace24><Uni>Courier New</Uni></DefaultMonospace24> + <ICULocale24><Uni>en</Uni></ICULocale24> + <KeyboardType24><Uni>standard</Uni></KeyboardType24> + <Collations24> + <LgCollation> + <Name30> + <AUni ws="en">Default Collation</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30> + </LgCollation> + <LgCollation> + <Name30> + <AUni ws="en">Case Sensitive</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CS_AI</Uni></WinCollation30> + </LgCollation> + </Collations24> + </LgWritingSystem> +</Languages> + +<Styles> + <StStyle> + <Name17><Uni>Normal</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni></Uni></BasedOn17> + <Next17><Uni>Normal</Uni></Next17> + <Rules17> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Bulleted List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Bulleted List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 1</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 1</Uni></Next17> + <Rules17> + <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 2</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 2</Uni></Next17> + <Rules17> + <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 3</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 3</Uni></Next17> + <Rules17> + <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Numbered List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Numbered List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="10"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>External Link</Uni></Name17> + <Type17><Integer val="1"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>External Link</Uni></Next17> + <Rules17> + <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/> + </Rules17> + </StStyle> +</Styles> + +<Body docRightToLeft="false"> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="48000" fontsizeUnit="mpt" fontFamily="Doulos SIL"></Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman">a͝a t͝a à̀͝a ʃ̀̀͝a a̖̖a ʃ̀̀a a̖̖a ʃ͝a</Run> + </Str> + </Contents16> + </StTxtPara> +</Body> + +<PageSetup> + <PageInfo> + <TopMargin9999><Integer val="72000"/></TopMargin9999> + <BottomMargin9999><Integer val="72000"/></BottomMargin9999> + <LeftMargin9999><Integer val="90000"/></LeftMargin9999> + <RightMargin9999><Integer val="90000"/></RightMargin9999> + <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999> + <FooterMargin9999><Integer val="36000"/></FooterMargin9999> + <PageSize9999><Integer val="0"/></PageSize9999> + <PageHeight9999><Integer val="792000"/></PageHeight9999> + <PageWidth9999><Integer val="612000"/></PageWidth9999> + <PageOrientation9999><Integer val="0"/></PageOrientation9999> + <Header9999> + <Str> + <Run ws="en">bridgingDiacTest.wpx</Run> + </Str> + </Header9999> + <Footer9999> + <Str> + <Run ws="en">&[page],&[date]</Run> + </Str> + </Footer9999> + </PageInfo> +</PageSetup> + +</WpDoc> diff --git a/Build/source/libs/graphite/test/RegressionTest/burmeseText.wpx b/Build/source/libs/graphite/test/RegressionTest/burmeseText.wpx new file mode 100644 index 00000000000..94d699a2a1c --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/burmeseText.wpx @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd">
+<WpDoc wpxVersion="2.0">
+
+<Languages>
+ <LgWritingSystem id="my" language="my" type="ISO-639-1">
+ <Name24>
+ <AUni ws="en">Burmese</AUni>
+ </Name24>
+ <Description24>
+ <AStr ws="en">
+ <Run></Run>
+ </AStr>
+ </Description24>
+ <Locale24><Integer val="1109"/></Locale24>
+ <RightToLeft24><Boolean val="false"/></RightToLeft24>
+ <DefaultSerif24><Uni>Padauk</Uni></DefaultSerif24>
+ <DefaultSansSerif24><Uni>Arial</Uni></DefaultSansSerif24>
+ <DefaultMonospace24><Uni>Courier</Uni></DefaultMonospace24>
+ <ICULocale24><Uni>my</Uni></ICULocale24>
+ <KeyboardType24><Uni>keyman</Uni></KeyboardType24>
+ <KeymanKeyboard24><Uni>Burmese Unicode 0.03</Uni></KeymanKeyboard24>
+ <Collations24>
+ <LgCollation>
+ <Name30>
+ <AUni ws="en">DefaultCollation</AUni>
+ </Name30>
+ <WinLCID30><Integer val="1033"/></WinLCID30>
+ <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30>
+ </LgCollation>
+ </Collations24>
+ </LgWritingSystem>
+</Languages>
+
+<Styles>
+ <StStyle>
+ <Name17><Uni>Normal</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni></Uni></BasedOn17>
+ <Next17><Uni>Normal</Uni></Next17>
+ <Rules17>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>Bulleted List</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>Bulleted List</Uni></Next17>
+ <Rules17>
+ <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>Heading 1</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>Heading 1</Uni></Next17>
+ <Rules17>
+ <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>Heading 2</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>Heading 2</Uni></Next17>
+ <Rules17>
+ <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>Heading 3</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>Heading 3</Uni></Next17>
+ <Rules17>
+ <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>Numbered List</Uni></Name17>
+ <Type17><Integer val="0"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>Numbered List</Uni></Next17>
+ <Rules17>
+ <Prop firstIndent="-18000" bulNumScheme="10"/>
+ </Rules17>
+ </StStyle>
+ <StStyle>
+ <Name17><Uni>External Link</Uni></Name17>
+ <Type17><Integer val="1"/></Type17>
+ <BasedOn17><Uni>Normal</Uni></BasedOn17>
+ <Next17><Uni>External Link</Uni></Next17>
+ <Rules17>
+ <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/>
+ </Rules17>
+ </StStyle>
+</Styles>
+
+<Body docRightToLeft="false">
+ <StTxtPara>
+ <StyleRules15>
+ <Prop rightToLeft="0" namedStyle="Normal"/>
+ </StyleRules15>
+ <Contents16>
+ <Str>
+ <Run ws="my" fontsize="20000" fontsizeUnit="mpt" fontFamily="Graphite Test Burmese">က္ယ္ဝန္ဟ္ပ္တုိ့၏ ပ္ယော္ရ္ဝ္ဟင္မ္ဟု၊ </Run>
+ </Str>
+ </Contents16>
+ </StTxtPara>
+</Body>
+
+<PageSetup>
+ <PageInfo>
+ <TopMargin9999><Integer val="72000"/></TopMargin9999>
+ <BottomMargin9999><Integer val="72000"/></BottomMargin9999>
+ <LeftMargin9999><Integer val="90000"/></LeftMargin9999>
+ <RightMargin9999><Integer val="90000"/></RightMargin9999>
+ <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999>
+ <FooterMargin9999><Integer val="36000"/></FooterMargin9999>
+ <PageSize9999><Integer val="0"/></PageSize9999>
+ <PageHeight9999><Integer val="792000"/></PageHeight9999>
+ <PageWidth9999><Integer val="612000"/></PageWidth9999>
+ <PageOrientation9999><Integer val="0"/></PageOrientation9999>
+ <Header9999>
+ <Str>
+ <Run ws="en">brumeseText.wpx</Run>
+ </Str>
+ </Header9999>
+ <Footer9999>
+ <Str>
+ <Run ws="en">&[page],&[date]</Run>
+ </Str>
+ </Footer9999>
+ </PageInfo>
+</PageSetup>
+
+</WpDoc>
diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_arabic.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_arabic.ttf Binary files differnew file mode 100644 index 00000000000..df25e54b3f3 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_arabic.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_badCmap.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_badCmap.ttf Binary files differnew file mode 100644 index 00000000000..d66c725f12e --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_badCmap.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_badVersion.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_badVersion.ttf Binary files differnew file mode 100644 index 00000000000..babe42e5352 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_badVersion.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_burmese.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_burmese.ttf Binary files differnew file mode 100644 index 00000000000..ab253fbbfd6 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_burmese.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_roman.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_roman.ttf Binary files differnew file mode 100644 index 00000000000..2001ff6b5ac --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_roman.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_taiviet.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_taiviet.ttf Binary files differnew file mode 100644 index 00000000000..3bf4a662b11 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_taiviet.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/grtest_xline.ttf b/Build/source/libs/graphite/test/RegressionTest/grtest_xline.ttf Binary files differnew file mode 100644 index 00000000000..537a4b9532a --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/grtest_xline.ttf diff --git a/Build/source/libs/graphite/test/RegressionTest/main.h b/Build/source/libs/graphite/test/RegressionTest/main.h new file mode 100644 index 00000000000..1fcdacf6293 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/main.h @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 2004 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: Main.h +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Header files to include in the Graphite regression test program. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +#ifdef _MSC_VER +#pragma once +#endif +#ifndef GRCOMPILER_H +#define GRCOMPILER_H 1 + +#define NO_EXCEPTIONS 1 + +// To allow call to IsDebuggerPresent: +#define _WIN32_WINNT WINVER + +//:>******************************************************************************************** +//:> Include files +//:>******************************************************************************************** +// #include "windows.h" +#include "stdafx.h" +////#include "resource.h" +// #include <hash_map> +#include <fstream> +#include <iostream> +#include <vector> +////#include <algorithm> +#include <string> +#ifdef _WIN32 +#include <crtdbg.h> +#endif // _WIN32 +#include <assert.h> + +////using std::max; +////using std::min; + +#include "GrCommon.h" +#include "GrPlatform.h" + +////////#include "LgCharPropsStub.h" + +#include "GrConstants.h" +///#include "TtfUtil.h" +///#include "Tt.h" + +#include "GrClient.h" +#include "ITextSource.h" +#include "SimpleTextSrc.h" +#include "IGrEngine.h" +#include "IGrJustifier.h" +#include "GrJustifier.h" +#include "SegmentAux.h" +#include "Font.h" +// #include "WinFont.h" +#include "FileFont.h" +#include "Segment.h" +#include "SegmentPainter.h" +// #include "WinSegmentPainter.h" + +#include "TestCase.h" +#include "RtTextSrc.h" + + +//:>******************************************************************************************** +//:> Functions +//:>******************************************************************************************** +void RunTests(int numberOfTests, TestCase * ptcaseList); +int RunOneTestCase(TestCase * ptcase, Segment * psegPrev, Segment ** ppsegRet, RtTextSrc ** pptsrcRet); +void OutputError(TestCase * ptcase, std::string strErr, int i = -1); +void OutputErrorWithValues(TestCase * ptcase, std::string strErr, int i, + int valueFound, int valueExpected); +void OutputErrorAux(TestCase * ptcase, std::string strErr, int i, + bool showValues, int valueFound, int valueExpected); +bool WriteToLog(std::string str, int i = -1); +bool WriteToLog(std::string str, int i, + bool showValues, int valueFound, int valueExpected); +bool WriteToLog(int n); + +#endif //!WRCOMPILER_H + diff --git a/Build/source/libs/graphite/test/RegressionTest/makedebug.bat b/Build/source/libs/graphite/test/RegressionTest/makedebug.bat new file mode 100644 index 00000000000..94d09eb720a --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/makedebug.bat @@ -0,0 +1,2 @@ +cls +nmake CFG=DEBUG -f makefile.vc
\ No newline at end of file diff --git a/Build/source/libs/graphite/test/RegressionTest/readme.txt b/Build/source/libs/graphite/test/RegressionTest/readme.txt new file mode 100644 index 00000000000..e9f7facad20 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/readme.txt @@ -0,0 +1,19 @@ +Graphite Regression Test + +COMPILING +Use makedebug.bat to build a debug version. Creating a release version is not supported. + +RUNNING +Extract the fonts from the fonts.zip file and install them. + +Options: +/d - breaks into the debugger (if any) when an error occurs +/s - silent mode; does not write to the standard output but only to the log file + +The program generates a file called grregtest.log with a list of errors. + +A file called tracelog.txt will be output for the tests for which tracing is turned on. + +ADDING TESTS +See TestCase.cpp. + diff --git a/Build/source/libs/graphite/test/RegressionTest/romanText.wpx b/Build/source/libs/graphite/test/RegressionTest/romanText.wpx new file mode 100644 index 00000000000..594cc886a0f --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/romanText.wpx @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd"> +<WpDoc wpxVersion="2.0"> + +<Languages> + <LgWritingSystem id="en" language="en" type="ISO-639-1"> + <Name24> + <AUni ws="en">English</AUni> + </Name24> + <Abbr24> + <AUni ws="en">Eng</AUni> + </Abbr24> + <Description24> + <AStr ws="en"> + <Run ws="en">The standard alphabetic representation of English (United States style).</Run> + </AStr> + </Description24> + <Locale24><Integer val="1033"/></Locale24> + <RightToLeft24><Boolean val="false"/></RightToLeft24> + <DefaultSerif24><Uni>Times New Roman</Uni></DefaultSerif24> + <DefaultSansSerif24><Uni>Arial</Uni></DefaultSansSerif24> + <DefaultBodyFont24><Uni>Charis SIL</Uni></DefaultBodyFont24> + <DefaultMonospace24><Uni>Courier New</Uni></DefaultMonospace24> + <ICULocale24><Uni>en</Uni></ICULocale24> + <KeyboardType24><Uni>standard</Uni></KeyboardType24> + <Collations24> + <LgCollation> + <Name30> + <AUni ws="en">Default Collation</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30> + </LgCollation> + <LgCollation> + <Name30> + <AUni ws="en">Case Sensitive</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CS_AI</Uni></WinCollation30> + </LgCollation> + </Collations24> + </LgWritingSystem> +</Languages> + +<Styles> + <StStyle> + <Name17><Uni>Normal</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni></Uni></BasedOn17> + <Next17><Uni>Normal</Uni></Next17> + <Rules17> + <Prop italic="off" bold="off" superscript="off" underline="none" fontsize="10000" fontsizeUnit="mpt" offset="0" offsetUnit="mpt" forecolor="black" backcolor="white" undercolor="black" align="leading" firstIndent="0" leadingIndent="0" trailingIndent="0" spaceBefore="0" spaceAfter="0" lineHeight="10000" lineHeightUnit="mpt" lineHeightType="atLeast" rightToLeft="0" borderTop="0" borderBottom="0" borderLeading="0" borderTrailing="0" borderColor="black" bulNumScheme="0" bulNumStartAt="1" fontFamily="<default serif>"> + <BulNumFontInfo backcolor="white" bold="off" fontsize="10000mpt" forecolor="black" italic="off" offset="0mpt" superscript="off" undercolor="black" underline="none" fontFamily="Times New Roman"/> + </Prop> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Bulleted List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Bulleted List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 1</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 1</Uni></Next17> + <Rules17> + <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 2</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 2</Uni></Next17> + <Rules17> + <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 3</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 3</Uni></Next17> + <Rules17> + <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Numbered List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Numbered List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="10"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>External Link</Uni></Name17> + <Type17><Integer val="1"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>External Link</Uni></Next17> + <Rules17> + <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/> + </Rules17> + </StStyle> +</Styles> + +<Body docRightToLeft="false"> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman">ẽ̀p͡sg˨˥˧ŊấĩĨm̼̀̈̄ffi</Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="20000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman">with features:</Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman" fontVariations="1026=1,1029=1,1032=1,1024=2,1051=0">ẽ̀p͡sg˨˥˧ŊấĩĨm̼̀̈̄ffi</Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman"></Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="20000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman">stacking and bridging:</Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop rightToLeft="0" namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman">a͝a t͝a à̀͝a </Run> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" forecolor="ff6000" fontFamily="Graphite Test Roman">ʃ̀̀͝a</Run> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman"> a̖̖a </Run> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" forecolor="blue" fontFamily="Graphite Test Roman">ʃ̀̀a</Run> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" fontFamily="Graphite Test Roman"> </Run> + <Run ws="en" fontsize="36000" fontsizeUnit="mpt" forecolor="yellow" fontFamily="Graphite Test Roman">a̖̖a</Run> + </Str> + </Contents16> + </StTxtPara> +</Body> + +<PageSetup> + <PageInfo> + <TopMargin9999><Integer val="72000"/></TopMargin9999> + <BottomMargin9999><Integer val="72000"/></BottomMargin9999> + <LeftMargin9999><Integer val="90000"/></LeftMargin9999> + <RightMargin9999><Integer val="90000"/></RightMargin9999> + <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999> + <FooterMargin9999><Integer val="36000"/></FooterMargin9999> + <PageSize9999><Integer val="0"/></PageSize9999> + <PageHeight9999><Integer val="792000"/></PageHeight9999> + <PageWidth9999><Integer val="612000"/></PageWidth9999> + <PageOrientation9999><Integer val="0"/></PageOrientation9999> + <Header9999> + <Str> + <Run ws="en">romanText.wpx</Run> + </Str> + </Header9999> + <Footer9999> + <Str> + <Run ws="en">&[page],&[date]</Run> + </Str> + </Footer9999> + </PageInfo> +</PageSetup> + +</WpDoc> diff --git a/Build/source/libs/graphite/test/RegressionTest/stdafx.cpp b/Build/source/libs/graphite/test/RegressionTest/stdafx.cpp new file mode 100644 index 00000000000..7f699d258e2 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// RegressionTest.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/Build/source/libs/graphite/test/RegressionTest/stdafx.h b/Build/source/libs/graphite/test/RegressionTest/stdafx.h new file mode 100644 index 00000000000..c5e242de5cb --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/stdafx.h @@ -0,0 +1,12 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + + +#include <iostream> +// #include <tchar.h> + +// TODO: reference additional headers your program requires here diff --git a/Build/source/libs/graphite/test/RegressionTest/taivietText.wpx b/Build/source/libs/graphite/test/RegressionTest/taivietText.wpx new file mode 100644 index 00000000000..964c4968611 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/taivietText.wpx @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd"> +<WpDoc wpxVersion="2.0"> + +<Languages> + <LgWritingSystem id="blt_TV" language="blt" type="ISO-639-2"> + <Name24> + <AUni ws="en">Tai Dam</AUni> + </Name24> + <Locale24><Integer val="1033"/></Locale24> + <RightToLeft24><Boolean val="false"/></RightToLeft24> + <FontVariation24><Uni>2001=0,2005=0,2101=1,1051=1,2102=1</Uni></FontVariation24> + <DefaultSerif24><Uni>Tai Heritage Graphite</Uni></DefaultSerif24> + <DefaultSansSerif24><Uni>Arial</Uni></DefaultSansSerif24> + <DefaultBodyFont24><Uni>Charis SIL</Uni></DefaultBodyFont24> + <DefaultMonospace24><Uni>Courier</Uni></DefaultMonospace24> + <ICULocale24><Uni>blt_TV</Uni></ICULocale24> + <KeyboardType24><Uni>standard</Uni></KeyboardType24> + <Collations24> + <LgCollation> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30> + </LgCollation> + </Collations24> + </LgWritingSystem> +</Languages> + +<Styles> + <StStyle> + <Name17><Uni>Normal</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni></Uni></BasedOn17> + <Next17><Uni>Normal</Uni></Next17> + <Rules17> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Bulleted List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Bulleted List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 1</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 1</Uni></Next17> + <Rules17> + <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 2</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 2</Uni></Next17> + <Rules17> + <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 3</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 3</Uni></Next17> + <Rules17> + <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Numbered List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Numbered List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="10"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>External Link</Uni></Name17> + <Type17><Integer val="1"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>External Link</Uni></Next17> + <Rules17> + <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/> + </Rules17> + </StStyle> +</Styles> + +<Body docRightToLeft="false"> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run></Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="blt_TV" fontsize="36000" fontsizeUnit="mpt" forecolor="transparent" fontFamily="Graphite Test TaiViet" fontVariations="2001=2,1051=0,2102=0"></Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="blt_TV" fontsize="36000" fontsizeUnit="mpt" forecolor="transparent" fontFamily="Graphite Test TaiViet" fontVariations="2001=2,2102=0"></Run> + </Str> + </Contents16> + </StTxtPara> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="blt_TV" fontsize="36000" fontsizeUnit="mpt" forecolor="transparent" fontFamily="Graphite Test TaiViet" fontVariations="2001=2,2102=1"></Run> + <Run ws="blt_TV" fontsize="36000" fontsizeUnit="mpt" forecolor="transparent" fontFamily="Graphite Test TaiViet" fontVariations="2001=2"></Run> + </Str> + </Contents16> + </StTxtPara> +</Body> + +<PageSetup> + <PageInfo> + <TopMargin9999><Integer val="72000"/></TopMargin9999> + <BottomMargin9999><Integer val="72000"/></BottomMargin9999> + <LeftMargin9999><Integer val="90000"/></LeftMargin9999> + <RightMargin9999><Integer val="90000"/></RightMargin9999> + <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999> + <FooterMargin9999><Integer val="36000"/></FooterMargin9999> + <PageSize9999><Integer val="0"/></PageSize9999> + <PageHeight9999><Integer val="792000"/></PageHeight9999> + <PageWidth9999><Integer val="612000"/></PageWidth9999> + <PageOrientation9999><Integer val="0"/></PageOrientation9999> + <Header9999> + <Str> + <Run ws="en">collision_examples.wpx</Run> + </Str> + </Header9999> + <Footer9999> + <Str> + <Run ws="en">&[page],&[date]</Run> + </Str> + </Footer9999> + </PageInfo> +</PageSetup> + +</WpDoc> diff --git a/Build/source/libs/graphite/test/RegressionTest/xline.gdl b/Build/source/libs/graphite/test/RegressionTest/xline.gdl new file mode 100644 index 00000000000..70bfa15902a --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/xline.gdl @@ -0,0 +1,146 @@ + +/********************************************************************************* + File: xline.gdl + + For testing cross-line contextualization. + + Compile with stddr.ttf + + To test, type something like these examples: + abc$x + abcx@ + abc$x@ + and force a line break after the x. +*********************************************************************************/ + +#include "stddef.gdh" + +Bidi = false; + +#define duplicated user1 + + +table(glyph) {MUnits = 1000 } + + g_A = codepoint("A"); + g_B = codepoint("B"); + g_C = codepoint("C"); + g_D = codepoint("D"); + g_E = codepoint("E"); + g_F = codepoint("F"); + g_G = codepoint("G"); + + g_a = codepoint("a"); + g_b = codepoint("b"); + g_c = codepoint("c"); + g_d = codepoint("d"); + g_e = codepoint("e"); + g_f = codepoint("f"); + g_g = codepoint("g"); + + g_x = codepoint("x"); + g_y = codepoint("y"); + g_z = codepoint("z"); + + g_asterisk = codepoint("*") { ptCenter = point(bb.width/2, bb.height/2) }; + g_dollar = codepoint("$") { xWid = aw }; + g_hash = codepoint("#"); + g_at = codepoint("@") { xWid = aw }; + g_amp = codepoint("&") {xWid = aw }; + g_percent = codepoint("%"); + + g_leftArrow = codepoint("<") { xWid = aw }; + g_rightArrow = codepoint(">") { xWid = aw }; + + clsUpper = codepoint("ABCDEFGHIJKLMNOPQRSTUVWXYZ") + { ptCenter = point(bb.width/2, ascent/2) }; + clsLower = codepoint("abcdefghijklmnopqrstuvwxyz"); + + clsMyAny = glyphid(2..216) { justify.stretch = 700m }; + + g_m = codepoint("m"); + g_Mlig = codepoint("M") { + component.one = box(0,0, bb.width/2, ascent); + component.two = box(bb.width/2,0, bb.width,ascent) }; + + gSpace = U+0020 { justify.stretch = 3000m }; + + clsXYZ = (g_x g_y g_z); + +endtable; // glyph + + +table(lb) + + // Allow non-optimal linebreaks after x, y, or z. + clsXYZ {break = BREAK_INTRA}; + +endtable; // lb + + +table(sub) + +pass(1) + + // Switch the $ and @ if they are both there, and insert & after the one on the first + // line and before the one on the second line. Note that these rules supercede the rule + // to insert the left- and right-arrows. + g_dollar _ _ g_at > @7 g_amp:7 g_amp:1 @1 + / _ _ ANY? # {break == BREAK_INTRA} ANY? _ _ ; + + g_dollar + clsXYZ {measure.endofline = g_at.aw - g_dollar.aw + g_amp.aw} + ANY {measure.startofline = g_dollar.aw - g_at.aw + g_amp.aw} + g_at; + g_dollar + clsXYZ {measure.endofline = g_at.aw - g_dollar.aw + g_amp.aw} + g_at {measure.startofline = g_dollar.aw - g_at.aw + g_amp.aw}; + + + // Just copy the $ to the following segment. + g_dollar _ > @1 {duplicated = true} g_dollar:1 + / _ {duplicated == false} ANY? ^ # {break == BREAK_INTRA} ANY? _ ; + + g_dollar + clsXYZ {measure.endofline = g_rightArrow.aw} + ANY {measure.startofline = g_dollar.aw + g_leftArrow.aw}; + + + // Just copy the @ to the previous segment. + _ g_at > g_at:5 @5 {duplicated = true} + / _ ANY? ^ # {break == BREAK_INTRA} ANY? _ {duplicated == false}; + + clsXYZ {measure.endofline = g_at.aw + g_rightArrow.aw} + ANY {measure.startofline = g_leftArrow.aw} + g_at; + + clsXYZ {measure.endofline = g_at.aw + g_rightArrow.aw} + g_at {measure.startofline = g_leftArrow.aw}; + + + // Insert a '<' at the beginning of the line and a '>' at the end. + _ > g_leftArrow / # _; + _ > g_rightArrow / clsMyAny _ # ^ ; + + clsMyAny {measure {startofline = g_leftArrow.aw; endofline = g_rightArrow.aw}}; + +endpass; + +pass(2) + + // Don't stretch trailing white space. + gSpace {justify.stretch = 0} / _ [gSpace [gSpace [gSpace gSpace?]? ]? ]? # ; + // In fact, don't stretch any line-boundary glyph. + clsMyAny {justify.stretch = 0} / _ #; + + +endpass; + +endtable; // sub + + +table(pos) + + clsMyAny {adv.x += justify.width}; + +endtable; // pos diff --git a/Build/source/libs/graphite/test/RegressionTest/xlineText.wpx b/Build/source/libs/graphite/test/RegressionTest/xlineText.wpx new file mode 100644 index 00000000000..a8d51fefda7 --- /dev/null +++ b/Build/source/libs/graphite/test/RegressionTest/xlineText.wpx @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE WpDoc SYSTEM "WorldPad.dtd"> +<WpDoc wpxVersion="2.0"> + +<Languages> + <LgWritingSystem id="en" language="en" type="ISO-639-1"> + <Name24> + <AUni ws="en">English</AUni> + </Name24> + <Locale24><Integer val="1033"/></Locale24> + <RightToLeft24><Boolean val="false"/></RightToLeft24> + <DefaultSerif24><Uni>Times New Roman</Uni></DefaultSerif24> + <DefaultSansSerif24><Uni>Arial</Uni></DefaultSansSerif24> + <DefaultMonospace24><Uni>Courier New</Uni></DefaultMonospace24> + <ICULocale24><Uni>en</Uni></ICULocale24> + <KeyboardType24><Uni>standard</Uni></KeyboardType24> + <Collations24> + <LgCollation> + <Name30> + <AUni ws="en">DefaultCollation</AUni> + </Name30> + <WinLCID30><Integer val="1033"/></WinLCID30> + <WinCollation30><Uni>Latin1_General_CI_AI</Uni></WinCollation30> + </LgCollation> + </Collations24> + </LgWritingSystem> +</Languages> + +<Styles> + <StStyle> + <Name17><Uni>Normal</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni></Uni></BasedOn17> + <Next17><Uni>Normal</Uni></Next17> + <Rules17> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Bulleted List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Bulleted List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="101" bulNumStartAt="1"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 1</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 1</Uni></Next17> + <Rules17> + <Prop bold="invert" fontsize="14000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 2</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 2</Uni></Next17> + <Rules17> + <Prop italic="invert" fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Heading 3</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Heading 3</Uni></Next17> + <Rules17> + <Prop fontsize="12000" fontsizeUnit="mpt" spaceBefore="12000" spaceAfter="3000"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>Numbered List</Uni></Name17> + <Type17><Integer val="0"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>Numbered List</Uni></Next17> + <Rules17> + <Prop firstIndent="-18000" bulNumScheme="10"/> + </Rules17> + </StStyle> + <StStyle> + <Name17><Uni>External Link</Uni></Name17> + <Type17><Integer val="1"/></Type17> + <BasedOn17><Uni>Normal</Uni></BasedOn17> + <Next17><Uni>External Link</Uni></Next17> + <Rules17> + <Prop underline="single" forecolor="7f007f" undercolor="7f007f"/> + </Rules17> + </StStyle> +</Styles> + +<Body docRightToLeft="false"> + <StTxtPara> + <StyleRules15> + <Prop namedStyle="Normal"/> + </StyleRules15> + <Contents16> + <Str> + <Run ws="en" fontsize="28000" fontsizeUnit="mpt" fontFamily="Graphite Test CrossLine">abcddddefx@ghijkmmmmn$yopppppqrsss$z@tttwwww</Run> + </Str> + </Contents16> + </StTxtPara> +</Body> + +<PageSetup> + <PageInfo> + <TopMargin9999><Integer val="72000"/></TopMargin9999> + <BottomMargin9999><Integer val="72000"/></BottomMargin9999> + <LeftMargin9999><Integer val="90000"/></LeftMargin9999> + <RightMargin9999><Integer val="90000"/></RightMargin9999> + <HeaderMargin9999><Integer val="36000"/></HeaderMargin9999> + <FooterMargin9999><Integer val="36000"/></FooterMargin9999> + <PageSize9999><Integer val="0"/></PageSize9999> + <PageHeight9999><Integer val="792000"/></PageHeight9999> + <PageWidth9999><Integer val="612000"/></PageWidth9999> + <PageOrientation9999><Integer val="0"/></PageOrientation9999> + <Header9999> + <Str> + <Run ws="en">xline_test.wpx</Run> + </Str> + </Header9999> + <Footer9999> + <Str> + <Run ws="en">&[page],&[date]</Run> + </Str> + </Footer9999> + </PageInfo> +</PageSetup> + +</WpDoc> |