FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
shape.c
1
22#include <freerdp/config.h>
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include <freerdp/freerdp.h>
29#include <freerdp/gdi/gdi.h>
30
31#include <freerdp/gdi/bitmap.h>
32#include <freerdp/gdi/region.h>
33#include <freerdp/gdi/shape.h>
34
35#include <freerdp/log.h>
36
37#include "clipping.h"
38#include "../gdi/gdi.h"
39
40#define TAG FREERDP_TAG("gdi.shape")
41
42static void Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2)
43{
44 INT32 e = 0;
45 INT32 e2 = 0;
46 INT32 dx = 0;
47 INT32 dy = 0;
48 INT32 a = 0;
49 INT32 b = 0;
50 INT32 c = 0;
51 a = (x1 < x2) ? x2 - x1 : x1 - x2;
52 b = (y1 < y2) ? y2 - y1 : y1 - y2;
53 c = b & 1;
54 dx = 4 * (1 - a) * b * b;
55 dy = 4 * (c + 1) * a * a;
56 e = dx + dy + c * a * a;
57
58 if (x1 > x2)
59 {
60 x1 = x2;
61 x2 += a;
62 }
63
64 if (y1 > y2)
65 y1 = y2;
66
67 y1 += (b + 1) / 2;
68 y2 = y1 - c;
69 a *= 8 * a;
70 c = 8 * b * b;
71
72 do
73 {
74 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x2),
75 WINPR_ASSERTING_INT_CAST(UINT32, y1), 0);
76 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x1),
77 WINPR_ASSERTING_INT_CAST(UINT32, y1), 0);
78 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x1),
79 WINPR_ASSERTING_INT_CAST(UINT32, y2), 0);
80 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(UINT32, x2),
81 WINPR_ASSERTING_INT_CAST(UINT32, y2), 0);
82 e2 = 2 * e;
83
84 if (e2 >= dx)
85 {
86 x1++;
87 x2--;
88 e += dx += c;
89 }
90
91 if (e2 <= dy)
92 {
93 y1++;
94 y2--;
95 e += dy += a;
96 }
97 } while (x1 <= x2);
98
99 while (y1 - y2 < b)
100 {
101 y1++;
102 y2--;
103
104 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(uint32_t, x1 - 1),
105 WINPR_ASSERTING_INT_CAST(uint32_t, y1), 0);
106 gdi_SetPixel(hdc, WINPR_ASSERTING_INT_CAST(uint32_t, x1 - 1),
107 WINPR_ASSERTING_INT_CAST(uint32_t, y2), 0);
108 }
109}
110
123BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
124{
125 Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
126 return TRUE;
127}
128
140BOOL gdi_FillRect(HGDI_DC hdc, const GDI_RECT* rect, HGDI_BRUSH hbr)
141{
142 UINT32 color = 0;
143 UINT32 dstColor = 0;
144 BOOL monochrome = FALSE;
145 INT32 nXDest = 0;
146 INT32 nYDest = 0;
147 INT32 nWidth = 0;
148 INT32 nHeight = 0;
149 const BYTE* srcp = NULL;
150 DWORD formatSize = 0;
151 gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
152
153 if (!hdc || !hbr)
154 return FALSE;
155
156 if (!gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL))
157 return TRUE;
158
159 switch (hbr->style)
160 {
161 case GDI_BS_SOLID:
162 color = hbr->color;
163
164 for (INT32 x = 0; x < nWidth; x++)
165 {
166 BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest);
167
168 if (dstp)
169 FreeRDPWriteColor(dstp, hdc->format, color);
170 }
171
172 srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
173 formatSize = FreeRDPGetBytesPerPixel(hdc->format);
174
175 for (INT32 y = 1; y < nHeight; y++)
176 {
177 BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
178 memcpy(dstp, srcp, 1ull * WINPR_ASSERTING_INT_CAST(size_t, nWidth) * formatSize);
179 }
180
181 break;
182
183 case GDI_BS_HATCHED:
184 case GDI_BS_PATTERN:
185 monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
186 formatSize = FreeRDPGetBytesPerPixel(hbr->pattern->format);
187
188 for (INT32 y = 0; y < nHeight; y++)
189 {
190 for (INT32 x = 0; x < nWidth; x++)
191 {
192 const size_t yOffset =
193 ((1ULL * WINPR_ASSERTING_INT_CAST(size_t, nYDest) +
194 WINPR_ASSERTING_INT_CAST(size_t, y)) *
195 WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->width) %
196 WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->height)) *
197 formatSize;
198 const size_t xOffset = ((1ULL * WINPR_ASSERTING_INT_CAST(size_t, nXDest) +
199 WINPR_ASSERTING_INT_CAST(size_t, x)) %
200 WINPR_ASSERTING_INT_CAST(size_t, hbr->pattern->width)) *
201 formatSize;
202 const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
203
204 if (monochrome)
205 {
206 if (*patp == 0)
207 dstColor = hdc->bkColor;
208 else
209 dstColor = hdc->textColor;
210 }
211 else
212 {
213 dstColor = FreeRDPReadColor(patp, hbr->pattern->format);
214 dstColor =
215 FreeRDPConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
216 }
217
218 BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest + y);
219 if (dstp)
220 FreeRDPWriteColor(dstp, hdc->format, dstColor);
221 }
222 }
223
224 break;
225
226 default:
227 break;
228 }
229
230 if (!gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight))
231 return FALSE;
232
233 return TRUE;
234}
235
244BOOL gdi_Polygon(WINPR_ATTR_UNUSED HGDI_DC hdc, WINPR_ATTR_UNUSED GDI_POINT* lpPoints,
245 WINPR_ATTR_UNUSED int nCount)
246{
247 WLog_ERR(TAG, "Not implemented!");
248 return FALSE;
249}
250
260BOOL gdi_PolyPolygon(WINPR_ATTR_UNUSED HGDI_DC hdc, WINPR_ATTR_UNUSED GDI_POINT* lpPoints,
261 WINPR_ATTR_UNUSED int* lpPolyCounts, WINPR_ATTR_UNUSED int nCount)
262{
263 WLog_ERR(TAG, "Not implemented!");
264 return FALSE;
265}
266
267BOOL gdi_Rectangle(HGDI_DC hdc, INT32 nXDst, INT32 nYDst, INT32 nWidth, INT32 nHeight)
268{
269 UINT32 color = 0;
270
271 if (!gdi_ClipCoords(hdc, &nXDst, &nYDst, &nWidth, &nHeight, NULL, NULL))
272 return TRUE;
273
274 color = hdc->textColor;
275
276 for (INT32 y = 0; y < nHeight; y++)
277 {
278 BYTE* dstLeft = gdi_get_bitmap_pointer(hdc, nXDst, nYDst + y);
279 BYTE* dstRight = gdi_get_bitmap_pointer(hdc, nXDst + nWidth - 1, nYDst + y);
280
281 if (dstLeft)
282 FreeRDPWriteColor(dstLeft, hdc->format, color);
283
284 if (dstRight)
285 FreeRDPWriteColor(dstRight, hdc->format, color);
286 }
287
288 for (INT32 x = 0; x < nWidth; x++)
289 {
290 BYTE* dstTop = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst);
291 BYTE* dstBottom = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst + nHeight - 1);
292
293 if (dstTop)
294 FreeRDPWriteColor(dstTop, hdc->format, color);
295
296 if (dstBottom)
297 FreeRDPWriteColor(dstBottom, hdc->format, color);
298 }
299
300 return FALSE;
301}