xref: /reactos/base/applications/mspaint/mouse.cpp (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * PROJECT:     PAINT for ReactOS
3*c2c66affSColin Finck  * LICENSE:     LGPL
4*c2c66affSColin Finck  * FILE:        base/applications/mspaint/mouse.cpp
5*c2c66affSColin Finck  * PURPOSE:     Things which should not be in the mouse event handler itself
6*c2c66affSColin Finck  * PROGRAMMERS: Benedikt Freisen
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck /* INCLUDES *********************************************************/
10*c2c66affSColin Finck 
11*c2c66affSColin Finck #include "precomp.h"
12*c2c66affSColin Finck 
13*c2c66affSColin Finck /* FUNCTIONS ********************************************************/
14*c2c66affSColin Finck 
15*c2c66affSColin Finck void
16*c2c66affSColin Finck placeSelWin()
17*c2c66affSColin Finck {
18*c2c66affSColin Finck     selectionWindow.MoveWindow(selectionModel.GetDestRectLeft() * toolsModel.GetZoom() / 1000, selectionModel.GetDestRectTop() * toolsModel.GetZoom() / 1000,
19*c2c66affSColin Finck         selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6, selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6, TRUE);
20*c2c66affSColin Finck     selectionWindow.BringWindowToTop();
21*c2c66affSColin Finck     imageArea.InvalidateRect(NULL, FALSE);
22*c2c66affSColin Finck }
23*c2c66affSColin Finck 
24*c2c66affSColin Finck void
25*c2c66affSColin Finck regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
26*c2c66affSColin Finck {
27*c2c66affSColin Finck     if (abs(x1 - x0) >= abs(y1 - y0))
28*c2c66affSColin Finck         y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
29*c2c66affSColin Finck     else
30*c2c66affSColin Finck         x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
31*c2c66affSColin Finck }
32*c2c66affSColin Finck 
33*c2c66affSColin Finck void
34*c2c66affSColin Finck roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1)
35*c2c66affSColin Finck {
36*c2c66affSColin Finck     if (abs(x1 - x0) >= abs(y1 - y0))
37*c2c66affSColin Finck     {
38*c2c66affSColin Finck         if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2)
39*c2c66affSColin Finck             y1 = y0;
40*c2c66affSColin Finck         else
41*c2c66affSColin Finck             y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
42*c2c66affSColin Finck     }
43*c2c66affSColin Finck     else
44*c2c66affSColin Finck     {
45*c2c66affSColin Finck         if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2)
46*c2c66affSColin Finck             x1 = x0;
47*c2c66affSColin Finck         else
48*c2c66affSColin Finck             x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
49*c2c66affSColin Finck     }
50*c2c66affSColin Finck }
51*c2c66affSColin Finck 
52*c2c66affSColin Finck POINT pointStack[256];
53*c2c66affSColin Finck short pointSP;
54*c2c66affSColin Finck 
55*c2c66affSColin Finck void
56*c2c66affSColin Finck startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
57*c2c66affSColin Finck {
58*c2c66affSColin Finck     start.x = x;
59*c2c66affSColin Finck     start.y = y;
60*c2c66affSColin Finck     last.x = x;
61*c2c66affSColin Finck     last.y = y;
62*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
63*c2c66affSColin Finck     {
64*c2c66affSColin Finck         case TOOL_FREESEL:
65*c2c66affSColin Finck             selectionWindow.ShowWindow(SW_HIDE);
66*c2c66affSColin Finck             selectionModel.ResetPtStack();
67*c2c66affSColin Finck             selectionModel.PushToPtStack(x, y);
68*c2c66affSColin Finck             break;
69*c2c66affSColin Finck         case TOOL_LINE:
70*c2c66affSColin Finck         case TOOL_RECT:
71*c2c66affSColin Finck         case TOOL_ELLIPSE:
72*c2c66affSColin Finck         case TOOL_RRECT:
73*c2c66affSColin Finck             imageModel.CopyPrevious();
74*c2c66affSColin Finck             break;
75*c2c66affSColin Finck         case TOOL_RECTSEL:
76*c2c66affSColin Finck         case TOOL_TEXT:
77*c2c66affSColin Finck             imageModel.CopyPrevious();
78*c2c66affSColin Finck             selectionWindow.ShowWindow(SW_HIDE);
79*c2c66affSColin Finck             selectionModel.SetSrcRectSizeToZero();
80*c2c66affSColin Finck             break;
81*c2c66affSColin Finck         case TOOL_RUBBER:
82*c2c66affSColin Finck             imageModel.CopyPrevious();
83*c2c66affSColin Finck             Erase(hdc, x, y, x, y, bg, toolsModel.GetRubberRadius());
84*c2c66affSColin Finck             break;
85*c2c66affSColin Finck         case TOOL_FILL:
86*c2c66affSColin Finck             imageModel.CopyPrevious();
87*c2c66affSColin Finck             Fill(hdc, x, y, fg);
88*c2c66affSColin Finck             break;
89*c2c66affSColin Finck         case TOOL_PEN:
90*c2c66affSColin Finck             imageModel.CopyPrevious();
91*c2c66affSColin Finck             SetPixel(hdc, x, y, fg);
92*c2c66affSColin Finck             break;
93*c2c66affSColin Finck         case TOOL_BRUSH:
94*c2c66affSColin Finck             imageModel.CopyPrevious();
95*c2c66affSColin Finck             Brush(hdc, x, y, x, y, fg, toolsModel.GetBrushStyle());
96*c2c66affSColin Finck             break;
97*c2c66affSColin Finck         case TOOL_AIRBRUSH:
98*c2c66affSColin Finck             imageModel.CopyPrevious();
99*c2c66affSColin Finck             Airbrush(hdc, x, y, fg, toolsModel.GetAirBrushWidth());
100*c2c66affSColin Finck             break;
101*c2c66affSColin Finck         case TOOL_BEZIER:
102*c2c66affSColin Finck             pointStack[pointSP].x = x;
103*c2c66affSColin Finck             pointStack[pointSP].y = y;
104*c2c66affSColin Finck             if (pointSP == 0)
105*c2c66affSColin Finck             {
106*c2c66affSColin Finck                 imageModel.CopyPrevious();
107*c2c66affSColin Finck                 pointSP++;
108*c2c66affSColin Finck             }
109*c2c66affSColin Finck             break;
110*c2c66affSColin Finck         case TOOL_SHAPE:
111*c2c66affSColin Finck             pointStack[pointSP].x = x;
112*c2c66affSColin Finck             pointStack[pointSP].y = y;
113*c2c66affSColin Finck             if (pointSP + 1 >= 2)
114*c2c66affSColin Finck                 Poly(hdc, pointStack, pointSP + 1, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
115*c2c66affSColin Finck             if (pointSP == 0)
116*c2c66affSColin Finck             {
117*c2c66affSColin Finck                 imageModel.CopyPrevious();
118*c2c66affSColin Finck                 pointSP++;
119*c2c66affSColin Finck             }
120*c2c66affSColin Finck             break;
121*c2c66affSColin Finck     }
122*c2c66affSColin Finck }
123*c2c66affSColin Finck 
124*c2c66affSColin Finck void
125*c2c66affSColin Finck whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
126*c2c66affSColin Finck {
127*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
128*c2c66affSColin Finck     {
129*c2c66affSColin Finck         case TOOL_FREESEL:
130*c2c66affSColin Finck             if (selectionModel.PtStackSize() == 1)
131*c2c66affSColin Finck                 imageModel.CopyPrevious();
132*c2c66affSColin Finck             selectionModel.PushToPtStack(max(0, min(x, imageModel.GetWidth())), max(0, min(y, imageModel.GetHeight())));
133*c2c66affSColin Finck             imageModel.ResetToPrevious();
134*c2c66affSColin Finck             selectionModel.DrawFramePoly(hdc);
135*c2c66affSColin Finck             break;
136*c2c66affSColin Finck         case TOOL_RECTSEL:
137*c2c66affSColin Finck         case TOOL_TEXT:
138*c2c66affSColin Finck         {
139*c2c66affSColin Finck             POINT temp;
140*c2c66affSColin Finck             imageModel.ResetToPrevious();
141*c2c66affSColin Finck             temp.x = max(0, min(x, imageModel.GetWidth()));
142*c2c66affSColin Finck             temp.y = max(0, min(y, imageModel.GetHeight()));
143*c2c66affSColin Finck             selectionModel.SetSrcAndDestRectFromPoints(start, temp);
144*c2c66affSColin Finck             RectSel(hdc, start.x, start.y, temp.x, temp.y);
145*c2c66affSColin Finck             break;
146*c2c66affSColin Finck         }
147*c2c66affSColin Finck         case TOOL_RUBBER:
148*c2c66affSColin Finck             Erase(hdc, last.x, last.y, x, y, bg, toolsModel.GetRubberRadius());
149*c2c66affSColin Finck             break;
150*c2c66affSColin Finck         case TOOL_PEN:
151*c2c66affSColin Finck             Line(hdc, last.x, last.y, x, y, fg, 1);
152*c2c66affSColin Finck             break;
153*c2c66affSColin Finck         case TOOL_BRUSH:
154*c2c66affSColin Finck             Brush(hdc, last.x, last.y, x, y, fg, toolsModel.GetBrushStyle());
155*c2c66affSColin Finck             break;
156*c2c66affSColin Finck         case TOOL_AIRBRUSH:
157*c2c66affSColin Finck             Airbrush(hdc, x, y, fg, toolsModel.GetAirBrushWidth());
158*c2c66affSColin Finck             break;
159*c2c66affSColin Finck         case TOOL_LINE:
160*c2c66affSColin Finck             imageModel.ResetToPrevious();
161*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
162*c2c66affSColin Finck                 roundTo8Directions(start.x, start.y, x, y);
163*c2c66affSColin Finck             Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth());
164*c2c66affSColin Finck             break;
165*c2c66affSColin Finck         case TOOL_BEZIER:
166*c2c66affSColin Finck             imageModel.ResetToPrevious();
167*c2c66affSColin Finck             pointStack[pointSP].x = x;
168*c2c66affSColin Finck             pointStack[pointSP].y = y;
169*c2c66affSColin Finck             switch (pointSP)
170*c2c66affSColin Finck             {
171*c2c66affSColin Finck                 case 1:
172*c2c66affSColin Finck                     Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, fg,
173*c2c66affSColin Finck                          toolsModel.GetLineWidth());
174*c2c66affSColin Finck                     break;
175*c2c66affSColin Finck                 case 2:
176*c2c66affSColin Finck                     Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], fg, toolsModel.GetLineWidth());
177*c2c66affSColin Finck                     break;
178*c2c66affSColin Finck                 case 3:
179*c2c66affSColin Finck                     Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], fg, toolsModel.GetLineWidth());
180*c2c66affSColin Finck                     break;
181*c2c66affSColin Finck             }
182*c2c66affSColin Finck             break;
183*c2c66affSColin Finck         case TOOL_RECT:
184*c2c66affSColin Finck             imageModel.ResetToPrevious();
185*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
186*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
187*c2c66affSColin Finck             Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
188*c2c66affSColin Finck             break;
189*c2c66affSColin Finck         case TOOL_SHAPE:
190*c2c66affSColin Finck             imageModel.ResetToPrevious();
191*c2c66affSColin Finck             pointStack[pointSP].x = x;
192*c2c66affSColin Finck             pointStack[pointSP].y = y;
193*c2c66affSColin Finck             if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
194*c2c66affSColin Finck                 roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
195*c2c66affSColin Finck                                    pointStack[pointSP].x, pointStack[pointSP].y);
196*c2c66affSColin Finck             if (pointSP + 1 >= 2)
197*c2c66affSColin Finck                 Poly(hdc, pointStack, pointSP + 1, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
198*c2c66affSColin Finck             break;
199*c2c66affSColin Finck         case TOOL_ELLIPSE:
200*c2c66affSColin Finck             imageModel.ResetToPrevious();
201*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
202*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
203*c2c66affSColin Finck             Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
204*c2c66affSColin Finck             break;
205*c2c66affSColin Finck         case TOOL_RRECT:
206*c2c66affSColin Finck             imageModel.ResetToPrevious();
207*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
208*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
209*c2c66affSColin Finck             RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
210*c2c66affSColin Finck             break;
211*c2c66affSColin Finck     }
212*c2c66affSColin Finck 
213*c2c66affSColin Finck     last.x = x;
214*c2c66affSColin Finck     last.y = y;
215*c2c66affSColin Finck }
216*c2c66affSColin Finck 
217*c2c66affSColin Finck void
218*c2c66affSColin Finck endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
219*c2c66affSColin Finck {
220*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
221*c2c66affSColin Finck     {
222*c2c66affSColin Finck         case TOOL_FREESEL:
223*c2c66affSColin Finck         {
224*c2c66affSColin Finck             selectionModel.CalculateBoundingBoxAndContents(hdc);
225*c2c66affSColin Finck             if (selectionModel.PtStackSize() > 1)
226*c2c66affSColin Finck             {
227*c2c66affSColin Finck                 selectionModel.DrawBackgroundPoly(hdc, bg);
228*c2c66affSColin Finck                 imageModel.CopyPrevious();
229*c2c66affSColin Finck 
230*c2c66affSColin Finck                 selectionModel.DrawSelection(hdc);
231*c2c66affSColin Finck 
232*c2c66affSColin Finck                 placeSelWin();
233*c2c66affSColin Finck                 selectionWindow.ShowWindow(SW_SHOW);
234*c2c66affSColin Finck                 ForceRefreshSelectionContents();
235*c2c66affSColin Finck             }
236*c2c66affSColin Finck             selectionModel.ResetPtStack();
237*c2c66affSColin Finck             break;
238*c2c66affSColin Finck         }
239*c2c66affSColin Finck         case TOOL_RECTSEL:
240*c2c66affSColin Finck             imageModel.ResetToPrevious();
241*c2c66affSColin Finck             if (selectionModel.IsSrcRectSizeNonzero())
242*c2c66affSColin Finck             {
243*c2c66affSColin Finck                 selectionModel.CalculateContents(hdc);
244*c2c66affSColin Finck                 selectionModel.DrawBackgroundRect(hdc, bg);
245*c2c66affSColin Finck                 imageModel.CopyPrevious();
246*c2c66affSColin Finck 
247*c2c66affSColin Finck                 selectionModel.DrawSelection(hdc);
248*c2c66affSColin Finck 
249*c2c66affSColin Finck                 placeSelWin();
250*c2c66affSColin Finck                 selectionWindow.ShowWindow(SW_SHOW);
251*c2c66affSColin Finck                 ForceRefreshSelectionContents();
252*c2c66affSColin Finck             }
253*c2c66affSColin Finck             break;
254*c2c66affSColin Finck         case TOOL_TEXT:
255*c2c66affSColin Finck             imageModel.ResetToPrevious();
256*c2c66affSColin Finck             if (selectionModel.IsSrcRectSizeNonzero())
257*c2c66affSColin Finck             {
258*c2c66affSColin Finck                 imageModel.CopyPrevious();
259*c2c66affSColin Finck 
260*c2c66affSColin Finck                 placeSelWin();
261*c2c66affSColin Finck                 selectionWindow.ShowWindow(SW_SHOW);
262*c2c66affSColin Finck                 ForceRefreshSelectionContents();
263*c2c66affSColin Finck             }
264*c2c66affSColin Finck             break;
265*c2c66affSColin Finck         case TOOL_RUBBER:
266*c2c66affSColin Finck             Erase(hdc, last.x, last.y, x, y, bg, toolsModel.GetRubberRadius());
267*c2c66affSColin Finck             break;
268*c2c66affSColin Finck         case TOOL_PEN:
269*c2c66affSColin Finck             Line(hdc, last.x, last.y, x, y, fg, 1);
270*c2c66affSColin Finck             SetPixel(hdc, x, y, fg);
271*c2c66affSColin Finck             break;
272*c2c66affSColin Finck         case TOOL_LINE:
273*c2c66affSColin Finck             imageModel.ResetToPrevious();
274*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
275*c2c66affSColin Finck                 roundTo8Directions(start.x, start.y, x, y);
276*c2c66affSColin Finck             Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth());
277*c2c66affSColin Finck             break;
278*c2c66affSColin Finck         case TOOL_BEZIER:
279*c2c66affSColin Finck             pointSP++;
280*c2c66affSColin Finck             if (pointSP == 4)
281*c2c66affSColin Finck                 pointSP = 0;
282*c2c66affSColin Finck             break;
283*c2c66affSColin Finck         case TOOL_RECT:
284*c2c66affSColin Finck             imageModel.ResetToPrevious();
285*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
286*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
287*c2c66affSColin Finck             Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
288*c2c66affSColin Finck             break;
289*c2c66affSColin Finck         case TOOL_SHAPE:
290*c2c66affSColin Finck             imageModel.ResetToPrevious();
291*c2c66affSColin Finck             pointStack[pointSP].x = x;
292*c2c66affSColin Finck             pointStack[pointSP].y = y;
293*c2c66affSColin Finck             if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
294*c2c66affSColin Finck                 roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
295*c2c66affSColin Finck                                    pointStack[pointSP].x, pointStack[pointSP].y);
296*c2c66affSColin Finck             pointSP++;
297*c2c66affSColin Finck             if (pointSP >= 2)
298*c2c66affSColin Finck             {
299*c2c66affSColin Finck                 if ((pointStack[0].x - x) * (pointStack[0].x - x) +
300*c2c66affSColin Finck                     (pointStack[0].y - y) * (pointStack[0].y - y) <= toolsModel.GetLineWidth() * toolsModel.GetLineWidth() + 1)
301*c2c66affSColin Finck                 {
302*c2c66affSColin Finck                     Poly(hdc, pointStack, pointSP, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), TRUE, FALSE);
303*c2c66affSColin Finck                     pointSP = 0;
304*c2c66affSColin Finck                 }
305*c2c66affSColin Finck                 else
306*c2c66affSColin Finck                 {
307*c2c66affSColin Finck                     Poly(hdc, pointStack, pointSP, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
308*c2c66affSColin Finck                 }
309*c2c66affSColin Finck             }
310*c2c66affSColin Finck             if (pointSP == 255)
311*c2c66affSColin Finck                 pointSP--;
312*c2c66affSColin Finck             break;
313*c2c66affSColin Finck         case TOOL_ELLIPSE:
314*c2c66affSColin Finck             imageModel.ResetToPrevious();
315*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
316*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
317*c2c66affSColin Finck             Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
318*c2c66affSColin Finck             break;
319*c2c66affSColin Finck         case TOOL_RRECT:
320*c2c66affSColin Finck             imageModel.ResetToPrevious();
321*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
322*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
323*c2c66affSColin Finck             RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
324*c2c66affSColin Finck             break;
325*c2c66affSColin Finck     }
326*c2c66affSColin Finck }
327*c2c66affSColin Finck 
328*c2c66affSColin Finck void
329*c2c66affSColin Finck startPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
330*c2c66affSColin Finck {
331*c2c66affSColin Finck     start.x = x;
332*c2c66affSColin Finck     start.y = y;
333*c2c66affSColin Finck     last.x = x;
334*c2c66affSColin Finck     last.y = y;
335*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
336*c2c66affSColin Finck     {
337*c2c66affSColin Finck         case TOOL_FREESEL:
338*c2c66affSColin Finck         case TOOL_TEXT:
339*c2c66affSColin Finck         case TOOL_LINE:
340*c2c66affSColin Finck         case TOOL_RECT:
341*c2c66affSColin Finck         case TOOL_ELLIPSE:
342*c2c66affSColin Finck         case TOOL_RRECT:
343*c2c66affSColin Finck             imageModel.CopyPrevious();
344*c2c66affSColin Finck             break;
345*c2c66affSColin Finck         case TOOL_RUBBER:
346*c2c66affSColin Finck             imageModel.CopyPrevious();
347*c2c66affSColin Finck             Replace(hdc, x, y, x, y, fg, bg, toolsModel.GetRubberRadius());
348*c2c66affSColin Finck             break;
349*c2c66affSColin Finck         case TOOL_FILL:
350*c2c66affSColin Finck             imageModel.CopyPrevious();
351*c2c66affSColin Finck             Fill(hdc, x, y, bg);
352*c2c66affSColin Finck             break;
353*c2c66affSColin Finck         case TOOL_PEN:
354*c2c66affSColin Finck             imageModel.CopyPrevious();
355*c2c66affSColin Finck             SetPixel(hdc, x, y, bg);
356*c2c66affSColin Finck             break;
357*c2c66affSColin Finck         case TOOL_BRUSH:
358*c2c66affSColin Finck             imageModel.CopyPrevious();
359*c2c66affSColin Finck             Brush(hdc, x, y, x, y, bg, toolsModel.GetBrushStyle());
360*c2c66affSColin Finck             break;
361*c2c66affSColin Finck         case TOOL_AIRBRUSH:
362*c2c66affSColin Finck             imageModel.CopyPrevious();
363*c2c66affSColin Finck             Airbrush(hdc, x, y, bg, toolsModel.GetAirBrushWidth());
364*c2c66affSColin Finck             break;
365*c2c66affSColin Finck         case TOOL_BEZIER:
366*c2c66affSColin Finck             pointStack[pointSP].x = x;
367*c2c66affSColin Finck             pointStack[pointSP].y = y;
368*c2c66affSColin Finck             if (pointSP == 0)
369*c2c66affSColin Finck             {
370*c2c66affSColin Finck                 imageModel.CopyPrevious();
371*c2c66affSColin Finck                 pointSP++;
372*c2c66affSColin Finck             }
373*c2c66affSColin Finck             break;
374*c2c66affSColin Finck         case TOOL_SHAPE:
375*c2c66affSColin Finck             pointStack[pointSP].x = x;
376*c2c66affSColin Finck             pointStack[pointSP].y = y;
377*c2c66affSColin Finck             if (pointSP + 1 >= 2)
378*c2c66affSColin Finck                 Poly(hdc, pointStack, pointSP + 1, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
379*c2c66affSColin Finck             if (pointSP == 0)
380*c2c66affSColin Finck             {
381*c2c66affSColin Finck                 imageModel.CopyPrevious();
382*c2c66affSColin Finck                 pointSP++;
383*c2c66affSColin Finck             }
384*c2c66affSColin Finck             break;
385*c2c66affSColin Finck     }
386*c2c66affSColin Finck }
387*c2c66affSColin Finck 
388*c2c66affSColin Finck void
389*c2c66affSColin Finck whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
390*c2c66affSColin Finck {
391*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
392*c2c66affSColin Finck     {
393*c2c66affSColin Finck         case TOOL_RUBBER:
394*c2c66affSColin Finck             Replace(hdc, last.x, last.y, x, y, fg, bg, toolsModel.GetRubberRadius());
395*c2c66affSColin Finck             break;
396*c2c66affSColin Finck         case TOOL_PEN:
397*c2c66affSColin Finck             Line(hdc, last.x, last.y, x, y, bg, 1);
398*c2c66affSColin Finck             break;
399*c2c66affSColin Finck         case TOOL_BRUSH:
400*c2c66affSColin Finck             Brush(hdc, last.x, last.y, x, y, bg, toolsModel.GetBrushStyle());
401*c2c66affSColin Finck             break;
402*c2c66affSColin Finck         case TOOL_AIRBRUSH:
403*c2c66affSColin Finck             Airbrush(hdc, x, y, bg, toolsModel.GetAirBrushWidth());
404*c2c66affSColin Finck             break;
405*c2c66affSColin Finck         case TOOL_LINE:
406*c2c66affSColin Finck             imageModel.ResetToPrevious();
407*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
408*c2c66affSColin Finck                 roundTo8Directions(start.x, start.y, x, y);
409*c2c66affSColin Finck             Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth());
410*c2c66affSColin Finck             break;
411*c2c66affSColin Finck         case TOOL_BEZIER:
412*c2c66affSColin Finck             imageModel.ResetToPrevious();
413*c2c66affSColin Finck             pointStack[pointSP].x = x;
414*c2c66affSColin Finck             pointStack[pointSP].y = y;
415*c2c66affSColin Finck             switch (pointSP)
416*c2c66affSColin Finck             {
417*c2c66affSColin Finck                 case 1:
418*c2c66affSColin Finck                     Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, bg,
419*c2c66affSColin Finck                          toolsModel.GetLineWidth());
420*c2c66affSColin Finck                     break;
421*c2c66affSColin Finck                 case 2:
422*c2c66affSColin Finck                     Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], bg, toolsModel.GetLineWidth());
423*c2c66affSColin Finck                     break;
424*c2c66affSColin Finck                 case 3:
425*c2c66affSColin Finck                     Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], bg, toolsModel.GetLineWidth());
426*c2c66affSColin Finck                     break;
427*c2c66affSColin Finck             }
428*c2c66affSColin Finck             break;
429*c2c66affSColin Finck         case TOOL_RECT:
430*c2c66affSColin Finck             imageModel.ResetToPrevious();
431*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
432*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
433*c2c66affSColin Finck             Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
434*c2c66affSColin Finck             break;
435*c2c66affSColin Finck         case TOOL_SHAPE:
436*c2c66affSColin Finck             imageModel.ResetToPrevious();
437*c2c66affSColin Finck             pointStack[pointSP].x = x;
438*c2c66affSColin Finck             pointStack[pointSP].y = y;
439*c2c66affSColin Finck             if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
440*c2c66affSColin Finck                 roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
441*c2c66affSColin Finck                                    pointStack[pointSP].x, pointStack[pointSP].y);
442*c2c66affSColin Finck             if (pointSP + 1 >= 2)
443*c2c66affSColin Finck                 Poly(hdc, pointStack, pointSP + 1, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
444*c2c66affSColin Finck             break;
445*c2c66affSColin Finck         case TOOL_ELLIPSE:
446*c2c66affSColin Finck             imageModel.ResetToPrevious();
447*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
448*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
449*c2c66affSColin Finck             Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
450*c2c66affSColin Finck             break;
451*c2c66affSColin Finck         case TOOL_RRECT:
452*c2c66affSColin Finck             imageModel.ResetToPrevious();
453*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
454*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
455*c2c66affSColin Finck             RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
456*c2c66affSColin Finck             break;
457*c2c66affSColin Finck     }
458*c2c66affSColin Finck 
459*c2c66affSColin Finck     last.x = x;
460*c2c66affSColin Finck     last.y = y;
461*c2c66affSColin Finck }
462*c2c66affSColin Finck 
463*c2c66affSColin Finck void
464*c2c66affSColin Finck endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
465*c2c66affSColin Finck {
466*c2c66affSColin Finck     switch (toolsModel.GetActiveTool())
467*c2c66affSColin Finck     {
468*c2c66affSColin Finck         case TOOL_RUBBER:
469*c2c66affSColin Finck             Replace(hdc, last.x, last.y, x, y, fg, bg, toolsModel.GetRubberRadius());
470*c2c66affSColin Finck             break;
471*c2c66affSColin Finck         case TOOL_PEN:
472*c2c66affSColin Finck             Line(hdc, last.x, last.y, x, y, bg, 1);
473*c2c66affSColin Finck             SetPixel(hdc, x, y, bg);
474*c2c66affSColin Finck             break;
475*c2c66affSColin Finck         case TOOL_LINE:
476*c2c66affSColin Finck             imageModel.ResetToPrevious();
477*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
478*c2c66affSColin Finck                 roundTo8Directions(start.x, start.y, x, y);
479*c2c66affSColin Finck             Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth());
480*c2c66affSColin Finck             break;
481*c2c66affSColin Finck         case TOOL_BEZIER:
482*c2c66affSColin Finck             pointSP++;
483*c2c66affSColin Finck             if (pointSP == 4)
484*c2c66affSColin Finck                 pointSP = 0;
485*c2c66affSColin Finck             break;
486*c2c66affSColin Finck         case TOOL_RECT:
487*c2c66affSColin Finck             imageModel.ResetToPrevious();
488*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
489*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
490*c2c66affSColin Finck             Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
491*c2c66affSColin Finck             break;
492*c2c66affSColin Finck         case TOOL_SHAPE:
493*c2c66affSColin Finck             imageModel.ResetToPrevious();
494*c2c66affSColin Finck             pointStack[pointSP].x = x;
495*c2c66affSColin Finck             pointStack[pointSP].y = y;
496*c2c66affSColin Finck             if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
497*c2c66affSColin Finck                 roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
498*c2c66affSColin Finck                                    pointStack[pointSP].x, pointStack[pointSP].y);
499*c2c66affSColin Finck             pointSP++;
500*c2c66affSColin Finck             if (pointSP >= 2)
501*c2c66affSColin Finck             {
502*c2c66affSColin Finck                 if ((pointStack[0].x - x) * (pointStack[0].x - x) +
503*c2c66affSColin Finck                     (pointStack[0].y - y) * (pointStack[0].y - y) <= toolsModel.GetLineWidth() * toolsModel.GetLineWidth() + 1)
504*c2c66affSColin Finck                 {
505*c2c66affSColin Finck                     Poly(hdc, pointStack, pointSP, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), TRUE, FALSE);
506*c2c66affSColin Finck                     pointSP = 0;
507*c2c66affSColin Finck                 }
508*c2c66affSColin Finck                 else
509*c2c66affSColin Finck                 {
510*c2c66affSColin Finck                     Poly(hdc, pointStack, pointSP, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
511*c2c66affSColin Finck                 }
512*c2c66affSColin Finck             }
513*c2c66affSColin Finck             if (pointSP == 255)
514*c2c66affSColin Finck                 pointSP--;
515*c2c66affSColin Finck             break;
516*c2c66affSColin Finck         case TOOL_ELLIPSE:
517*c2c66affSColin Finck             imageModel.ResetToPrevious();
518*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
519*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
520*c2c66affSColin Finck             Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
521*c2c66affSColin Finck             break;
522*c2c66affSColin Finck         case TOOL_RRECT:
523*c2c66affSColin Finck             imageModel.ResetToPrevious();
524*c2c66affSColin Finck             if (GetAsyncKeyState(VK_SHIFT) < 0)
525*c2c66affSColin Finck                 regularize(start.x, start.y, x, y);
526*c2c66affSColin Finck             RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
527*c2c66affSColin Finck             break;
528*c2c66affSColin Finck     }
529*c2c66affSColin Finck }
530