~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/cfb/cfbline.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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