goo/FixedPoint.cc | 51 +++++++++++++++++++++++++++++++------------------ goo/FixedPoint.h | 15 ++++++++++++-- splash/Splash.cc | 12 +++++++++++ splash/SplashFTFont.cc | 16 +++++++-------- splash/SplashMath.h | 8 ++++--- splash/SplashXPath.cc | 9 ++++++++ 6 files changed, 80 insertions(+), 31 deletions(-)
New commits: commit faaba717046ba87ef5ded614e2bcab6260a9f7c2 Author: Albert Astals Cid <[email protected]> Date: Tue Aug 30 16:36:24 2011 +0200 xpdf303: FixedPoint improvements diff --git a/goo/FixedPoint.cc b/goo/FixedPoint.cc index 79a6a9a..26b2f0f 100644 --- a/goo/FixedPoint.cc +++ b/goo/FixedPoint.cc @@ -82,28 +82,32 @@ FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) { } int FixedPoint::mul(int x, int y) { -#if 1 //~tmp - return ((FixPtInt64)x * y) >> fixptShift; -#else - int ah0, ah, bh, al, bl; - ah0 = x & fixptMaskH; - ah = x >> fixptShift; - al = x - ah0; - bh = y >> fixptShift; - bl = y - (bh << fixptShift); - return ah0 * bh + ah * bl + al * bh + ((al * bl) >> fixptShift); -#endif + FixPtInt64 z; + + z = ((FixPtInt64)x * y) >> fixptShift; + if (z > 0x7fffffffLL) { + return 0x7fffffff; + } else if (z < -0x80000000LL) { + return 0x80000000; + } else { + return (int)z; + } } int FixedPoint::div(int x, int y) { -#if 1 //~tmp - return ((FixPtInt64)x << fixptShift) / y; -#else -#endif + FixPtInt64 z; + + z = ((FixPtInt64)x << fixptShift) / y; + if (z > 0x7fffffffLL) { + return 0x7fffffff; + } else if (z < -0x80000000LL) { + return 0x80000000; + } else { + return (int)z; + } } GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) { -#if 1 //~tmp FixPtInt64 z; z = ((FixPtInt64)x.val << fixptShift) / y.val; @@ -113,8 +117,19 @@ GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) { } result->val = z; return gTrue; -#else -#endif +} + +GBool FixedPoint::checkDet(FixedPoint m11, FixedPoint m12, + FixedPoint m21, FixedPoint m22, + FixedPoint epsilon) { + FixPtInt64 det, e; + + det = (FixPtInt64)m11.val * (FixPtInt64)m22.val + - (FixPtInt64)m12.val * (FixPtInt64)m21.val; + e = (FixPtInt64)epsilon.val << fixptShift; + // NB: this comparison has to be >= not > because epsilon can be + // truncated to zero as a fixed point value. + return det >= e || det <= -e; } #endif // USE_FIXEDPOINT diff --git a/goo/FixedPoint.h b/goo/FixedPoint.h index 08936bc..afe21d9 100644 --- a/goo/FixedPoint.h +++ b/goo/FixedPoint.h @@ -45,7 +45,7 @@ public: operator int() { return val >> fixptShift; } - int getRaw() { return val; } + int get16Dot16() { return val; } FixedPoint operator =(FixedPoint x) { val = x.val; return *this; } @@ -132,6 +132,11 @@ public: static int round(FixedPoint x) { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; } + // Computes (x+y)/2 avoiding overflow and LSbit accuracy issues. + static FixedPoint avg(FixedPoint x, FixedPoint y) + { return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); } + + static FixedPoint sqrt(FixedPoint x); static FixedPoint pow(FixedPoint x, FixedPoint y); @@ -140,6 +145,12 @@ public: // overflow. static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result); + // Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case + // where the multiplications overflow. + static GBool checkDet(FixedPoint m11, FixedPoint m12, + FixedPoint m21, FixedPoint m22, + FixedPoint epsilon); + private: static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; } @@ -147,7 +158,7 @@ private: static int mul(int x, int y); static int div(int x, int y); - int val; // 16.16 fixed point + int val; // fixed point: (n-fixptShift).(fixptShift) }; #endif // USE_FIXEDPOINT diff --git a/splash/Splash.cc b/splash/Splash.cc index 9deec10..c385409 100644 --- a/splash/Splash.cc +++ b/splash/Splash.cc @@ -1397,7 +1397,11 @@ SplashPath *Splash::flattenPath(SplashPath *path, SplashCoord *matrix, int i; fPath = new SplashPath(); +#if USE_FIXEDPOINT + flatness2 = flatness; +#else flatness2 = flatness * flatness; +#endif i = 0; while (i < path->length) { flag = path->flags[i]; @@ -1462,13 +1466,21 @@ void Splash::flattenCurve(SplashCoord x0, SplashCoord y0, // line) transform(matrix, (xl0 + xr3) * 0.5, (yl0 + yr3) * 0.5, &mx, &my); transform(matrix, xx1, yy1, &tx, &ty); +#if USE_FIXEDPOINT + d1 = splashDist(tx, ty, mx, my); +#else dx = tx - mx; dy = ty - my; d1 = dx*dx + dy*dy; +#endif transform(matrix, xx2, yy2, &tx, &ty); +#if USE_FIXEDPOINT + d2 = splashDist(tx, ty, mx, my); +#else dx = tx - mx; dy = ty - my; d2 = dx*dx + dy*dy; +#endif // if the curve is flat enough, or no more subdivisions are // allowed, add the straight line segment diff --git a/splash/SplashFTFont.cc b/splash/SplashFTFont.cc index eea3d64..55a4957 100644 --- a/splash/SplashFTFont.cc +++ b/splash/SplashFTFont.cc @@ -146,14 +146,14 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA, // compute the transform matrix #if USE_FIXEDPOINT - matrix.xx = (FT_Fixed)((mat[0] / size).getRaw()); - matrix.yx = (FT_Fixed)((mat[1] / size).getRaw()); - matrix.xy = (FT_Fixed)((mat[2] / size).getRaw()); - matrix.yy = (FT_Fixed)((mat[3] / size).getRaw()); - textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)).getRaw()); - textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)).getRaw()); - textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)).getRaw()); - textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)).getRaw()); + matrix.xx = (FT_Fixed)((mat[0] / size).get16Dot16()); + matrix.yx = (FT_Fixed)((mat[1] / size).get16Dot16()); + matrix.xy = (FT_Fixed)((mat[2] / size).get16Dot16()); + matrix.yy = (FT_Fixed)((mat[3] / size).get16Dot16()); + textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)).get16Dot16()); + textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)).get16Dot16()); + textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)).get16Dot16()); + textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)).get16Dot16()); #else matrix.xx = (FT_Fixed)((mat[0] / size) * 65536); matrix.yx = (FT_Fixed)((mat[1] / size) * 65536); diff --git a/splash/SplashMath.h b/splash/SplashMath.h index 924af6a..272c90c 100644 --- a/splash/SplashMath.h +++ b/splash/SplashMath.h @@ -97,15 +97,17 @@ static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0, #if USE_FIXEDPOINT // this handles the situation where dx*dx or dy*dy is too large to // fit in the 16.16 fixed point format - SplashCoord dxa, dya; + SplashCoord dxa, dya, d; dxa = splashAbs(dx); dya = splashAbs(dy); if (dxa == 0 && dya == 0) { return 0; } else if (dxa > dya) { - return dxa * FixedPoint::sqrt(dya / dxa + 1); + d = dya / dxa; + return dxa * FixedPoint::sqrt(d*d + 1); } else { - return dya * FixedPoint::sqrt(dxa / dya + 1); + d = dxa / dya; + return dya * FixedPoint::sqrt(d*d + 1); } #else return splashSqrt(dx * dx + dy * dy); diff --git a/splash/SplashXPath.cc b/splash/SplashXPath.cc index 37d164d..c51c908 100644 --- a/splash/SplashXPath.cc +++ b/splash/SplashXPath.cc @@ -289,7 +289,11 @@ void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0, SplashCoord dx, dy, mx, my, d1, d2, flatness2; int p1, p2, p3; +#if USE_FIXEDPOINT + flatness2 = flatness; +#else flatness2 = flatness * flatness; +#endif // initial segment p1 = 0; @@ -315,12 +319,17 @@ void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0, // line) mx = (xl0 + xr3) * 0.5; my = (yl0 + yr3) * 0.5; +#if USE_FIXEDPOINT + d1 = splashDist(xx1, yy1, mx, my); + d2 = splashDist(xx2, yy2, mx, my); +#else dx = xx1 - mx; dy = yy1 - my; d1 = dx*dx + dy*dy; dx = xx2 - mx; dy = yy2 - my; d2 = dx*dx + dy*dy; +#endif // if the curve is flat enough, or no more subdivisions are // allowed, add the straight line segment _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
