diff options
Diffstat (limited to 'pdf/splash/SplashXPath.cc')
-rw-r--r-- | pdf/splash/SplashXPath.cc | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/pdf/splash/SplashXPath.cc b/pdf/splash/SplashXPath.cc deleted file mode 100644 index e1a3afb..0000000 --- a/pdf/splash/SplashXPath.cc +++ /dev/null @@ -1,417 +0,0 @@ -//======================================================================== -// -// SplashXPath.cc -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#include "gmem.h" -#include "SplashMath.h" -#include "SplashPath.h" -#include "SplashXPath.h" - -//------------------------------------------------------------------------ - -#define maxCurveSplits (1 << 10) - -//------------------------------------------------------------------------ -// SplashXPath -//------------------------------------------------------------------------ - -SplashXPath::SplashXPath() { - segs = NULL; - length = size = 0; -} - -SplashXPath::SplashXPath(SplashPath *path, SplashCoord flatness, - GBool closeSubpaths) { - SplashCoord xc, yc, dx, dy, r, x0, y0, x1, y1; - int quad0, quad1, quad; - int i, curSubpath; - GBool last; - - segs = NULL; - length = size = 0; - - i = 0; - curSubpath = 0; - while (i < path->length) { - - // first point in subpath - skip it - if (path->flags[i] & splashPathFirst) { - curSubpath = i; - ++i; - - } else { - - // curve segment - if (path->flags[i] & splashPathCurve) { - addCurve(path->pts[i-1].x, path->pts[i-1].y, - path->pts[i ].x, path->pts[i ].y, - path->pts[i+1].x, path->pts[i+1].y, - path->pts[i+2].x, path->pts[i+2].y, - flatness, - (path->flags[i-1] & splashPathFirst), - (path->flags[i+2] & splashPathLast), - !closeSubpaths && - (path->flags[i-1] & splashPathFirst) && - !(path->flags[i-1] & splashPathClosed), - !closeSubpaths && - (path->flags[i+2] & splashPathLast) && - !(path->flags[i+2] & splashPathClosed)); - i += 3; - - // clockwise circular arc - } else if (path->flags[i] & splashPathArcCW) { - xc = path->pts[i].x; - yc = path->pts[i].y; - dx = path->pts[i+1].x - xc; - dy = path->pts[i+1].y - yc; - r = splashSqrt(dx * dx + dy * dy); - if (path->pts[i-1].x < xc && path->pts[i-1].y <= yc) { - quad0 = 0; - } else if (path->pts[i-1].x >= xc && path->pts[i-1].y < yc) { - quad0 = 1; - } else if (path->pts[i-1].x > xc && path->pts[i-1].y >= yc) { - quad0 = 2; - } else { - quad0 = 3; - } - if (path->pts[i+1].x <= xc && path->pts[i+1].y < yc) { - quad1 = 0; - } else if (path->pts[i+1].x > xc && path->pts[i+1].y <= yc) { - quad1 = 1; - } else if (path->pts[i+1].x >= xc && path->pts[i+1].y > yc) { - quad1 = 2; - } else { - quad1 = 3; - } - x0 = path->pts[i-1].x; - y0 = path->pts[i-1].y; - x1 = y1 = 0; // make gcc happy - quad = quad0; - while (1) { - switch (quad) { - case 0: x1 = xc; y1 = yc - r; break; - case 1: x1 = xc + r; y1 = yc; break; - case 2: x1 = xc; y1 = yc + r; break; - case 3: x1 = xc - r; y1 = yc; break; - } - last = gFalse; - if (quad == quad1) { - switch (quad) { - case 0: - case 1: last = path->pts[i+1].x > x0; break; - case 2: - case 3: last = path->pts[i+1].x < x0; break; - } - } - if (last) { - addArc(x0, y0, path->pts[i+1].x, path->pts[i+1].y, - xc, yc, r, quad, flatness, - quad == quad0 && (path->flags[i-1] & splashPathFirst), - (path->flags[i+1] & splashPathLast), - quad == quad0 && !closeSubpaths && - (path->flags[i-1] & splashPathFirst) && - !(path->flags[i-1] & splashPathClosed), - !closeSubpaths && - (path->flags[i+1] & splashPathLast) && - !(path->flags[i+1] & splashPathClosed)); - break; - } else { - addArc(x0, y0, x1, y1, - xc, yc, r, quad, flatness, - quad == quad0 && (path->flags[i-1] & splashPathFirst), - gFalse, - quad == quad0 && !closeSubpaths && - (path->flags[i-1] & splashPathFirst) && - !(path->flags[i-1] & splashPathClosed), - gFalse); - x0 = x1; - y0 = y1; - quad = (quad + 1) & 3; - } - } - i += 2; - - // line segment - } else { - addSegment(path->pts[i-1].x, path->pts[i-1].y, - path->pts[i].x, path->pts[i].y, - path->flags[i-1] & splashPathFirst, - path->flags[i] & splashPathLast, - !closeSubpaths && - (path->flags[i-1] & splashPathFirst) && - !(path->flags[i-1] & splashPathClosed), - !closeSubpaths && - (path->flags[i] & splashPathLast) && - !(path->flags[i] & splashPathClosed)); - ++i; - } - - // close a subpath - if (closeSubpaths && - (path->flags[i-1] & splashPathLast) && - (path->pts[i-1].x != path->pts[curSubpath].x || - path->pts[i-1].y != path->pts[curSubpath]. y)) { - addSegment(path->pts[i-1].x, path->pts[i-1].y, - path->pts[curSubpath].x, path->pts[curSubpath].y, - gFalse, gTrue, gFalse, gFalse); - } - } - } -} - -SplashXPath::SplashXPath(SplashXPath *xPath) { - length = xPath->length; - size = xPath->size; - segs = (SplashXPathSeg *)gmalloc(size * sizeof(SplashXPathSeg)); - memcpy(segs, xPath->segs, length * sizeof(SplashXPathSeg)); -} - -SplashXPath::~SplashXPath() { - gfree(segs); -} - -// Add space for <nSegs> more segments -void SplashXPath::grow(int nSegs) { - if (length + nSegs > size) { - if (size == 0) { - size = 32; - } - while (size < length + nSegs) { - size *= 2; - } - segs = (SplashXPathSeg *)grealloc(segs, size * sizeof(SplashXPathSeg)); - } -} - -void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3, - SplashCoord flatness, - GBool first, GBool last, GBool end0, GBool end1) { - SplashCoord cx[maxCurveSplits + 1][3]; - SplashCoord cy[maxCurveSplits + 1][3]; - int cNext[maxCurveSplits + 1]; - SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; - SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; - SplashCoord dx, dy, mx, my, d1, d2, flatness2; - int p1, p2, p3; - - flatness2 = flatness * flatness; - - // initial segment - p1 = 0; - p2 = maxCurveSplits; - cx[p1][0] = x0; cy[p1][0] = y0; - cx[p1][1] = x1; cy[p1][1] = y1; - cx[p1][2] = x2; cy[p1][2] = y2; - cx[p2][0] = x3; cy[p2][0] = y3; - cNext[p1] = p2; - - while (p1 < maxCurveSplits) { - - // get the next segment - xl0 = cx[p1][0]; yl0 = cy[p1][0]; - xx1 = cx[p1][1]; yy1 = cy[p1][1]; - xx2 = cx[p1][2]; yy2 = cy[p1][2]; - p2 = cNext[p1]; - xr3 = cx[p2][0]; yr3 = cy[p2][0]; - - // compute the distances from the control points to the - // midpoint of the straight line (this is a bit of a hack, but - // it's much faster than computing the actual distances to the - // line) - mx = (xl0 + xr3) * 0.5; - my = (yl0 + yr3) * 0.5; - dx = xx1 - mx; - dy = yy1 - my; - d1 = dx*dx + dy*dy; - dx = xx2 - mx; - dy = yy2 - my; - d2 = dx*dx + dy*dy; - - // if the curve is flat enough, or no more subdivisions are - // allowed, add the straight line segment - if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) { - addSegment(xl0, yl0, xr3, yr3, - p1 == 0 && first, - p2 == maxCurveSplits && last, - p1 == 0 && end0, - p2 == maxCurveSplits && end1); - p1 = p2; - - // otherwise, subdivide the curve - } else { - xl1 = (xl0 + xx1) * 0.5; - yl1 = (yl0 + yy1) * 0.5; - xh = (xx1 + xx2) * 0.5; - yh = (yy1 + yy2) * 0.5; - xl2 = (xl1 + xh) * 0.5; - yl2 = (yl1 + yh) * 0.5; - xr2 = (xx2 + xr3) * 0.5; - yr2 = (yy2 + yr3) * 0.5; - xr1 = (xh + xr2) * 0.5; - yr1 = (yh + yr2) * 0.5; - xr0 = (xl2 + xr1) * 0.5; - yr0 = (yl2 + yr1) * 0.5; - // add the new subdivision points - p3 = (p1 + p2) / 2; - cx[p1][1] = xl1; cy[p1][1] = yl1; - cx[p1][2] = xl2; cy[p1][2] = yl2; - cNext[p1] = p3; - cx[p3][0] = xr0; cy[p3][0] = yr0; - cx[p3][1] = xr1; cy[p3][1] = yr1; - cx[p3][2] = xr2; cy[p3][2] = yr2; - cNext[p3] = p2; - } - } -} - -void SplashXPath::addArc(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord xc, SplashCoord yc, - SplashCoord r, int quad, - SplashCoord flatness, - GBool first, GBool last, GBool end0, GBool end1) { - SplashCoord px[maxCurveSplits + 1]; - SplashCoord py[maxCurveSplits + 1]; - int pNext[maxCurveSplits + 1]; - SplashCoord r2, flatness2; - SplashCoord xx0, yy0, xx1, yy1, xm, ym, t, dx, dy; - int p1, p2, p3; - - r2 = r * r; - flatness2 = flatness * flatness; - - // initial segment - p1 = 0; - p2 = maxCurveSplits; - px[p1] = x0; py[p1] = y0; - px[p2] = x1; py[p2] = y1; - pNext[p1] = p2; - - while (p1 < maxCurveSplits) { - - // get the next segment - xx0 = px[p1]; yy0 = py[p1]; - p2 = pNext[p1]; - xx1 = px[p2]; yy1 = py[p2]; - - // compute the arc midpoint - t = (xx0 - xc) * (xx1 - xc) - (yy0 - yc) * (yy1 - yc); - xm = splashSqrt(0.5 * (r2 + t)); - ym = splashSqrt(0.5 * (r2 - t)); - switch (quad) { - case 0: xm = xc - xm; ym = yc - ym; break; - case 1: xm = xc + xm; ym = yc - ym; break; - case 2: xm = xc + xm; ym = yc + ym; break; - case 3: xm = xc - xm; ym = yc + ym; break; - } - - // compute distance from midpoint of straight segment to midpoint - // of arc - dx = 0.5 * (xx0 + xx1) - xm; - dy = 0.5 * (yy0 + yy1) - ym; - - // if the arc is flat enough, or no more subdivisions are allowed, - // add the straight line segment - if (p2 - p1 == 1 || dx * dx + dy * dy <= flatness2) { - addSegment(xx0, yy0, xx1, yy1, - p1 == 0 && first, - p2 == maxCurveSplits && last, - p1 == 0 && end0, - p2 == maxCurveSplits && end1); - p1 = p2; - - // otherwise, subdivide the arc - } else { - p3 = (p1 + p2) / 2; - px[p3] = xm; - py[p3] = ym; - pNext[p1] = p3; - pNext[p3] = p2; - } - } -} - -void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - GBool first, GBool last, GBool end0, GBool end1) { - grow(1); - segs[length].x0 = x0; - segs[length].y0 = y0; - segs[length].x1 = x1; - segs[length].y1 = y1; - segs[length].flags = 0; - if (first) { - segs[length].flags |= splashXPathFirst; - } - if (last) { - segs[length].flags |= splashXPathLast; - } - if (end0) { - segs[length].flags |= splashXPathEnd0; - } - if (end1) { - segs[length].flags |= splashXPathEnd1; - } - if (y1 == y0) { - segs[length].dxdy = segs[length].dydx = 0; - segs[length].flags |= splashXPathHoriz; - if (x1 == x0) { - segs[length].flags |= splashXPathVert; - } - } else if (x1 == x0) { - segs[length].dxdy = segs[length].dydx = 0; - segs[length].flags |= splashXPathVert; - } else { - segs[length].dxdy = (x1 - x0) / (y1 - y0); - segs[length].dydx = 1 / segs[length].dxdy; - } - if (y0 > y1) { - segs[length].flags |= splashXPathFlip; - } - ++length; -} - -static int cmpXPathSegs(const void *arg0, const void *arg1) { - SplashXPathSeg *seg0 = (SplashXPathSeg *)arg0; - SplashXPathSeg *seg1 = (SplashXPathSeg *)arg1; - SplashCoord x0, y0, x1, y1; - - if (seg0->flags & splashXPathFlip) { - x0 = seg0->x1; - y0 = seg0->y1; - } else { - x0 = seg0->x0; - y0 = seg0->y0; - } - if (seg1->flags & splashXPathFlip) { - x1 = seg1->x1; - y1 = seg1->y1; - } else { - x1 = seg1->x0; - y1 = seg1->y0; - } - if (y0 != y1) { - return (y0 > y1) ? 1 : -1; - } - if (x0 != x1) { - return (x0 > x1) ? 1 : -1; - } - return 0; -} - -void SplashXPath::sort() { - qsort(segs, length, sizeof(SplashXPathSeg), &cmpXPathSegs); -} |