~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/xaa/xaaDashLine.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c,v 1.4 2001/10/28 03:34:04 tsi Exp $ */
 
2
 
 
3
#ifdef HAVE_XORG_CONFIG_H
 
4
#include <xorg-config.h>
 
5
#endif
 
6
 
 
7
#include <X11/X.h>
 
8
#include "misc.h"
 
9
#include "xf86.h"
 
10
#include "xf86_ansic.h"
 
11
#include "xf86_OSproc.h"
 
12
 
 
13
#include "scrnintstr.h"
 
14
#include "pixmapstr.h"
 
15
#include "miline.h"
 
16
#include "xf86str.h"
 
17
#include "xaa.h"
 
18
#include "xaalocal.h"
 
19
 
 
20
 
 
21
void
 
22
#ifdef POLYSEGMENT
 
23
XAAPolySegmentDashed(
 
24
    DrawablePtr pDrawable,
 
25
    GCPtr       pGC,
 
26
    int         nseg,
 
27
    xSegment    *pSeg
 
28
#else
 
29
XAAPolyLinesDashed(
 
30
    DrawablePtr pDrawable,
 
31
    GCPtr       pGC,
 
32
    int         mode,           /* Origin or Previous */
 
33
    int         npt,            /* number of points */
 
34
    DDXPointPtr pptInit
 
35
#endif
 
36
){
 
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;
 
44
    int nbox;
 
45
    BoxPtr pbox;
 
46
#ifndef POLYSEGMENT
 
47
    DDXPointPtr ppt;
 
48
#endif
 
49
    unsigned int oc1, oc2;
 
50
    int dmin, dmaj, e, octant;
 
51
    int x1, x2, y1, y2, tmp, len, offset;
 
52
    int PatternLength, PatternOffset;
 
53
 
 
54
    if(!nboxInit)
 
55
        return;
 
56
 
 
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;
 
62
#ifdef POLYSEGMENT
 
63
        int n = nseg;
 
64
        xSegment *s = pSeg;
 
65
 
 
66
        while (n--)
 
67
#else
 
68
        int n = npt;
 
69
        int xorgtmp = xorg;
 
70
        int yorgtmp = yorg;
 
71
 
 
72
        ppt = pptInit;
 
73
        x2 = ppt->x + xorgtmp;
 
74
        y2 = ppt->y + yorgtmp;
 
75
        while (--n)
 
76
#endif
 
77
        {
 
78
#ifdef POLYSEGMENT
 
79
            x1 = s->x1 + xorg;
 
80
            y1 = s->y1 + yorg;
 
81
            x2 = s->x2 + xorg;
 
82
            y2 = s->y2 + yorg;
 
83
            s++;
 
84
#else
 
85
            x1 = x2;
 
86
            y1 = y2;
 
87
            ++ppt;
 
88
            if (mode == CoordModePrevious) {
 
89
                xorgtmp = x1;
 
90
                yorgtmp = y1;
 
91
            }
 
92
            x2 = ppt->x + xorgtmp;
 
93
            y2 = ppt->y + yorgtmp;
 
94
#endif
 
95
            if (x1 > maxValX || x1 < minValX ||
 
96
                x2 > maxValX || x2 < minValX ||
 
97
                y1 > maxValY || y1 < minValY ||
 
98
                y2 > maxValY || y2 < minValY) {
 
99
#ifdef POLYSEGMENT
 
100
                XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
 
101
#else
 
102
                XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
 
103
#endif
 
104
                return;
 
105
            }
 
106
        }
 
107
    }
 
108
 
 
109
    PatternLength = pGCPriv->DashLength; 
 
110
    PatternOffset = pGC->dashOffset % PatternLength;
 
111
 
 
112
    (*infoRec->SetupForDashedLine)(infoRec->pScrn, pGC->fgPixel,
 
113
                (pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
 
114
                pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
 
115
 
 
116
 
 
117
#ifdef POLYSEGMENT
 
118
    while (nseg--)
 
119
#else
 
120
    ppt = pptInit;
 
121
    x2 = ppt->x + xorg;
 
122
    y2 = ppt->y + yorg;
 
123
    while(--npt)
 
124
#endif
 
125
    {
 
126
        nbox = nboxInit;
 
127
        pbox = pboxInit;
 
128
 
 
129
#ifdef POLYSEGMENT
 
130
        x1 = pSeg->x1 + xorg;   
 
131
        y1 = pSeg->y1 + yorg;
 
132
        x2 = pSeg->x2 + xorg;   
 
133
        y2 = pSeg->y2 + yorg;
 
134
        pSeg++;
 
135
#else
 
136
        x1 = x2; 
 
137
        y1 = y2;
 
138
        ++ppt;
 
139
        if (mode == CoordModePrevious) {
 
140
            xorg = x1; 
 
141
            yorg = y1;
 
142
        }
 
143
        x2 = ppt->x + xorg; 
 
144
        y2 = ppt->y + yorg;
 
145
#endif
 
146
 
 
147
 
 
148
        if (infoRec->SubsequentDashedBresenhamLine) {
 
149
            if((dmaj = x2 - x1) < 0) {
 
150
                dmaj = -dmaj;
 
151
                octant = XDECREASING;
 
152
            } else octant = 0;             
 
153
 
 
154
            if((dmin = y2 - y1) < 0) {
 
155
                dmin = -dmin;
 
156
                octant |= YDECREASING;
 
157
            }   
 
158
        
 
159
            if(dmin >= dmaj){
 
160
                tmp = dmin; dmin = dmaj; dmaj = tmp;
 
161
                octant |= YMAJOR;
 
162
            }
 
163
 
 
164
            e = -dmaj - ((bias >> octant) & 1);
 
165
            len = dmaj;
 
166
            dmin <<= 1;
 
167
            dmaj <<= 1;
 
168
        } else {        /* Muffle compiler */
 
169
            dmin = dmaj = e = octant = len = 0;
 
170
        }
 
171
 
 
172
        while(nbox--) {
 
173
            oc1 = oc2 = 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, 
 
180
#ifdef POLYSEGMENT
 
181
                                (pGC->capStyle != CapNotLast) ? 0 :
 
182
#endif
 
183
                                OMIT_LAST, PatternOffset);
 
184
                } else {
 
185
                    (*infoRec->SubsequentDashedBresenhamLine)(
 
186
                                infoRec->pScrn, x1, y1, dmaj, dmin, e, 
 
187
#ifdef POLYSEGMENT
 
188
                                (pGC->capStyle != CapNotLast) ? (len+1) :
 
189
#endif
 
190
                                len, octant, PatternOffset);
 
191
                }
 
192
                break;
 
193
            } else if (oc1 & oc2) { /* completely clipped */
 
194
                pbox++;
 
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);
 
198
 
 
199
                if(infoRec->SubsequentDashedBresenhamLine) {
 
200
                    (*infoRec->SubsequentDashedBresenhamLine)(
 
201
                                infoRec->pScrn, x1, y1, dmaj, dmin, e, 
 
202
#ifdef POLYSEGMENT
 
203
                                (pGC->capStyle != CapNotLast) ? (len+1) :
 
204
#endif
 
205
                                len, octant, PatternOffset);
 
206
                } else {
 
207
                        (*infoRec->SubsequentDashedTwoPointLine)(
 
208
                                infoRec->pScrn, x1, y1, x2, y2, 
 
209
#ifdef POLYSEGMENT
 
210
                                (pGC->capStyle != CapNotLast) ? 0 :
 
211
#endif
 
212
                                OMIT_LAST, PatternOffset
 
213
                        );
 
214
                }
 
215
                (*infoRec->DisableClipping)(infoRec->pScrn);
 
216
                pbox++;
 
217
            } else {
 
218
                int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
 
219
                int clip1 = 0, clip2 = 0;
 
220
                int err, adx, ady;
 
221
                    
 
222
                if(octant & YMAJOR) {
 
223
                    ady = dmaj >> 1;
 
224
                    adx = dmin >> 1;
 
225
                } else {
 
226
                    ady = dmin >> 1;
 
227
                    adx = dmaj >> 1;
 
228
                }
 
229
 
 
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)
 
235
                {
 
236
                    pbox++;
 
237
                    continue;
 
238
                }
 
239
 
 
240
                if (octant & YMAJOR)
 
241
                    len = abs(new_y2 - new_y1);
 
242
                else
 
243
                    len = abs(new_x2 - new_x1);
 
244
#ifdef POLYSEGMENT
 
245
                if (clip2 != 0 || pGC->capStyle != CapNotLast)
 
246
                    len++;
 
247
#else
 
248
                len += (clip2 != 0);
 
249
#endif
 
250
                if (len) {
 
251
                    int abserr, clipdx, clipdy;
 
252
                        /* unwind bresenham error term to first point */
 
253
                    if (clip1) {
 
254
                        clipdx = abs(new_x1 - x1);
 
255
                        clipdy = abs(new_y1 - y1);
 
256
 
 
257
                        if (octant & YMAJOR)
 
258
                            err = e + clipdy*dmin - clipdx*dmaj;
 
259
                        else
 
260
                            err = e + clipdx*dmin - clipdy*dmaj;
 
261
                    } else
 
262
                        err = e;
 
263
 
 
264
#define range infoRec->DashedBresenhamLineErrorTermBits
 
265
                    abserr = abs(err);                      
 
266
                    while((abserr & range) || 
 
267
                          (dmaj & range) ||
 
268
                          (dmin & range)) {
 
269
                        dmin >>= 1;
 
270
                        dmaj >>= 1;
 
271
                        abserr >>= 1;
 
272
                        err /= 2;
 
273
                    }
 
274
 
 
275
                    if(octant & YMAJOR)
 
276
                        offset = abs(new_y1 - y1);
 
277
                    else 
 
278
                        offset = abs(new_x1 - x1);
 
279
 
 
280
                    offset += PatternOffset;
 
281
                    offset %= PatternLength;
 
282
 
 
283
                    (*infoRec->SubsequentDashedBresenhamLine)(
 
284
                                infoRec->pScrn, new_x1, new_y1,
 
285
                                dmaj, dmin, err, len, octant, offset);
 
286
                }
 
287
                pbox++;
 
288
            }
 
289
        } /* while (nbox--) */
 
290
#ifndef POLYSEGMENT
 
291
        len = abs(y2 - y1);
 
292
        tmp = abs(x2 - x1);
 
293
        PatternOffset += (len > tmp) ? len : tmp;
 
294
        PatternOffset %= PatternLength;
 
295
#endif
 
296
    } /* while (nline--) */
 
297
 
 
298
#ifndef POLYSEGMENT
 
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.)
 
302
    */
 
303
 
 
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)))
 
308
    {
 
309
        nbox = nboxInit;
 
310
        pbox = pboxInit;
 
311
        while (nbox--) {
 
312
            if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
 
313
                (x2 <  pbox->x2) && (y2 <  pbox->y2))
 
314
            {
 
315
                if(infoRec->SubsequentDashedTwoPointLine) {
 
316
                        (*infoRec->SubsequentDashedTwoPointLine)(
 
317
                                infoRec->pScrn, x2, y2, x2, y2, 0,
 
318
                                PatternOffset);
 
319
                } else {
 
320
                        (*infoRec->SubsequentDashedBresenhamLine)(
 
321
                                infoRec->pScrn, x2, y2, 2, 0, -1, 
 
322
                                1, 0, PatternOffset);
 
323
                }
 
324
                break;
 
325
            } else
 
326
                pbox++;
 
327
        }
 
328
    }
 
329
#endif
 
330
 
 
331
    SET_SYNC_FLAG(infoRec);
 
332
}
 
333