1
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c,v 1.4 2001/10/28 03:34:04 tsi Exp $ */
3
#ifdef HAVE_XORG_CONFIG_H
4
#include <xorg-config.h>
10
#include "xf86_ansic.h"
11
#include "xf86_OSproc.h"
13
#include "scrnintstr.h"
14
#include "pixmapstr.h"
24
DrawablePtr pDrawable,
30
DrawablePtr pDrawable,
32
int mode, /* Origin or Previous */
33
int npt, /* number of points */
37
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
38
XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
39
BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
40
int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
41
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
42
int xorg = pDrawable->x;
43
int yorg = pDrawable->y;
49
unsigned int oc1, oc2;
50
int dmin, dmaj, e, octant;
51
int x1, x2, y1, y2, tmp, len, offset;
52
int PatternLength, PatternOffset;
57
if (infoRec->DashedLineFlags & LINE_LIMIT_COORDS) {
58
int minValX = infoRec->DashedLineLimits.x1;
59
int maxValX = infoRec->DashedLineLimits.x2;
60
int minValY = infoRec->DashedLineLimits.y1;
61
int maxValY = infoRec->DashedLineLimits.y2;
73
x2 = ppt->x + xorgtmp;
74
y2 = ppt->y + yorgtmp;
88
if (mode == CoordModePrevious) {
92
x2 = ppt->x + xorgtmp;
93
y2 = ppt->y + yorgtmp;
95
if (x1 > maxValX || x1 < minValX ||
96
x2 > maxValX || x2 < minValX ||
97
y1 > maxValY || y1 < minValY ||
98
y2 > maxValY || y2 < minValY) {
100
XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
102
XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
109
PatternLength = pGCPriv->DashLength;
110
PatternOffset = pGC->dashOffset % PatternLength;
112
(*infoRec->SetupForDashedLine)(infoRec->pScrn, pGC->fgPixel,
113
(pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
114
pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
130
x1 = pSeg->x1 + xorg;
131
y1 = pSeg->y1 + yorg;
132
x2 = pSeg->x2 + xorg;
133
y2 = pSeg->y2 + yorg;
139
if (mode == CoordModePrevious) {
148
if (infoRec->SubsequentDashedBresenhamLine) {
149
if((dmaj = x2 - x1) < 0) {
151
octant = XDECREASING;
154
if((dmin = y2 - y1) < 0) {
156
octant |= YDECREASING;
160
tmp = dmin; dmin = dmaj; dmaj = tmp;
164
e = -dmaj - ((bias >> octant) & 1);
168
} else { /* Muffle compiler */
169
dmin = dmaj = e = octant = len = 0;
174
OUTCODES(oc1, x1, y1, pbox);
175
OUTCODES(oc2, x2, y2, pbox);
176
if (!(oc1 | oc2)) { /* uncliped */
177
if(infoRec->SubsequentDashedTwoPointLine) {
178
(*infoRec->SubsequentDashedTwoPointLine)(
179
infoRec->pScrn, x1, y1, x2, y2,
181
(pGC->capStyle != CapNotLast) ? 0 :
183
OMIT_LAST, PatternOffset);
185
(*infoRec->SubsequentDashedBresenhamLine)(
186
infoRec->pScrn, x1, y1, dmaj, dmin, e,
188
(pGC->capStyle != CapNotLast) ? (len+1) :
190
len, octant, PatternOffset);
193
} else if (oc1 & oc2) { /* completely clipped */
195
} else if (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE) {
196
(*infoRec->SetClippingRectangle)(infoRec->pScrn,
197
pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
199
if(infoRec->SubsequentDashedBresenhamLine) {
200
(*infoRec->SubsequentDashedBresenhamLine)(
201
infoRec->pScrn, x1, y1, dmaj, dmin, e,
203
(pGC->capStyle != CapNotLast) ? (len+1) :
205
len, octant, PatternOffset);
207
(*infoRec->SubsequentDashedTwoPointLine)(
208
infoRec->pScrn, x1, y1, x2, y2,
210
(pGC->capStyle != CapNotLast) ? 0 :
212
OMIT_LAST, PatternOffset
215
(*infoRec->DisableClipping)(infoRec->pScrn);
218
int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
219
int clip1 = 0, clip2 = 0;
222
if(octant & YMAJOR) {
230
if (miZeroClipLine(pbox->x1, pbox->y1,
231
pbox->x2 - 1, pbox->y2 - 1,
232
&new_x1, &new_y1, &new_x2, &new_y2,
233
adx, ady, &clip1, &clip2,
234
octant, bias, oc1, oc2) == -1)
241
len = abs(new_y2 - new_y1);
243
len = abs(new_x2 - new_x1);
245
if (clip2 != 0 || pGC->capStyle != CapNotLast)
251
int abserr, clipdx, clipdy;
252
/* unwind bresenham error term to first point */
254
clipdx = abs(new_x1 - x1);
255
clipdy = abs(new_y1 - y1);
258
err = e + clipdy*dmin - clipdx*dmaj;
260
err = e + clipdx*dmin - clipdy*dmaj;
264
#define range infoRec->DashedBresenhamLineErrorTermBits
266
while((abserr & range) ||
276
offset = abs(new_y1 - y1);
278
offset = abs(new_x1 - x1);
280
offset += PatternOffset;
281
offset %= PatternLength;
283
(*infoRec->SubsequentDashedBresenhamLine)(
284
infoRec->pScrn, new_x1, new_y1,
285
dmaj, dmin, err, len, octant, offset);
289
} /* while (nbox--) */
293
PatternOffset += (len > tmp) ? len : tmp;
294
PatternOffset %= PatternLength;
296
} /* while (nline--) */
299
/* paint the last point if the end style isn't CapNotLast.
300
(Assume that a projecting, butt, or round cap that is one
301
pixel wide is the same as the single pixel of the endpoint.)
304
if ((pGC->capStyle != CapNotLast) &&
305
((ppt->x + xorg != pptInit->x + pDrawable->x) ||
306
(ppt->y + yorg != pptInit->y + pDrawable->y) ||
307
(ppt == pptInit + 1)))
312
if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
313
(x2 < pbox->x2) && (y2 < pbox->y2))
315
if(infoRec->SubsequentDashedTwoPointLine) {
316
(*infoRec->SubsequentDashedTwoPointLine)(
317
infoRec->pScrn, x2, y2, x2, y2, 0,
320
(*infoRec->SubsequentDashedBresenhamLine)(
321
infoRec->pScrn, x2, y2, 2, 0, -1,
322
1, 0, PatternOffset);
331
SET_SYNC_FLAG(infoRec);