1 //========================================================================
5 //========================================================================
10 #pragma implementation
16 #include "SplashErrorCodes.h"
17 #include "SplashMath.h"
18 #include "SplashPath.h"
19 #include "SplashXPath.h"
20 #include "SplashXPathScanner.h"
21 #include "SplashClip.h"
23 //------------------------------------------------------------------------
25 //------------------------------------------------------------------------
27 #define splashClipEO 0x01 // use even-odd rule
29 //------------------------------------------------------------------------
31 //------------------------------------------------------------------------
33 SplashClip::SplashClip(SplashCoord x0, SplashCoord y0,
34 SplashCoord x1, SplashCoord y1) {
36 xMin = splashFloor(x0);
37 xMax = splashFloor(x1);
39 xMin = splashFloor(x1);
40 xMax = splashFloor(x0);
43 yMin = splashFloor(y0);
44 yMax = splashFloor(y1);
46 yMin = splashFloor(y1);
47 yMax = splashFloor(y0);
55 SplashClip::SplashClip(SplashClip *clip) {
62 length = clip->length;
64 paths = (SplashXPath **)gmalloc(size * sizeof(SplashXPath *));
65 flags = (Guchar *)gmalloc(size * sizeof(Guchar));
66 scanners = (SplashXPathScanner **)
67 gmalloc(size * sizeof(SplashXPathScanner *));
68 for (i = 0; i < length; ++i) {
69 paths[i] = clip->paths[i]->copy();
70 flags[i] = clip->flags[i];
71 scanners[i] = new SplashXPathScanner(paths[i], flags[i] & splashClipEO);
75 SplashClip::~SplashClip() {
78 for (i = 0; i < length; ++i) {
87 void SplashClip::grow(int nPaths) {
88 if (length + nPaths > size) {
92 while (size < length + nPaths) {
95 paths = (SplashXPath **)grealloc(paths, size * sizeof(SplashXPath *));
96 flags = (Guchar *)grealloc(flags, size * sizeof(Guchar));
97 scanners = (SplashXPathScanner **)
98 grealloc(scanners, size * sizeof(SplashXPathScanner *));
102 void SplashClip::resetToRect(SplashCoord x0, SplashCoord y0,
103 SplashCoord x1, SplashCoord y1) {
106 for (i = 0; i < length; ++i) {
119 xMin = splashFloor(x0);
120 xMax = splashFloor(x1);
122 xMin = splashFloor(x1);
123 xMax = splashFloor(x0);
126 yMin = splashFloor(y0);
127 yMax = splashFloor(y1);
129 yMin = splashFloor(y1);
130 yMax = splashFloor(y0);
134 SplashError SplashClip::clipToRect(SplashCoord x0, SplashCoord y0,
135 SplashCoord x1, SplashCoord y1) {
136 int x0I, y0I, x1I, y1I;
139 x0I = splashFloor(x0);
140 x1I = splashFloor(x1);
142 x0I = splashFloor(x1);
143 x1I = splashFloor(x0);
152 y0I = splashFloor(y0);
153 y1I = splashFloor(y1);
155 y0I = splashFloor(y1);
156 y1I = splashFloor(y0);
167 SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord flatness,
171 xPath = new SplashXPath(path, flatness, gTrue);
173 // check for an empty path
174 if (xPath->length == 0) {
179 // check for a rectangle
180 } else if (xPath->length == 4 &&
181 ((xPath->segs[0].x0 == xPath->segs[0].x1 &&
182 xPath->segs[0].x0 == xPath->segs[1].x0 &&
183 xPath->segs[0].x0 == xPath->segs[3].x1 &&
184 xPath->segs[2].x0 == xPath->segs[2].x1 &&
185 xPath->segs[2].x0 == xPath->segs[1].x1 &&
186 xPath->segs[2].x0 == xPath->segs[3].x0 &&
187 xPath->segs[1].y0 == xPath->segs[1].y1 &&
188 xPath->segs[1].y0 == xPath->segs[0].y1 &&
189 xPath->segs[1].y0 == xPath->segs[2].y0 &&
190 xPath->segs[3].y0 == xPath->segs[3].y1 &&
191 xPath->segs[3].y0 == xPath->segs[0].y0 &&
192 xPath->segs[3].y0 == xPath->segs[2].y1) ||
193 (xPath->segs[0].y0 == xPath->segs[0].y1 &&
194 xPath->segs[0].y0 == xPath->segs[1].y0 &&
195 xPath->segs[0].y0 == xPath->segs[3].y1 &&
196 xPath->segs[2].y0 == xPath->segs[2].y1 &&
197 xPath->segs[2].y0 == xPath->segs[1].y1 &&
198 xPath->segs[2].y0 == xPath->segs[3].y0 &&
199 xPath->segs[1].x0 == xPath->segs[1].x1 &&
200 xPath->segs[1].x0 == xPath->segs[0].x1 &&
201 xPath->segs[1].x0 == xPath->segs[2].x0 &&
202 xPath->segs[3].x0 == xPath->segs[3].x1 &&
203 xPath->segs[3].x0 == xPath->segs[0].x0 &&
204 xPath->segs[3].x0 == xPath->segs[2].x1))) {
205 clipToRect(xPath->segs[0].x0, xPath->segs[0].y0,
206 xPath->segs[2].x0, xPath->segs[2].y0);
212 paths[length] = xPath;
213 flags[length] = eo ? splashClipEO : 0;
214 scanners[length] = new SplashXPathScanner(xPath, eo);
221 GBool SplashClip::test(int x, int y) {
224 // check the rectangle
225 if (x < xMin || x > xMax || y < yMin || y > yMax) {
230 for (i = 0; i < length; ++i) {
231 if (!scanners[i]->test(x, y)) {
239 SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
240 int rectXMax, int rectYMax) {
241 if (rectXMax < xMin || rectXMin > xMax ||
242 rectYMax < yMin || rectYMin > yMax) {
243 return splashClipAllOutside;
245 if (rectXMin >= xMin && rectXMax <= xMax &&
246 rectYMin >= yMin && rectYMax <= yMax &&
248 return splashClipAllInside;
250 return splashClipPartial;
253 SplashClipResult SplashClip::testSpan(int spanXMin, int spanXMax, int spanY) {
256 if (spanXMax < xMin || spanXMin > xMax ||
257 spanY < yMin || spanY > yMax) {
258 return splashClipAllOutside;
260 if (!(spanXMin >= xMin && spanXMax <= xMax &&
261 spanY >= yMin && spanY <= yMax)) {
262 return splashClipPartial;
264 for (i = 0; i < length; ++i) {
265 if (!scanners[i]->testSpan(xMin, xMax, spanY)) {
266 return splashClipPartial;
269 return splashClipAllInside;