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 InvalidateRect(hImageArea
, NULL
, FALSE
);
25 regularize(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
27 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
28 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
30 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
34 roundTo8Directions(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
36 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
38 if (abs(*y1
- y0
) * 5 < abs(*x1
- x0
) * 2)
41 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
45 if (abs(*x1
- x0
) * 5 < abs(*y1
- y0
) * 2)
48 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
52 POINT pointStack
[256];
54 POINT
*ptStack
= NULL
;
58 startPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
67 ShowWindow(hSelection
, SW_HIDE
);
69 HeapFree(GetProcessHeap(), 0, ptStack
);
70 ptStack
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * 1024);
84 ShowWindow(hSelection
, SW_HIDE
);
85 rectSel_src
[2] = rectSel_src
[3] = 0;
89 Erase(hdc
, x
, y
, x
, y
, bg
, rubberRadius
);
97 SetPixel(hdc
, x
, y
, fg
);
101 Brush(hdc
, x
, y
, x
, y
, fg
, brushStyle
);
105 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
108 pointStack
[pointSP
].x
= x
;
109 pointStack
[pointSP
].y
= y
;
117 pointStack
[pointSP
].x
= x
;
118 pointStack
[pointSP
].y
= y
;
119 if (pointSP
+ 1 >= 2)
120 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
131 whilePaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
139 if (ptSP
% 1024 == 0)
140 ptStack
= HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, ptStack
, sizeof(POINT
) * (ptSP
+ 1024));
141 ptStack
[ptSP
].x
= max(0, min(x
, imgXRes
));
142 ptStack
[ptSP
].y
= max(0, min(y
, imgYRes
));
144 Poly(hdc
, ptStack
, ptSP
+ 1, 0, 0, 2, 0, FALSE
);
150 temp
.x
= max(0, min(x
, imgXRes
));
151 temp
.y
= max(0, min(y
, imgYRes
));
152 rectSel_dest
[0] = rectSel_src
[0] = min(start
.x
, temp
.x
);
153 rectSel_dest
[1] = rectSel_src
[1] = min(start
.y
, temp
.y
);
154 rectSel_dest
[2] = rectSel_src
[2] = max(start
.x
, temp
.x
) - min(start
.x
, temp
.x
);
155 rectSel_dest
[3] = rectSel_src
[3] = max(start
.y
, temp
.y
) - min(start
.y
, temp
.y
);
156 RectSel(hdc
, start
.x
, start
.y
, temp
.x
, temp
.y
);
160 Erase(hdc
, last
.x
, last
.y
, x
, y
, bg
, rubberRadius
);
163 Line(hdc
, last
.x
, last
.y
, x
, y
, fg
, 1);
166 Brush(hdc
, last
.x
, last
.y
, x
, y
, fg
, brushStyle
);
169 Airbrush(hdc
, x
, y
, fg
, airBrushWidth
);
173 if (GetAsyncKeyState(VK_SHIFT
) < 0)
174 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
175 Line(hdc
, start
.x
, start
.y
, x
, y
, fg
, lineWidth
);
179 pointStack
[pointSP
].x
= x
;
180 pointStack
[pointSP
].y
= y
;
184 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, fg
,
188 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], fg
, lineWidth
);
191 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], fg
, lineWidth
);
197 if (GetAsyncKeyState(VK_SHIFT
) < 0)
198 regularize(start
.x
, start
.y
, &x
, &y
);
199 Rect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
203 pointStack
[pointSP
].x
= x
;
204 pointStack
[pointSP
].y
= y
;
205 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
206 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
207 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
208 if (pointSP
+ 1 >= 2)
209 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
213 if (GetAsyncKeyState(VK_SHIFT
) < 0)
214 regularize(start
.x
, start
.y
, &x
, &y
);
215 Ellp(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
219 if (GetAsyncKeyState(VK_SHIFT
) < 0)
220 regularize(start
.x
, start
.y
, &x
, &y
);
221 RRect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
230 endPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
238 rectSel_src
[0] = rectSel_src
[1] = 0x7fffffff;
239 rectSel_src
[2] = rectSel_src
[3] = 0;
240 for (i
= 0; i
<= ptSP
; i
++)
242 if (ptStack
[i
].x
< rectSel_src
[0])
243 rectSel_src
[0] = ptStack
[i
].x
;
244 if (ptStack
[i
].y
< rectSel_src
[1])
245 rectSel_src
[1] = ptStack
[i
].y
;
246 if (ptStack
[i
].x
> rectSel_src
[2])
247 rectSel_src
[2] = ptStack
[i
].x
;
248 if (ptStack
[i
].y
> rectSel_src
[3])
249 rectSel_src
[3] = ptStack
[i
].y
;
251 rectSel_src
[2] += 1 - rectSel_src
[0];
252 rectSel_src
[3] += 1 - rectSel_src
[1];
253 rectSel_dest
[0] = rectSel_src
[0];
254 rectSel_dest
[1] = rectSel_src
[1];
255 rectSel_dest
[2] = rectSel_src
[2];
256 rectSel_dest
[3] = rectSel_src
[3];
259 DeleteObject(hSelMask
);
260 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
261 DeleteObject(SelectObject(hSelDC
, hSelMask
));
262 ptStackCopy
= HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * (ptSP
+ 1));
263 for (i
= 0; i
<= ptSP
; i
++)
265 ptStackCopy
[i
].x
= ptStack
[i
].x
- rectSel_src
[0];
266 ptStackCopy
[i
].y
= ptStack
[i
].y
- rectSel_src
[1];
268 Poly(hSelDC
, ptStackCopy
, ptSP
+ 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE
);
269 HeapFree(GetProcessHeap(), 0, ptStackCopy
);
270 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
272 MaskBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
273 rectSel_src
[1], hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, WHITENESS
));
274 Poly(hdc
, ptStack
, ptSP
+ 1, bg
, bg
, 1, 2, TRUE
);
277 MaskBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
278 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
281 ShowWindow(hSelection
, SW_SHOW
);
282 /* force refresh of selection contents */
283 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
284 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
285 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
287 HeapFree(GetProcessHeap(), 0, ptStack
);
293 if ((rectSel_src
[2] != 0) && (rectSel_src
[3] != 0))
295 DeleteObject(hSelMask
);
296 hSelMask
= CreateBitmap(rectSel_src
[2], rectSel_src
[3], 1, 1, NULL
);
297 DeleteObject(SelectObject(hSelDC
, hSelMask
));
298 Rect(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], 0x00ffffff, 0x00ffffff, 1, 2);
299 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(rectSel_src
[2], rectSel_src
[3]));
301 BitBlt(hSelDC
, 0, 0, rectSel_src
[2], rectSel_src
[3], hDrawingDC
, rectSel_src
[0],
302 rectSel_src
[1], SRCCOPY
);
303 Rect(hdc
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[0] + rectSel_src
[2],
304 rectSel_src
[1] + rectSel_src
[3], bgColor
, bgColor
, 0, TRUE
);
307 BitBlt(hDrawingDC
, rectSel_src
[0], rectSel_src
[1], rectSel_src
[2], rectSel_src
[3], hSelDC
, 0,
311 ShowWindow(hSelection
, SW_SHOW
);
312 /* force refresh of selection contents */
313 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
314 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
315 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
319 Erase(hdc
, last
.x
, last
.y
, x
, y
, bg
, rubberRadius
);
322 Line(hdc
, last
.x
, last
.y
, x
, y
, fg
, 1);
323 SetPixel(hdc
, x
, y
, fg
);
327 if (GetAsyncKeyState(VK_SHIFT
) < 0)
328 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
329 Line(hdc
, start
.x
, start
.y
, x
, y
, fg
, lineWidth
);
338 if (GetAsyncKeyState(VK_SHIFT
) < 0)
339 regularize(start
.x
, start
.y
, &x
, &y
);
340 Rect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
344 pointStack
[pointSP
].x
= x
;
345 pointStack
[pointSP
].y
= y
;
346 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
347 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
348 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
352 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
353 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
355 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, TRUE
);
360 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, lineWidth
, shapeStyle
, FALSE
);
368 if (GetAsyncKeyState(VK_SHIFT
) < 0)
369 regularize(start
.x
, start
.y
, &x
, &y
);
370 Ellp(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
374 if (GetAsyncKeyState(VK_SHIFT
) < 0)
375 regularize(start
.x
, start
.y
, &x
, &y
);
376 RRect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, lineWidth
, shapeStyle
);
382 startPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
400 Replace(hdc
, x
, y
, x
, y
, fg
, bg
, rubberRadius
);
408 SetPixel(hdc
, x
, y
, bg
);
412 Brush(hdc
, x
, y
, x
, y
, bg
, brushStyle
);
416 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
419 pointStack
[pointSP
].x
= x
;
420 pointStack
[pointSP
].y
= y
;
428 pointStack
[pointSP
].x
= x
;
429 pointStack
[pointSP
].y
= y
;
430 if (pointSP
+ 1 >= 2)
431 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
442 whilePaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
447 Replace(hdc
, last
.x
, last
.y
, x
, y
, fg
, bg
, rubberRadius
);
450 Line(hdc
, last
.x
, last
.y
, x
, y
, bg
, 1);
453 Brush(hdc
, last
.x
, last
.y
, x
, y
, bg
, brushStyle
);
456 Airbrush(hdc
, x
, y
, bg
, airBrushWidth
);
460 if (GetAsyncKeyState(VK_SHIFT
) < 0)
461 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
462 Line(hdc
, start
.x
, start
.y
, x
, y
, bg
, lineWidth
);
466 pointStack
[pointSP
].x
= x
;
467 pointStack
[pointSP
].y
= y
;
471 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, bg
,
475 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], bg
, lineWidth
);
478 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], bg
, lineWidth
);
484 if (GetAsyncKeyState(VK_SHIFT
) < 0)
485 regularize(start
.x
, start
.y
, &x
, &y
);
486 Rect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
490 pointStack
[pointSP
].x
= x
;
491 pointStack
[pointSP
].y
= y
;
492 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
493 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
494 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
495 if (pointSP
+ 1 >= 2)
496 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
500 if (GetAsyncKeyState(VK_SHIFT
) < 0)
501 regularize(start
.x
, start
.y
, &x
, &y
);
502 Ellp(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
506 if (GetAsyncKeyState(VK_SHIFT
) < 0)
507 regularize(start
.x
, start
.y
, &x
, &y
);
508 RRect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
517 endPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
522 Replace(hdc
, last
.x
, last
.y
, x
, y
, fg
, bg
, rubberRadius
);
525 Line(hdc
, last
.x
, last
.y
, x
, y
, bg
, 1);
526 SetPixel(hdc
, x
, y
, bg
);
530 if (GetAsyncKeyState(VK_SHIFT
) < 0)
531 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
532 Line(hdc
, start
.x
, start
.y
, x
, y
, bg
, lineWidth
);
541 if (GetAsyncKeyState(VK_SHIFT
) < 0)
542 regularize(start
.x
, start
.y
, &x
, &y
);
543 Rect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
547 pointStack
[pointSP
].x
= x
;
548 pointStack
[pointSP
].y
= y
;
549 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
550 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
551 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
555 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
556 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= lineWidth
* lineWidth
+ 1)
558 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, TRUE
);
563 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, lineWidth
, shapeStyle
, FALSE
);
571 if (GetAsyncKeyState(VK_SHIFT
) < 0)
572 regularize(start
.x
, start
.y
, &x
, &y
);
573 Ellp(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);
577 if (GetAsyncKeyState(VK_SHIFT
) < 0)
578 regularize(start
.x
, start
.y
, &x
, &y
);
579 RRect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, lineWidth
, shapeStyle
);