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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
57 ULONG Pixel
= Brush
->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
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
128 ULONG Pixel
= Brush
->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
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
198 ULONG Pixel
= Brush
->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
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
268 ULONG Pixel
= Brush
->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
= Brush
->iSolidColor
;
348 INTENG_ENTER_LEAVE EnterLeave
;
360 DestRect
.right
= x1
+ 1;
365 DestRect
.bottom
= y2
;
370 DestRect
.bottom
= y1
+ 1;
373 if (! IntEngEnter(&EnterLeave
, DestObj
, &DestRect
, FALSE
, &Translate
, &OutputObj
))
388 if (0 == deltax
&& 0 == deltay
)
419 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
422 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
423 for (i
= 0; i
< RectEnum
.c
&& RectEnum
.arcl
[i
].top
+ Translate
.y
<= y1
; i
++)
425 if (y1
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
&&
426 RectEnum
.arcl
[i
].left
+ Translate
.x
<= hx
+ deltax
&&
427 hx
< RectEnum
.arcl
[i
].right
+ Translate
.x
&&
428 max(hx
, RectEnum
.arcl
[i
].left
+ Translate
.x
) <
429 min(hx
+ deltax
, RectEnum
.arcl
[i
].right
+ Translate
.x
))
431 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_HLine(
433 max(hx
, RectEnum
.arcl
[i
].left
+ Translate
.x
),
434 min(hx
+ deltax
, RectEnum
.arcl
[i
].right
+ Translate
.x
),
443 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
446 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
447 for (i
= 0; i
< RectEnum
.c
; i
++)
449 if (RectEnum
.arcl
[i
].left
+ Translate
.x
<= x1
&&
450 x1
< RectEnum
.arcl
[i
].right
+ Translate
.x
&&
451 RectEnum
.arcl
[i
].top
+ Translate
.y
<= vy
+ deltay
&&
452 vy
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
)
454 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_VLine(
456 max(vy
, RectEnum
.arcl
[i
].top
+ Translate
.y
),
457 min(vy
+ deltay
, RectEnum
.arcl
[i
].bottom
+ Translate
.y
),
470 NWtoSE(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
474 SWtoNE(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
481 NEtoSW(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
485 SEtoNW(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
490 return IntEngLeave(&EnterLeave
);
494 IntEngLineTo(SURFOBJ
*DestSurf
,
506 PGDIBRUSHINST GdiBrush
;
510 DestObj
= CONTAINING_RECORD(DestSurf
, BITMAPOBJ
, SurfObj
);
513 GdiBrush
= CONTAINING_RECORD(
518 ASSERT(GdiBrush
->GdiBrushObject
);
520 if (GdiBrush
->GdiBrushObject
->flAttrs
& GDIBRUSH_IS_NULL
)
526 /* Clip lines totally outside the clip region. This is not done as an
527 * optimization (there are very few lines drawn outside the region) but
528 * as a workaround for what seems to be a problem in the CL54XX driver */
529 if (NULL
== ClipObj
|| DC_TRIVIAL
== ClipObj
->iDComplexity
)
532 b
.right
= DestSurf
->sizlBitmap
.cx
;
534 b
.bottom
= DestSurf
->sizlBitmap
.cy
;
538 b
= ClipObj
->rclBounds
;
540 if ((x1
< b
.left
&& x2
< b
.left
) || (b
.right
<= x1
&& b
.right
<= x2
) ||
541 (y1
< b
.top
&& y2
< b
.top
) || (b
.bottom
<= y1
&& b
.bottom
<= y2
))
546 b
.left
= min(x1
, x2
);
547 b
.right
= max(x1
, x2
);
549 b
.bottom
= max(y1
, y2
);
550 if (b
.left
== b
.right
) b
.right
++;
551 if (b
.top
== b
.bottom
) b
.bottom
++;
553 BITMAPOBJ_LockBitmapBits(DestObj
);
554 MouseSafetyOnDrawStart(DestSurf
, x1
, y1
, x2
, y2
);
556 if (DestObj
->flHooks
& HOOK_LINETO
)
558 /* Call the driver's DrvLineTo */
559 ret
= GDIDEVFUNCS(DestSurf
).LineTo(
560 DestSurf
, ClipObj
, Brush
, x1
, y1
, x2
, y2
, &b
, Mix
);
564 if (! ret
&& (DestObj
->flHooks
& HOOK_STROKEPATH
))
566 /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
572 ret
= EngLineTo(DestSurf
, ClipObj
, Brush
, x1
, y1
, x2
, y2
, RectBounds
, Mix
);
575 MouseSafetyOnDrawEnd(DestSurf
);
576 BITMAPOBJ_UnlockBitmapBits(DestObj
);
582 IntEngPolyline(SURFOBJ
*DestSurf
,
593 //Draw the Polyline with a call to IntEngLineTo for each segment.
594 for (i
= 1; i
< dCount
; i
++)
596 rect
.left
= min(pt
[i
-1].x
, pt
[i
].x
);
597 rect
.top
= min(pt
[i
-1].y
, pt
[i
].y
);
598 rect
.right
= max(pt
[i
-1].x
, pt
[i
].x
);
599 rect
.bottom
= max(pt
[i
-1].y
, pt
[i
].y
);
600 ret
= IntEngLineTo(DestSurf
,