2 * FreeRDP: A Remote Desktop Protocol Client
5 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
24 #include <freerdp/api.h>
25 #include <freerdp/freerdp.h>
26 #include <freerdp/gdi/gdi.h>
28 #include <freerdp/gdi/region.h>
31 * Create a region from rectangular coordinates.\n
35 * @param nRightRect x2
36 * @param nBottomRect y2
40 HGDI_RGN gdi_CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
42 HGDI_RGN hRgn = (HGDI_RGN) malloc(sizeof(GDI_RGN));
43 hRgn->objectType = GDIOBJECT_REGION;
46 hRgn->w = nRightRect - nLeftRect + 1;
47 hRgn->h = nBottomRect - nTopRect + 1;
53 * Create a new rectangle.
58 * @return new rectangle
61 HGDI_RECT gdi_CreateRect(int xLeft, int yTop, int xRight, int yBottom)
63 HGDI_RECT hRect = (HGDI_RECT) malloc(sizeof(GDI_RECT));
64 hRect->objectType = GDIOBJECT_RECT;
67 hRect->right = xRight;
68 hRect->bottom = yBottom;
73 * Convert a rectangle to a region.
74 * @param rect source rectangle
75 * @param rgn destination region
78 INLINE void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn)
82 rgn->w = rect->right - rect->left + 1;
83 rgn->h = rect->bottom - rect->top + 1;
87 * Convert rectangular coordinates to a region.
92 * @param rgn destination region
95 INLINE void gdi_CRectToRgn(int left, int top, int right, int bottom, HGDI_RGN rgn)
99 rgn->w = right - left + 1;
100 rgn->h = bottom - top + 1;
104 * Convert a rectangle to region coordinates.
105 * @param rect source rectangle
112 INLINE void gdi_RectToCRgn(HGDI_RECT rect, int *x, int *y, int *w, int *h)
116 *w = rect->right - rect->left + 1;
117 *h = rect->bottom - rect->top + 1;
121 * Convert rectangular coordinates to region coordinates.
132 INLINE void gdi_CRectToCRgn(int left, int top, int right, int bottom, int *x, int *y, int *w, int *h)
136 *w = right - left + 1;
137 *h = bottom - top + 1;
141 * Convert a region to a rectangle.
142 * @param rgn source region
143 * @param rect destination rectangle
146 INLINE void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect)
150 rect->right = rgn->x + rgn->w - 1;
151 rect->bottom = rgn->y + rgn->h - 1;
155 * Convert region coordinates to a rectangle.
160 * @param rect destination rectangle
163 INLINE void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect)
167 rect->right = x + w - 1;
168 rect->bottom = y + h - 1;
172 * Convert a region to rectangular coordinates.
173 * @param rgn source region
180 INLINE void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom)
184 *right = rgn->x + rgn->w - 1;
185 *bottom = rgn->y + rgn->h - 1;
189 * Convert region coordinates to rectangular coordinates.
200 INLINE void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom)
209 * Check if copying would involve overlapping regions
213 * @param height height
214 * @param srcx source x1
215 * @param srcy source y1
216 * @return 1 if there is an overlap, 0 otherwise
219 INLINE int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy)
224 gdi_CRgnToRect(x, y, width, height, &dst);
225 gdi_CRgnToRect(srcx, srcy, width, height, &src);
227 return (dst.right > src.left && dst.left < src.right &&
228 dst.bottom > src.top && dst.top < src.bottom) ? 1 : 0;
232 * Set the coordinates of a given rectangle.\n
234 * @param rc rectangle
239 * @return 1 if successful, 0 otherwise
242 INLINE int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom)
247 rc->bottom = yBottom;
252 * Set the coordinates of a given region.
256 * @param nWidth width
257 * @param nHeight height
261 INLINE int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight)
272 * Convert rectangular coordinates to a region
273 * @param hRgn destination region
274 * @param nLeftRect x1
276 * @param nRightRect x2
277 * @param nBottomRect y2
281 INLINE int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
283 gdi_CRectToRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, hRgn);
289 * Compare two regions for equality.\n
291 * @param hSrcRgn1 first region
292 * @param hSrcRgn2 second region
293 * @return 1 if both regions are equal, 0 otherwise
296 INLINE int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2)
298 if ((hSrcRgn1->x == hSrcRgn2->x) &&
299 (hSrcRgn1->y == hSrcRgn2->y) &&
300 (hSrcRgn1->w == hSrcRgn2->w) &&
301 (hSrcRgn1->h == hSrcRgn2->h))
310 * Copy coordinates from a rectangle to another rectangle
311 * @param dst destination rectangle
312 * @param src source rectangle
313 * @return 1 if successful, 0 otherwise
316 INLINE int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src)
318 dst->left = src->left;
320 dst->right = src->right;
321 dst->bottom = src->bottom;
326 * Check if a point is inside a rectangle.\n
328 * @param rc rectangle
329 * @param x point x position
330 * @param y point y position
331 * @return 1 if the point is inside, 0 otherwise
334 INLINE int gdi_PtInRect(HGDI_RECT rc, int x, int y)
337 * points on the left and top sides are considered in,
338 * while points on the right and bottom sides are considered out
341 if (x >= rc->left && x <= rc->right)
343 if (y >= rc->top && y <= rc->bottom)
353 * Invalidate a given region, such that it is redrawn on the next region update.\n
355 * @param hdc device context
363 INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h)
370 if (hdc->hwnd == NULL)
373 if (hdc->hwnd->invalid == NULL)
376 cinvalid = hdc->hwnd->cinvalid;
378 if (hdc->hwnd->ninvalid + 1 > hdc->hwnd->count)
380 hdc->hwnd->count *= 2;
381 cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count));
384 gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h);
385 hdc->hwnd->cinvalid = cinvalid;
387 invalid = hdc->hwnd->invalid;
399 gdi_CRgnToRect(x, y, w, h, &rgn);
400 gdi_RgnToRect(invalid, &inv);
408 if (rgn.left < inv.left)
411 if (rgn.top < inv.top)
414 if (rgn.right > inv.right)
415 inv.right = rgn.right;
417 if (rgn.bottom > inv.bottom)
418 inv.bottom = rgn.bottom;
420 gdi_RectToRgn(&inv, invalid);