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 *********************************************************/
13 /* FUNCTIONS ********************************************************/
18 MoveWindow(hSelection
, rectSel_dest
[0] * zoom
/ 1000, rectSel_dest
[1] * zoom
/ 1000,
19 rectSel_dest
[2] * zoom
/ 1000 + 6, rectSel_dest
[3] * zoom
/ 1000 + 6, TRUE
);
20 BringWindowToTop(hSelection
);
21 SendMessage(hImageArea
, WM_PAINT
, 0, 0);
22 //SendMessage(hSelection, WM_PAINT, 0, 0);
26 regularize(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
28 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
29 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
31 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
35 roundTo8Directions(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
37 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
39 if (abs(*y1
- y0
) * 5 < abs(*x1
- x0
) * 2)
42 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
46 if (abs(*x1
- x0
) * 5 < abs(*y1
- y0
) * 2)
49 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
53 POINT pointStack
[256];
55 POINT
*ptStack
= NULL
;
59 startPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
68 ShowWindow(hSelection
, SW_HIDE
);
70 HeapFree(GetProcessHeap(), 0, ptStack
);
71 ptStack
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * 1024);
85 ShowWindow(hSelection
, SW_HIDE
);
86 rectSel_src
[2] = rectSel_src
[3] = 0;
90 Erase(hdc
, x
, y
, x
, y
, bg
, rubberRadius
);
98 SetPixel(hdc
, x
, y
, fg
);
102 Brush(hdc
, x
, y
, x
, y
, fg
, brushStyle
);
106 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
109 pointStack
[pointSP
].x
= x
;
110 pointStack
[pointSP
].y
= y
;
118 pointStack
[pointSP
].x
= x
;
119 pointStack
[pointSP
].y
= y
;
120 if (pointSP
+ 1 >= 2)
121 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
132 whilePaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
140 if (ptSP
% 1024 == 0)
141 ptStack
= HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, ptStack
, sizeof(POINT
) * (ptSP
+ 1024));
142 ptStack
[ptSP
].x
= max(0, min(x
, imgXRes
));
143 ptStack
[ptSP
].y
= max(0, min(y
, imgYRes
));
145 Poly(hdc
, ptStack
, ptSP
+ 1, 0, 0, 2, 0, FALSE
);
152 tempX
= max(0, min(x
, imgXRes
));
153 tempY
= max(0, min(y
, imgYRes
));
154 rectSel_dest
[0] = rectSel_src
[0] = min(startX
, tempX
);
155 rectSel_dest
[1] = rectSel_src
[1] = min(startY
, tempY
);
156 rectSel_dest
[2] = rectSel_src
[2] = max(startX
, tempX
) - min(startX
, tempX
);
157 rectSel_dest
[3] = rectSel_src
[3] = max(startY
, tempY
) - min(startY
, tempY
);
158 RectSel(hdc
, startX
, startY
, tempX
, tempY
);
162 Erase(hdc
, lastX
, lastY
, x
, y
, bg
, rubberRadius
);
165 Line(hdc
, lastX
, lastY
, x
, y
, fg
, 1);
168 Brush(hdc
, lastX
, lastY
, x
, y
, fg
, brushStyle
);
171 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
175 if (GetAsyncKeyState(VK_SHIFT
) < 0)
176 roundTo8Directions(startX
, startY
, &x
, &y
);
177 Line(hdc
, startX
, startY
, x
, y
, fg
, lineWidth
);
181 pointStack
[pointSP
].x
= x
;
182 pointStack
[pointSP
].y
= y
;
186 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, fg
,
190 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], fg
, lineWidth
);
193 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], fg
, lineWidth
);
199 if (GetAsyncKeyState(VK_SHIFT
) < 0)
200 regularize(startX
, startY
, &x
, &y
);
201 Rect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
205 pointStack
[pointSP
].x
= x
;
206 pointStack
[pointSP
].y
= y
;
207 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
208 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
209 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
210 if (pointSP
+ 1 >= 2)
211 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
215 if (GetAsyncKeyState(VK_SHIFT
) < 0)
216 regularize(startX
, startY
, &x
, &y
);
217 Ellp(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
221 if (GetAsyncKeyState(VK_SHIFT
) < 0)
222 regularize(startX
, startY
, &x
, &y
);
223 RRect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
232 endPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
240 rectSel_src
[0] = rectSel_src
[1] = 0x7fffffff;
241 rectSel_src
[2] = rectSel_src
[3] = 0;
242 for (i
= 0; i
<= ptSP
; i
++)
244 if (ptStack
[i
].x
< rectSel_src
[0])
245 rectSel_src
[0] = ptStack
[i
].x
;
246 if (ptStack
[i
].y
< rectSel_src
[1])
247 rectSel_src
[1] = ptStack
[i
].y
;
248 if (ptStack
[i
].x
> rectSel_src
[2])
249 rectSel_src
[2] = ptStack
[i
].x
;
250 if (ptStack
[i
].y
> rectSel_src
[3])
251 rectSel_src
[3] = ptStack
[i
].y
;
253 rectSel_src
[2] += 1 - rectSel_src
[0];
254 rectSel_src
[3] += 1 - rectSel_src
[1];
255 rectSel_dest
[0] = rectSel_src
[0];
256 rectSel_dest
[1] = rectSel_src
[1];
257 rectSel_dest
[2] = rectSel_src
[2];
258 rectSel_dest
[3] = rectSel_src
[3];
261 DeleteObject(hSelMask
);
262 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
263 DeleteObject(SelectObject(hSelDC
, hSelMask
));
264 ptStackCopy
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * (ptSP
+ 1));
265 for (i
= 0; i
<= ptSP
; i
++)
267 ptStackCopy
[i
].x
= ptStack
[i
].x
- rectSel_src
[0];
268 ptStackCopy
[i
].y
= ptStack
[i
].y
- rectSel_src
[1];
270 Poly(hSelDC
, ptStackCopy
, ptSP
+ 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE
);
271 HeapFree(GetProcessHeap(), 0, ptStackCopy
);
272 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
274 MaskBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
275 rectSel_src
[1], hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, WHITENESS
));
276 Poly(hdc
, ptStack
, ptSP
+ 1, bg
, bg
, 1, 2, TRUE
);
279 MaskBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
280 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
283 ShowWindow(hSelection
, SW_SHOW
);
284 /* force refresh of selection contents */
285 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
286 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
287 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
289 HeapFree(GetProcessHeap(), 0, ptStack
);
295 if ((rectSel_src
[2] != 0) && (rectSel_src
[3] != 0))
297 DeleteObject(hSelMask
);
298 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
299 DeleteObject(SelectObject(hSelDC
, hSelMask
));
300 Rect(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], 0x00ffffff, 0x00ffffff, 1, 2);
301 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
303 BitBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
304 rectSel_src
[1], SRCCOPY
);
305 Rect(hdc
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[0] + rectSel_src
[2],
306 rectSel_src
[1] + rectSel_src
[3], bgColor
, bgColor
, 0, TRUE
);
309 BitBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
313 ShowWindow(hSelection
, SW_SHOW
);
314 /* force refresh of selection contents */
315 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
316 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
317 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
321 Erase(hdc
, lastX
, lastY
, x
, y
, bg
, rubberRadius
);
324 Line(hdc
, lastX
, lastY
, x
, y
, fg
, 1);
325 SetPixel(hdc
, x
, y
, fg
);
329 if (GetAsyncKeyState(VK_SHIFT
) < 0)
330 roundTo8Directions(startX
, startY
, &x
, &y
);
331 Line(hdc
, startX
, startY
, x
, y
, fg
, lineWidth
);
340 if (GetAsyncKeyState(VK_SHIFT
) < 0)
341 regularize(startX
, startY
, &x
, &y
);
342 Rect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
346 pointStack
[pointSP
].x
= x
;
347 pointStack
[pointSP
].y
= y
;
348 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
349 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
350 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
354 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
355 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
357 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, TRUE
);
362 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
370 if (GetAsyncKeyState(VK_SHIFT
) < 0)
371 regularize(startX
, startY
, &x
, &y
);
372 Ellp(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
376 if (GetAsyncKeyState(VK_SHIFT
) < 0)
377 regularize(startX
, startY
, &x
, &y
);
378 RRect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
384 startPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
402 Replace(hdc
, x
, y
, x
, y
, fg
, bg
, rubberRadius
);
410 SetPixel(hdc
, x
, y
, bg
);
414 Brush(hdc
, x
, y
, x
, y
, bg
, brushStyle
);
418 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
421 pointStack
[pointSP
].x
= x
;
422 pointStack
[pointSP
].y
= y
;
430 pointStack
[pointSP
].x
= x
;
431 pointStack
[pointSP
].y
= y
;
432 if (pointSP
+ 1 >= 2)
433 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
444 whilePaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
449 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
452 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
455 Brush(hdc
, lastX
, lastY
, x
, y
, bg
, brushStyle
);
458 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
462 if (GetAsyncKeyState(VK_SHIFT
) < 0)
463 roundTo8Directions(startX
, startY
, &x
, &y
);
464 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
468 pointStack
[pointSP
].x
= x
;
469 pointStack
[pointSP
].y
= y
;
473 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, bg
,
477 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], bg
, lineWidth
);
480 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], bg
, lineWidth
);
486 if (GetAsyncKeyState(VK_SHIFT
) < 0)
487 regularize(startX
, startY
, &x
, &y
);
488 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
492 pointStack
[pointSP
].x
= x
;
493 pointStack
[pointSP
].y
= y
;
494 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
495 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
496 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
497 if (pointSP
+ 1 >= 2)
498 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
502 if (GetAsyncKeyState(VK_SHIFT
) < 0)
503 regularize(startX
, startY
, &x
, &y
);
504 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
508 if (GetAsyncKeyState(VK_SHIFT
) < 0)
509 regularize(startX
, startY
, &x
, &y
);
510 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
519 endPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
524 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
527 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
528 SetPixel(hdc
, x
, y
, bg
);
532 if (GetAsyncKeyState(VK_SHIFT
) < 0)
533 roundTo8Directions(startX
, startY
, &x
, &y
);
534 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
543 if (GetAsyncKeyState(VK_SHIFT
) < 0)
544 regularize(startX
, startY
, &x
, &y
);
545 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
549 pointStack
[pointSP
].x
= x
;
550 pointStack
[pointSP
].y
= y
;
551 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
552 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
553 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
557 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
558 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
560 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, TRUE
);
565 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
573 if (GetAsyncKeyState(VK_SHIFT
) < 0)
574 regularize(startX
, startY
, &x
, &y
);
575 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
579 if (GetAsyncKeyState(VK_SHIFT
) < 0)
580 regularize(startX
, startY
, &x
, &y
);
581 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);