]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbline.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbline.c
1 /***********************************************************
2
3 Copyright (c) 1987  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
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 X CONSORTIUM 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 X Consortium 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 X Consortium.
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 /* $XConsortium: mfbline.c,v 5.19 94/07/28 14:28:21 dpw 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 "mfb.h"
59 #include "maskbits.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 mfbSegmentSS (pDrawable, pGC, nseg, pSeg)
94     DrawablePtr pDrawable;
95     GCPtr       pGC;
96     int         nseg;
97     register xSegment   *pSeg;
98 #else
99 mfbLineSS (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     PixelType *addrlBase;       /* pointer to start of drawable */
119     PixelType *addrl;           /* address of destination pixmap */
120     int nlwidth;                /* width in longwords of destination pixmap */
121     int xorg, yorg;             /* origin of window */
122
123     int adx;            /* abs values of dx and dy */
124     int ady;
125     int signdx;         /* sign of dx and dy */
126     int signdy;
127     int e, e1, e2;              /* bresenham error and increments */
128     int len;                    /* length of segment */
129     int axis;                   /* major axis */
130     int octant;
131     unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
132
133                                 /* a bunch of temporaries */
134     register int y1, y2;
135     register int x1, x2;
136     RegionPtr cclip;
137     int             alu;
138
139     if (!(pGC->planemask & 1))
140         return;
141
142     cclip = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
143     alu = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
144     pboxInit = REGION_RECTS(cclip);
145     nboxInit = REGION_NUM_RECTS(cclip);
146
147     mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
148
149     xorg = pDrawable->x;
150     yorg = pDrawable->y;
151 #ifdef POLYSEGMENT
152     while (nseg--)
153 #else
154     ppt = pptInit;
155     x2 = ppt->x + xorg;
156     y2 = ppt->y + yorg;
157     while(--npt)
158 #endif
159     {
160         nbox = nboxInit;
161         pbox = pboxInit;
162
163 #ifdef POLYSEGMENT
164         x1 = pSeg->x1 + xorg;
165         y1 = pSeg->y1 + yorg;
166         x2 = pSeg->x2 + xorg;
167         y2 = pSeg->y2 + yorg;
168         pSeg++;
169 #else
170         x1 = x2;
171         y1 = y2;
172         ++ppt;
173         if (mode == CoordModePrevious)
174         {
175             xorg = x1;
176             yorg = y1;
177         }
178         x2 = ppt->x + xorg;
179         y2 = ppt->y + yorg;
180 #endif
181
182         if (x1 == x2) /* vertical line */
183         {
184             /* make the line go top to bottom of screen, keeping
185                endpoint semantics
186             */
187             if (y1 > y2)
188             {
189                 register int tmp;
190
191                 tmp = y2;
192                 y2 = y1 + 1;
193                 y1 = tmp + 1;
194 #ifdef POLYSEGMENT
195                 if (pGC->capStyle != CapNotLast)
196                     y1--;
197 #endif
198             }
199 #ifdef POLYSEGMENT
200             else if (pGC->capStyle != CapNotLast)
201                 y2++;
202 #endif
203             /* get to first band that might contain part of line */
204             while ((nbox) && (pbox->y2 <= y1))
205             {
206                 pbox++;
207                 nbox--;
208             }
209
210             if (nbox)
211             {
212                 /* stop when lower edge of box is beyond end of line */
213                 while((nbox) && (y2 >= pbox->y1))
214                 {
215                     if ((x1 >= pbox->x1) && (x1 < pbox->x2))
216                     {
217                         int y1t, y2t;
218                         /* this box has part of the line in it */
219                         y1t = max(y1, pbox->y1);
220                         y2t = min(y2, pbox->y2);
221                         if (y1t != y2t)
222                         {
223                             mfbVertS (alu,
224                                       addrlBase, nlwidth, 
225                                       x1, y1t, y2t-y1t);
226                         }
227                     }
228                     nbox--;
229                     pbox++;
230                 }
231             }
232 #ifndef POLYSEGMENT
233             y2 = ppt->y + yorg;
234 #endif
235         }
236         else if (y1 == y2) /* horizontal line */
237         {
238             /* force line from left to right, keeping
239                endpoint semantics
240             */
241             if (x1 > x2)
242             {
243                 register int tmp;
244
245                 tmp = x2;
246                 x2 = x1 + 1;
247                 x1 = tmp + 1;
248 #ifdef POLYSEGMENT
249                 if (pGC->capStyle != CapNotLast)
250                     x1--;
251 #endif
252             }
253 #ifdef POLYSEGMENT
254             else if (pGC->capStyle != CapNotLast)
255                 x2++;
256 #endif
257
258             /* find the correct band */
259             while( (nbox) && (pbox->y2 <= y1))
260             {
261                 pbox++;
262                 nbox--;
263             }
264
265             /* try to draw the line, if we haven't gone beyond it */
266             if ((nbox) && (pbox->y1 <= y1))
267             {
268                 int tmp;
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                         mfbHorzS (alu,
296                                   addrlBase, 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                     mfbBresS (alu,
351                           addrlBase, 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                         mfbBresS   
402                             (alu,
403                              addrlBase, nlwidth,
404                              signdx, signdy, axis, new_x1, new_y1,
405                              err, e1, e2, len);
406                     }
407                     pbox++;
408                 }
409             } /* while (nbox--) */
410         } /* sloped line */
411     } /* while (nline--) */
412
413 #ifndef POLYSEGMENT
414
415     /* paint the last point if the end style isn't CapNotLast.
416        (Assume that a projecting, butt, or round cap that is one
417         pixel wide is the same as the single pixel of the endpoint.)
418     */
419
420     if ((pGC->capStyle != CapNotLast) &&
421         ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
422          (ppt->y + yorg != pptInit->y + pDrawable->y) ||
423          (ppt == pptInit + 1)))
424     {
425         PixelType _mask;
426
427         if (alu == RROP_BLACK)
428                 _mask = rmask[x2 & PIM];
429         else
430                 _mask = mask[x2 & PIM];
431
432         nbox = nboxInit;
433         pbox = pboxInit;
434         while (nbox--)
435         {
436             if ((x2 >= pbox->x1) &&
437                 (y2 >= pbox->y1) &&
438                 (x2 <  pbox->x2) &&
439                 (y2 <  pbox->y2))
440             {
441                 addrl = mfbScanline(addrlBase, x2, y2, nlwidth);
442                 switch(alu)
443                 {
444                     case RROP_BLACK:
445                         *addrl &= _mask;
446                         break;
447                     case RROP_WHITE:
448                         *addrl |= _mask;
449                         break;
450                     case RROP_INVERT:
451                         *addrl ^= _mask;
452                         break;
453                 }
454                 break;
455             }
456             else
457                 pbox++;
458         }
459     }
460 #endif
461 }
462
463 /*
464  * Draw dashed 1-pixel lines.
465  */
466
467 void
468 #ifdef POLYSEGMENT
469 mfbSegmentSD (pDrawable, pGC, nseg, pSeg)
470     DrawablePtr pDrawable;
471     register GCPtr      pGC;
472     int         nseg;
473     register xSegment   *pSeg;
474 #else
475 mfbLineSD( pDrawable, pGC, mode, npt, pptInit)
476     DrawablePtr pDrawable;
477     register GCPtr pGC;
478     int mode;           /* Origin or Previous */
479     int npt;            /* number of points */
480     DDXPointPtr pptInit;
481 #endif
482 {
483     int nboxInit;
484     register int nbox;
485     BoxPtr pboxInit;
486     register BoxPtr pbox;
487 #ifndef POLYSEGMENT
488     register DDXPointPtr ppt;   /* pointer to list of translated points */
489 #endif
490
491     register unsigned int oc1;  /* outcode of point 1 */
492     register unsigned int oc2;  /* outcode of point 2 */
493
494     PixelType *addrl;           /* address of destination pixmap */
495     int nlwidth;                /* width in longwords of destination pixmap */
496     int xorg, yorg;             /* origin of window */
497
498     int adx;            /* abs values of dx and dy */
499     int ady;
500     int signdx;         /* sign of dx and dy */
501     int signdy;
502     int e, e1, e2;              /* bresenham error and increments */
503     int len;                    /* length of segment */
504     int axis;                   /* major axis */
505     int octant;
506     unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
507     int x1, x2, y1, y2;
508     RegionPtr cclip;
509     int             fgrop, bgrop;
510     unsigned char   *pDash;
511     int             dashOffset;
512     int             numInDashList;
513     int             dashIndex;
514     int             isDoubleDash;
515     int             dashIndexTmp, dashOffsetTmp;
516     int             unclippedlen;
517
518     if (!(pGC->planemask & 1))
519         return;
520
521     cclip = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
522     fgrop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
523     pboxInit = REGION_RECTS(cclip);
524     nboxInit = REGION_NUM_RECTS(cclip);
525
526    mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl); 
527
528     /* compute initial dash values */
529      
530     pDash = (unsigned char *) pGC->dash;
531     numInDashList = pGC->numInDashList;
532     isDoubleDash = (pGC->lineStyle == LineDoubleDash);
533     dashIndex = 0;
534     dashOffset = 0;
535     miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
536                 numInDashList, &dashOffset);
537
538     if (isDoubleDash)
539         bgrop = mfbReduceRop(pGC->alu, pGC->bgPixel);
540
541     xorg = pDrawable->x;
542     yorg = pDrawable->y;
543 #ifdef POLYSEGMENT
544     while (nseg--)
545 #else
546     ppt = pptInit;
547     x2 = ppt->x + xorg;
548     y2 = ppt->y + yorg;
549     while(--npt)
550 #endif
551     {
552         nbox = nboxInit;
553         pbox = pboxInit;
554
555 #ifdef POLYSEGMENT
556         x1 = pSeg->x1 + xorg;
557         y1 = pSeg->y1 + yorg;
558         x2 = pSeg->x2 + xorg;
559         y2 = pSeg->y2 + yorg;
560         pSeg++;
561 #else
562         x1 = x2;
563         y1 = y2;
564         ++ppt;
565         if (mode == CoordModePrevious)
566         {
567             xorg = x1;
568             yorg = y1;
569         }
570         x2 = ppt->x + xorg;
571         y2 = ppt->y + yorg;
572 #endif
573
574         CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
575
576         if (adx > ady)
577         {
578             axis = X_AXIS;
579             e1 = ady << 1;
580             e2 = e1 - (adx << 1);
581             e = e1 - adx;
582             unclippedlen = adx;
583         }
584         else
585         {
586             axis = Y_AXIS;
587             e1 = adx << 1;
588             e2 = e1 - (ady << 1);
589             e = e1 - ady;
590             unclippedlen = ady;
591             SetYMajorOctant(octant);
592         }
593
594         FIXUP_ERROR(e, octant, bias);
595
596         /* we have bresenham parameters and two points.
597            all we have to do now is clip and draw.
598         */
599
600         while(nbox--)
601         {
602             oc1 = 0;
603             oc2 = 0;
604             OUTCODES(oc1, x1, y1, pbox);
605             OUTCODES(oc2, x2, y2, pbox);
606             if ((oc1 | oc2) == 0)
607             {
608 #ifdef POLYSEGMENT
609                 if (pGC->capStyle != CapNotLast)
610                     unclippedlen++;
611                 dashIndexTmp = dashIndex;
612                 dashOffsetTmp = dashOffset;
613                 mfbBresD (fgrop, bgrop,
614                       &dashIndexTmp, pDash, numInDashList,
615                       &dashOffsetTmp, isDoubleDash,
616                       addrl, nlwidth,
617                       signdx, signdy, axis, x1, y1,
618                       e, e1, e2, unclippedlen);
619                 break;
620 #else
621                 mfbBresD (fgrop, bgrop,
622                       &dashIndex, pDash, numInDashList,
623                       &dashOffset, isDoubleDash,
624                       addrl, nlwidth,
625                       signdx, signdy, axis, x1, y1,
626                       e, e1, e2, unclippedlen);
627                 goto dontStep;
628 #endif
629             }
630             else if (oc1 & oc2)
631             {
632                 pbox++;
633             }
634             else /* have to clip */
635             {
636                 int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
637                 int clip1 = 0, clip2 = 0;
638                 int clipdx, clipdy;
639                 int err;
640                 
641                 if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
642                                    &new_x1, &new_y1, &new_x2, &new_y2,
643                                    adx, ady, &clip1, &clip2,
644                                    octant, bias, oc1, oc2) == -1)
645                 {
646                     pbox++;
647                     continue;
648                 }
649                 dashIndexTmp = dashIndex;
650                 dashOffsetTmp = dashOffset;
651                 if (clip1)
652                 {
653                     int dlen;
654                     
655                     if (axis == X_AXIS)
656                         dlen = abs(new_x1 - x1);
657                     else
658                         dlen = abs(new_y1 - y1);
659                     miStepDash (dlen, &dashIndexTmp, pDash,
660                                 numInDashList, &dashOffsetTmp);
661                 }
662                 if (axis == X_AXIS)
663                     len = abs(new_x2 - new_x1);
664                 else
665                     len = abs(new_y2 - new_y1);
666 #ifdef POLYSEGMENT
667                 if (clip2 != 0 || pGC->capStyle != CapNotLast)
668                     len++;
669 #else
670                 len += (clip2 != 0);
671 #endif
672                 if (len)
673                 {
674                     /* unwind bresenham error term to first point */
675                     if (clip1)
676                     {
677                         clipdx = abs(new_x1 - x1);
678                         clipdy = abs(new_y1 - y1);
679                         if (axis == X_AXIS)
680                             err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
681                         else
682                             err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
683                     }
684                     else
685                         err = e;
686                     mfbBresD (fgrop, bgrop,
687                               &dashIndexTmp, pDash, numInDashList,
688                               &dashOffsetTmp, isDoubleDash,
689                               addrl, nlwidth,
690                               signdx, signdy, axis, new_x1, new_y1,
691                               err, e1, e2, len);
692                 }
693                 pbox++;
694             }
695         } /* while (nbox--) */
696 #ifndef POLYSEGMENT
697         /*
698          * walk the dash list around to the next line
699          */
700         miStepDash (unclippedlen, &dashIndex, pDash,
701                     numInDashList, &dashOffset);
702 dontStep:       ;
703 #endif
704     } /* while (nline--) */
705
706 #ifndef POLYSEGMENT
707     /* paint the last point if the end style isn't CapNotLast.
708        (Assume that a projecting, butt, or round cap that is one
709         pixel wide is the same as the single pixel of the endpoint.)
710     */
711
712     if ((pGC->capStyle != CapNotLast) &&
713         ((dashIndex & 1) == 0 || isDoubleDash) &&
714         ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
715          (ppt->y + yorg != pptInit->y + pDrawable->y) ||
716          (ppt == pptInit + 1)))
717     {
718         nbox = nboxInit;
719         pbox = pboxInit;
720         while (nbox--)
721         {
722             if ((x2 >= pbox->x1) &&
723                 (y2 >= pbox->y1) &&
724                 (x2 <  pbox->x2) &&
725                 (y2 <  pbox->y2))
726             {
727                 unsigned long _mask;
728                 int rop;
729
730                 rop = fgrop;
731                 if (dashIndex & 1)
732                     rop = bgrop;
733                 if (rop == RROP_BLACK)
734                     _mask = rmask[x2 & PIM];
735                 else
736                     _mask = mask[x2 & PIM];
737                 addrl = mfbScanline(addrl, x2, y2, nlwidth);
738                 if (rop == RROP_BLACK)
739                     *addrl &= _mask;
740                 else if (rop == RROP_WHITE)
741                     *addrl |= _mask;
742                 else
743                     *addrl ^= _mask;
744                 break;
745             }
746             else
747                 pbox++;
748         }
749     }
750 #endif
751 }