xref: /reactos/win32ss/gdi/eng/lineto.c (revision 40462c92)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * PURPOSE:          Line functions
5  * FILE:             win32ss/gdi/eng/lineto.c
6  * PROGRAMER:        ReactOS Team
7  */
8 
9 #include <win32k.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 static void FASTCALL
15 TranslateRects(RECT_ENUM *RectEnum, POINTL* Translate)
16 {
17     RECTL* CurrentRect;
18 
19     if (0 != Translate->x || 0 != Translate->y)
20     {
21         for (CurrentRect = RectEnum->arcl; CurrentRect < RectEnum->arcl + RectEnum->c; CurrentRect++)
22         {
23             CurrentRect->left += Translate->x;
24             CurrentRect->right += Translate->x;
25             CurrentRect->top += Translate->y;
26             CurrentRect->bottom += Translate->y;
27         }
28     }
29 }
30 
31 LONG
32 HandleStyles(
33     BRUSHOBJ *pbo,
34     POINTL* Translate,
35     LONG x,
36     LONG y,
37     LONG deltax,
38     LONG deltay,
39     LONG dx,
40     LONG dy,
41     PULONG piStyle)
42 {
43     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
44     PULONG pulStyles = pebo->pbrush->pStyle;
45     ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount;
46     LONG diStyle, offStyle, lStyleMax;
47 
48     if (cStyles > 0)
49     {
50         if (deltax > deltay)
51         {
52             offStyle = (- Translate->x) % pebo->pbrush->ulStyleSize;
53             diStyle = dx;
54             lStyleMax = x;
55         }
56         else
57         {
58             offStyle = (- Translate->y) % pebo->pbrush->ulStyleSize;
59             diStyle = dy;
60             lStyleMax = y;
61         }
62 
63         /* Now loop until we have found the style index */
64         for (iStyle = 0; offStyle >= pulStyles[iStyle]; iStyle++)
65         {
66             offStyle -= pulStyles[iStyle];
67         }
68 
69         if (diStyle > 0)
70         {
71             lStyleMax += pulStyles[iStyle] - offStyle;
72         }
73         else
74         {
75             lStyleMax -= offStyle + 1;
76         }
77     }
78     else
79     {
80         iStyle = 0;
81         lStyleMax = MAX_COORD;
82     }
83 
84     *piStyle = iStyle;
85     return lStyleMax;
86 }
87 
88 /*
89  * Draw a line from top-left to bottom-right
90  */
91 void FASTCALL
92 NWtoSE(SURFOBJ* OutputObj, CLIPOBJ* Clip,
93        BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay,
94        POINTL* Translate)
95 {
96     int i;
97     int error;
98     BOOLEAN EnumMore;
99     RECTL* ClipRect;
100     RECT_ENUM RectEnum;
101     ULONG Pixel = pbo->iSolidColor;
102     LONG delta;
103     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
104     PULONG pulStyles = pebo->pbrush->pStyle;
105     ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount;
106     LONG lStyleMax;
107 
108     lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, 1, 1, &iStyle);
109 
110     CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
111     EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
112     TranslateRects(&RectEnum, Translate);
113     ClipRect = RectEnum.arcl;
114     delta = max(deltax, deltay);
115     i = 0;
116     error = delta >> 1;
117     while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
118     {
119         while ((ClipRect < RectEnum.arcl + RectEnum.c /* there's still a current clip rect */
120                 && (ClipRect->bottom <= y             /* but it's above us */
121                     || (ClipRect->top <= y && ClipRect->right <= x))) /* or to the left of us */
122                 || EnumMore)                           /* no current clip rect, but rects left */
123         {
124             /* Skip to the next clip rect */
125             if (RectEnum.arcl + RectEnum.c <= ClipRect)
126             {
127                 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
128                 TranslateRects(&RectEnum, Translate);
129                 ClipRect = RectEnum.arcl;
130             }
131             else
132             {
133                 ClipRect++;
134             }
135         }
136         if (ClipRect < RectEnum.arcl + RectEnum.c) /* If there's no current clip rect we're done */
137         {
138             if ((ClipRect->left <= x && ClipRect->top <= y) && ((iStyle & 1) == 0))
139             {
140                 DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel(
141                     OutputObj, x, y, Pixel);
142             }
143             if (deltax < deltay)
144             {
145                 y++;
146                 if (y == lStyleMax)
147                 {
148                     iStyle = (iStyle + 1) % cStyles;
149                     lStyleMax = y + pulStyles[iStyle];
150                 }
151                 error = error + deltax;
152                 if (deltay <= error)
153                 {
154                     x++;
155                     error = error - deltay;
156                 }
157             }
158             else
159             {
160                 x++;
161                 if (x == lStyleMax)
162                 {
163                     iStyle = (iStyle + 1) % cStyles;
164                     lStyleMax = x + pulStyles[iStyle];
165                 }
166                 error = error + deltay;
167                 if (deltax <= error)
168                 {
169                     y++;
170                     error = error - deltax;
171                 }
172             }
173             i++;
174         }
175     }
176 }
177 
178 void FASTCALL
179 SWtoNE(SURFOBJ* OutputObj, CLIPOBJ* Clip,
180        BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay,
181        POINTL* Translate)
182 {
183     int i;
184     int error;
185     BOOLEAN EnumMore;
186     RECTL* ClipRect;
187     RECT_ENUM RectEnum;
188     ULONG Pixel = pbo->iSolidColor;
189     LONG delta;
190     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
191     PULONG pulStyles = pebo->pbrush->pStyle;
192     ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount;
193     LONG lStyleMax;
194 
195     lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, 1, -1, &iStyle);
196 
197     CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0);
198     EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
199     TranslateRects(&RectEnum, Translate);
200     ClipRect = RectEnum.arcl;
201     delta = max(deltax, deltay);
202     i = 0;
203     error = delta >> 1;
204     while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
205     {
206         while ((ClipRect < RectEnum.arcl + RectEnum.c
207                 && (y < ClipRect->top
208                     || (y < ClipRect->bottom && ClipRect->right <= x)))
209                 || EnumMore)
210         {
211             if (RectEnum.arcl + RectEnum.c <= ClipRect)
212             {
213                 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
214                 TranslateRects(&RectEnum, Translate);
215                 ClipRect = RectEnum.arcl;
216             }
217             else
218             {
219                 ClipRect++;
220             }
221         }
222         if (ClipRect < RectEnum.arcl + RectEnum.c)
223         {
224             if ((ClipRect->left <= x && y < ClipRect->bottom) && ((iStyle & 1) == 0))
225             {
226                 DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel(
227                     OutputObj, x, y, Pixel);
228             }
229             if (deltax < deltay)
230             {
231                 y--;
232                 if (y == lStyleMax)
233                 {
234                     iStyle = (iStyle - 1) % cStyles;
235                     lStyleMax = y - pulStyles[iStyle];
236                 }
237                 error = error + deltax;
238                 if (deltay <= error)
239                 {
240                     x++;
241                     error = error - deltay;
242                 }
243             }
244             else
245             {
246                 x++;
247                 if (x == lStyleMax)
248                 {
249                     iStyle = (iStyle + 1) % cStyles;
250                     lStyleMax = x + pulStyles[iStyle];
251                 }
252                 error = error + deltay;
253                 if (deltax <= error)
254                 {
255                     y--;
256                     error = error - deltax;
257                 }
258             }
259             i++;
260         }
261     }
262 }
263 
264 void FASTCALL
265 NEtoSW(SURFOBJ* OutputObj, CLIPOBJ* Clip,
266        BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay,
267        POINTL* Translate)
268 {
269     int i;
270     int error;
271     BOOLEAN EnumMore;
272     RECTL* ClipRect;
273     RECT_ENUM RectEnum;
274     ULONG Pixel = pbo->iSolidColor;
275     LONG delta;
276     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
277     PULONG pulStyles = pebo->pbrush->pStyle;
278     ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount;
279     LONG lStyleMax;
280 
281     lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, -1, 1, &iStyle);
282 
283     CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0);
284     EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
285     TranslateRects(&RectEnum, Translate);
286     ClipRect = RectEnum.arcl;
287     delta = max(deltax, deltay);
288     i = 0;
289     error = delta >> 1;
290     while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
291     {
292         while ((ClipRect < RectEnum.arcl + RectEnum.c
293                 && (ClipRect->bottom <= y
294                     || (ClipRect->top <= y && x < ClipRect->left)))
295                 || EnumMore)
296         {
297             if (RectEnum.arcl + RectEnum.c <= ClipRect)
298             {
299                 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
300                 TranslateRects(&RectEnum, Translate);
301                 ClipRect = RectEnum.arcl;
302             }
303             else
304             {
305                 ClipRect++;
306             }
307         }
308         if (ClipRect < RectEnum.arcl + RectEnum.c)
309         {
310             if ((x < ClipRect->right && ClipRect->top <= y) && ((iStyle & 1) == 0))
311             {
312                 DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel(
313                     OutputObj, x, y, Pixel);
314             }
315             if (deltax < deltay)
316             {
317                 y++;
318                 if (y == lStyleMax)
319                 {
320                     iStyle = (iStyle + 1) % cStyles;
321                     lStyleMax = y + pulStyles[iStyle];
322                 }
323                 error = error + deltax;
324                 if (deltay <= error)
325                 {
326                     x--;
327                     error = error - deltay;
328                 }
329             }
330             else
331             {
332                 x--;
333                 if (x == lStyleMax)
334                 {
335                     iStyle = (iStyle - 1) % cStyles;
336                     lStyleMax = x - pulStyles[iStyle];
337                 }
338                 error = error + deltay;
339                 if (deltax <= error)
340                 {
341                     y++;
342                     error = error - deltax;
343                 }
344             }
345             i++;
346         }
347     }
348 }
349 
350 void FASTCALL
351 SEtoNW(SURFOBJ* OutputObj, CLIPOBJ* Clip,
352        BRUSHOBJ* pbo, LONG x, LONG y, LONG deltax, LONG deltay,
353        POINTL* Translate)
354 {
355     int i;
356     int error;
357     BOOLEAN EnumMore;
358     RECTL* ClipRect;
359     RECT_ENUM RectEnum;
360     ULONG Pixel = pbo->iSolidColor;
361     LONG delta;
362     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
363     PULONG pulStyles = pebo->pbrush->pStyle;
364     ULONG iStyle, cStyles = pebo->pbrush->dwStyleCount;
365     LONG lStyleMax;
366 
367     lStyleMax = HandleStyles(pbo, Translate, x, y, deltax, deltay, -1, -1, &iStyle);
368 
369     CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0);
370     EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
371     TranslateRects(&RectEnum, Translate);
372     ClipRect = RectEnum.arcl;
373     delta = max(deltax, deltay);
374     i = 0;
375     error = delta >> 1;
376     while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
377     {
378         while ((ClipRect < RectEnum.arcl + RectEnum.c
379                 && (y < ClipRect->top
380                     || (y < ClipRect->bottom && x < ClipRect->left)))
381                 || EnumMore)
382         {
383             if (RectEnum.arcl + RectEnum.c <= ClipRect)
384             {
385                 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
386                 TranslateRects(&RectEnum, Translate);
387                 ClipRect = RectEnum.arcl;
388             }
389             else
390             {
391                 ClipRect++;
392             }
393         }
394         if (ClipRect < RectEnum.arcl + RectEnum.c)
395         {
396             if ((x < ClipRect->right && y < ClipRect->bottom) && ((iStyle & 1) == 0))
397             {
398                 DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_PutPixel(
399                     OutputObj, x, y, Pixel);
400             }
401             if (deltax < deltay)
402             {
403                 y--;
404                 if (y == lStyleMax)
405                 {
406                     iStyle = (iStyle - 1) % cStyles;
407                     lStyleMax = y - pulStyles[iStyle];
408                 }
409                 error = error + deltax;
410                 if (deltay <= error)
411                 {
412                     x--;
413                     error = error - deltay;
414                 }
415             }
416             else
417             {
418                 x--;
419                 if (x == lStyleMax)
420                 {
421                     iStyle = (iStyle - 1) % cStyles;
422                     lStyleMax = x - pulStyles[iStyle];
423                 }
424                 error = error + deltay;
425                 if (deltax <= error)
426                 {
427                     y--;
428                     error = error - deltax;
429                 }
430             }
431             i++;
432         }
433     }
434 }
435 
436 /*
437  * @implemented
438  */
439 BOOL APIENTRY
440 EngLineTo(
441     _Inout_ SURFOBJ *DestObj,
442     _In_ CLIPOBJ *Clip,
443     _In_ BRUSHOBJ *pbo,
444     _In_ LONG x1,
445     _In_ LONG y1,
446     _In_ LONG x2,
447     _In_ LONG y2,
448     _In_opt_ RECTL *RectBounds,
449     _In_ MIX mix)
450 {
451     LONG x, y, deltax, deltay, xchange, ychange, hx, vy;
452     ULONG i;
453     ULONG Pixel = pbo->iSolidColor;
454     SURFOBJ *OutputObj;
455     RECTL DestRect;
456     POINTL Translate;
457     INTENG_ENTER_LEAVE EnterLeave;
458     RECT_ENUM RectEnum;
459     BOOL EnumMore;
460     CLIPOBJ *pcoPriv = NULL;
461     PEBRUSHOBJ pebo = (PEBRUSHOBJ)pbo;
462     ULONG cStyles = pebo->pbrush->dwStyleCount;
463 
464     if (x1 < x2)
465     {
466         DestRect.left = x1;
467         DestRect.right = x2;
468     }
469     else
470     {
471         DestRect.left = x2;
472         DestRect.right = x1 + 1;
473     }
474     if (y1 < y2)
475     {
476         DestRect.top = y1;
477         DestRect.bottom = y2;
478     }
479     else
480     {
481         DestRect.top = y2;
482         DestRect.bottom = y1 + 1;
483     }
484 
485     if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
486     {
487         return FALSE;
488     }
489 
490     if (!Clip)
491     {
492         Clip = pcoPriv = EngCreateClip();
493         if (!Clip)
494         {
495             return FALSE;
496         }
497         IntEngUpdateClipRegion((XCLIPOBJ*)Clip, 0, 0, RectBounds);
498     }
499 
500     x1 += Translate.x;
501     x2 += Translate.x;
502     y1 += Translate.y;
503     y2 += Translate.y;
504 
505     x = x1;
506     y = y1;
507     deltax = x2 - x1;
508     deltay = y2 - y1;
509 
510     if (0 == deltax && 0 == deltay)
511     {
512         return TRUE;
513     }
514 
515     if (deltax < 0)
516     {
517         xchange = -1;
518         deltax = - deltax;
519         hx = x2 + 1;
520     }
521     else
522     {
523         xchange = 1;
524         hx = x1;
525     }
526 
527     if (deltay < 0)
528     {
529         ychange = -1;
530         deltay = - deltay;
531         vy = y2 + 1;
532     }
533     else
534     {
535         ychange = 1;
536         vy = y1;
537     }
538 
539     if ((y1 == y2) && (cStyles == 0))
540     {
541         CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
542         do
543         {
544             EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
545             for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top + Translate.y <= y1; i++)
546             {
547                 if (y1 < RectEnum.arcl[i].bottom + Translate.y &&
548                         RectEnum.arcl[i].left + Translate.x <= hx + deltax &&
549                         hx < RectEnum.arcl[i].right + Translate.x &&
550                         max(hx, RectEnum.arcl[i].left + Translate.x) <
551                         min(hx + deltax, RectEnum.arcl[i].right + Translate.x))
552                 {
553                     DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_HLine(
554                         OutputObj,
555                         max(hx, RectEnum.arcl[i].left + Translate.x),
556                         min(hx + deltax, RectEnum.arcl[i].right + Translate.x),
557                         y1, Pixel);
558                 }
559             }
560         }
561         while (EnumMore);
562     }
563     else if ((x1 == x2) && (cStyles == 0))
564     {
565         CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
566         do
567         {
568             EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
569             for (i = 0; i < RectEnum.c; i++)
570             {
571                 if (RectEnum.arcl[i].left + Translate.x <= x1 &&
572                         x1 < RectEnum.arcl[i].right + Translate.x &&
573                         RectEnum.arcl[i].top + Translate.y <= vy + deltay &&
574                         vy < RectEnum.arcl[i].bottom + Translate.y)
575                 {
576                     DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_VLine(
577                         OutputObj, x1,
578                         max(vy, RectEnum.arcl[i].top + Translate.y),
579                         min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y),
580                         Pixel);
581                 }
582             }
583         }
584         while (EnumMore);
585     }
586     else
587     {
588         if (0 < xchange)
589         {
590             if (0 < ychange)
591             {
592                 NWtoSE(OutputObj, Clip, pbo, x, y, deltax, deltay, &Translate);
593             }
594             else
595             {
596                 SWtoNE(OutputObj, Clip, pbo, x, y, deltax, deltay, &Translate);
597             }
598         }
599         else
600         {
601             if (0 < ychange)
602             {
603                 NEtoSW(OutputObj, Clip, pbo, x, y, deltax, deltay, &Translate);
604             }
605             else
606             {
607                 SEtoNW(OutputObj, Clip, pbo, x, y, deltax, deltay, &Translate);
608             }
609         }
610     }
611 
612     if (pcoPriv)
613     {
614         EngDeleteClip(pcoPriv);
615     }
616 
617     return IntEngLeave(&EnterLeave);
618 }
619 
620 BOOL APIENTRY
621 IntEngLineTo(SURFOBJ *psoDest,
622              CLIPOBJ *ClipObj,
623              BRUSHOBJ *pbo,
624              LONG x1,
625              LONG y1,
626              LONG x2,
627              LONG y2,
628              RECTL *RectBounds,
629              MIX Mix)
630 {
631     BOOLEAN ret;
632     SURFACE *psurfDest;
633     PEBRUSHOBJ GdiBrush;
634     RECTL b;
635 
636     ASSERT(psoDest);
637     psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
638     ASSERT(psurfDest);
639 
640     GdiBrush = CONTAINING_RECORD(
641                    pbo,
642                    EBRUSHOBJ,
643                    BrushObject);
644     ASSERT(GdiBrush);
645     ASSERT(GdiBrush->pbrush);
646 
647     if (GdiBrush->pbrush->flAttrs & BR_IS_NULL)
648         return TRUE;
649 
650     /* No success yet */
651     ret = FALSE;
652 
653     /* Clip lines totally outside the clip region. This is not done as an
654      * optimization (there are very few lines drawn outside the region) but
655      * as a workaround for what seems to be a problem in the CL54XX driver */
656     if (NULL == ClipObj || DC_TRIVIAL == ClipObj->iDComplexity)
657     {
658         b.left = 0;
659         b.right = psoDest->sizlBitmap.cx;
660         b.top = 0;
661         b.bottom = psoDest->sizlBitmap.cy;
662     }
663     else
664     {
665         b = ClipObj->rclBounds;
666     }
667     if ((x1 < b.left && x2 < b.left) || (b.right <= x1 && b.right <= x2) ||
668             (y1 < b.top && y2 < b.top) || (b.bottom <= y1 && b.bottom <= y2))
669     {
670         return TRUE;
671     }
672 
673     b.left = min(x1, x2);
674     b.right = max(x1, x2);
675     b.top = min(y1, y2);
676     b.bottom = max(y1, y2);
677     if (b.left == b.right) b.right++;
678     if (b.top == b.bottom) b.bottom++;
679 
680     if (psurfDest->flags & HOOK_LINETO)
681     {
682         /* Call the driver's DrvLineTo */
683         ret = GDIDEVFUNCS(psoDest).LineTo(
684                   psoDest, ClipObj, pbo, x1, y1, x2, y2, &b, Mix);
685     }
686 
687 #if 0
688     if (! ret && (psurfDest->flags & HOOK_STROKEPATH))
689     {
690         /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
691     }
692 #endif
693 
694     if (! ret)
695     {
696         ret = EngLineTo(psoDest, ClipObj, pbo, x1, y1, x2, y2, RectBounds, Mix);
697     }
698 
699     return ret;
700 }
701 
702 BOOL APIENTRY
703 IntEngPolyline(SURFOBJ *psoDest,
704                CLIPOBJ *Clip,
705                BRUSHOBJ *pbo,
706                CONST LPPOINT  pt,
707                LONG dCount,
708                MIX Mix)
709 {
710     LONG i;
711     RECTL rect;
712     BOOL ret = FALSE;
713 
714     // Draw the Polyline with a call to IntEngLineTo for each segment.
715     for (i = 1; i < dCount; i++)
716     {
717         rect.left = min(pt[i-1].x, pt[i].x);
718         rect.top = min(pt[i-1].y, pt[i].y);
719         rect.right = max(pt[i-1].x, pt[i].x);
720         rect.bottom = max(pt[i-1].y, pt[i].y);
721         ret = IntEngLineTo(psoDest,
722                            Clip,
723                            pbo,
724                            pt[i-1].x,
725                            pt[i-1].y,
726                            pt[i].x,
727                            pt[i].y,
728                            &rect,
729                            Mix);
730         if (!ret)
731         {
732             break;
733         }
734     }
735 
736     return ret;
737 }
738 
739 /* EOF */
740