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

« back to all changes in this revision

Viewing changes to mfb/mfbline.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/mfb/mfbline.c,v 1.6 2001/01/17 22:37:03 dawes Exp $ */
 
2
/***********************************************************
 
3
 
 
4
Copyright 1987, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 
 
26
 
 
27
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
28
 
 
29
                        All Rights Reserved
 
30
 
 
31
Permission to use, copy, modify, and distribute this software and its 
 
32
documentation for any purpose and without fee is hereby granted, 
 
33
provided that the above copyright notice appear in all copies and that
 
34
both that copyright notice and this permission notice appear in 
 
35
supporting documentation, and that the name of Digital not be
 
36
used in advertising or publicity pertaining to distribution of the
 
37
software without specific, written prior permission.  
 
38
 
 
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
45
SOFTWARE.
 
46
 
 
47
******************************************************************/
 
48
/* $Xorg: mfbline.c,v 1.4 2001/02/09 02:05:19 xorgcvs Exp $ */
 
49
#ifdef HAVE_DIX_CONFIG_H
 
50
#include <dix-config.h>
 
51
#endif
 
52
 
 
53
#include <X11/X.h>
 
54
 
 
55
#include "gcstruct.h"
 
56
#include "windowstr.h"
 
57
#include "pixmapstr.h"
 
58
#include "regionstr.h"
 
59
#include "scrnintstr.h"
 
60
#include "mistruct.h"
 
61
 
 
62
#include "mfb.h"
 
63
#include "maskbits.h"
 
64
#include "miline.h"
 
65
 
 
66
/* single-pixel lines on a color frame buffer
 
67
 
 
68
   NON-SLOPED LINES
 
69
   horizontal lines are always drawn left to right; we have to
 
70
move the endpoints right by one after they're swapped.
 
71
   horizontal lines will be confined to a single band of a
 
72
region.  the code finds that band (giving up if the lower
 
73
bound of the band is above the line we're drawing); then it
 
74
finds the first box in that band that contains part of the
 
75
line.  we clip the line to subsequent boxes in that band.
 
76
   vertical lines are always drawn top to bottom (y-increasing.)
 
77
this requires adding one to the y-coordinate of each endpoint
 
78
after swapping.
 
79
 
 
80
   SLOPED LINES
 
81
   when clipping a sloped line, we bring the second point inside
 
82
the clipping box, rather than one beyond it, and then add 1 to
 
83
the length of the line before drawing it.  this lets us use
 
84
the same box for finding the outcodes for both endpoints.  since
 
85
the equation for clipping the second endpoint to an edge gives us
 
86
1 beyond the edge, we then have to move the point towards the
 
87
first point by one step on the major axis.
 
88
   eventually, there will be a diagram here to explain what's going
 
89
on.  the method uses Cohen-Sutherland outcodes to determine
 
90
outsideness, and a method similar to Pike's layers for doing the
 
91
actual clipping.
 
92
 
 
93
*/
 
94
 
 
95
void
 
96
#ifdef POLYSEGMENT
 
97
mfbSegmentSS (pDrawable, pGC, nseg, pSeg)
 
98
    DrawablePtr pDrawable;
 
99
    GCPtr       pGC;
 
100
    int         nseg;
 
101
    register xSegment   *pSeg;
 
102
#else
 
103
mfbLineSS (pDrawable, pGC, mode, npt, pptInit)
 
104
    DrawablePtr pDrawable;
 
105
    GCPtr       pGC;
 
106
    int         mode;           /* Origin or Previous */
 
107
    int         npt;            /* number of points */
 
108
    DDXPointPtr pptInit;
 
109
#endif
 
110
{
 
111
    int nboxInit;
 
112
    register int nbox;
 
113
    BoxPtr pboxInit;
 
114
    register BoxPtr pbox;
 
115
#ifndef POLYSEGMENT
 
116
    register DDXPointPtr ppt;   /* pointer to list of translated points */
 
117
#endif
 
118
 
 
119
    unsigned int oc1;           /* outcode of point 1 */
 
120
    unsigned int oc2;           /* outcode of point 2 */
 
121
 
 
122
    PixelType *addrlBase;       /* pointer to start of drawable */
 
123
#ifndef POLYSEGMENT
 
124
    PixelType *addrl;           /* address of destination pixmap */
 
125
#endif
 
126
    int nlwidth;                /* width in longwords of destination pixmap */
 
127
    int xorg, yorg;             /* origin of window */
 
128
 
 
129
    int adx;            /* abs values of dx and dy */
 
130
    int ady;
 
131
    int signdx;         /* sign of dx and dy */
 
132
    int signdy;
 
133
    int e, e1, e2;              /* bresenham error and increments */
 
134
    int len;                    /* length of segment */
 
135
    int axis;                   /* major axis */
 
136
    int octant;
 
137
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
 
138
 
 
139
                                /* a bunch of temporaries */
 
140
    register int y1, y2;
 
141
    register int x1, x2;
 
142
    RegionPtr cclip;
 
143
    int             alu;
 
144
 
 
145
    if (!(pGC->planemask & 1))
 
146
        return;
 
147
 
 
148
    cclip = pGC->pCompositeClip;
 
149
    alu = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
 
150
    pboxInit = REGION_RECTS(cclip);
 
151
    nboxInit = REGION_NUM_RECTS(cclip);
 
152
 
 
153
    mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
 
154
 
 
155
    xorg = pDrawable->x;
 
156
    yorg = pDrawable->y;
 
157
#ifdef POLYSEGMENT
 
158
    while (nseg--)
 
159
#else
 
160
    ppt = pptInit;
 
161
    x2 = ppt->x + xorg;
 
162
    y2 = ppt->y + yorg;
 
163
    while(--npt)
 
164
#endif
 
165
    {
 
166
        nbox = nboxInit;
 
167
        pbox = pboxInit;
 
168
 
 
169
#ifdef POLYSEGMENT
 
170
        x1 = pSeg->x1 + xorg;
 
171
        y1 = pSeg->y1 + yorg;
 
172
        x2 = pSeg->x2 + xorg;
 
173
        y2 = pSeg->y2 + yorg;
 
174
        pSeg++;
 
175
#else
 
176
        x1 = x2;
 
177
        y1 = y2;
 
178
        ++ppt;
 
179
        if (mode == CoordModePrevious)
 
180
        {
 
181
            xorg = x1;
 
182
            yorg = y1;
 
183
        }
 
184
        x2 = ppt->x + xorg;
 
185
        y2 = ppt->y + yorg;
 
186
#endif
 
187
 
 
188
        if (x1 == x2) /* vertical line */
 
189
        {
 
190
            /* make the line go top to bottom of screen, keeping
 
191
               endpoint semantics
 
192
            */
 
193
            if (y1 > y2)
 
194
            {
 
195
                register int tmp;
 
196
 
 
197
                tmp = y2;
 
198
                y2 = y1 + 1;
 
199
                y1 = tmp + 1;
 
200
#ifdef POLYSEGMENT
 
201
                if (pGC->capStyle != CapNotLast)
 
202
                    y1--;
 
203
#endif
 
204
            }
 
205
#ifdef POLYSEGMENT
 
206
            else if (pGC->capStyle != CapNotLast)
 
207
                y2++;
 
208
#endif
 
209
            /* get to first band that might contain part of line */
 
210
            while ((nbox) && (pbox->y2 <= y1))
 
211
            {
 
212
                pbox++;
 
213
                nbox--;
 
214
            }
 
215
 
 
216
            if (nbox)
 
217
            {
 
218
                /* stop when lower edge of box is beyond end of line */
 
219
                while((nbox) && (y2 >= pbox->y1))
 
220
                {
 
221
                    if ((x1 >= pbox->x1) && (x1 < pbox->x2))
 
222
                    {
 
223
                        int y1t, y2t;
 
224
                        /* this box has part of the line in it */
 
225
                        y1t = max(y1, pbox->y1);
 
226
                        y2t = min(y2, pbox->y2);
 
227
                        if (y1t != y2t)
 
228
                        {
 
229
                            mfbVertS (alu,
 
230
                                      addrlBase, nlwidth, 
 
231
                                      x1, y1t, y2t-y1t);
 
232
                        }
 
233
                    }
 
234
                    nbox--;
 
235
                    pbox++;
 
236
                }
 
237
            }
 
238
#ifndef POLYSEGMENT
 
239
            y2 = ppt->y + yorg;
 
240
#endif
 
241
        }
 
242
        else if (y1 == y2) /* horizontal line */
 
243
        {
 
244
            /* force line from left to right, keeping
 
245
               endpoint semantics
 
246
            */
 
247
            if (x1 > x2)
 
248
            {
 
249
                register int tmp;
 
250
 
 
251
                tmp = x2;
 
252
                x2 = x1 + 1;
 
253
                x1 = tmp + 1;
 
254
#ifdef POLYSEGMENT
 
255
                if (pGC->capStyle != CapNotLast)
 
256
                    x1--;
 
257
#endif
 
258
            }
 
259
#ifdef POLYSEGMENT
 
260
            else if (pGC->capStyle != CapNotLast)
 
261
                x2++;
 
262
#endif
 
263
 
 
264
            /* find the correct band */
 
265
            while( (nbox) && (pbox->y2 <= y1))
 
266
            {
 
267
                pbox++;
 
268
                nbox--;
 
269
            }
 
270
 
 
271
            /* try to draw the line, if we haven't gone beyond it */
 
272
            if ((nbox) && (pbox->y1 <= y1))
 
273
            {
 
274
                int tmp;
 
275
 
 
276
                /* when we leave this band, we're done */
 
277
                tmp = pbox->y1;
 
278
                while((nbox) && (pbox->y1 == tmp))
 
279
                {
 
280
                    int x1t, x2t;
 
281
 
 
282
                    if (pbox->x2 <= x1)
 
283
                    {
 
284
                        /* skip boxes until one might contain start point */
 
285
                        nbox--;
 
286
                        pbox++;
 
287
                        continue;
 
288
                    }
 
289
 
 
290
                    /* stop if left of box is beyond right of line */
 
291
                    if (pbox->x1 >= x2)
 
292
                    {
 
293
                        nbox = 0;
 
294
                        break;
 
295
                    }
 
296
 
 
297
                    x1t = max(x1, pbox->x1);
 
298
                    x2t = min(x2, pbox->x2);
 
299
                    if (x1t != x2t)
 
300
                    {
 
301
                        mfbHorzS (alu,
 
302
                                  addrlBase, nlwidth, 
 
303
                                  x1t, y1, x2t-x1t);
 
304
                    }
 
305
                    nbox--;
 
306
                    pbox++;
 
307
                }
 
308
            }
 
309
#ifndef POLYSEGMENT
 
310
            x2 = ppt->x + xorg;
 
311
#endif
 
312
        }
 
313
        else    /* sloped line */
 
314
        {
 
315
            CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
 
316
                           1, 1, octant);
 
317
 
 
318
            if (adx > ady)
 
319
            {
 
320
                axis = X_AXIS;
 
321
                e1 = ady << 1;
 
322
                e2 = e1 - (adx << 1);
 
323
                e = e1 - adx;
 
324
            }
 
325
            else
 
326
            {
 
327
                axis = Y_AXIS;
 
328
                e1 = adx << 1;
 
329
                e2 = e1 - (ady << 1);
 
330
                e = e1 - ady;
 
331
                SetYMajorOctant(octant);
 
332
            }
 
333
 
 
334
            FIXUP_ERROR(e, octant, bias);
 
335
 
 
336
            /* we have bresenham parameters and two points.
 
337
               all we have to do now is clip and draw.
 
338
            */
 
339
 
 
340
            while(nbox--)
 
341
            {
 
342
                oc1 = 0;
 
343
                oc2 = 0;
 
344
                OUTCODES(oc1, x1, y1, pbox);
 
345
                OUTCODES(oc2, x2, y2, pbox);
 
346
                if ((oc1 | oc2) == 0)
 
347
                {
 
348
                    if (axis == X_AXIS)
 
349
                        len = adx;
 
350
                    else
 
351
                        len = ady;
 
352
#ifdef POLYSEGMENT
 
353
                    if (pGC->capStyle != CapNotLast)
 
354
                        len++;
 
355
#endif
 
356
                    mfbBresS (alu,
 
357
                          addrlBase, nlwidth,
 
358
                          signdx, signdy, axis, x1, y1,
 
359
                          e, e1, e2, len);
 
360
                    break;
 
361
                }
 
362
                else if (oc1 & oc2)
 
363
                {
 
364
                    pbox++;
 
365
                }
 
366
                else
 
367
                {
 
368
                    int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
 
369
                    int clip1 = 0, clip2 = 0;
 
370
                    int clipdx, clipdy;
 
371
                    int err;
 
372
                    
 
373
                    if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
 
374
                                       pbox->y2-1,
 
375
                                       &new_x1, &new_y1, &new_x2, &new_y2,
 
376
                                       adx, ady, &clip1, &clip2,
 
377
                                       octant, bias, oc1, oc2) == -1)
 
378
                    {
 
379
                        pbox++;
 
380
                        continue;
 
381
                    }
 
382
 
 
383
                    if (axis == X_AXIS)
 
384
                        len = abs(new_x2 - new_x1);
 
385
                    else
 
386
                        len = abs(new_y2 - new_y1);
 
387
#ifdef POLYSEGMENT
 
388
                    if (clip2 != 0 || pGC->capStyle != CapNotLast)
 
389
                        len++;
 
390
#else
 
391
                    len += (clip2 != 0);
 
392
#endif
 
393
                    if (len)
 
394
                    {
 
395
                        /* unwind bresenham error term to first point */
 
396
                        if (clip1)
 
397
                        {
 
398
                            clipdx = abs(new_x1 - x1);
 
399
                            clipdy = abs(new_y1 - y1);
 
400
                            if (axis == X_AXIS)
 
401
                                err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
 
402
                            else
 
403
                                err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
 
404
                        }
 
405
                        else
 
406
                            err = e;
 
407
                        mfbBresS   
 
408
                            (alu,
 
409
                             addrlBase, nlwidth,
 
410
                             signdx, signdy, axis, new_x1, new_y1,
 
411
                             err, e1, e2, len);
 
412
                    }
 
413
                    pbox++;
 
414
                }
 
415
            } /* while (nbox--) */
 
416
        } /* sloped line */
 
417
    } /* while (nline--) */
 
418
 
 
419
#ifndef POLYSEGMENT
 
420
 
 
421
    /* paint the last point if the end style isn't CapNotLast.
 
422
       (Assume that a projecting, butt, or round cap that is one
 
423
        pixel wide is the same as the single pixel of the endpoint.)
 
424
    */
 
425
 
 
426
    if ((pGC->capStyle != CapNotLast) &&
 
427
        ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
 
428
         (ppt->y + yorg != pptInit->y + pDrawable->y) ||
 
429
         (ppt == pptInit + 1)))
 
430
    {
 
431
        PixelType _mask;
 
432
 
 
433
        if (alu == RROP_BLACK)
 
434
                _mask = rmask[x2 & PIM];
 
435
        else
 
436
                _mask = mask[x2 & PIM];
 
437
 
 
438
        nbox = nboxInit;
 
439
        pbox = pboxInit;
 
440
        while (nbox--)
 
441
        {
 
442
            if ((x2 >= pbox->x1) &&
 
443
                (y2 >= pbox->y1) &&
 
444
                (x2 <  pbox->x2) &&
 
445
                (y2 <  pbox->y2))
 
446
            {
 
447
                addrl = mfbScanline(addrlBase, x2, y2, nlwidth);
 
448
                switch(alu)
 
449
                {
 
450
                    case RROP_BLACK:
 
451
                        *addrl &= _mask;
 
452
                        break;
 
453
                    case RROP_WHITE:
 
454
                        *addrl |= _mask;
 
455
                        break;
 
456
                    case RROP_INVERT:
 
457
                        *addrl ^= _mask;
 
458
                        break;
 
459
                }
 
460
                break;
 
461
            }
 
462
            else
 
463
                pbox++;
 
464
        }
 
465
    }
 
466
#endif
 
467
}
 
468
 
 
469
/*
 
470
 * Draw dashed 1-pixel lines.
 
471
 */
 
472
 
 
473
void
 
474
#ifdef POLYSEGMENT
 
475
mfbSegmentSD (pDrawable, pGC, nseg, pSeg)
 
476
    DrawablePtr pDrawable;
 
477
    register GCPtr      pGC;
 
478
    int         nseg;
 
479
    register xSegment   *pSeg;
 
480
#else
 
481
mfbLineSD( pDrawable, pGC, mode, npt, pptInit)
 
482
    DrawablePtr pDrawable;
 
483
    register GCPtr pGC;
 
484
    int mode;           /* Origin or Previous */
 
485
    int npt;            /* number of points */
 
486
    DDXPointPtr pptInit;
 
487
#endif
 
488
{
 
489
    int nboxInit;
 
490
    register int nbox;
 
491
    BoxPtr pboxInit;
 
492
    register BoxPtr pbox;
 
493
#ifndef POLYSEGMENT
 
494
    register DDXPointPtr ppt;   /* pointer to list of translated points */
 
495
#endif
 
496
 
 
497
    register unsigned int oc1;  /* outcode of point 1 */
 
498
    register unsigned int oc2;  /* outcode of point 2 */
 
499
 
 
500
    PixelType *addrl;           /* address of destination pixmap */
 
501
    int nlwidth;                /* width in longwords of destination pixmap */
 
502
    int xorg, yorg;             /* origin of window */
 
503
 
 
504
    int adx;            /* abs values of dx and dy */
 
505
    int ady;
 
506
    int signdx;         /* sign of dx and dy */
 
507
    int signdy;
 
508
    int e, e1, e2;              /* bresenham error and increments */
 
509
    int len;                    /* length of segment */
 
510
    int axis;                   /* major axis */
 
511
    int octant;
 
512
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
 
513
    int x1, x2, y1, y2;
 
514
    RegionPtr cclip;
 
515
    int             fgrop = 0, bgrop = 0;
 
516
    unsigned char   *pDash;
 
517
    int             dashOffset;
 
518
    int             numInDashList;
 
519
    int             dashIndex;
 
520
    int             isDoubleDash;
 
521
    int             dashIndexTmp, dashOffsetTmp;
 
522
    int             unclippedlen;
 
523
 
 
524
    if (!(pGC->planemask & 1))
 
525
        return;
 
526
 
 
527
    cclip = pGC->pCompositeClip;
 
528
    fgrop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
 
529
    pboxInit = REGION_RECTS(cclip);
 
530
    nboxInit = REGION_NUM_RECTS(cclip);
 
531
 
 
532
   mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl); 
 
533
 
 
534
    /* compute initial dash values */
 
535
     
 
536
    pDash = (unsigned char *) pGC->dash;
 
537
    numInDashList = pGC->numInDashList;
 
538
    isDoubleDash = (pGC->lineStyle == LineDoubleDash);
 
539
    dashIndex = 0;
 
540
    dashOffset = 0;
 
541
    miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
 
542
                numInDashList, &dashOffset);
 
543
 
 
544
    if (isDoubleDash)
 
545
        bgrop = mfbReduceRop(pGC->alu, pGC->bgPixel);
 
546
 
 
547
    xorg = pDrawable->x;
 
548
    yorg = pDrawable->y;
 
549
#ifdef POLYSEGMENT
 
550
    while (nseg--)
 
551
#else
 
552
    ppt = pptInit;
 
553
    x2 = ppt->x + xorg;
 
554
    y2 = ppt->y + yorg;
 
555
    while(--npt)
 
556
#endif
 
557
    {
 
558
        nbox = nboxInit;
 
559
        pbox = pboxInit;
 
560
 
 
561
#ifdef POLYSEGMENT
 
562
        x1 = pSeg->x1 + xorg;
 
563
        y1 = pSeg->y1 + yorg;
 
564
        x2 = pSeg->x2 + xorg;
 
565
        y2 = pSeg->y2 + yorg;
 
566
        pSeg++;
 
567
#else
 
568
        x1 = x2;
 
569
        y1 = y2;
 
570
        ++ppt;
 
571
        if (mode == CoordModePrevious)
 
572
        {
 
573
            xorg = x1;
 
574
            yorg = y1;
 
575
        }
 
576
        x2 = ppt->x + xorg;
 
577
        y2 = ppt->y + yorg;
 
578
#endif
 
579
 
 
580
        CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
 
581
 
 
582
        if (adx > ady)
 
583
        {
 
584
            axis = X_AXIS;
 
585
            e1 = ady << 1;
 
586
            e2 = e1 - (adx << 1);
 
587
            e = e1 - adx;
 
588
            unclippedlen = adx;
 
589
        }
 
590
        else
 
591
        {
 
592
            axis = Y_AXIS;
 
593
            e1 = adx << 1;
 
594
            e2 = e1 - (ady << 1);
 
595
            e = e1 - ady;
 
596
            unclippedlen = ady;
 
597
            SetYMajorOctant(octant);
 
598
        }
 
599
 
 
600
        FIXUP_ERROR(e, octant, bias);
 
601
 
 
602
        /* we have bresenham parameters and two points.
 
603
           all we have to do now is clip and draw.
 
604
        */
 
605
 
 
606
        while(nbox--)
 
607
        {
 
608
            oc1 = 0;
 
609
            oc2 = 0;
 
610
            OUTCODES(oc1, x1, y1, pbox);
 
611
            OUTCODES(oc2, x2, y2, pbox);
 
612
            if ((oc1 | oc2) == 0)
 
613
            {
 
614
#ifdef POLYSEGMENT
 
615
                if (pGC->capStyle != CapNotLast)
 
616
                    unclippedlen++;
 
617
                dashIndexTmp = dashIndex;
 
618
                dashOffsetTmp = dashOffset;
 
619
                mfbBresD (fgrop, bgrop,
 
620
                      &dashIndexTmp, pDash, numInDashList,
 
621
                      &dashOffsetTmp, isDoubleDash,
 
622
                      addrl, nlwidth,
 
623
                      signdx, signdy, axis, x1, y1,
 
624
                      e, e1, e2, unclippedlen);
 
625
                break;
 
626
#else
 
627
                mfbBresD (fgrop, bgrop,
 
628
                      &dashIndex, pDash, numInDashList,
 
629
                      &dashOffset, isDoubleDash,
 
630
                      addrl, nlwidth,
 
631
                      signdx, signdy, axis, x1, y1,
 
632
                      e, e1, e2, unclippedlen);
 
633
                goto dontStep;
 
634
#endif
 
635
            }
 
636
            else if (oc1 & oc2)
 
637
            {
 
638
                pbox++;
 
639
            }
 
640
            else /* have to clip */
 
641
            {
 
642
                int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
 
643
                int clip1 = 0, clip2 = 0;
 
644
                int clipdx, clipdy;
 
645
                int err;
 
646
                
 
647
                if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
 
648
                                   &new_x1, &new_y1, &new_x2, &new_y2,
 
649
                                   adx, ady, &clip1, &clip2,
 
650
                                   octant, bias, oc1, oc2) == -1)
 
651
                {
 
652
                    pbox++;
 
653
                    continue;
 
654
                }
 
655
                dashIndexTmp = dashIndex;
 
656
                dashOffsetTmp = dashOffset;
 
657
                if (clip1)
 
658
                {
 
659
                    int dlen;
 
660
                    
 
661
                    if (axis == X_AXIS)
 
662
                        dlen = abs(new_x1 - x1);
 
663
                    else
 
664
                        dlen = abs(new_y1 - y1);
 
665
                    miStepDash (dlen, &dashIndexTmp, pDash,
 
666
                                numInDashList, &dashOffsetTmp);
 
667
                }
 
668
                if (axis == X_AXIS)
 
669
                    len = abs(new_x2 - new_x1);
 
670
                else
 
671
                    len = abs(new_y2 - new_y1);
 
672
#ifdef POLYSEGMENT
 
673
                if (clip2 != 0 || pGC->capStyle != CapNotLast)
 
674
                    len++;
 
675
#else
 
676
                len += (clip2 != 0);
 
677
#endif
 
678
                if (len)
 
679
                {
 
680
                    /* unwind bresenham error term to first point */
 
681
                    if (clip1)
 
682
                    {
 
683
                        clipdx = abs(new_x1 - x1);
 
684
                        clipdy = abs(new_y1 - y1);
 
685
                        if (axis == X_AXIS)
 
686
                            err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
 
687
                        else
 
688
                            err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
 
689
                    }
 
690
                    else
 
691
                        err = e;
 
692
                    mfbBresD (fgrop, bgrop,
 
693
                              &dashIndexTmp, pDash, numInDashList,
 
694
                              &dashOffsetTmp, isDoubleDash,
 
695
                              addrl, nlwidth,
 
696
                              signdx, signdy, axis, new_x1, new_y1,
 
697
                              err, e1, e2, len);
 
698
                }
 
699
                pbox++;
 
700
            }
 
701
        } /* while (nbox--) */
 
702
#ifndef POLYSEGMENT
 
703
        /*
 
704
         * walk the dash list around to the next line
 
705
         */
 
706
        miStepDash (unclippedlen, &dashIndex, pDash,
 
707
                    numInDashList, &dashOffset);
 
708
dontStep:       ;
 
709
#endif
 
710
    } /* while (nline--) */
 
711
 
 
712
#ifndef POLYSEGMENT
 
713
    /* paint the last point if the end style isn't CapNotLast.
 
714
       (Assume that a projecting, butt, or round cap that is one
 
715
        pixel wide is the same as the single pixel of the endpoint.)
 
716
    */
 
717
 
 
718
    if ((pGC->capStyle != CapNotLast) &&
 
719
        ((dashIndex & 1) == 0 || isDoubleDash) &&
 
720
        ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
 
721
         (ppt->y + yorg != pptInit->y + pDrawable->y) ||
 
722
         (ppt == pptInit + 1)))
 
723
    {
 
724
        nbox = nboxInit;
 
725
        pbox = pboxInit;
 
726
        while (nbox--)
 
727
        {
 
728
            if ((x2 >= pbox->x1) &&
 
729
                (y2 >= pbox->y1) &&
 
730
                (x2 <  pbox->x2) &&
 
731
                (y2 <  pbox->y2))
 
732
            {
 
733
                MfbBits _mask;
 
734
                int rop;
 
735
 
 
736
                rop = fgrop;
 
737
                if (dashIndex & 1)
 
738
                    rop = bgrop;
 
739
                if (rop == RROP_BLACK)
 
740
                    _mask = rmask[x2 & PIM];
 
741
                else
 
742
                    _mask = mask[x2 & PIM];
 
743
                addrl = mfbScanline(addrl, x2, y2, nlwidth);
 
744
                if (rop == RROP_BLACK)
 
745
                    *addrl &= _mask;
 
746
                else if (rop == RROP_WHITE)
 
747
                    *addrl |= _mask;
 
748
                else
 
749
                    *addrl ^= _mask;
 
750
                break;
 
751
            }
 
752
            else
 
753
                pbox++;
 
754
        }
 
755
    }
 
756
#endif
 
757
}