Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright © 1998 Keith Packard | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Keith Packard not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Keith Packard makes no | |
11 | * representations about the suitability of this software for any purpose. It | |
12 | * is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifdef HAVE_DIX_CONFIG_H | |
24 | #include <dix-config.h> | |
25 | #endif | |
26 | ||
27 | #include <stdlib.h> | |
28 | ||
29 | #include "fb.h" | |
30 | #include "miline.h" | |
31 | ||
32 | #define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ | |
33 | ((dir < 0) ? FbStipLeft(mask,bpp) : \ | |
34 | FbStipRight(mask,bpp))) | |
35 | ||
36 | void | |
37 | fbBresSolid(DrawablePtr pDrawable, | |
38 | GCPtr pGC, | |
39 | int dashOffset, | |
40 | int signdx, | |
41 | int signdy, | |
42 | int axis, int x1, int y1, int e, int e1, int e3, int len) | |
43 | { | |
44 | FbStip *dst; | |
45 | FbStride dstStride; | |
46 | int dstBpp; | |
47 | int dstXoff, dstYoff; | |
48 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
49 | FbStip and = (FbStip) pPriv->and; | |
50 | FbStip xor = (FbStip) pPriv->xor; | |
51 | FbStip mask, mask0; | |
52 | FbStip bits; | |
53 | ||
54 | fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
55 | dst += ((y1 + dstYoff) * dstStride); | |
56 | x1 = (x1 + dstXoff) * dstBpp; | |
57 | dst += x1 >> FB_STIP_SHIFT; | |
58 | x1 &= FB_STIP_MASK; | |
59 | mask0 = FbStipMask(0, dstBpp); | |
60 | mask = FbStipRight(mask0, x1); | |
61 | if (signdx < 0) | |
62 | mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp); | |
63 | if (signdy < 0) | |
64 | dstStride = -dstStride; | |
65 | if (axis == X_AXIS) { | |
66 | bits = 0; | |
67 | while (len--) { | |
68 | if (e >= 0) { | |
69 | WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); | |
70 | bits = 0; | |
71 | dst += dstStride; | |
72 | e += e3; | |
73 | } | |
74 | bits |= mask; | |
75 | mask = fbBresShiftMask(mask, signdx, dstBpp); | |
76 | if (!mask) { | |
77 | WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); | |
78 | bits = 0; | |
79 | dst += signdx; | |
80 | mask = mask0; | |
81 | } | |
82 | e += e1; | |
83 | } | |
84 | if (bits) | |
85 | WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); | |
86 | } | |
87 | else { | |
88 | while (len--) { | |
89 | if (e >= 0) { | |
90 | e += e3; | |
91 | mask = fbBresShiftMask(mask, signdx, dstBpp); | |
92 | if (!mask) { | |
93 | dst += signdx; | |
94 | mask = mask0; | |
95 | } | |
96 | } | |
97 | WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); | |
98 | dst += dstStride; | |
99 | e += e1; | |
100 | } | |
101 | } | |
102 | ||
103 | fbFinishAccess(pDrawable); | |
104 | } | |
105 | ||
106 | void | |
107 | fbBresDash(DrawablePtr pDrawable, | |
108 | GCPtr pGC, | |
109 | int dashOffset, | |
110 | int signdx, | |
111 | int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) | |
112 | { | |
113 | FbStip *dst; | |
114 | FbStride dstStride; | |
115 | int dstBpp; | |
116 | int dstXoff, dstYoff; | |
117 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
118 | FbStip and = (FbStip) pPriv->and; | |
119 | FbStip xor = (FbStip) pPriv->xor; | |
120 | FbStip bgand = (FbStip) pPriv->bgand; | |
121 | FbStip bgxor = (FbStip) pPriv->bgxor; | |
122 | FbStip mask, mask0; | |
123 | ||
124 | FbDashDeclare; | |
125 | int dashlen; | |
126 | Bool even; | |
127 | Bool doOdd; | |
128 | ||
129 | fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
130 | doOdd = pGC->lineStyle == LineDoubleDash; | |
131 | ||
132 | FbDashInit(pGC, pPriv, dashOffset, dashlen, even); | |
133 | ||
134 | dst += ((y1 + dstYoff) * dstStride); | |
135 | x1 = (x1 + dstXoff) * dstBpp; | |
136 | dst += x1 >> FB_STIP_SHIFT; | |
137 | x1 &= FB_STIP_MASK; | |
138 | mask0 = FbStipMask(0, dstBpp); | |
139 | mask = FbStipRight(mask0, x1); | |
140 | if (signdx < 0) | |
141 | mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp); | |
142 | if (signdy < 0) | |
143 | dstStride = -dstStride; | |
144 | while (len--) { | |
145 | if (even) | |
146 | WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); | |
147 | else if (doOdd) | |
148 | WRITE(dst, FbDoMaskRRop(READ(dst), bgand, bgxor, mask)); | |
149 | if (axis == X_AXIS) { | |
150 | mask = fbBresShiftMask(mask, signdx, dstBpp); | |
151 | if (!mask) { | |
152 | dst += signdx; | |
153 | mask = mask0; | |
154 | } | |
155 | e += e1; | |
156 | if (e >= 0) { | |
157 | dst += dstStride; | |
158 | e += e3; | |
159 | } | |
160 | } | |
161 | else { | |
162 | dst += dstStride; | |
163 | e += e1; | |
164 | if (e >= 0) { | |
165 | e += e3; | |
166 | mask = fbBresShiftMask(mask, signdx, dstBpp); | |
167 | if (!mask) { | |
168 | dst += signdx; | |
169 | mask = mask0; | |
170 | } | |
171 | } | |
172 | } | |
173 | FbDashStep(dashlen, even); | |
174 | } | |
175 | ||
176 | fbFinishAccess(pDrawable); | |
177 | } | |
178 | ||
179 | void | |
180 | fbBresFill(DrawablePtr pDrawable, | |
181 | GCPtr pGC, | |
182 | int dashOffset, | |
183 | int signdx, | |
184 | int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) | |
185 | { | |
186 | while (len--) { | |
187 | fbFill(pDrawable, pGC, x1, y1, 1, 1); | |
188 | if (axis == X_AXIS) { | |
189 | x1 += signdx; | |
190 | e += e1; | |
191 | if (e >= 0) { | |
192 | e += e3; | |
193 | y1 += signdy; | |
194 | } | |
195 | } | |
196 | else { | |
197 | y1 += signdy; | |
198 | e += e1; | |
199 | if (e >= 0) { | |
200 | e += e3; | |
201 | x1 += signdx; | |
202 | } | |
203 | } | |
204 | } | |
205 | } | |
206 | ||
207 | static void | |
208 | fbSetFg(DrawablePtr pDrawable, GCPtr pGC, Pixel fg) | |
209 | { | |
210 | if (fg != pGC->fgPixel) { | |
211 | ChangeGCVal val; | |
212 | ||
213 | val.val = fg; | |
214 | ChangeGC(NullClient, pGC, GCForeground, &val); | |
215 | ValidateGC(pDrawable, pGC); | |
216 | } | |
217 | } | |
218 | ||
219 | void | |
220 | fbBresFillDash(DrawablePtr pDrawable, | |
221 | GCPtr pGC, | |
222 | int dashOffset, | |
223 | int signdx, | |
224 | int signdy, | |
225 | int axis, int x1, int y1, int e, int e1, int e3, int len) | |
226 | { | |
227 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
228 | ||
229 | FbDashDeclare; | |
230 | int dashlen; | |
231 | Bool even; | |
232 | Bool doOdd; | |
233 | Bool doBg; | |
234 | Pixel fg, bg; | |
235 | ||
236 | fg = pGC->fgPixel; | |
237 | bg = pGC->bgPixel; | |
238 | ||
239 | /* whether to fill the odd dashes */ | |
240 | doOdd = pGC->lineStyle == LineDoubleDash; | |
241 | /* whether to switch fg to bg when filling odd dashes */ | |
242 | doBg = doOdd && (pGC->fillStyle == FillSolid || | |
243 | pGC->fillStyle == FillStippled); | |
244 | ||
245 | /* compute current dash position */ | |
246 | FbDashInit(pGC, pPriv, dashOffset, dashlen, even); | |
247 | ||
248 | while (len--) { | |
249 | if (even || doOdd) { | |
250 | if (doBg) { | |
251 | if (even) | |
252 | fbSetFg(pDrawable, pGC, fg); | |
253 | else | |
254 | fbSetFg(pDrawable, pGC, bg); | |
255 | } | |
256 | fbFill(pDrawable, pGC, x1, y1, 1, 1); | |
257 | } | |
258 | if (axis == X_AXIS) { | |
259 | x1 += signdx; | |
260 | e += e1; | |
261 | if (e >= 0) { | |
262 | e += e3; | |
263 | y1 += signdy; | |
264 | } | |
265 | } | |
266 | else { | |
267 | y1 += signdy; | |
268 | e += e1; | |
269 | if (e >= 0) { | |
270 | e += e3; | |
271 | x1 += signdx; | |
272 | } | |
273 | } | |
274 | FbDashStep(dashlen, even); | |
275 | } | |
276 | if (doBg) | |
277 | fbSetFg(pDrawable, pGC, fg); | |
278 | } | |
279 | ||
280 | static void | |
281 | fbBresSolid24RRop(DrawablePtr pDrawable, | |
282 | GCPtr pGC, | |
283 | int dashOffset, | |
284 | int signdx, | |
285 | int signdy, | |
286 | int axis, int x1, int y1, int e, int e1, int e3, int len) | |
287 | { | |
288 | FbStip *dst; | |
289 | FbStride dstStride; | |
290 | int dstBpp; | |
291 | int dstXoff, dstYoff; | |
292 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
293 | FbStip and = pPriv->and; | |
294 | FbStip xor = pPriv->xor; | |
295 | FbStip leftMask, rightMask; | |
296 | int nl; | |
297 | FbStip *d; | |
298 | int x; | |
299 | int rot; | |
300 | FbStip andT, xorT; | |
301 | ||
302 | fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
303 | dst += ((y1 + dstYoff) * dstStride); | |
304 | x1 = (x1 + dstXoff) * 24; | |
305 | if (signdy < 0) | |
306 | dstStride = -dstStride; | |
307 | signdx *= 24; | |
308 | while (len--) { | |
309 | d = dst + (x1 >> FB_STIP_SHIFT); | |
310 | x = x1 & FB_STIP_MASK; | |
311 | rot = FbFirst24Rot(x); | |
312 | andT = FbRot24Stip(and, rot); | |
313 | xorT = FbRot24Stip(xor, rot); | |
314 | FbMaskStip(x, 24, leftMask, nl, rightMask); | |
315 | if (leftMask) { | |
316 | WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, leftMask)); | |
317 | d++; | |
318 | andT = FbNext24Stip(andT); | |
319 | xorT = FbNext24Stip(xorT); | |
320 | } | |
321 | if (rightMask) | |
322 | WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, rightMask)); | |
323 | if (axis == X_AXIS) { | |
324 | x1 += signdx; | |
325 | e += e1; | |
326 | if (e >= 0) { | |
327 | e += e3; | |
328 | dst += dstStride; | |
329 | } | |
330 | } | |
331 | else { | |
332 | dst += dstStride; | |
333 | e += e1; | |
334 | if (e >= 0) { | |
335 | e += e3; | |
336 | x1 += signdx; | |
337 | } | |
338 | } | |
339 | } | |
340 | ||
341 | fbFinishAccess(pDrawable); | |
342 | } | |
343 | ||
344 | static void | |
345 | fbBresDash24RRop(DrawablePtr pDrawable, | |
346 | GCPtr pGC, | |
347 | int dashOffset, | |
348 | int signdx, | |
349 | int signdy, | |
350 | int axis, int x1, int y1, int e, int e1, int e3, int len) | |
351 | { | |
352 | FbStip *dst; | |
353 | FbStride dstStride; | |
354 | int dstBpp; | |
355 | int dstXoff, dstYoff; | |
356 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
357 | FbStip andT, xorT; | |
358 | FbStip fgand = pPriv->and; | |
359 | FbStip fgxor = pPriv->xor; | |
360 | FbStip bgand = pPriv->bgand; | |
361 | FbStip bgxor = pPriv->bgxor; | |
362 | FbStip leftMask, rightMask; | |
363 | int nl; | |
364 | FbStip *d; | |
365 | int x; | |
366 | int rot; | |
367 | ||
368 | FbDashDeclare; | |
369 | int dashlen; | |
370 | Bool even; | |
371 | Bool doOdd; | |
372 | ||
373 | fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
374 | doOdd = pGC->lineStyle == LineDoubleDash; | |
375 | ||
376 | /* compute current dash position */ | |
377 | FbDashInit(pGC, pPriv, dashOffset, dashlen, even); | |
378 | ||
379 | dst += ((y1 + dstYoff) * dstStride); | |
380 | x1 = (x1 + dstXoff) * 24; | |
381 | if (signdy < 0) | |
382 | dstStride = -dstStride; | |
383 | signdx *= 24; | |
384 | while (len--) { | |
385 | if (even || doOdd) { | |
386 | if (even) { | |
387 | andT = fgand; | |
388 | xorT = fgxor; | |
389 | } | |
390 | else { | |
391 | andT = bgand; | |
392 | xorT = bgxor; | |
393 | } | |
394 | d = dst + (x1 >> FB_STIP_SHIFT); | |
395 | x = x1 & FB_STIP_MASK; | |
396 | rot = FbFirst24Rot(x); | |
397 | andT = FbRot24Stip(andT, rot); | |
398 | xorT = FbRot24Stip(xorT, rot); | |
399 | FbMaskStip(x, 24, leftMask, nl, rightMask); | |
400 | if (leftMask) { | |
401 | WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, leftMask)); | |
402 | d++; | |
403 | andT = FbNext24Stip(andT); | |
404 | xorT = FbNext24Stip(xorT); | |
405 | } | |
406 | if (rightMask) | |
407 | WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, rightMask)); | |
408 | } | |
409 | if (axis == X_AXIS) { | |
410 | x1 += signdx; | |
411 | e += e1; | |
412 | if (e >= 0) { | |
413 | e += e3; | |
414 | dst += dstStride; | |
415 | } | |
416 | } | |
417 | else { | |
418 | dst += dstStride; | |
419 | e += e1; | |
420 | if (e >= 0) { | |
421 | e += e3; | |
422 | x1 += signdx; | |
423 | } | |
424 | } | |
425 | FbDashStep(dashlen, even); | |
426 | } | |
427 | ||
428 | fbFinishAccess(pDrawable); | |
429 | } | |
430 | ||
431 | /* | |
432 | * For drivers that want to bail drawing some lines, this | |
433 | * function takes care of selecting the appropriate rasterizer | |
434 | * based on the contents of the specified GC. | |
435 | */ | |
436 | ||
437 | FbBres * | |
438 | fbSelectBres(DrawablePtr pDrawable, GCPtr pGC) | |
439 | { | |
440 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
441 | int dstBpp = pDrawable->bitsPerPixel; | |
442 | FbBres *bres; | |
443 | ||
444 | if (pGC->lineStyle == LineSolid) { | |
445 | bres = fbBresFill; | |
446 | if (pGC->fillStyle == FillSolid) { | |
447 | bres = fbBresSolid; | |
448 | if (dstBpp == 24) | |
449 | bres = fbBresSolid24RRop; | |
450 | if (pPriv->and == 0) { | |
451 | switch (dstBpp) { | |
452 | case 8: | |
453 | bres = fbBresSolid8; | |
454 | break; | |
455 | case 16: | |
456 | bres = fbBresSolid16; | |
457 | break; | |
458 | case 24: | |
459 | bres = fbBresSolid24; | |
460 | break; | |
461 | case 32: | |
462 | bres = fbBresSolid32; | |
463 | break; | |
464 | } | |
465 | } | |
466 | } | |
467 | } | |
468 | else { | |
469 | bres = fbBresFillDash; | |
470 | if (pGC->fillStyle == FillSolid) { | |
471 | bres = fbBresDash; | |
472 | if (dstBpp == 24) | |
473 | bres = fbBresDash24RRop; | |
474 | if (pPriv->and == 0 && | |
475 | (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) { | |
476 | switch (dstBpp) { | |
477 | case 8: | |
478 | bres = fbBresDash8; | |
479 | break; | |
480 | case 16: | |
481 | bres = fbBresDash16; | |
482 | break; | |
483 | case 24: | |
484 | bres = fbBresDash24; | |
485 | break; | |
486 | case 32: | |
487 | bres = fbBresDash32; | |
488 | break; | |
489 | } | |
490 | } | |
491 | } | |
492 | } | |
493 | return bres; | |
494 | } | |
495 | ||
496 | void | |
497 | fbBres(DrawablePtr pDrawable, | |
498 | GCPtr pGC, | |
499 | int dashOffset, | |
500 | int signdx, | |
501 | int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len) | |
502 | { | |
503 | (*fbSelectBres(pDrawable, pGC)) (pDrawable, pGC, dashOffset, | |
504 | signdx, signdy, axis, x1, y1, | |
505 | e, e1, e3, len); | |
506 | } | |
507 | ||
508 | void | |
509 | fbSegment(DrawablePtr pDrawable, | |
510 | GCPtr pGC, | |
511 | int x1, int y1, int x2, int y2, Bool drawLast, int *dashOffset) | |
512 | { | |
513 | FbBres *bres; | |
514 | RegionPtr pClip = fbGetCompositeClip(pGC); | |
515 | BoxPtr pBox; | |
516 | int nBox; | |
517 | int adx; /* abs values of dx and dy */ | |
518 | int ady; | |
519 | int signdx; /* sign of dx and dy */ | |
520 | int signdy; | |
521 | int e, e1, e2, e3; /* bresenham error and increments */ | |
522 | int len; /* length of segment */ | |
523 | int axis; /* major axis */ | |
524 | int octant; | |
525 | int dashoff; | |
526 | int doff; | |
527 | unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); | |
528 | unsigned int oc1; /* outcode of point 1 */ | |
529 | unsigned int oc2; /* outcode of point 2 */ | |
530 | ||
531 | nBox = RegionNumRects(pClip); | |
532 | pBox = RegionRects(pClip); | |
533 | ||
534 | bres = fbSelectBres(pDrawable, pGC); | |
535 | ||
536 | CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant); | |
537 | ||
538 | if (adx > ady) { | |
539 | axis = X_AXIS; | |
540 | e1 = ady << 1; | |
541 | e2 = e1 - (adx << 1); | |
542 | e = e1 - adx; | |
543 | len = adx; | |
544 | } | |
545 | else { | |
546 | axis = Y_AXIS; | |
547 | e1 = adx << 1; | |
548 | e2 = e1 - (ady << 1); | |
549 | e = e1 - ady; | |
550 | SetYMajorOctant(octant); | |
551 | len = ady; | |
552 | } | |
553 | ||
554 | FIXUP_ERROR(e, octant, bias); | |
555 | ||
556 | /* | |
557 | * Adjust error terms to compare against zero | |
558 | */ | |
559 | e3 = e2 - e1; | |
560 | e = e - e1; | |
561 | ||
562 | /* we have bresenham parameters and two points. | |
563 | all we have to do now is clip and draw. | |
564 | */ | |
565 | ||
566 | if (drawLast) | |
567 | len++; | |
568 | dashoff = *dashOffset; | |
569 | *dashOffset = dashoff + len; | |
570 | while (nBox--) { | |
571 | oc1 = 0; | |
572 | oc2 = 0; | |
573 | OUTCODES(oc1, x1, y1, pBox); | |
574 | OUTCODES(oc2, x2, y2, pBox); | |
575 | if ((oc1 | oc2) == 0) { | |
576 | (*bres) (pDrawable, pGC, dashoff, | |
577 | signdx, signdy, axis, x1, y1, e, e1, e3, len); | |
578 | break; | |
579 | } | |
580 | else if (oc1 & oc2) { | |
581 | pBox++; | |
582 | } | |
583 | else { | |
584 | int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; | |
585 | int clip1 = 0, clip2 = 0; | |
586 | int clipdx, clipdy; | |
587 | int err; | |
588 | ||
589 | if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2 - 1, | |
590 | pBox->y2 - 1, | |
591 | &new_x1, &new_y1, &new_x2, &new_y2, | |
592 | adx, ady, &clip1, &clip2, | |
593 | octant, bias, oc1, oc2) == -1) { | |
594 | pBox++; | |
595 | continue; | |
596 | } | |
597 | ||
598 | if (axis == X_AXIS) | |
599 | len = abs(new_x2 - new_x1); | |
600 | else | |
601 | len = abs(new_y2 - new_y1); | |
602 | if (clip2 != 0 || drawLast) | |
603 | len++; | |
604 | if (len) { | |
605 | /* unwind bresenham error term to first point */ | |
606 | doff = dashoff; | |
607 | err = e; | |
608 | if (clip1) { | |
609 | clipdx = abs(new_x1 - x1); | |
610 | clipdy = abs(new_y1 - y1); | |
611 | if (axis == X_AXIS) { | |
612 | doff += clipdx; | |
613 | err += e3 * clipdy + e1 * clipdx; | |
614 | } | |
615 | else { | |
616 | doff += clipdy; | |
617 | err += e3 * clipdx + e1 * clipdy; | |
618 | } | |
619 | } | |
620 | (*bres) (pDrawable, pGC, doff, | |
621 | signdx, signdy, axis, new_x1, new_y1, | |
622 | err, e1, e3, len); | |
623 | } | |
624 | pBox++; | |
625 | } | |
626 | } /* while (nBox--) */ | |
627 | } |