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.
22 #include <ddk/winddi.h>
23 #include <ddk/ntddmou.h>
24 #include <include/inteng.h>
25 #include <include/dib.h>
28 #include "../dib/dib.h"
31 #include <include/mouse.h>
32 #include <include/object.h>
33 #include <include/surface.h>
36 TranslateRects(RECT_ENUM *RectEnum, PPOINTL Translate)
40 if (0 != Translate->x || 0 != Translate->y)
42 for (CurrentRect = RectEnum->arcl; CurrentRect < RectEnum->arcl + RectEnum->c; CurrentRect++)
44 CurrentRect->left += Translate->x;
45 CurrentRect->right += Translate->x;
46 CurrentRect->top += Translate->y;
47 CurrentRect->bottom += Translate->y;
53 * Draw a line from top-left to bottom-right
56 NWtoSE(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
57 PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
65 ULONG Pixel = Brush->iSolidColor;
68 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
69 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
70 TranslateRects(&RectEnum, Translate);
71 ClipRect = RectEnum.arcl;
72 delta = max(deltax, deltay);
75 while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
77 while ((ClipRect < RectEnum.arcl + RectEnum.c /* there's still a current clip rect */
78 && (ClipRect->bottom <= y /* but it's above us */
79 || (ClipRect->top <= y && ClipRect->right <= x))) /* or to the left of us */
80 || EnumMore) /* no current clip rect, but rects left */
82 /* Skip to the next clip rect */
83 if (RectEnum.arcl + RectEnum.c <= ClipRect)
85 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
86 TranslateRects(&RectEnum, Translate);
87 ClipRect = RectEnum.arcl;
94 if (ClipRect < RectEnum.arcl + RectEnum.c) /* If there's no current clip rect we're done */
96 if (ClipRect->left <= x && ClipRect->top <= y)
98 OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
103 error = error + deltax;
107 error = error - deltay;
113 error = error + deltay;
117 error = error - deltax;
126 SWtoNE(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
127 PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
135 ULONG Pixel = Brush->iSolidColor;
138 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, ENUM_RECT_LIMIT);
139 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
140 TranslateRects(&RectEnum, Translate);
141 ClipRect = RectEnum.arcl;
142 delta = max(deltax, deltay);
145 while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
147 while ((ClipRect < RectEnum.arcl + RectEnum.c
148 && (y < ClipRect->top
149 || (y < ClipRect->bottom && ClipRect->right <= x)))
152 if (RectEnum.arcl + RectEnum.c <= ClipRect)
154 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
155 TranslateRects(&RectEnum, Translate);
156 ClipRect = RectEnum.arcl;
163 if (ClipRect < RectEnum.arcl + RectEnum.c)
165 if (ClipRect->left <= x && y < ClipRect->bottom)
167 OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
172 error = error + deltax;
176 error = error - deltay;
182 error = error + deltay;
186 error = error - deltax;
195 NEtoSW(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
196 PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
204 ULONG Pixel = Brush->iSolidColor;
207 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, ENUM_RECT_LIMIT);
208 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
209 TranslateRects(&RectEnum, Translate);
210 ClipRect = RectEnum.arcl;
211 delta = max(deltax, deltay);
214 while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
216 while ((ClipRect < RectEnum.arcl + RectEnum.c
217 && (ClipRect->bottom <= y
218 || (ClipRect->top <= y && x < ClipRect->left)))
221 if (RectEnum.arcl + RectEnum.c <= ClipRect)
223 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
224 TranslateRects(&RectEnum, Translate);
225 ClipRect = RectEnum.arcl;
232 if (ClipRect < RectEnum.arcl + RectEnum.c)
234 if (x < ClipRect->right && ClipRect->top <= y)
236 OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
241 error = error + deltax;
245 error = error - deltay;
251 error = error + deltay;
255 error = error - deltax;
264 SEtoNW(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
265 PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
273 ULONG Pixel = Brush->iSolidColor;
276 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, ENUM_RECT_LIMIT);
277 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
278 TranslateRects(&RectEnum, Translate);
279 ClipRect = RectEnum.arcl;
280 delta = max(deltax, deltay);
283 while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
285 while ((ClipRect < RectEnum.arcl + RectEnum.c
286 && (y < ClipRect->top
287 || (y < ClipRect->bottom && x < ClipRect->left)))
290 if (RectEnum.arcl + RectEnum.c <= ClipRect)
292 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
293 TranslateRects(&RectEnum, Translate);
294 ClipRect = RectEnum.arcl;
301 if (ClipRect < RectEnum.arcl + RectEnum.c)
303 if (x < ClipRect->right && y < ClipRect->bottom)
305 OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
310 error = error + deltax;
314 error = error - deltay;
320 error = error + deltay;
324 error = error - deltax;
336 EngLineTo(SURFOBJ *DestObj,
346 LONG x, y, deltax, deltay, xchange, ychange, hx, vy;
348 ULONG Pixel = Brush->iSolidColor;
353 INTENG_ENTER_LEAVE EnterLeave;
364 DestRect.right = x2 + 1;
369 DestRect.bottom = y2;
373 DestRect.bottom = y2 + 1;
376 if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
386 OutputGDI = AccessInternalObjectFromUserObject(OutputObj);
419 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
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)
429 OutputGDI->DIB_HLine(OutputObj,
430 max(hx, RectEnum.arcl[i].left + Translate.x),
431 min(hx + deltax, RectEnum.arcl[i].right + Translate.x),
440 CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
443 EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
444 for (i = 0; i < RectEnum.c; i++)
446 if (RectEnum.arcl[i].left + Translate.x <= x1 &&
447 x1 < RectEnum.arcl[i].right + Translate.x &&
448 RectEnum.arcl[i].top + Translate.y <= vy + deltay &&
449 vy < RectEnum.arcl[i].bottom + Translate.y)
451 OutputGDI->DIB_VLine(OutputObj, x1,
452 max(vy, RectEnum.arcl[i].top + Translate.y),
453 min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y),
466 NWtoSE(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
470 SWtoNE(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
477 NEtoSW(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
481 SEtoNW(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
486 return IntEngLeave(&EnterLeave);
490 IntEngLineTo(SURFOBJ *DestSurf,
505 SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf);
507 MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
509 if (NULL != SurfGDI->LineTo)
511 /* Call the driver's DrvLineTo */
512 ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
516 if (! ret && NULL != SurfGDI->StrokePath)
518 /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
524 ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
527 MouseSafetyOnDrawEnd(DestSurf, SurfGDI);
533 IntEngPolyline(SURFOBJ *DestSurf,
544 //Draw the Polyline with a call to IntEngLineTo for each segment.
545 for (i = 1; i < dCount; i++)
547 rect.left = MIN(pt[i-1].x, pt[i].x);
548 rect.top = MIN(pt[i-1].y, pt[i].y);
549 rect.right = MAX(pt[i-1].x, pt[i].x);
550 rect.bottom = MAX(pt[i-1].y, pt[i].y);
551 ret = IntEngLineTo(DestSurf,