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.
19 * $Id: lineto.c,v 1.35 2004/07/14 20:48:57 navaraf Exp $
24 TranslateRects(RECT_ENUM
*RectEnum
, POINTL
* Translate
)
28 if (0 != Translate
->x
|| 0 != Translate
->y
)
30 for (CurrentRect
= RectEnum
->arcl
; CurrentRect
< RectEnum
->arcl
+ RectEnum
->c
; CurrentRect
++)
32 CurrentRect
->left
+= Translate
->x
;
33 CurrentRect
->right
+= Translate
->x
;
34 CurrentRect
->top
+= Translate
->y
;
35 CurrentRect
->bottom
+= Translate
->y
;
41 * Draw a line from top-left to bottom-right
44 NWtoSE(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
45 BRUSHOBJ
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
53 ULONG Pixel
= Brush
->iSolidColor
;
56 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
57 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
58 TranslateRects(&RectEnum
, Translate
);
59 ClipRect
= RectEnum
.arcl
;
60 delta
= max(deltax
, deltay
);
63 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
65 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
/* there's still a current clip rect */
66 && (ClipRect
->bottom
<= y
/* but it's above us */
67 || (ClipRect
->top
<= y
&& ClipRect
->right
<= x
))) /* or to the left of us */
68 || EnumMore
) /* no current clip rect, but rects left */
70 /* Skip to the next clip rect */
71 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
73 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
74 TranslateRects(&RectEnum
, Translate
);
75 ClipRect
= RectEnum
.arcl
;
82 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
) /* If there's no current clip rect we're done */
84 if (ClipRect
->left
<= x
&& ClipRect
->top
<= y
)
86 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
87 OutputObj
, x
, y
, Pixel
);
92 error
= error
+ deltax
;
96 error
= error
- deltay
;
102 error
= error
+ deltay
;
106 error
= error
- deltax
;
115 SWtoNE(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
116 BRUSHOBJ
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
124 ULONG Pixel
= Brush
->iSolidColor
;
127 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTUP
, 0);
128 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
129 TranslateRects(&RectEnum
, Translate
);
130 ClipRect
= RectEnum
.arcl
;
131 delta
= max(deltax
, deltay
);
134 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
136 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
137 && (y
< ClipRect
->top
138 || (y
< ClipRect
->bottom
&& ClipRect
->right
<= x
)))
141 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
143 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
144 TranslateRects(&RectEnum
, Translate
);
145 ClipRect
= RectEnum
.arcl
;
152 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
154 if (ClipRect
->left
<= x
&& y
< ClipRect
->bottom
)
156 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
157 OutputObj
, x
, y
, Pixel
);
162 error
= error
+ deltax
;
166 error
= error
- deltay
;
172 error
= error
+ deltay
;
176 error
= error
- deltax
;
185 NEtoSW(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
186 BRUSHOBJ
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
194 ULONG Pixel
= Brush
->iSolidColor
;
197 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_LEFTDOWN
, 0);
198 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
199 TranslateRects(&RectEnum
, Translate
);
200 ClipRect
= RectEnum
.arcl
;
201 delta
= max(deltax
, deltay
);
204 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
206 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
207 && (ClipRect
->bottom
<= y
208 || (ClipRect
->top
<= y
&& x
< ClipRect
->left
)))
211 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
213 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
214 TranslateRects(&RectEnum
, Translate
);
215 ClipRect
= RectEnum
.arcl
;
222 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
224 if (x
< ClipRect
->right
&& ClipRect
->top
<= y
)
226 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
227 OutputObj
, x
, y
, Pixel
);
232 error
= error
+ deltax
;
236 error
= error
- deltay
;
242 error
= error
+ deltay
;
246 error
= error
- deltax
;
255 SEtoNW(SURFOBJ
* OutputObj
, CLIPOBJ
* Clip
,
256 BRUSHOBJ
* Brush
, LONG x
, LONG y
, LONG deltax
, LONG deltay
,
264 ULONG Pixel
= Brush
->iSolidColor
;
267 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_LEFTUP
, 0);
268 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
269 TranslateRects(&RectEnum
, Translate
);
270 ClipRect
= RectEnum
.arcl
;
271 delta
= max(deltax
, deltay
);
274 while (i
< delta
&& (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
|| EnumMore
))
276 while ((ClipRect
< RectEnum
.arcl
+ RectEnum
.c
277 && (y
< ClipRect
->top
278 || (y
< ClipRect
->bottom
&& x
< ClipRect
->left
)))
281 if (RectEnum
.arcl
+ RectEnum
.c
<= ClipRect
)
283 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
284 TranslateRects(&RectEnum
, Translate
);
285 ClipRect
= RectEnum
.arcl
;
292 if (ClipRect
< RectEnum
.arcl
+ RectEnum
.c
)
294 if (x
< ClipRect
->right
&& y
< ClipRect
->bottom
)
296 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_PutPixel(
297 OutputObj
, x
, y
, Pixel
);
302 error
= error
+ deltax
;
306 error
= error
- deltay
;
312 error
= error
+ deltay
;
316 error
= error
- deltax
;
328 EngLineTo(SURFOBJ
*DestObj
,
338 LONG x
, y
, deltax
, deltay
, xchange
, ychange
, hx
, vy
;
340 ULONG Pixel
= Brush
->iSolidColor
;
344 INTENG_ENTER_LEAVE EnterLeave
;
356 DestRect
.right
= x1
+ 1;
361 DestRect
.bottom
= y2
;
366 DestRect
.bottom
= y1
+ 1;
369 if (! IntEngEnter(&EnterLeave
, DestObj
, &DestRect
, FALSE
, &Translate
, &OutputObj
))
410 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
413 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
414 for (i
= 0; i
< RectEnum
.c
&& RectEnum
.arcl
[i
].top
+ Translate
.y
<= y1
; i
++)
416 if (y1
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
&&
417 RectEnum
.arcl
[i
].left
+ Translate
.x
<= hx
+ deltax
&&
418 hx
< RectEnum
.arcl
[i
].right
+ Translate
.x
)
420 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_HLine(
422 max(hx
, RectEnum
.arcl
[i
].left
+ Translate
.x
),
423 min(hx
+ deltax
, RectEnum
.arcl
[i
].right
+ Translate
.x
),
432 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, CD_RIGHTDOWN
, 0);
435 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
436 for (i
= 0; i
< RectEnum
.c
; i
++)
438 if (RectEnum
.arcl
[i
].left
+ Translate
.x
<= x1
&&
439 x1
< RectEnum
.arcl
[i
].right
+ Translate
.x
&&
440 RectEnum
.arcl
[i
].top
+ Translate
.y
<= vy
+ deltay
&&
441 vy
< RectEnum
.arcl
[i
].bottom
+ Translate
.y
)
443 DibFunctionsForBitmapFormat
[OutputObj
->iBitmapFormat
].DIB_VLine(
445 max(vy
, RectEnum
.arcl
[i
].top
+ Translate
.y
),
446 min(vy
+ deltay
, RectEnum
.arcl
[i
].bottom
+ Translate
.y
),
459 NWtoSE(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
463 SWtoNE(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
470 NEtoSW(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
474 SEtoNW(OutputObj
, Clip
, Brush
, x
, y
, deltax
, deltay
, &Translate
);
479 return IntEngLeave(&EnterLeave
);
483 IntEngLineTo(BITMAPOBJ
*DestObj
,
494 SURFOBJ
*DestSurf
= &DestObj
->SurfObj
;
495 PGDIBRUSHINST GdiBrush
;
498 GdiBrush
= CONTAINING_RECORD(
503 if (GdiBrush
->GdiBrushObject
->flAttrs
& GDIBRUSH_IS_NULL
)
509 b
.left
= min(x1
, x2
);
510 b
.right
= max(x1
, x2
);
512 b
.bottom
= max(y1
, y2
);
513 if (b
.left
== b
.right
) b
.right
++;
514 if (b
.top
== b
.bottom
) b
.bottom
++;
515 MouseSafetyOnDrawStart(DestSurf
, x1
, y1
, x2
, y2
);
517 if (DestObj
->flHooks
& HOOK_LINETO
)
519 /* Call the driver's DrvLineTo */
520 ret
= GDIDEVFUNCS(DestSurf
).LineTo(
521 DestSurf
, Clip
, Brush
, x1
, y1
, x2
, y2
, /*RectBounds*/&b
, mix
);
525 if (! ret
&& (DestObj
->flHooks
& HOOK_STROKEPATH
))
527 /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
533 ret
= EngLineTo(DestSurf
, Clip
, Brush
, x1
, y1
, x2
, y2
, RectBounds
, mix
);
536 MouseSafetyOnDrawEnd(DestSurf
);
542 IntEngPolyline(BITMAPOBJ
*DestObj
,
553 //Draw the Polyline with a call to IntEngLineTo for each segment.
554 for (i
= 1; i
< dCount
; i
++)
556 rect
.left
= min(pt
[i
-1].x
, pt
[i
].x
);
557 rect
.top
= min(pt
[i
-1].y
, pt
[i
].y
);
558 rect
.right
= max(pt
[i
-1].x
, pt
[i
].x
);
559 rect
.bottom
= max(pt
[i
-1].y
, pt
[i
].y
);
560 ret
= IntEngLineTo(DestObj
,