summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc645
1 files changed, 0 insertions, 645 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
deleted file mode 100644
index 4c77765723e..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
+++ /dev/null
@@ -1,645 +0,0 @@
-//========================================================================
-//
-// SplashXPath.cc
-//
-// Copyright 2003-2013 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#if HAVE_STD_SORT
-#include <algorithm>
-#endif
-#include "gmem.h"
-#include "gmempp.h"
-#include "SplashMath.h"
-#include "SplashPath.h"
-#include "SplashXPath.h"
-
-//------------------------------------------------------------------------
-
-#define minCosSquaredJoinAngle 0.75
-#define maxPointToLineDistanceSquared 0.04
-
-//------------------------------------------------------------------------
-
-struct SplashXPathPoint {
- SplashCoord x, y;
-};
-
-struct SplashXPathAdjust {
- int firstPt, lastPt; // range of points
- GBool vert; // vertical or horizontal hint
- SplashCoord x0a, x0b, // hint boundaries
- xma, xmb,
- x1a, x1b;
- SplashCoord x0, x1, xm; // adjusted coordinates
-};
-
-//------------------------------------------------------------------------
-
-// Transform a point from user space to device space.
-inline void SplashXPath::transform(SplashCoord *matrix,
- SplashCoord xi, SplashCoord yi,
- SplashCoord *xo, SplashCoord *yo) {
- // [ m[0] m[1] 0 ]
- // [xo yo 1] = [xi yi 1] * [ m[2] m[3] 0 ]
- // [ m[4] m[5] 1 ]
- *xo = xi * matrix[0] + yi * matrix[2] + matrix[4];
- *yo = xi * matrix[1] + yi * matrix[3] + matrix[5];
-}
-
-//------------------------------------------------------------------------
-// SplashXPath
-//------------------------------------------------------------------------
-
-// SplashXPath segment coords are clipped to +/-maxCoord to avoid
-// problems. The xMin/yMin/xMax/yMax fields are 32-bit integers, so
-// coords need to be < 2^31 / aa{Horiz,Vert}.
-#define maxCoord 100000000.0
-
-void SplashXPath::clampCoords(SplashCoord *x, SplashCoord *y) {
-#if !USE_FIXEDPOINT
- if (*x > maxCoord) {
- *x = maxCoord;
- } else if (*x < -maxCoord) {
- *x = -maxCoord;
- }
- if (*y > maxCoord) {
- *y = maxCoord;
- } else if (*y < -maxCoord) {
- *y = -maxCoord;
- }
-#endif
-}
-
-SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool closeSubpaths,
- GBool simplify,
- SplashStrokeAdjustMode strokeAdjMode) {
- SplashXPathPoint *pts;
- SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xsp, ysp, t;
- int curSubpath, firstSegInSubpath, i;
- GBool adjusted;
-
- //--- transform the points
- pts = (SplashXPathPoint *)gmallocn(path->length, sizeof(SplashXPathPoint));
- for (i = 0; i < path->length; ++i) {
- transform(matrix, path->pts[i].x, path->pts[i].y, &pts[i].x, &pts[i].y);
- clampCoords(&pts[i].x, &pts[i].y);
- }
-
- //--- do stroke adjustment
- if (path->hints) {
- adjusted = strokeAdjust(pts, path->hints, path->hintsLength,
- strokeAdjMode);
- } else {
- adjusted = gFalse;
- }
-
- //--- construct the segments
-
- segs = NULL;
- length = size = 0;
-
- x0 = y0 = xsp = ysp = 0; // make gcc happy
- curSubpath = 0;
- firstSegInSubpath = 0;
- i = 0;
- while (i < path->length) {
-
- // first point in subpath - skip it
- if (path->flags[i] & splashPathFirst) {
- x0 = pts[i].x;
- y0 = pts[i].y;
- xsp = x0;
- ysp = y0;
- curSubpath = i;
- ++i;
-
- } else {
-
- // curve segment
- if (path->flags[i] & splashPathCurve) {
- x1 = pts[i].x;
- y1 = pts[i].y;
- x2 = pts[i+1].x;
- y2 = pts[i+1].y;
- x3 = pts[i+2].x;
- y3 = pts[i+2].y;
- addCurve(x0, y0, x1, y1, x2, y2, x3, y3,
- 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));
- x0 = x3;
- y0 = y3;
- i += 3;
-
- // line segment
- } else {
- x1 = pts[i].x;
- y1 = pts[i].y;
- addSegment(x0, y0, x1, y1);
- x0 = x1;
- y0 = y1;
- ++i;
- }
-
- // end a subpath
- if (path->flags[i-1] & splashPathLast) {
- if (closeSubpaths &&
- (pts[i-1].x != pts[curSubpath].x ||
- pts[i-1].y != pts[curSubpath].y)) {
- addSegment(x0, y0, xsp, ysp);
- }
- if (simplify && !adjusted) {
- mergeSegments(firstSegInSubpath);
- }
- firstSegInSubpath = length;
- }
- }
- }
-
- gfree(pts);
-
- finishSegments();
-
- //--- check for a rectangle
- isRect = gFalse;
- rectX0 = rectY0 = rectX1 = rectY1 = 0;
- if (length == 4) {
-#if HAVE_STD_SORT
- std::sort(segs, segs + length, SplashXPathSeg::cmpY);
-#else
- qsort(segs, length, sizeof(SplashXPathSeg), &SplashXPathSeg::cmpY);
-#endif
- if (segs[0].y0 == segs[0].y1 &&
- segs[1].x0 == segs[1].x1 &&
- segs[2].x0 == segs[2].x1 &&
- segs[3].y0 == segs[3].y1) {
- isRect = gTrue;
- rectX0 = segs[1].x0;
- rectX1 = segs[2].x0;
- rectY0 = segs[0].y0;
- rectY1 = segs[3].y0;
- } else if (segs[0].x0 == segs[0].x1 &&
- segs[1].y0 == segs[1].y1 &&
- segs[2].x0 == segs[2].x1 &&
- segs[3].y0 == segs[3].y1) {
- isRect = gTrue;
- rectX0 = segs[0].x0;
- rectX1 = segs[2].x0;
- rectY0 = segs[1].y0;
- rectY1 = segs[3].y0;
- } else if (segs[0].x0 == segs[0].x1 &&
- segs[1].x0 == segs[1].x1 &&
- segs[2].y0 == segs[2].y1 &&
- segs[3].y0 == segs[3].y1) {
- isRect = gTrue;
- rectX0 = segs[0].x0;
- rectX1 = segs[1].x0;
- rectY0 = segs[2].y0;
- rectY1 = segs[3].y0;
- }
- if (isRect) {
- if (rectX0 > rectX1) {
- t = rectX0; rectX0 = rectX1; rectX1 = t;
- }
- if (rectY0 > rectY1) {
- t = rectY0; rectY0 = rectY1; rectY1 = t;
- }
- }
- }
-}
-
-GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts,
- SplashPathHint *hints, int nHints,
- SplashStrokeAdjustMode strokeAdjMode) {
- SplashXPathAdjust *adjusts, *adjust;
- SplashPathHint *hint;
- SplashCoord x0, y0, x1, y1, x2, y2, x3, y3;
- SplashCoord adj0, adj1, w, d;
- int xi0, xi1;
- int i, j;
- GBool adjusted;
-
- adjusted = gFalse;
-
- // set up the stroke adjustment hints
- adjusts = (SplashXPathAdjust *)gmallocn(nHints, sizeof(SplashXPathAdjust));
- for (i = 0; i < nHints; ++i) {
- hint = &hints[i];
- x0 = pts[hint->ctrl0 ].x; y0 = pts[hint->ctrl0 ].y;
- x1 = pts[hint->ctrl0 + 1].x; y1 = pts[hint->ctrl0 + 1].y;
- x2 = pts[hint->ctrl1 ].x; y2 = pts[hint->ctrl1 ].y;
- x3 = pts[hint->ctrl1 + 1].x; y3 = pts[hint->ctrl1 + 1].y;
- w = -1;
- if (splashAbs(x0 - x1) < 0.01 && splashAbs(x2 - x3) < 0.01) {
- adjusts[i].vert = gTrue;
- adj0 = x0;
- adj1 = x2;
- if (hint->projectingCap) {
- w = splashAbs(y1 - y0);
- }
- } else if (splashAbs(y0 - y1) < 0.01 && splashAbs(y2 - y3) < 0.01) {
- adjusts[i].vert = gFalse;
- adj0 = y0;
- adj1 = y2;
- if (hint->projectingCap) {
- w = splashAbs(x1 - x0);
- }
- } else {
- goto done;
- }
- if (adj0 > adj1) {
- x0 = adj0;
- adj0 = adj1;
- adj1 = x0;
- }
- d = adj1 - adj0;
- if (d > 0.04) {
- d = 0.01;
- } else {
- d *= 0.25;
- }
- adjusts[i].x0a = adj0 - d;
- adjusts[i].x0b = adj0 + d;
- adjusts[i].xma = (SplashCoord)0.5 * (adj0 + adj1) - d;
- adjusts[i].xmb = (SplashCoord)0.5 * (adj0 + adj1) + d;
- adjusts[i].x1a = adj1 - d;
- adjusts[i].x1b = adj1 + d;
- splashStrokeAdjust(adj0, adj1, &xi0, &xi1, strokeAdjMode, w);
- adjusts[i].x0 = (SplashCoord)xi0;
- // the "minus epsilon" thing here is needed when vector
- // antialiasing is turned off -- otherwise stroke adjusted lines
- // will touch an extra pixel on one edge
- adjusts[i].x1 = (SplashCoord)xi1 - 0.001;
- adjusts[i].xm = (SplashCoord)0.5 * (adjusts[i].x0 + adjusts[i].x1);
- adjusts[i].firstPt = hint->firstPt;
- adjusts[i].lastPt = hint->lastPt;
- }
-
- // perform stroke adjustment
- for (i = 0, adjust = adjusts; i < nHints; ++i, ++adjust) {
- for (j = adjust->firstPt; j <= adjust->lastPt; ++j) {
- if (adjust->vert) {
- x0 = pts[j].x;
- if (x0 > adjust->x0a && x0 < adjust->x0b) {
- pts[j].x = adjust->x0;
- } else if (x0 > adjust->xma && x0 < adjust->xmb) {
- pts[j].x = adjust->xm;
- } else if (x0 > adjust->x1a && x0 < adjust->x1b) {
- pts[j].x = adjust->x1;
- }
- } else {
- y0 = pts[j].y;
- if (y0 > adjust->x0a && y0 < adjust->x0b) {
- pts[j].y = adjust->x0;
- } else if (y0 > adjust->xma && y0 < adjust->xmb) {
- pts[j].y = adjust->xm;
- } else if (y0 > adjust->x1a && y0 < adjust->x1b) {
- pts[j].y = adjust->x1;
- }
- }
- }
- }
- adjusted = gTrue;
-
- done:
- gfree(adjusts);
- return adjusted;
-}
-
-SplashXPath::SplashXPath(SplashXPath *xPath) {
- length = xPath->length;
- size = xPath->size;
- segs = (SplashXPathSeg *)gmallocn(size, sizeof(SplashXPathSeg));
- memcpy(segs, xPath->segs, length * sizeof(SplashXPathSeg));
- xMin = xPath->xMin;
- yMin = xPath->yMin;
- xMax = xPath->xMax;
- yMax = xPath->yMax;
-}
-
-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 *)greallocn(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[splashMaxCurveSplits + 1][3];
- SplashCoord cy[splashMaxCurveSplits + 1][3];
- int cNext[splashMaxCurveSplits + 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;
-
-#if USE_FIXEDPOINT
- flatness2 = flatness;
-#else
- flatness2 = flatness * flatness;
-#endif
-
- // initial segment
- p1 = 0;
- p2 = splashMaxCurveSplits;
- 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 < splashMaxCurveSplits) {
-
- // 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;
-#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
- if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) {
- addSegment(xl0, yl0, xr3, yr3);
- 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::addSegment(SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1) {
- grow(1);
- segs[length].x0 = x0;
- segs[length].y0 = y0;
- segs[length].x1 = x1;
- segs[length].y1 = y1;
- ++length;
-}
-
-// Returns true if the angle between (x0,y0)-(x1,y1) and
-// (x1,y1)-(x2,y2) is close to 180 degrees.
-static GBool joinAngleIsFlat(SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord x2, SplashCoord y2) {
- SplashCoord dx1, dy1, dx2, dy2, d, len1, len2;
-
- dx1 = x1 - x0;
- dy1 = y1 - y0;
- dx2 = x2 - x1;
- dy2 = y2 - y1;
- d = dx1 * dx2 + dy1 * dy2;
- len1 = dx1 * dx1 + dy1 * dy1;
- len2 = dx2 * dx2 + dy2 * dy2;
- return d > 0 && d * d > len1 * len2 * minCosSquaredJoinAngle;
-}
-
-// Returns true if (x1,y1) is sufficiently close to the segment
-// (x0,y0)-(x2,y2), looking at the perpendicular point-to-line
-// distance.
-static GBool pointCloseToSegment(SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord x2, SplashCoord y2) {
- SplashCoord t1, t2, dx, dy;
-
- // compute the perpendicular distance from the point to the segment,
- // i.e., the projection of (x0,y0)-(x1,y1) onto a unit normal to the
- // segment (this actually computes the square of the distance)
- dx = x2 - x0;
- dy = y2 - y0;
- t1 = dx*dx + dy*dy;
- if (t1 < 0.0001) {
- // degenerate case: (x0,y0) and (x2,y2) are (nearly) identical --
- // just compute the distance to (x1,y1)
- dx = x0 - x1;
- dy = y0 - y1;
- t2 = dx*dx + dy*dy;
- return t2 < maxPointToLineDistanceSquared;
- }
- t2 = x1 * dy - dx * y1 - x0 * y2 + x2 * y0;
- // actual distance = t2 / sqrt(t1)
- return t2 * t2 < t1 * maxPointToLineDistanceSquared;
-}
-
-// Attempt to simplify the path by merging sequences of consecutive
-// segments in [first] .. [length]-1.
-void SplashXPath::mergeSegments(int first) {
- GBool horiz, vert;
- int in, out, prev, i, j;
-
- in = out = first;
- while (in < length) {
-
- // skip zero-length segments
- if (segs[in].x0 == segs[in].x1 && segs[in].y0 == segs[in].y1) {
- ++in;
- continue;
- }
-
- horiz = segs[in].y0 == segs[in].y1;
- vert = segs[in].x0 == segs[in].x1;
-
- // check for a sequence of mergeable segments: in .. i
- prev = in;
- for (i = in + 1; i < length; ++i) {
-
- // skip zero-length segments
- if (segs[i].x0 == segs[i].x1 && segs[i].y0 == segs[i].y1) {
- continue;
- }
-
- // check for a horizontal or vertical segment
- if ((horiz && segs[in].y0 != segs[in].y1) ||
- (vert && segs[in].x0 != segs[in].x1)) {
- break;
- }
-
- // check the angle between segs i-1 and i
- // (actually, we compare seg i to the previous non-zero-length
- // segment, which may not be i-1)
- if (!joinAngleIsFlat(segs[prev].x0, segs[prev].y0,
- segs[i].x0, segs[i].y0,
- segs[i].x1, segs[i].y1)) {
- break;
- }
-
- // check the distances from the ends of segs in .. i-1 to the
- // proposed new segment
- for (j = in; j < i; ++j) {
- if (!pointCloseToSegment(segs[in].x0, segs[in].y0,
- segs[j].x1, segs[j].y1,
- segs[i].x1, segs[i].y1)) {
- break;
- }
- }
- if (j < i) {
- break;
- }
-
- prev = i;
- }
-
- // we can merge segs: in .. i-1
- // (this may be the single segment: in)
- segs[out].x0 = segs[in].x0;
- segs[out].y0 = segs[in].y0;
- segs[out].x1 = segs[i-1].x1;
- segs[out].y1 = segs[i-1].y1;
- in = i;
- ++out;
- }
-
- length = out;
-}
-
-void SplashXPath::finishSegments() {
- SplashXPathSeg *seg;
- SplashCoord xMinFP, xMaxFP, yMinFP, yMaxFP, t;
- int i;
-
- xMinFP = yMinFP = xMaxFP = yMaxFP = 0;
-
- for (i = 0; i < length; ++i) {
- seg = &segs[i];
-
- //--- compute the slopes
- if (seg->y0 <= seg->y1) {
- seg->count = 1;
- } else {
- t = seg->x0; seg->x0 = seg->x1; seg->x1 = t;
- t = seg->y0; seg->y0 = seg->y1; seg->y1 = t;
- seg->count = -1;
- }
-#if USE_FIXEDPOINT
- if (seg->y0 == seg->y1 || seg->x0 == seg->x1 ||
- !FixedPoint::divCheck(seg->x1 - seg->x0, seg->y1 - seg->y0,
- &seg->dxdy) ||
- !FixedPoint::divCheck(seg->y1 - seg->y0, seg->x1 - seg->x0,
- &seg->dydx)) {
- seg->dxdy = 0;
- seg->dydx = 0;
- }
-#else
- if (splashAbs(seg->y1 - seg->y0) < 1e-200 ||
- splashAbs(seg->x1 - seg->x0) < 1e-200) {
- seg->dxdy = 0;
- seg->dydx = 0;
- } else {
- seg->dxdy = (seg->x1 - seg->x0) / (seg->y1 - seg->y0);
- if (seg->dxdy == 0) {
- seg->dydx = 0;
- } else {
- seg->dydx = 1 / seg->dxdy;
- }
- }
-#endif
-
- //--- update bbox
- if (i == 0) {
- if (seg->x0 <= seg->x1) {
- xMinFP = seg->x0;
- xMaxFP = seg->x1;
- } else {
- xMinFP = seg->x1;
- xMaxFP = seg->x0;
- }
- yMinFP = seg->y0;
- yMaxFP = seg->y1;
- } else {
- if (seg->x0 < xMinFP) {
- xMinFP = seg->x0;
- } else if (seg->x0 > xMaxFP) {
- xMaxFP = seg->x0;
- }
- if (seg->x1 < xMinFP) {
- xMinFP = seg->x1;
- } else if (seg->x1 > xMaxFP) {
- xMaxFP = seg->x1;
- }
- if (seg->y0 < yMinFP) {
- yMinFP = seg->y0;
- }
- if (seg->y1 > yMaxFP) {
- yMaxFP = seg->y1;
- }
- }
- }
-
- xMin = splashFloor(xMinFP);
- yMin = splashFloor(yMinFP);
- xMax = splashFloor(xMaxFP);
- yMax = splashFloor(yMaxFP);
-}