2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 TranslateRects(RECT_ENUM
*RectEnum
, POINTL
* Translate
)
32 if (0 != Translate
->x
|| 0 != Translate
->y
)
34 for (CurrentRect
= RectEnum
->arcl
; CurrentRect
< RectEnum
->arcl
+ RectEnum
->c
; CurrentRect
++)
36 CurrentRect
->left
+= Translate
->x
;
37 CurrentRect
->right
+= Translate
->x
;
38 CurrentRect
->top
+= Translate
->y
;
39 CurrentRect
->bottom
+= Translate
->y
;
45 * Draw a line from top-left to bottom-right
48 NWtoSE(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
49 BRUSHOBJ
* pbo
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
57 ULONG Pixel
= pbo
->iSolidColor
;
60 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
61 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
62 TranslateRects(&RectEnum
, Translate
);
63 ClipRect
= RectEnum
.arcl
;
64 delta
= max(deltax
, deltay
);
67 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
69 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
/* there's still a current clip rect */
70 && (ClipRect
->bottom
<= y
/* but it's above us */
71 || (ClipRect
->top
<= y
&& ClipRect
->right
<= x
))) /* or to the left of us */
72 || EnumMore
) /* no current clip rect, but rects left */
74 /* Skip to the next clip rect */
75 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
77 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
78 TranslateRects(&RectEnum
, Translate
);
79 ClipRect
= RectEnum
.arcl
;
86 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
) /* If there's no current clip rect we're done */
88 if (ClipRect
->left
<= x
&& ClipRect
->top
<= y
)
90 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
91 OutputObj
, x
, y
, Pixel
);
96 error
= error
+ deltax
;
100 error
= error
- deltay
;
106 error
= error
+ deltay
;
110 error
= error
- deltax
;
119 SWtoNE(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
120 BRUSHOBJ
* pbo
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
128 ULONG Pixel
= pbo
->iSolidColor
;
131 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTUP
, 0);
132 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
133 TranslateRects(&RectEnum
, Translate
);
134 ClipRect
= RectEnum
.arcl
;
135 delta
= max(deltax
, deltay
);
138 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
140 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
141 && (y
< ClipRect
->top
142 || (y
< ClipRect
->bottom
&& ClipRect
->right
<= x
)))
145 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
147 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
148 TranslateRects(&RectEnum
, Translate
);
149 ClipRect
= RectEnum
.arcl
;
156 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
158 if (ClipRect
->left
<= x
&& y
< ClipRect
->bottom
)
160 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
161 OutputObj
, x
, y
, Pixel
);
166 error
= error
+ deltax
;
170 error
= error
- deltay
;
176 error
= error
+ deltay
;
180 error
= error
- deltax
;
189 NEtoSW(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
190 BRUSHOBJ
* pbo
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
198 ULONG Pixel
= pbo
->iSolidColor
;
201 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_LEFTDOWN
, 0);
202 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
203 TranslateRects(&RectEnum
, Translate
);
204 ClipRect
= RectEnum
.arcl
;
205 delta
= max(deltax
, deltay
);
208 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
210 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
211 && (ClipRect
->bottom
<= y
212 || (ClipRect
->top
<= y
&& x
< ClipRect
->left
)))
215 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
217 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
218 TranslateRects(&RectEnum
, Translate
);
219 ClipRect
= RectEnum
.arcl
;
226 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
228 if (x
< ClipRect
->right
&& ClipRect
->top
<= y
)
230 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
231 OutputObj
, x
, y
, Pixel
);
236 error
= error
+ deltax
;
240 error
= error
- deltay
;
246 error
= error
+ deltay
;
250 error
= error
- deltax
;
259 SEtoNW(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
260 BRUSHOBJ
* pbo
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
268 ULONG Pixel
= pbo
->iSolidColor
;
271 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_LEFTUP
, 0);
272 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
273 TranslateRects(&RectEnum
, Translate
);
274 ClipRect
= RectEnum
.arcl
;
275 delta
= max(deltax
, deltay
);
278 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
280 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
281 && (y
< ClipRect
->top
282 || (y
< ClipRect
->bottom
&& x
< ClipRect
->left
)))
285 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
287 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
288 TranslateRects(&RectEnum
, Translate
);
289 ClipRect
= RectEnum
.arcl
;
296 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
298 if (x
< ClipRect
->right
&& y
< ClipRect
->bottom
)
300 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
301 OutputObj
, x
, y
, Pixel
);
306 error
= error
+ deltax
;
310 error
= error
- deltay
;
316 error
= error
+ deltay
;
320 error
= error
- deltax
;
332 EngLineTo(SURFOBJ
*DestObj
,
342 LONG x
, y
, deltax
, deltay
, xchange
, ychange
, hx
, vy
;
344 ULONG Pixel
= pbo
->iSolidColor
;
348 INTENG_ENTER_LEAVE EnterLeave
;
351 CLIPOBJ
*pcoPriv
= NULL
;
361 DestRect
.right
= x1
+ 1;
366 DestRect
.bottom
= y2
;
371 DestRect
.bottom
= y1
+ 1;
374 if (! IntEngEnter(&EnterLeave
, DestObj
, &DestRect
, FALSE
, &Translate
, &OutputObj
))
381 Clip
= pcoPriv
= IntEngCreateClipRegion(0, 0, RectBounds
);
398 if (0 == deltax
&& 0 == deltay
)
429 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
432 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
433 for (i
= 0; i
< RectEnum
.c
&& RectEnum
.arcl
[i
].top
+ Translate
.y
<= y1
; i
++)
435 if (y1
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
&&
436 RectEnum
.arcl
[i
].left
+ Translate
.x
<= hx
+ deltax
&&
437 hx
< RectEnum
.arcl
[i
].right
+ Translate
.x
&&
438 max(hx
, RectEnum
.arcl
[i
].left
+ Translate
.x
) <
439 min(hx
+ deltax
, RectEnum
.arcl
[i
].right
+ Translate
.x
))
441 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_HLine(
443 max(hx
, RectEnum
.arcl
[i
].left
+ Translate
.x
),
444 min(hx
+ deltax
, RectEnum
.arcl
[i
].right
+ Translate
.x
),
453 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
456 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
457 for (i
= 0; i
< RectEnum
.c
; i
++)
459 if (RectEnum
.arcl
[i
].left
+ Translate
.x
<= x1
&&
460 x1
< RectEnum
.arcl
[i
].right
+ Translate
.x
&&
461 RectEnum
.arcl
[i
].top
+ Translate
.y
<= vy
+ deltay
&&
462 vy
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
)
464 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_VLine(
466 max(vy
, RectEnum
.arcl
[i
].top
+ Translate
.y
),
467 min(vy
+ deltay
, RectEnum
.arcl
[i
].bottom
+ Translate
.y
),
480 NWtoSE(OutputObj
, Clip
, pbo
, x
, y
, deltax
, deltay
, &Translate
);
484 SWtoNE(OutputObj
, Clip
, pbo
, x
, y
, deltax
, deltay
, &Translate
);
491 NEtoSW(OutputObj
, Clip
, pbo
, x
, y
, deltax
, deltay
, &Translate
);
495 SEtoNW(OutputObj
, Clip
, pbo
, x
, y
, deltax
, deltay
, &Translate
);
502 IntEngDeleteClipRegion(pcoPriv
);
505 return IntEngLeave(&EnterLeave
);
509 IntEngLineTo(SURFOBJ
*psoDest
,
525 psurfDest
= CONTAINING_RECORD(psoDest
, SURFACE
, SurfObj
);
528 GdiBrush
= CONTAINING_RECORD(
533 ASSERT(GdiBrush
->pbrush
);
535 if (GdiBrush
->pbrush
->flAttrs
& GDIBRUSH_IS_NULL
)
541 /* Clip lines totally outside the clip region. This is not done as an
542 * optimization (there are very few lines drawn outside the region) but
543 * as a workaround for what seems to be a problem in the CL54XX driver */
544 if (NULL
== ClipObj
|| DC_TRIVIAL
== ClipObj
->iDComplexity
)
547 b
.right
= psoDest
->sizlBitmap
.cx
;
549 b
.bottom
= psoDest
->sizlBitmap
.cy
;
553 b
= ClipObj
->rclBounds
;
555 if ((x1
< b
.left
&& x2
< b
.left
) || (b
.right
<= x1
&& b
.right
<= x2
) ||
556 (y1
< b
.top
&& y2
< b
.top
) || (b
.bottom
<= y1
&& b
.bottom
<= y2
))
561 b
.left
= min(x1
, x2
);
562 b
.right
= max(x1
, x2
);
564 b
.bottom
= max(y1
, y2
);
565 if (b
.left
== b
.right
) b
.right
++;
566 if (b
.top
== b
.bottom
) b
.bottom
++;
568 SURFACE_LockBitmapBits(psurfDest
);
569 MouseSafetyOnDrawStart(psoDest
, x1
, y1
, x2
, y2
);
571 if (psurfDest
->flHooks
& HOOK_LINETO
)
573 /* Call the driver's DrvLineTo */
574 ret
= GDIDEVFUNCS(psoDest
).LineTo(
575 psoDest
, ClipObj
, pbo
, x1
, y1
, x2
, y2
, &b
, Mix
);
579 if (! ret
&& (psurfDest
->flHooks
& HOOK_STROKEPATH
))
581 /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
587 ret
= EngLineTo(psoDest
, ClipObj
, pbo
, x1
, y1
, x2
, y2
, RectBounds
, Mix
);
590 MouseSafetyOnDrawEnd(psoDest
);
591 SURFACE_UnlockBitmapBits(psurfDest
);
597 IntEngPolyline(SURFOBJ
*psoDest
,
608 //Draw the Polyline with a call to IntEngLineTo for each segment.
609 for (i
= 1; i
< dCount
; i
++)
611 rect
.left
= min(pt
[i
-1].x
, pt
[i
].x
);
612 rect
.top
= min(pt
[i
-1].y
, pt
[i
].y
);
613 rect
.right
= max(pt
[i
-1].x
, pt
[i
].x
);
614 rect
.bottom
= max(pt
[i
-1].y
, pt
[i
].y
);
615 ret
= IntEngLineTo(psoDest
,