FreeRDP
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 
42 static 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 
123 BOOL 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 
140 BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_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 
244 BOOL gdi_Polygon(HGDI_DC hdc, GDI_POINT* lpPoints, int nCount)
245 {
246  WLog_ERR(TAG, "Not implemented!");
247  return FALSE;
248 }
249 
259 BOOL gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT* lpPoints, int* lpPolyCounts, int nCount)
260 {
261  WLog_ERR(TAG, "Not implemented!");
262  return FALSE;
263 }
264 
265 BOOL gdi_Rectangle(HGDI_DC hdc, INT32 nXDst, INT32 nYDst, INT32 nWidth, INT32 nHeight)
266 {
267  UINT32 color = 0;
268 
269  if (!gdi_ClipCoords(hdc, &nXDst, &nYDst, &nWidth, &nHeight, NULL, NULL))
270  return TRUE;
271 
272  color = hdc->textColor;
273 
274  for (INT32 y = 0; y < nHeight; y++)
275  {
276  BYTE* dstLeft = gdi_get_bitmap_pointer(hdc, nXDst, nYDst + y);
277  BYTE* dstRight = gdi_get_bitmap_pointer(hdc, nXDst + nWidth - 1, nYDst + y);
278 
279  if (dstLeft)
280  FreeRDPWriteColor(dstLeft, hdc->format, color);
281 
282  if (dstRight)
283  FreeRDPWriteColor(dstRight, hdc->format, color);
284  }
285 
286  for (INT32 x = 0; x < nWidth; x++)
287  {
288  BYTE* dstTop = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst);
289  BYTE* dstBottom = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst + nHeight - 1);
290 
291  if (dstTop)
292  FreeRDPWriteColor(dstTop, hdc->format, color);
293 
294  if (dstBottom)
295  FreeRDPWriteColor(dstBottom, hdc->format, color);
296  }
297 
298  return FALSE;
299 }