[NTOSKRNL]
[reactos.git] / base / applications / mspaint / drawing.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/drawing.c
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 = 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 = 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 = 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 = 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 = 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 = 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 = 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)
71 {
72 LOGBRUSH logbrush;
73 HBRUSH oldBrush;
74 HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, thickness, fg));
75 logbrush.lbStyle = (style == 0) ? BS_HOLLOW : BS_SOLID;
76 logbrush.lbColor = (style == 2) ? fg : bg;
77 logbrush.lbHatch = 0;
78 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
79 if (closed)
80 Polygon(hdc, lpPoints, nCount);
81 else
82 Polyline(hdc, lpPoints, nCount);
83 DeleteObject(SelectObject(hdc, oldBrush));
84 DeleteObject(SelectObject(hdc, oldPen));
85 }
86
87 void
88 Bezier(HDC hdc, POINT p1, POINT p2, POINT p3, POINT p4, COLORREF color, int thickness)
89 {
90 HPEN oldPen;
91 POINT fourPoints[4];
92 fourPoints[0] = p1;
93 fourPoints[1] = p2;
94 fourPoints[2] = p3;
95 fourPoints[3] = p4;
96 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, thickness, color));
97 PolyBezier(hdc, fourPoints, 4);
98 DeleteObject(SelectObject(hdc, oldPen));
99 }
100
101 void
102 Fill(HDC hdc, LONG x, LONG y, COLORREF color)
103 {
104 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
105 ExtFloodFill(hdc, x, y, GetPixel(hdc, x, y), FLOODFILLSURFACE);
106 DeleteObject(SelectObject(hdc, oldBrush));
107 }
108
109 void
110 Erase(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG radius)
111 {
112 short a;
113 HPEN oldPen;
114 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
115 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
116 for(a = 0; a <= 100; a++)
117 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - radius + 1,
118 (y1 * (100 - a) + y2 * a) / 100 - radius + 1, (x1 * (100 - a) + x2 * a) / 100 + radius + 1,
119 (y1 * (100 - a) + y2 * a) / 100 + radius + 1);
120 DeleteObject(SelectObject(hdc, oldBrush));
121 DeleteObject(SelectObject(hdc, oldPen));
122 }
123
124 void
125 Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
126 {
127 LONG a, x, y;
128
129 for(a = 0; a <= 100; a++)
130 for(y = (y1 * (100 - a) + y2 * a) / 100 - radius + 1;
131 y < (y1 * (100 - a) + y2 * a) / 100 + radius + 1; y++)
132 for(x = (x1 * (100 - a) + x2 * a) / 100 - radius + 1;
133 x < (x1 * (100 - a) + x2 * a) / 100 + radius + 1; x++)
134 if (GetPixel(hdc, x, y) == fg)
135 SetPixel(hdc, x, y, bg);
136 }
137
138 void
139 Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r)
140 {
141 LONG a, b;
142
143 for(b = -r; b <= r; b++)
144 for(a = -r; a <= r; a++)
145 if ((a * a + b * b <= r * r) && (rand() % 4 == 0))
146 SetPixel(hdc, x + a, y + b, color);
147 }
148
149 void
150 Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, COLORREF style)
151 {
152 HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
153 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
154 short a;
155 switch (style)
156 {
157 case 0:
158 for(a = 0; a <= 100; a++)
159 Ellipse(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3,
160 (x1 * (100 - a) + x2 * a) / 100 + 4, (y1 * (100 - a) + y2 * a) / 100 + 4);
161 break;
162 case 1:
163 for(a = 0; a <= 100; a++)
164 Ellipse(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1,
165 (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
166 break;
167 case 2:
168 MoveToEx(hdc, x1, y1, NULL);
169 LineTo(hdc, x2, y2);
170 SetPixel(hdc, x2, y2, color);
171 break;
172 case 3:
173 for(a = 0; a <= 100; a++)
174 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3,
175 (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 + 5);
176 break;
177 case 4:
178 for(a = 0; a <= 100; a++)
179 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 - 2,
180 (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
181 break;
182 case 5:
183 for(a = 0; a <= 100; a++)
184 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1,
185 (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 + 1);
186 break;
187 case 6:
188 for(a = 0; a <= 100; a++)
189 {
190 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 + 5, NULL);
191 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 - 3);
192 }
193 break;
194 case 7:
195 for(a = 0; a <= 100; a++)
196 {
197 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 + 3, NULL);
198 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 - 2);
199 }
200 break;
201 case 8:
202 for(a = 0; a <= 100; a++)
203 {
204 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 + 1, NULL);
205 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 - 1);
206 }
207 break;
208 case 9:
209 for(a = 0; a <= 100; a++)
210 {
211 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3, NULL);
212 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 + 5);
213 }
214 break;
215 case 10:
216 for(a = 0; a <= 100; a++)
217 {
218 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 - 2, NULL);
219 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
220 }
221 break;
222 case 11:
223 for(a = 0; a <= 100; a++)
224 {
225 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1, NULL);
226 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 + 1);
227 }
228 break;
229 }
230 DeleteObject(SelectObject(hdc, oldBrush));
231 DeleteObject(SelectObject(hdc, oldPen));
232 }
233
234 void
235 RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
236 {
237 HBRUSH oldBrush;
238 LOGBRUSH logbrush;
239 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
240 logbrush.lbStyle = BS_HOLLOW;
241 logbrush.lbColor = 0;
242 logbrush.lbHatch = 0;
243 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
244 Rectangle(hdc, x1, y1, x2, y2);
245 DeleteObject(SelectObject(hdc, oldBrush));
246 DeleteObject(SelectObject(hdc, oldPen));
247 }
248
249 void
250 SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
251 {
252 HBRUSH oldBrush;
253 LOGBRUSH logbrush;
254 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
255 logbrush.lbStyle = BS_HOLLOW;
256 logbrush.lbColor = 0;
257 logbrush.lbHatch = 0;
258 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
259 Rectangle(hdc, x1, y1, x2, y2);
260 DeleteObject(SelectObject(hdc, oldBrush));
261 DeleteObject(SelectObject(hdc, oldPen));
262 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00000000));
263 oldBrush = SelectObject(hdc, CreateSolidBrush(0x00000000));
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 }