[MSPAINT_NEW] Convert to C++, update header comments
[reactos.git] / reactos / base / applications / mspaint_new / drawing.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint_new/drawing.cpp
5 * PURPOSE: The drawing functions used by the tools
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 /* FUNCTIONS ********************************************************/
14
15 void
16 Line(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, int thickness)
17 {
18 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, color));
19 MoveToEx(hdc, x1, y1, NULL);
20 LineTo(hdc, x2, y2);
21 DeleteObject(SelectObject(hdc, oldPen));
22 }
23
24 void
25 Rect(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, int thickness, int style)
26 {
27 HBRUSH oldBrush;
28 LOGBRUSH logbrush;
29 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, fg));
30 logbrush.lbStyle = (style == 0) ? BS_HOLLOW : BS_SOLID;
31 logbrush.lbColor = (style == 2) ? fg : bg;
32 logbrush.lbHatch = 0;
33 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
34 Rectangle(hdc, x1, y1, x2, y2);
35 DeleteObject(SelectObject(hdc, oldBrush));
36 DeleteObject(SelectObject(hdc, oldPen));
37 }
38
39 void
40 Ellp(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, int thickness, int style)
41 {
42 HBRUSH oldBrush;
43 LOGBRUSH logbrush;
44 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, fg));
45 logbrush.lbStyle = (style == 0) ? BS_HOLLOW : BS_SOLID;
46 logbrush.lbColor = (style == 2) ? fg : bg;
47 logbrush.lbHatch = 0;
48 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
49 Ellipse(hdc, x1, y1, x2, y2);
50 DeleteObject(SelectObject(hdc, oldBrush));
51 DeleteObject(SelectObject(hdc, oldPen));
52 }
53
54 void
55 RRect(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, int thickness, int style)
56 {
57 LOGBRUSH logbrush;
58 HBRUSH oldBrush;
59 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, fg));
60 logbrush.lbStyle = (style == 0) ? BS_HOLLOW : BS_SOLID;
61 logbrush.lbColor = (style == 2) ? fg : bg;
62 logbrush.lbHatch = 0;
63 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
64 RoundRect(hdc, x1, y1, x2, y2, 16, 16);
65 DeleteObject(SelectObject(hdc, oldBrush));
66 DeleteObject(SelectObject(hdc, oldPen));
67 }
68
69 void
70 Poly(HDC hdc, POINT * lpPoints, int nCount, COLORREF fg, COLORREF bg, int thickness, int style, BOOL closed, BOOL inverted)
71 {
72 LOGBRUSH logbrush;
73 HBRUSH oldBrush;
74 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, fg));
75 UINT oldRop = GetROP2(hdc);
76
77 if (inverted)
78 SetROP2(hdc, R2_NOTXORPEN);
79
80 logbrush.lbStyle = (style == 0) ? BS_HOLLOW : BS_SOLID;
81 logbrush.lbColor = (style == 2) ? fg : bg;
82 logbrush.lbHatch = 0;
83 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
84 if (closed)
85 Polygon(hdc, lpPoints, nCount);
86 else
87 Polyline(hdc, lpPoints, nCount);
88 DeleteObject(SelectObject(hdc, oldBrush));
89 DeleteObject(SelectObject(hdc, oldPen));
90
91 SetROP2(hdc, oldRop);
92 }
93
94 void
95 Bezier(HDC hdc, POINT p1, POINT p2, POINT p3, POINT p4, COLORREF color, int thickness)
96 {
97 HPEN oldPen;
98 POINT fourPoints[4];
99 fourPoints[0] = p1;
100 fourPoints[1] = p2;
101 fourPoints[2] = p3;
102 fourPoints[3] = p4;
103 oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, thickness, color));
104 PolyBezier(hdc, fourPoints, 4);
105 DeleteObject(SelectObject(hdc, oldPen));
106 }
107
108 void
109 Fill(HDC hdc, LONG x, LONG y, COLORREF color)
110 {
111 HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
112 ExtFloodFill(hdc, x, y, GetPixel(hdc, x, y), FLOODFILLSURFACE);
113 DeleteObject(SelectObject(hdc, oldBrush));
114 }
115
116 void
117 Erase(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG radius)
118 {
119 LONG a, b;
120 HPEN oldPen;
121 HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
122
123 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
124 oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
125 for(a = 0; a <= b; a++)
126 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - radius + 1,
127 (y1 * (b - a) + y2 * a) / b - radius + 1, (x1 * (b - a) + x2 * a) / b + radius + 1,
128 (y1 * (b - a) + y2 * a) / b + radius + 1);
129 DeleteObject(SelectObject(hdc, oldBrush));
130 DeleteObject(SelectObject(hdc, oldPen));
131 }
132
133 void
134 Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
135 {
136 LONG a, b, x, y;
137 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
138
139 for(a = 0; a <= b; a++)
140 for(y = (y1 * (b - a) + y2 * a) / b - radius + 1;
141 y < (y1 * (b - a) + y2 * a) / b + radius + 1; y++)
142 for(x = (x1 * (b - a) + x2 * a) / b - radius + 1;
143 x < (x1 * (b - a) + x2 * a) / b + radius + 1; x++)
144 if (GetPixel(hdc, x, y) == fg)
145 SetPixel(hdc, x, y, bg);
146 }
147
148 void
149 Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r)
150 {
151 LONG a, b;
152
153 for(b = -r; b <= r; b++)
154 for(a = -r; a <= r; a++)
155 if ((a * a + b * b <= r * r) && (rand() % 4 == 0))
156 SetPixel(hdc, x + a, y + b, color);
157 }
158
159 void
160 Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style)
161 {
162 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
163 HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color));
164 LONG a, b;
165 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
166 switch (style)
167 {
168 case 0:
169 for(a = 0; a <= b; a++)
170 Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
171 (x1 * (b - a) + x2 * a) / b + 4, (y1 * (b - a) + y2 * a) / b + 4);
172 break;
173 case 1:
174 for(a = 0; a <= b; a++)
175 Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1,
176 (x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3);
177 break;
178 case 2:
179 MoveToEx(hdc, x1, y1, NULL);
180 LineTo(hdc, x2, y2);
181 SetPixel(hdc, x2, y2, color);
182 break;
183 case 3:
184 for(a = 0; a <= b; a++)
185 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
186 (x1 * (b - a) + x2 * a) / b + 5, (y1 * (b - a) + y2 * a) / b + 5);
187 break;
188 case 4:
189 for(a = 0; a <= b; a++)
190 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 2, (y1 * (b - a) + y2 * a) / b - 2,
191 (x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3);
192 break;
193 case 5:
194 for(a = 0; a <= b; a++)
195 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1,
196 (x1 * (b - a) + x2 * a) / b + 1, (y1 * (b - a) + y2 * a) / b + 1);
197 break;
198 case 6:
199 case 7:
200 case 8:
201 case 9:
202 case 10:
203 case 11:
204 {
205 POINT offsTop[] = {{4, -3}, {2, -2}, {0, 0},
206 {-3, -3}, {-2, -2}, {-1, 0}};
207 POINT offsBtm[] = {{-3, 4}, {-2, 2}, {-1, 1},
208 {4, 4}, {2, 2}, {0, 1}};
209 LONG idx = style - 6;
210 POINT pts[4];
211 pts[0].x = x1 + offsTop[idx].x;
212 pts[0].y = y1 + offsTop[idx].y;
213 pts[1].x = x1 + offsBtm[idx].x;
214 pts[1].y = y1 + offsBtm[idx].y;
215 pts[2].x = x2 + offsBtm[idx].x;
216 pts[2].y = y2 + offsBtm[idx].y;
217 pts[3].x = x2 + offsTop[idx].x;
218 pts[3].y = y2 + offsTop[idx].y;
219 Polygon(hdc, pts, 4);
220 break;
221 }
222 }
223 DeleteObject(SelectObject(hdc, oldBrush));
224 DeleteObject(SelectObject(hdc, oldPen));
225 }
226
227 void
228 RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
229 {
230 HBRUSH oldBrush;
231 LOGBRUSH logbrush;
232 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
233 UINT oldRop = GetROP2(hdc);
234
235 SetROP2(hdc, R2_NOTXORPEN);
236
237 logbrush.lbStyle = BS_HOLLOW;
238 logbrush.lbColor = 0;
239 logbrush.lbHatch = 0;
240 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
241 Rectangle(hdc, x1, y1, x2, y2);
242 DeleteObject(SelectObject(hdc, oldBrush));
243 DeleteObject(SelectObject(hdc, oldPen));
244
245 SetROP2(hdc, oldRop);
246 }
247
248 void
249 SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, DWORD system_selection_color)
250 {
251 HBRUSH oldBrush;
252 LOGBRUSH logbrush;
253 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_DOT, 1, system_selection_color));
254
255 logbrush.lbStyle = BS_HOLLOW;
256 logbrush.lbColor = 0;
257 logbrush.lbHatch = 0;
258 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
259 Rectangle(hdc, x1, y1, x2, y2); /* SEL BOX FRAME */
260 DeleteObject(SelectObject(hdc, oldBrush));
261 DeleteObject(SelectObject(hdc, oldPen));
262 oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, system_selection_color));
263 oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(system_selection_color));
264 Rectangle(hdc, x1 - 1, y1 - 1, x1 + 2, y1 + 2);
265 Rectangle(hdc, x2 - 2, y1 - 1, x2 + 2, y1 + 2);
266 Rectangle(hdc, x1 - 1, y2 - 2, x1 + 2, y2 + 1);
267 Rectangle(hdc, x2 - 2, y2 - 2, x2 + 2, y2 + 1);
268 Rectangle(hdc, (x1 + x2) / 2 - 1, y1 - 1, (x1 + x2) / 2 + 2, y1 + 2);
269 Rectangle(hdc, (x1 + x2) / 2 - 1, y2 - 2, (x1 + x2) / 2 + 2, y2 + 1);
270 Rectangle(hdc, x1 - 1, (y1 + y2) / 2 - 1, x1 + 2, (y1 + y2) / 2 + 2);
271 Rectangle(hdc, x2 - 2, (y1 + y2) / 2 - 1, x2 + 1, (y1 + y2) / 2 + 2);
272 DeleteObject(SelectObject(hdc, oldBrush));
273 DeleteObject(SelectObject(hdc, oldPen));
274 }
275
276 void
277 Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style)
278 {
279 HFONT oldFont;
280 RECT rect = {x1, y1, x2, y2};
281 COLORREF oldColor;
282 COLORREF oldBkColor;
283 int oldBkMode;
284 oldFont = (HFONT) SelectObject(hdc, font);
285 oldColor = SetTextColor(hdc, fg);
286 oldBkColor = SetBkColor(hdc, bg);
287 oldBkMode = SetBkMode(hdc, TRANSPARENT);
288 if (style == 0)
289 Rect(hdc, x1, y1, x2, y2, bg, bg, 1, 2);
290 DrawText(hdc, lpchText, -1, &rect, DT_EDITCONTROL);
291 SelectObject(hdc, oldFont);
292 SetTextColor(hdc, oldColor);
293 SetBkColor(hdc, oldBkColor);
294 SetBkMode(hdc, oldBkMode);
295 }