[poppler] Branch 'xpdf303merge' - goo/FixedPoint.cc goo/FixedPoint.h splash/Splash.cc splash/SplashFTFont.cc splash/SplashMath.h splash/SplashXPath.cc
Albert Astals Cid
aacid at kemper.freedesktop.org
Tue Aug 30 07:40:39 PDT 2011
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 <aacid at kde.org>
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
More information about the poppler
mailing list