2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/mspaint/drawing.cpp
5 * PURPOSE: The drawing functions used by the tools
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
13 /* FUNCTIONS ********************************************************/
16 Line(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF color
, int thickness
)
18 HPEN oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_SOLID
, thickness
, color
));
19 MoveToEx(hdc
, x1
, y1
, NULL
);
21 DeleteObject(SelectObject(hdc
, oldPen
));
25 Rect(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF fg
, COLORREF bg
, int thickness
, int style
)
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
;
33 oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateBrushIndirect(&logbrush
));
34 Rectangle(hdc
, x1
, y1
, x2
, y2
);
35 DeleteObject(SelectObject(hdc
, oldBrush
));
36 DeleteObject(SelectObject(hdc
, oldPen
));
40 Ellp(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF fg
, COLORREF bg
, int thickness
, int style
)
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
;
48 oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateBrushIndirect(&logbrush
));
49 Ellipse(hdc
, x1
, y1
, x2
, y2
);
50 DeleteObject(SelectObject(hdc
, oldBrush
));
51 DeleteObject(SelectObject(hdc
, oldPen
));
55 RRect(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF fg
, COLORREF bg
, int thickness
, int style
)
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
;
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
));
70 Poly(HDC hdc
, POINT
* lpPoints
, int nCount
, COLORREF fg
, COLORREF bg
, int thickness
, int style
, BOOL closed
, BOOL inverted
)
74 HPEN oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_SOLID
, thickness
, fg
));
75 UINT oldRop
= GetROP2(hdc
);
78 SetROP2(hdc
, R2_NOTXORPEN
);
80 logbrush
.lbStyle
= (style
== 0) ? BS_HOLLOW
: BS_SOLID
;
81 logbrush
.lbColor
= (style
== 2) ? fg
: bg
;
83 oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateBrushIndirect(&logbrush
));
85 Polygon(hdc
, lpPoints
, nCount
);
87 Polyline(hdc
, lpPoints
, nCount
);
88 DeleteObject(SelectObject(hdc
, oldBrush
));
89 DeleteObject(SelectObject(hdc
, oldPen
));
95 Bezier(HDC hdc
, POINT p1
, POINT p2
, POINT p3
, POINT p4
, COLORREF color
, int thickness
)
103 oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_SOLID
, thickness
, color
));
104 PolyBezier(hdc
, fourPoints
, 4);
105 DeleteObject(SelectObject(hdc
, oldPen
));
109 Fill(HDC hdc
, LONG x
, LONG y
, COLORREF color
)
111 HBRUSH oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateSolidBrush(color
));
112 ExtFloodFill(hdc
, x
, y
, GetPixel(hdc
, x
, y
), FLOODFILLSURFACE
);
113 DeleteObject(SelectObject(hdc
, oldBrush
));
117 Erase(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF color
, LONG radius
)
121 HBRUSH oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateSolidBrush(color
));
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
++)
127 (x1
* (b
- a
) + x2
* a
) / b
- radius
,
128 (y1
* (b
- a
) + y2
* a
) / b
- radius
,
129 (x1
* (b
- a
) + x2
* a
) / b
+ radius
,
130 (y1
* (b
- a
) + y2
* a
) / b
+ radius
);
131 DeleteObject(SelectObject(hdc
, oldBrush
));
132 DeleteObject(SelectObject(hdc
, oldPen
));
136 Replace(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF fg
, COLORREF bg
, LONG radius
)
139 b
= max(1, max(abs(x2
- x1
), abs(y2
- y1
)));
141 for(a
= 0; a
<= b
; a
++)
142 for(y
= (y1
* (b
- a
) + y2
* a
) / b
- radius
+ 1;
143 y
< (y1
* (b
- a
) + y2
* a
) / b
+ radius
+ 1; y
++)
144 for(x
= (x1
* (b
- a
) + x2
* a
) / b
- radius
+ 1;
145 x
< (x1
* (b
- a
) + x2
* a
) / b
+ radius
+ 1; x
++)
146 if (GetPixel(hdc
, x
, y
) == fg
)
147 SetPixel(hdc
, x
, y
, bg
);
151 Airbrush(HDC hdc
, LONG x
, LONG y
, COLORREF color
, LONG r
)
155 for(b
= -r
; b
<= r
; b
++)
156 for(a
= -r
; a
<= r
; a
++)
157 if ((a
* a
+ b
* b
<= r
* r
) && (rand() % 4 == 0))
158 SetPixel(hdc
, x
+ a
, y
+ b
, color
);
162 Brush(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF color
, LONG style
)
164 HPEN oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_SOLID
, 1, color
));
165 HBRUSH oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateSolidBrush(color
));
167 b
= max(1, max(abs(x2
- x1
), abs(y2
- y1
)));
171 for(a
= 0; a
<= b
; a
++)
172 Ellipse(hdc
, (x1
* (b
- a
) + x2
* a
) / b
- 3, (y1
* (b
- a
) + y2
* a
) / b
- 3,
173 (x1
* (b
- a
) + x2
* a
) / b
+ 4, (y1
* (b
- a
) + y2
* a
) / b
+ 4);
176 for(a
= 0; a
<= b
; a
++)
178 (x1
* (b
- a
) + x2
* a
) / b
- 2,
179 (y1
* (b
- a
) + y2
* a
) / b
- 2,
180 (x1
* (b
- a
) + x2
* a
) / b
+ 2,
181 (y1
* (b
- a
) + y2
* a
) / b
+ 2);
184 MoveToEx(hdc
, x1
, y1
, NULL
);
186 SetPixel(hdc
, x2
, y2
, color
);
189 for(a
= 0; a
<= b
; a
++)
191 (x1
* (b
- a
) + x2
* a
) / b
- 4,
192 (y1
* (b
- a
) + y2
* a
) / b
- 4,
193 (x1
* (b
- a
) + x2
* a
) / b
+ 4,
194 (y1
* (b
- a
) + y2
* a
) / b
+ 4);
197 for(a
= 0; a
<= b
; a
++)
198 Rectangle(hdc
, (x1
* (b
- a
) + x2
* a
) / b
- 2, (y1
* (b
- a
) + y2
* a
) / b
- 2,
199 (x1
* (b
- a
) + x2
* a
) / b
+ 3, (y1
* (b
- a
) + y2
* a
) / b
+ 3);
202 for(a
= 0; a
<= b
; a
++)
203 Rectangle(hdc
, (x1
* (b
- a
) + x2
* a
) / b
- 1, (y1
* (b
- a
) + y2
* a
) / b
- 1,
204 (x1
* (b
- a
) + x2
* a
) / b
+ 1, (y1
* (b
- a
) + y2
* a
) / b
+ 1);
213 POINT offsTop
[] = {{3, -3}, {2, -2}, {0, 0},
214 {-4, -4}, {-2, -2}, {-1, 0}};
215 POINT offsBtm
[] = {{-3, 3}, {-2, 2}, {-1, 1},
216 {3, 3}, {2, 2}, {0, 1}};
217 LONG idx
= style
- 6;
219 pts
[0].x
= x1
+ offsTop
[idx
].x
;
220 pts
[0].y
= y1
+ offsTop
[idx
].y
;
221 pts
[1].x
= x1
+ offsBtm
[idx
].x
;
222 pts
[1].y
= y1
+ offsBtm
[idx
].y
;
223 pts
[2].x
= x2
+ offsBtm
[idx
].x
;
224 pts
[2].y
= y2
+ offsBtm
[idx
].y
;
225 pts
[3].x
= x2
+ offsTop
[idx
].x
;
226 pts
[3].y
= y2
+ offsTop
[idx
].y
;
227 Polygon(hdc
, pts
, 4);
231 DeleteObject(SelectObject(hdc
, oldBrush
));
232 DeleteObject(SelectObject(hdc
, oldPen
));
236 RectSel(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
)
240 HPEN oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_DOT
, 1, GetSysColor(COLOR_HIGHLIGHT
)));
241 UINT oldRop
= GetROP2(hdc
);
243 SetROP2(hdc
, R2_NOTXORPEN
);
245 logbrush
.lbStyle
= BS_HOLLOW
;
246 logbrush
.lbColor
= 0;
247 logbrush
.lbHatch
= 0;
248 oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateBrushIndirect(&logbrush
));
249 Rectangle(hdc
, x1
, y1
, x2
, y2
);
250 DeleteObject(SelectObject(hdc
, oldBrush
));
251 DeleteObject(SelectObject(hdc
, oldPen
));
253 SetROP2(hdc
, oldRop
);
257 Text(HDC hdc
, LONG x1
, LONG y1
, LONG x2
, LONG y2
, COLORREF fg
, COLORREF bg
, LPCTSTR lpchText
, HFONT font
, LONG style
)
259 INT iSaveDC
= SaveDC(hdc
); // We will modify the clipping region. Save now.
262 SetRect(&rc
, x1
, y1
, x2
, y2
);
264 if (style
== 0) // Transparent
266 SetBkMode(hdc
, TRANSPARENT
);
271 SetBkMode(hdc
, OPAQUE
);
274 HBRUSH hbr
= CreateSolidBrush(bg
);
275 FillRect(hdc
, &rc
, hbr
); // Fill the background
279 IntersectClipRect(hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
281 HGDIOBJ hFontOld
= SelectObject(hdc
, font
);
282 SetTextColor(hdc
, fg
);
283 const UINT uFormat
= DT_LEFT
| DT_TOP
| DT_EDITCONTROL
| DT_NOPREFIX
| DT_NOCLIP
|
284 DT_EXPANDTABS
| DT_WORDBREAK
;
285 DrawText(hdc
, lpchText
, -1, &rc
, uFormat
);
286 SelectObject(hdc
, hFontOld
);
288 RestoreDC(hdc
, iSaveDC
); // Restore
292 ColorKeyedMaskBlt(HDC hdcDest
, int nXDest
, int nYDest
, int nWidth
, int nHeight
,
293 HDC hdcSrc
, int nXSrc
, int nYSrc
, int nSrcWidth
, int nSrcHeight
,
294 HBITMAP hbmMask
, COLORREF keyColor
)
296 HDC hTempDC1
, hTempDC2
;
297 HBITMAP hbmTempColor
, hbmTempMask
;
298 HGDIOBJ hbmOld1
, hbmOld2
;
302 if (keyColor
== CLR_INVALID
)
304 ::StretchBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
,
305 hdcSrc
, nXSrc
, nYSrc
, nSrcWidth
, nSrcHeight
, SRCCOPY
);
309 ::GdiTransparentBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
,
310 hdcSrc
, nXSrc
, nYSrc
, nSrcWidth
, nSrcHeight
, keyColor
);
314 else if (nWidth
== nSrcWidth
&& nHeight
== nSrcHeight
&& keyColor
== CLR_INVALID
)
316 ::MaskBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
,
317 hdcSrc
, nXSrc
, nYSrc
, hbmMask
, 0, 0, MAKEROP4(SRCCOPY
, 0xAA0029));
321 hTempDC1
= ::CreateCompatibleDC(hdcDest
);
322 hTempDC2
= ::CreateCompatibleDC(hdcDest
);
323 hbmTempMask
= ::CreateBitmap(nWidth
, nHeight
, 1, 1, NULL
);
324 hbmTempColor
= CreateColorDIB(nWidth
, nHeight
, RGB(255, 255, 255));
326 // hbmTempMask <-- hbmMask (stretched)
327 hbmOld1
= ::SelectObject(hTempDC1
, hbmMask
);
328 hbmOld2
= ::SelectObject(hTempDC2
, hbmTempMask
);
329 ::StretchBlt(hTempDC2
, 0, 0, nWidth
, nHeight
, hTempDC1
, 0, 0, nSrcWidth
, nSrcHeight
, SRCCOPY
);
330 ::SelectObject(hTempDC2
, hbmOld2
);
331 ::SelectObject(hTempDC1
, hbmOld1
);
333 hbmOld1
= ::SelectObject(hTempDC1
, hbmTempColor
);
334 if (keyColor
== CLR_INVALID
)
336 // hbmTempColor <-- hdcSrc (stretched)
337 ::StretchBlt(hTempDC1
, 0, 0, nWidth
, nHeight
,
338 hdcSrc
, nXSrc
, nYSrc
, nSrcWidth
, nSrcHeight
, SRCCOPY
);
340 // hdcDest <-- hbmTempColor (masked)
341 ::MaskBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hTempDC1
, 0, 0,
342 hbmTempMask
, 0, 0, MAKEROP4(SRCCOPY
, 0xAA0029));
346 // hbmTempColor <-- hdcDest
347 ::BitBlt(hTempDC1
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, SRCCOPY
);
349 // hbmTempColor <-- hdcSrc (color key)
350 ::GdiTransparentBlt(hTempDC1
, 0, 0, nWidth
, nHeight
,
351 hdcSrc
, nXSrc
, nYSrc
, nSrcWidth
, nSrcHeight
, keyColor
);
353 // hdcDest <-- hbmTempColor (masked)
354 ::MaskBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hTempDC1
, 0, 0,
355 hbmTempMask
, 0, 0, MAKEROP4(SRCCOPY
, 0xAA0029));
357 ::SelectObject(hTempDC1
, hbmOld1
);
359 ::DeleteObject(hbmTempColor
);
360 ::DeleteObject(hbmTempMask
);
361 ::DeleteDC(hTempDC2
);
362 ::DeleteDC(hTempDC1
);