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
);
282 MaskBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
283 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
286 ShowWindow(hSelection
, SW_SHOW
);
288 HeapFree(GetProcessHeap(), 0, ptStack
);
294 if ((rectSel_src
[2] != 0) && (rectSel_src
[3] != 0))
296 DeleteObject(hSelMask
);
297 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
298 DeleteObject(SelectObject(hSelDC
, hSelMask
));
299 Rect(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], 0x00ffffff, 0x00ffffff, 1, 2);
300 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
302 BitBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
303 rectSel_src
[1], SRCCOPY
);
304 Rect(hdc
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[0] + rectSel_src
[2],
305 rectSel_src
[1] + rectSel_src
[3], bgColor
, bgColor
, 0, TRUE
);
308 BitBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
312 ShowWindow(hSelection
, SW_SHOW
);
316 Erase(hdc
, lastX
, lastY
, x
, y
, bg
, rubberRadius
);
319 Line(hdc
, lastX
, lastY
, x
, y
, fg
, 1);
320 SetPixel(hdc
, x
, y
, fg
);
324 if (GetAsyncKeyState(VK_SHIFT
) < 0)
325 roundTo8Directions(startX
, startY
, &x
, &y
);
326 Line(hdc
, startX
, startY
, x
, y
, fg
, lineWidth
);
335 if (GetAsyncKeyState(VK_SHIFT
) < 0)
336 regularize(startX
, startY
, &x
, &y
);
337 Rect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
341 pointStack
[pointSP
].x
= x
;
342 pointStack
[pointSP
].y
= y
;
343 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
344 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
345 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
349 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
350 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
352 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, TRUE
);
357 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
365 if (GetAsyncKeyState(VK_SHIFT
) < 0)
366 regularize(startX
, startY
, &x
, &y
);
367 Ellp(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
371 if (GetAsyncKeyState(VK_SHIFT
) < 0)
372 regularize(startX
, startY
, &x
, &y
);
373 RRect(hdc
, startX
, startY
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
379 startPaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
397 Replace(hdc
, x
, y
, x
, y
, fg
, bg
, rubberRadius
);
405 SetPixel(hdc
, x
, y
, bg
);
409 Brush(hdc
, x
, y
, x
, y
, bg
, brushStyle
);
413 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
416 pointStack
[pointSP
].x
= x
;
417 pointStack
[pointSP
].y
= y
;
425 pointStack
[pointSP
].x
= x
;
426 pointStack
[pointSP
].y
= y
;
427 if (pointSP
+ 1 >= 2)
428 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
439 whilePaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
444 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
447 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
450 Brush(hdc
, lastX
, lastY
, x
, y
, bg
, brushStyle
);
453 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
457 if (GetAsyncKeyState(VK_SHIFT
) < 0)
458 roundTo8Directions(startX
, startY
, &x
, &y
);
459 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
463 pointStack
[pointSP
].x
= x
;
464 pointStack
[pointSP
].y
= y
;
468 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, bg
,
472 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], bg
, lineWidth
);
475 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], bg
, lineWidth
);
481 if (GetAsyncKeyState(VK_SHIFT
) < 0)
482 regularize(startX
, startY
, &x
, &y
);
483 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
487 pointStack
[pointSP
].x
= x
;
488 pointStack
[pointSP
].y
= y
;
489 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
490 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
491 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
492 if (pointSP
+ 1 >= 2)
493 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
497 if (GetAsyncKeyState(VK_SHIFT
) < 0)
498 regularize(startX
, startY
, &x
, &y
);
499 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
503 if (GetAsyncKeyState(VK_SHIFT
) < 0)
504 regularize(startX
, startY
, &x
, &y
);
505 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
514 endPaintingR(HDC hdc
, short x
, short y
, int fg
, int bg
)
519 Replace(hdc
, lastX
, lastY
, x
, y
, fg
, bg
, rubberRadius
);
522 Line(hdc
, lastX
, lastY
, x
, y
, bg
, 1);
523 SetPixel(hdc
, x
, y
, bg
);
527 if (GetAsyncKeyState(VK_SHIFT
) < 0)
528 roundTo8Directions(startX
, startY
, &x
, &y
);
529 Line(hdc
, startX
, startY
, x
, y
, bg
, lineWidth
);
538 if (GetAsyncKeyState(VK_SHIFT
) < 0)
539 regularize(startX
, startY
, &x
, &y
);
540 Rect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
544 pointStack
[pointSP
].x
= x
;
545 pointStack
[pointSP
].y
= y
;
546 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
547 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
548 (short *)&pointStack
[pointSP
].x
, (short *)&pointStack
[pointSP
].y
);
552 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
553 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
555 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, TRUE
);
560 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
568 if (GetAsyncKeyState(VK_SHIFT
) < 0)
569 regularize(startX
, startY
, &x
, &y
);
570 Ellp(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
574 if (GetAsyncKeyState(VK_SHIFT
) < 0)
575 regularize(startX
, startY
, &x
, &y
);
576 RRect(hdc
, startX
, startY
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);