Create a branch for header work.
[reactos.git] / base / applications / paint / 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 <windows.h>
12
13 /* FUNCTIONS ********************************************************/
14
15 void
16 Line(HDC hdc, short x1, short y1, short x2, short y2, int 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, short x1, short y1, short x2, short y2, int fg, int 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, short x1, short y1, short x2, short y2, int fg, int 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, short x1, short y1, short x2, short y2, int fg, int 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, int fg, int 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, int 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, int x, int y, int 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, short x1, short y1, short x2, short y2, int color, int 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, short x1, short y1, short x2, short y2, int fg, int bg, int radius)
126 {
127 short a, x, y;
128 for(a = 0; a <= 100; a++)
129 for(y = (y1 * (100 - a) + y2 * a) / 100 - radius + 1;
130 y < (y1 * (100 - a) + y2 * a) / 100 + radius + 1; y++)
131 for(x = (x1 * (100 - a) + x2 * a) / 100 - radius + 1;
132 x < (x1 * (100 - a) + x2 * a) / 100 + radius + 1; x++)
133 if (GetPixel(hdc, x, y) == fg)
134 SetPixel(hdc, x, y, bg);
135 }
136
137 void
138 Airbrush(HDC hdc, short x, short y, int color, int r)
139 {
140 short a;
141 short b;
142 for(b = -r; b <= r; b++)
143 for(a = -r; a <= r; a++)
144 if ((a * a + b * b <= r * r) && (rand() % 4 == 0))
145 SetPixel(hdc, x + a, y + b, color);
146 }
147
148 void
149 Brush(HDC hdc, short x1, short y1, short x2, short y2, int color, int style)
150 {
151 HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, color));
152 HBRUSH oldBrush = SelectObject(hdc, CreateSolidBrush(color));
153 short a;
154 switch (style)
155 {
156 case 0:
157 for(a = 0; a <= 100; a++)
158 Ellipse(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3,
159 (x1 * (100 - a) + x2 * a) / 100 + 4, (y1 * (100 - a) + y2 * a) / 100 + 4);
160 break;
161 case 1:
162 for(a = 0; a <= 100; a++)
163 Ellipse(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1,
164 (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
165 break;
166 case 2:
167 MoveToEx(hdc, x1, y1, NULL);
168 LineTo(hdc, x2, y2);
169 SetPixel(hdc, x2, y2, color);
170 break;
171 case 3:
172 for(a = 0; a <= 100; a++)
173 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3,
174 (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 + 5);
175 break;
176 case 4:
177 for(a = 0; a <= 100; a++)
178 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 - 2,
179 (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
180 break;
181 case 5:
182 for(a = 0; a <= 100; a++)
183 Rectangle(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1,
184 (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 + 1);
185 break;
186 case 6:
187 for(a = 0; a <= 100; a++)
188 {
189 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 + 5, NULL);
190 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 - 3);
191 }
192 break;
193 case 7:
194 for(a = 0; a <= 100; a++)
195 {
196 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 + 3, NULL);
197 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 - 2);
198 }
199 break;
200 case 8:
201 for(a = 0; a <= 100; a++)
202 {
203 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 + 1, NULL);
204 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 - 1);
205 }
206 break;
207 case 9:
208 for(a = 0; a <= 100; a++)
209 {
210 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 3, (y1 * (100 - a) + y2 * a) / 100 - 3, NULL);
211 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 5, (y1 * (100 - a) + y2 * a) / 100 + 5);
212 }
213 break;
214 case 10:
215 for(a = 0; a <= 100; a++)
216 {
217 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 2, (y1 * (100 - a) + y2 * a) / 100 - 2, NULL);
218 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 3, (y1 * (100 - a) + y2 * a) / 100 + 3);
219 }
220 break;
221 case 11:
222 for(a = 0; a <= 100; a++)
223 {
224 MoveToEx(hdc, (x1 * (100 - a) + x2 * a) / 100 - 1, (y1 * (100 - a) + y2 * a) / 100 - 1, NULL);
225 LineTo(hdc, (x1 * (100 - a) + x2 * a) / 100 + 1, (y1 * (100 - a) + y2 * a) / 100 + 1);
226 }
227 break;
228 }
229 DeleteObject(SelectObject(hdc, oldBrush));
230 DeleteObject(SelectObject(hdc, oldPen));
231 }
232
233 void
234 RectSel(HDC hdc, short x1, short y1, short x2, short y2)
235 {
236 HBRUSH oldBrush;
237 LOGBRUSH logbrush;
238 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
239 logbrush.lbStyle = BS_HOLLOW;
240 logbrush.lbColor = 0;
241 logbrush.lbHatch = 0;
242 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
243 Rectangle(hdc, x1, y1, x2, y2);
244 DeleteObject(SelectObject(hdc, oldBrush));
245 DeleteObject(SelectObject(hdc, oldPen));
246 }
247
248 void
249 SelectionFrame(HDC hdc, int x1, int y1, int x2, int y2)
250 {
251 HBRUSH oldBrush;
252 LOGBRUSH logbrush;
253 HPEN oldPen = SelectObject(hdc, CreatePen(PS_DOT, 1, 0x00000000));
254 logbrush.lbStyle = BS_HOLLOW;
255 logbrush.lbColor = 0;
256 logbrush.lbHatch = 0;
257 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
258 Rectangle(hdc, x1, y1, x2, y2);
259 DeleteObject(SelectObject(hdc, oldBrush));
260 DeleteObject(SelectObject(hdc, oldPen));
261 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00000000));
262 oldBrush = SelectObject(hdc, CreateSolidBrush(0x00000000));
263 Rectangle(hdc, x1 - 1, y1 - 1, x1 + 2, y1 + 2);
264 Rectangle(hdc, x2 - 2, y1 - 1, x2 + 2, y1 + 2);
265 Rectangle(hdc, x1 - 1, y2 - 2, x1 + 2, y2 + 1);
266 Rectangle(hdc, x2 - 2, y2 - 2, x2 + 2, y2 + 1);
267 Rectangle(hdc, (x1 + x2) / 2 - 1, y1 - 1, (x1 + x2) / 2 + 2, y1 + 2);
268 Rectangle(hdc, (x1 + x2) / 2 - 1, y2 - 2, (x1 + x2) / 2 + 2, y2 + 1);
269 Rectangle(hdc, x1 - 1, (y1 + y2) / 2 - 1, x1 + 2, (y1 + y2) / 2 + 2);
270 Rectangle(hdc, x2 - 2, (y1 + y2) / 2 - 1, x2 + 1, (y1 + y2) / 2 + 2);
271 DeleteObject(SelectObject(hdc, oldBrush));
272 DeleteObject(SelectObject(hdc, oldPen));
273 }