2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/paint/mouse.c
5 * PURPOSE: Things which should not be in the mouse event handler itself
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
11 #include "globalvar.h"
16 /* FUNCTIONS ********************************************************/
21 MoveWindow(hSelection
, rectSel_dest
[0] * zoom
/ 1000, rectSel_dest
[1] * zoom
/ 1000,
22 rectSel_dest
[2] * zoom
/ 1000 + 6, rectSel_dest
[3] * zoom
/ 1000 + 6, TRUE
);
23 BringWindowToTop(hSelection
);
24 SendMessage(hImageArea
, WM_PAINT
, 0, 0);
25 //SendMessage(hSelection, WM_PAINT, 0, 0);
29 regularize(short x0
, short y0
, short *x1
, short *y1
)
31 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
32 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
34 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
38 roundTo8Directions(short x0
, short y0
, short *x1
, short *y1
)
40 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
42 if (abs(*y1
- y0
) * 5 < abs(*x1
- x0
) * 2)
45 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
49 if (abs(*x1
- x0
) * 5 < abs(*y1
- y0
) * 2)
52 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
56 POINT pointStack
[256];
58 POINT
*ptStack
= NULL
;
62 startPaintingL(HDC hdc
, short x
, short y
, int fg
, int bg
)
71 ShowWindow(hSelection
, SW_HIDE
);
73 HeapFree(GetProcessHeap(), 0, ptStack
);
74 ptStack
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * 1024);
88 ShowWindow(hSelection
, SW_HIDE
);
89 rectSel_src
[2] = rectSel_src
[3] = 0;
93 Erase(hdc
, x
, y
, x
, y
, bg
, rubberRadius
);
101 SetPixel(hdc
, x
, y
, fg
);
105 Brush(hdc
, x
, y
, x
, y
, fg
, brushStyle
);
109 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
112 pointStack
[pointSP
].x
= x
;
113 pointStack
[pointSP
].y
= y
;
121 pointStack
[pointSP
].x
= x
;
122 pointStack
[pointSP
].y
= y
;
123 if (pointSP
+ 1 >= 2)
124 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
135 whilePaintingL(HDC hdc
, short x
, short y
, int fg
, int bg
)
143 if (ptSP
% 1024 == 0)
144 ptStack
= HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, ptStack
, sizeof(POINT
) * (ptSP
+ 1024));
145 ptStack
[ptSP
].x
= max(0, min(x
, imgXRes
));
146 ptStack
[ptSP
].y
= max(0, min(y
, imgYRes
));
148 Poly(hdc
, ptStack
, ptSP
+ 1, 0, 0, 2, 0, FALSE
);
155 tempX
= max(0, min(x
, imgXRes
));
156 tempY
= max(0, min(y
, imgYRes
));
157 rectSel_dest
[0] = rectSel_src
[0] = min(startX
, tempX
);
158 rectSel_dest
[1] = rectSel_src
[1] = min(startY
, tempY
);
159 rectSel_dest
[2] = rectSel_src
[2] = max(startX
, tempX
) - min(startX
, tempX
);
160 rectSel_dest
[3] = rectSel_src
[3] = max(startY
, tempY
) - min(startY
, tempY
);
161 RectSel(hdc
, startX
, startY
, tempX
, tempY
);
165 Erase(hdc
, lastX
, lastY
, x
, y
, bg
, rubberRadius
);
168 Line(hdc
, lastX
, lastY
, x
, y
, fg
, 1);
171 Brush(hdc
, lastX
, lastY
, x
, y
, fg
, brushStyle
);
174 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
178 if (GetAsyncKeyState(VK_SHIFT
) < 0)
179 roundTo8Directions(startX
, startY
, &x
, &y
);
180 Line(hdc
, startX
, startY
, x
, y
, fg
, lineWidth
);
184 pointStack
[pointSP
].x
= x
;
185 pointStack
[pointSP
].y
= y
;
189 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, fg
,
193 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], fg
, lineWidth
);
196 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], fg
, lineWidth
);
202 if (GetAsyncKeyState(VK_SHIFT
) < 0)
203 regularize(startX
, startY
, &x
, &y
);
204 Rect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
208 pointStack
[pointSP
].x
= x
;
209 pointStack
[pointSP
].y
= y
;
210 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
211 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
212 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
213 if (pointSP
+ 1 >= 2)
214 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
218 if (GetAsyncKeyState(VK_SHIFT
) < 0)
219 regularize(startX
, startY
, &x
, &y
);
220 Ellp(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
224 if (GetAsyncKeyState(VK_SHIFT
) < 0)
225 regularize(startX
, startY
, &x
, &y
);
226 RRect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
235 endPaintingL(HDC hdc
, short x
, short y
, int fg
, int bg
)
243 rectSel_src
[0] = rectSel_src
[1] = 0x7fffffff;
244 rectSel_src
[2] = rectSel_src
[3] = 0;
245 for (i
= 0; i
<= ptSP
; i
++)
247 if (ptStack
[i
].x
< rectSel_src
[0])
248 rectSel_src
[0] = ptStack
[i
].x
;
249 if (ptStack
[i
].y
< rectSel_src
[1])
250 rectSel_src
[1] = ptStack
[i
].y
;
251 if (ptStack
[i
].x
> rectSel_src
[2])
252 rectSel_src
[2] = ptStack
[i
].x
;
253 if (ptStack
[i
].y
> rectSel_src
[3])
254 rectSel_src
[3] = ptStack
[i
].y
;
256 rectSel_src
[2] += 1 - rectSel_src
[0];
257 rectSel_src
[3] += 1 - rectSel_src
[1];
258 rectSel_dest
[0] = rectSel_src
[0];
259 rectSel_dest
[1] = rectSel_src
[1];
260 rectSel_dest
[2] = rectSel_src
[2];
261 rectSel_dest
[3] = rectSel_src
[3];
264 DeleteObject(hSelMask
);
265 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
266 DeleteObject(SelectObject(hSelDC
, hSelMask
));
267 ptStackCopy
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * (ptSP
+ 1));
268 for (i
= 0; i
<= ptSP
; i
++)
270 ptStackCopy
[i
].x
= ptStack
[i
].x
- rectSel_src
[0];
271 ptStackCopy
[i
].y
= ptStack
[i
].y
- rectSel_src
[1];
273 Poly(hSelDC
, ptStackCopy
, ptSP
+ 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE
);
274 HeapFree(GetProcessHeap(), 0, ptStackCopy
);
275 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
277 MaskBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
278 rectSel_src
[1], hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, WHITENESS
));
279 Poly(hdc
, ptStack
, ptSP
+ 1, bg
, bg
, 1, 2, TRUE
);
283 ShowWindow(hSelection
, SW_SHOW
);
285 HeapFree(GetProcessHeap(), 0, ptStack
);
291 if ((rectSel_src
[2] != 0) && (rectSel_src
[3] != 0))
293 DeleteObject(hSelMask
);
294 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
295 DeleteObject(SelectObject(hSelDC
, hSelMask
));
296 Rect(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], 0x00ffffff, 0x00ffffff, 1, 2);
297 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
299 BitBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
300 rectSel_src
[1], SRCCOPY
);
301 Rect(hdc
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[0] + rectSel_src
[2],
302 rectSel_src
[1] + rectSel_src
[3], bgColor
, bgColor
, 0, TRUE
);
306 ShowWindow(hSelection
, SW_SHOW
);
310 Erase(hdc
, lastX
, lastY
, x
, y
, bg
, rubberRadius
);
313 Line(hdc
, lastX
, lastY
, x
, y
, fg
, 1);
314 SetPixel(hdc
, x
, y
, fg
);
318 if (GetAsyncKeyState(VK_SHIFT
) < 0)
319 roundTo8Directions(startX
, startY
, &x
, &y
);
320 Line(hdc
, startX
, startY
, x
, y
, fg
, lineWidth
);
329 if (GetAsyncKeyState(VK_SHIFT
) < 0)
330 regularize(startX
, startY
, &x
, &y
);
331 Rect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
335 pointStack
[pointSP
].x
= x
;
336 pointStack
[pointSP
].y
= y
;
337 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
338 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
339 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
343 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
344 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
346 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, TRUE
);
351 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
359 if (GetAsyncKeyState(VK_SHIFT
) < 0)
360 regularize(startX
, startY
, &x
, &y
);
361 Ellp(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
365 if (GetAsyncKeyState(VK_SHIFT
) < 0)
366 regularize(startX
, startY
, &x
, &y
);
367 RRect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
373 startPaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
391 Replace(hdc
, x
, y
, x
, y
, fg
, bg
, rubberRadius
);
399 SetPixel(hdc
, x
, y
, bg
);
403 Brush(hdc
, x
, y
, x
, y
, bg
, brushStyle
);
407 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
410 pointStack
[pointSP
].x
= x
;
411 pointStack
[pointSP
].y
= y
;
419 pointStack
[pointSP
].x
= x
;
420 pointStack
[pointSP
].y
= y
;
421 if (pointSP
+ 1 >= 2)
422 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
433 whilePaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
438 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
441 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
444 Brush(hdc
, lastX
, lastY
, x
, y
, bg
, brushStyle
);
447 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
451 if (GetAsyncKeyState(VK_SHIFT
) < 0)
452 roundTo8Directions(startX
, startY
, &x
, &y
);
453 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
457 pointStack
[pointSP
].x
= x
;
458 pointStack
[pointSP
].y
= y
;
462 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, bg
,
466 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], bg
, lineWidth
);
469 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], bg
, lineWidth
);
475 if (GetAsyncKeyState(VK_SHIFT
) < 0)
476 regularize(startX
, startY
, &x
, &y
);
477 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
481 pointStack
[pointSP
].x
= x
;
482 pointStack
[pointSP
].y
= y
;
483 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
484 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
485 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
486 if (pointSP
+ 1 >= 2)
487 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
491 if (GetAsyncKeyState(VK_SHIFT
) < 0)
492 regularize(startX
, startY
, &x
, &y
);
493 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
497 if (GetAsyncKeyState(VK_SHIFT
) < 0)
498 regularize(startX
, startY
, &x
, &y
);
499 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
508 endPaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
513 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
516 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
517 SetPixel(hdc
, x
, y
, bg
);
521 if (GetAsyncKeyState(VK_SHIFT
) < 0)
522 roundTo8Directions(startX
, startY
, &x
, &y
);
523 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
532 if (GetAsyncKeyState(VK_SHIFT
) < 0)
533 regularize(startX
, startY
, &x
, &y
);
534 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
538 pointStack
[pointSP
].x
= x
;
539 pointStack
[pointSP
].y
= y
;
540 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
541 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
542 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
546 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
547 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
549 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, TRUE
);
554 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
562 if (GetAsyncKeyState(VK_SHIFT
) < 0)
563 regularize(startX
, startY
, &x
, &y
);
564 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
568 if (GetAsyncKeyState(VK_SHIFT
) < 0)
569 regularize(startX
, startY
, &x
, &y
);
570 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);