* Turkish translation update and improvements by Erdem Ersoy.
[reactos.git] / reactos / 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 LONG a, b;
113 HPEN oldPen;
114 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
115
116 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
117 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
118 for(a = 0; a <= b; a++)
119 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - radius + 1,
120 (y1 * (b - a) + y2 * a) / b - radius + 1, (x1 * (b - a) + x2 * a) / b + radius + 1,
121 (y1 * (b - a) + y2 * a) / b + radius + 1);
122 DeleteObject(SelectObject(hdc, oldBrush));
123 DeleteObject(SelectObject(hdc, oldPen));
124 }
125
126 void
127 Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
128 {
129 LONG a, b, x, y;
130 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
131
132 for(a = 0; a <= b; a++)
133 for(y = (y1 * (b - a) + y2 * a) / b - radius + 1;
134 y < (y1 * (b - a) + y2 * a) / b + radius + 1; y++)
135 for(x = (x1 * (b - a) + x2 * a) / b - radius + 1;
136 x < (x1 * (b - a) + x2 * a) / b + radius + 1; x++)
137 if (GetPixel(hdc, x, y) == fg)
138 SetPixel(hdc, x, y, bg);
139 }
140
141 void
142 Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r)
143 {
144 LONG a, b;
145
146 for(b = -r; b <= r; b++)
147 for(a = -r; a <= r; a++)
148 if ((a * a + b * b <= r * r) && (rand() % 4 == 0))
149 SetPixel(hdc, x + a, y + b, color);
150 }
151
152 void
153 Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style)
154 {
155 HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
156 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
157 LONG a, b;
158 b = max(1, max(abs(x2 - x1), abs(y2 - y1)));
159 switch (style)
160 {
161 case 0:
162 for(a = 0; a <= b; a++)
163 Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
164 (x1 * (b - a) + x2 * a) / b + 4, (y1 * (b - a) + y2 * a) / b + 4);
165 break;
166 case 1:
167 for(a = 0; a <= b; a++)
168 Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1,
169 (x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3);
170 break;
171 case 2:
172 MoveToEx(hdc, x1, y1, NULL);
173 LineTo(hdc, x2, y2);
174 SetPixel(hdc, x2, y2, color);
175 break;
176 case 3:
177 for(a = 0; a <= b; a++)
178 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3,
179 (x1 * (b - a) + x2 * a) / b + 5, (y1 * (b - a) + y2 * a) / b + 5);
180 break;
181 case 4:
182 for(a = 0; a <= b; a++)
183 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 2, (y1 * (b - a) + y2 * a) / b - 2,
184 (x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3);
185 break;
186 case 5:
187 for(a = 0; a <= b; a++)
188 Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1,
189 (x1 * (b - a) + x2 * a) / b + 1, (y1 * (b - a) + y2 * a) / b + 1);
190 break;
191 case 6:
192 case 7:
193 case 8:
194 case 9:
195 case 10:
196 case 11:
197 {
198 POINT offsTop[] = {{4, 3}, {2, -2}, {0, 0},
199 {-3, -3}, {-2, -2}, {-1, 0}};
200 POINT offsBtm[] = {{-3, 4}, {-2, 2}, {-1, 1},
201 {4, 4}, {2, 2}, {0, 1}};
202 LONG idx = style - 6;
203 POINT pts[4];
204 pts[0].x = x1 + offsTop[idx].x;
205 pts[0].y = y1 + offsTop[idx].y;
206 pts[1].x = x1 + offsBtm[idx].x;
207 pts[1].y = y1 + offsBtm[idx].y;
208 pts[2].x = x2 + offsBtm[idx].x;
209 pts[2].y = y2 + offsBtm[idx].y;
210 pts[3].x = x2 + offsTop[idx].x;
211 pts[3].y = y2 + offsTop[idx].y;
212 Polygon(hdc, pts, 4);
213 break;
214 }
215 }
216 DeleteObject(SelectObject(hdc, oldBrush));
217 DeleteObject(SelectObject(hdc, oldPen));
218 }
219
220 void
221 RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
222 {
223 HBRUSH oldBrush;
224 LOGBRUSH logbrush;
225 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
226 logbrush.lbStyle = BS_HOLLOW;
227 logbrush.lbColor = 0;
228 logbrush.lbHatch = 0;
229 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
230 Rectangle(hdc, x1, y1, x2, y2);
231 DeleteObject(SelectObject(hdc, oldBrush));
232 DeleteObject(SelectObject(hdc, oldPen));
233 }
234
235 void
236 SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2)
237 {
238 HBRUSH oldBrush;
239 LOGBRUSH logbrush;
240 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
241 logbrush.lbStyle = BS_HOLLOW;
242 logbrush.lbColor = 0;
243 logbrush.lbHatch = 0;
244 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
245 Rectangle(hdc, x1, y1, x2, y2);
246 DeleteObject(SelectObject(hdc, oldBrush));
247 DeleteObject(SelectObject(hdc, oldPen));
248 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00000000));
249 oldBrush = SelectObject(hdc, CreateSolidBrush(0x00000000));
250 Rectangle(hdc, x1 - 1, y1 - 1, x1 + 2, y1 + 2);
251 Rectangle(hdc, x2 - 2, y1 - 1, x2 + 2, y1 + 2);
252 Rectangle(hdc, x1 - 1, y2 - 2, x1 + 2, y2 + 1);
253 Rectangle(hdc, x2 - 2, y2 - 2, x2 + 2, y2 + 1);
254 Rectangle(hdc, (x1 + x2) / 2 - 1, y1 - 1, (x1 + x2) / 2 + 2, y1 + 2);
255 Rectangle(hdc, (x1 + x2) / 2 - 1, y2 - 2, (x1 + x2) / 2 + 2, y2 + 1);
256 Rectangle(hdc, x1 - 1, (y1 + y2) / 2 - 1, x1 + 2, (y1 + y2) / 2 + 2);
257 Rectangle(hdc, x2 - 2, (y1 + y2) / 2 - 1, x2 + 1, (y1 + y2) / 2 + 2);
258 DeleteObject(SelectObject(hdc, oldBrush));
259 DeleteObject(SelectObject(hdc, oldPen));
260 }