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, x2, y1, 0);
75  gdi_SetPixel(hdc, x1, y1, 0);
76  gdi_SetPixel(hdc, x1, y2, 0);
77  gdi_SetPixel(hdc, x2, y2, 0);
78  e2 = 2 * e;
79 
80  if (e2 >= dx)
81  {
82  x1++;
83  x2--;
84  e += dx += c;
85  }
86 
87  if (e2 <= dy)
88  {
89  y1++;
90  y2--;
91  e += dy += a;
92  }
93  } while (x1 <= x2);
94 
95  while (y1 - y2 < b)
96  {
97  gdi_SetPixel(hdc, x1 - 1, ++y1, 0);
98  gdi_SetPixel(hdc, x1 - 1, --y2, 0);
99  }
100 }
101 
114 BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
115 {
116  Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
117  return TRUE;
118 }
119 
131 BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_RECT rect, HGDI_BRUSH hbr)
132 {
133  UINT32 color = 0;
134  UINT32 dstColor = 0;
135  BOOL monochrome = FALSE;
136  INT32 nXDest = 0;
137  INT32 nYDest = 0;
138  INT32 nWidth = 0;
139  INT32 nHeight = 0;
140  const BYTE* srcp = NULL;
141  DWORD formatSize = 0;
142  gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight);
143 
144  if (!hdc || !hbr)
145  return FALSE;
146 
147  if (!gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL))
148  return TRUE;
149 
150  switch (hbr->style)
151  {
152  case GDI_BS_SOLID:
153  color = hbr->color;
154 
155  for (INT32 x = 0; x < nWidth; x++)
156  {
157  BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest);
158 
159  if (dstp)
160  FreeRDPWriteColor(dstp, hdc->format, color);
161  }
162 
163  srcp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest);
164  formatSize = FreeRDPGetBytesPerPixel(hdc->format);
165 
166  for (INT32 y = 1; y < nHeight; y++)
167  {
168  BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
169  memcpy(dstp, srcp, 1ull * nWidth * formatSize);
170  }
171 
172  break;
173 
174  case GDI_BS_HATCHED:
175  case GDI_BS_PATTERN:
176  monochrome = (hbr->pattern->format == PIXEL_FORMAT_MONO);
177  formatSize = FreeRDPGetBytesPerPixel(hbr->pattern->format);
178 
179  for (INT32 y = 0; y < nHeight; y++)
180  {
181  for (INT32 x = 0; x < nWidth; x++)
182  {
183  const size_t yOffset =
184  ((1ULL * nYDest + y) * hbr->pattern->width % hbr->pattern->height) *
185  formatSize;
186  const size_t xOffset = ((1ULL * nXDest + x) % hbr->pattern->width) * formatSize;
187  const BYTE* patp = &hbr->pattern->data[yOffset + xOffset];
188 
189  if (monochrome)
190  {
191  if (*patp == 0)
192  dstColor = hdc->bkColor;
193  else
194  dstColor = hdc->textColor;
195  }
196  else
197  {
198  dstColor = FreeRDPReadColor(patp, hbr->pattern->format);
199  dstColor =
200  FreeRDPConvertColor(dstColor, hbr->pattern->format, hdc->format, NULL);
201  }
202 
203  BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest + x, nYDest + y);
204  if (dstp)
205  FreeRDPWriteColor(dstp, hdc->format, dstColor);
206  }
207  }
208 
209  break;
210 
211  default:
212  break;
213  }
214 
215  if (!gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight))
216  return FALSE;
217 
218  return TRUE;
219 }
220 
229 BOOL gdi_Polygon(HGDI_DC hdc, GDI_POINT* lpPoints, int nCount)
230 {
231  WLog_ERR(TAG, "Not implemented!");
232  return FALSE;
233 }
234 
244 BOOL gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT* lpPoints, int* lpPolyCounts, int nCount)
245 {
246  WLog_ERR(TAG, "Not implemented!");
247  return FALSE;
248 }
249 
250 BOOL gdi_Rectangle(HGDI_DC hdc, INT32 nXDst, INT32 nYDst, INT32 nWidth, INT32 nHeight)
251 {
252  UINT32 color = 0;
253 
254  if (!gdi_ClipCoords(hdc, &nXDst, &nYDst, &nWidth, &nHeight, NULL, NULL))
255  return TRUE;
256 
257  color = hdc->textColor;
258 
259  for (INT32 y = 0; y < nHeight; y++)
260  {
261  BYTE* dstLeft = gdi_get_bitmap_pointer(hdc, nXDst, nYDst + y);
262  BYTE* dstRight = gdi_get_bitmap_pointer(hdc, nXDst + nWidth - 1, nYDst + y);
263 
264  if (dstLeft)
265  FreeRDPWriteColor(dstLeft, hdc->format, color);
266 
267  if (dstRight)
268  FreeRDPWriteColor(dstRight, hdc->format, color);
269  }
270 
271  for (INT32 x = 0; x < nWidth; x++)
272  {
273  BYTE* dstTop = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst);
274  BYTE* dstBottom = gdi_get_bitmap_pointer(hdc, nXDst + x, nYDst + nHeight - 1);
275 
276  if (dstTop)
277  FreeRDPWriteColor(dstTop, hdc->format, color);
278 
279  if (dstBottom)
280  FreeRDPWriteColor(dstBottom, hdc->format, color);
281  }
282 
283  return FALSE;
284 }