ReactOS 0.4.17-dev-243-g1369312
region.c File Reference
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "objbase.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
Include dependency graph for region.c:

Go to the source code of this file.

Classes

struct  region_header
 
struct  region_data_header
 
struct  path_header
 
struct  packed_point
 

Macros

#define FLAGS_INTPATH   0x4000
 

Typedefs

typedef struct packed_point packed_point
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (gdiplus)
 
static void get_region_bounding_box (struct region_element *element, REAL *min_x, REAL *min_y, REAL *max_x, REAL *max_y, BOOL *empty, BOOL *infinite)
 
static INT get_element_size (const region_element *element)
 
static GpStatus init_region (GpRegion *region, const RegionType type)
 
static GpStatus clone_element (const region_element *element, region_element **element2)
 
static void fuse_region (GpRegion *region, region_element *left, region_element *right, const CombineMode mode)
 
GpStatus WINGDIPAPI GdipCloneRegion (GpRegion *region, GpRegion **clone)
 
GpStatus WINGDIPAPI GdipCombineRegionPath (GpRegion *region, GpPath *path, CombineMode mode)
 
GpStatus WINGDIPAPI GdipCombineRegionRect (GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode)
 
GpStatus WINGDIPAPI GdipCombineRegionRectI (GpRegion *region, GDIPCONST GpRect *rect, CombineMode mode)
 
GpStatus WINGDIPAPI GdipCombineRegionRegion (GpRegion *region1, GpRegion *region2, CombineMode mode)
 
GpStatus WINGDIPAPI GdipCreateRegion (GpRegion **region)
 
GpStatus WINGDIPAPI GdipCreateRegionPath (GpPath *path, GpRegion **region)
 
GpStatus WINGDIPAPI GdipCreateRegionRect (GDIPCONST GpRectF *rect, GpRegion **region)
 
GpStatus WINGDIPAPI GdipCreateRegionRectI (GDIPCONST GpRect *rect, GpRegion **region)
 
GpStatus WINGDIPAPI GdipCreateRegionHrgn (HRGN hrgn, GpRegion **region)
 
GpStatus WINGDIPAPI GdipDeleteRegion (GpRegion *region)
 
GpStatus WINGDIPAPI GdipGetRegionBounds (GpRegion *region, GpGraphics *graphics, GpRectF *rect)
 
GpStatus WINGDIPAPI GdipGetRegionBoundsI (GpRegion *region, GpGraphics *graphics, GpRect *rect)
 
static void write_dword (DWORD *location, INT *offset, const DWORD write)
 
static void write_float (DWORD *location, INT *offset, const FLOAT write)
 
static void write_element (const region_element *element, DWORD *buffer, INT *filled)
 
DWORD write_region_data (const GpRegion *region, void *data)
 
GpStatus WINGDIPAPI GdipGetRegionData (GpRegion *region, BYTE *buffer, UINT size, UINT *needed)
 
static GpStatus read_element (struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
 
GpStatus WINGDIPAPI GdipCreateRegionRgnData (GDIPCONST BYTE *data, INT size, GpRegion **region)
 
GpStatus WINGDIPAPI GdipGetRegionDataSize (GpRegion *region, UINT *needed)
 
static GpStatus get_path_hrgn (GpPath *path, GpGraphics *graphics, HRGN *hrgn)
 
static GpStatus get_region_hrgn (struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
 
GpStatus WINGDIPAPI GdipGetRegionHRgn (GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
 
GpStatus WINGDIPAPI GdipIsEmptyRegion (GpRegion *region, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsEqualRegion (GpRegion *region, GpRegion *region2, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsInfiniteRegion (GpRegion *region, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsVisibleRegionRect (GpRegion *region, REAL x, REAL y, REAL w, REAL h, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsVisibleRegionRectI (GpRegion *region, INT x, INT y, INT w, INT h, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint (GpRegion *region, REAL x, REAL y, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipIsVisibleRegionPointI (GpRegion *region, INT x, INT y, GpGraphics *graphics, BOOL *res)
 
GpStatus WINGDIPAPI GdipSetEmpty (GpRegion *region)
 
GpStatus WINGDIPAPI GdipSetInfinite (GpRegion *region)
 
static GpStatus transform_region_element (region_element *element, GpMatrix *matrix)
 
GpStatus WINGDIPAPI GdipTransformRegion (GpRegion *region, GpMatrix *matrix)
 
static void translate_region_element (region_element *element, REAL dx, REAL dy)
 
GpStatus WINGDIPAPI GdipTranslateRegion (GpRegion *region, REAL dx, REAL dy)
 
GpStatus WINGDIPAPI GdipTranslateRegionI (GpRegion *region, INT dx, INT dy)
 
static GpStatus get_region_scans_data (GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
 
GpStatus WINGDIPAPI GdipGetRegionScansCount (GpRegion *region, UINT *count, GpMatrix *matrix)
 
GpStatus WINGDIPAPI GdipGetRegionScansI (GpRegion *region, GpRect *scans, INT *count, GpMatrix *matrix)
 
GpStatus WINGDIPAPI GdipGetRegionScans (GpRegion *region, GpRectF *scans, INT *count, GpMatrix *matrix)
 

Macro Definition Documentation

◆ FLAGS_INTPATH

#define FLAGS_INTPATH   0x4000

Definition at line 78 of file region.c.

Typedef Documentation

◆ packed_point

Function Documentation

◆ clone_element()

static GpStatus clone_element ( const region_element element,
region_element **  element2 
)
inlinestatic

Definition at line 144 of file region.c.

146{
148
149 /* root node is allocated with GpRegion */
150 if(!*element2){
151 *element2 = calloc(1, sizeof(region_element));
152 if (!*element2)
153 return OutOfMemory;
154 }
155
156 (*element2)->type = element->type;
157
158 switch (element->type)
159 {
160 case RegionDataRect:
161 (*element2)->elementdata.rect = element->elementdata.rect;
162 return Ok;
165 return Ok;
166 case RegionDataPath:
167 stat = GdipClonePath(element->elementdata.path, &(*element2)->elementdata.path);
168 if (stat == Ok) return Ok;
169 break;
170 default:
171 (*element2)->elementdata.combine.left = NULL;
172 (*element2)->elementdata.combine.right = NULL;
173
174 stat = clone_element(element->elementdata.combine.left,
175 &(*element2)->elementdata.combine.left);
176 if (stat == Ok)
177 {
178 stat = clone_element(element->elementdata.combine.right,
179 &(*element2)->elementdata.combine.right);
180 if (stat == Ok) return Ok;
181 }
182 break;
183 }
184
185 delete_element(*element2);
186 *element2 = NULL;
187 return stat;
188}
#define stat
Definition: acwin.h:100
#define NULL
Definition: types.h:112
GpStatus WINGDIPAPI GdipClonePath(GpPath *path, GpPath **clone)
static GpStatus clone_element(const region_element *element, region_element **element2)
Definition: region.c:144
void delete_element(region_element *element)
Definition: gdiplus.c:465
@ RegionDataEmptyRect
@ RegionDataRect
@ RegionDataInfiniteRect
@ RegionDataPath
Status
Definition: gdiplustypes.h:24
@ Ok
Definition: gdiplustypes.h:25
@ OutOfMemory
Definition: gdiplustypes.h:28
#define calloc
Definition: rosglue.h:14
Definition: stat.h:66

Referenced by clone_element(), GdipCloneRegion(), GdipCombineRegionPath(), GdipCombineRegionRect(), and GdipCombineRegionRegion().

◆ fuse_region()

static void fuse_region ( GpRegion region,
region_element left,
region_element right,
const CombineMode  mode 
)
inlinestatic

Definition at line 193 of file region.c.

195{
196 region->node.type = mode;
197 region->node.elementdata.combine.left = left;
198 region->node.elementdata.combine.right = right;
199 region->num_children += 2;
200}
GLdouble GLdouble right
Definition: glext.h:10859
GLenum mode
Definition: glext.h:6217
GLint left
Definition: glext.h:7726
region_element node
DWORD num_children
struct region_element::@405::@406 combine
union region_element::@405 elementdata

Referenced by GdipCombineRegionPath(), GdipCombineRegionRect(), and GdipCombineRegionRegion().

◆ GdipCloneRegion()

GpStatus WINGDIPAPI GdipCloneRegion ( GpRegion region,
GpRegion **  clone 
)

Definition at line 215 of file region.c.

216{
218
219 TRACE("%p %p\n", region, clone);
220
221 if (!(region && clone))
222 return InvalidParameter;
223
224 *clone = calloc(1, sizeof(GpRegion));
225 if (!*clone)
226 return OutOfMemory;
227 element = &(*clone)->node;
228
229 (*clone)->num_children = region->num_children;
230 return clone_element(&region->node, &element);
231}
@ InvalidParameter
Definition: gdiplustypes.h:27
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by GdipCombineRegionRegion(), GdipGetClip(), GdipPlayMetafileRecord(), GdipSetClipRegion(), get_clip_hrgn(), get_region_scans_data(), init_container(), restore_container(), and SOFTWARE_GdipFillRegion().

◆ GdipCombineRegionPath()

GpStatus WINGDIPAPI GdipCombineRegionPath ( GpRegion region,
GpPath path,
CombineMode  mode 
)

Definition at line 236 of file region.c.

237{
238 GpRegion *path_region;
241
242 TRACE("%p %p %d\n", region, path, mode);
243
244 if (!(region && path))
245 return InvalidParameter;
246
247 stat = GdipCreateRegionPath(path, &path_region);
248 if (stat != Ok)
249 return stat;
250
251 /* simply replace region data */
253 delete_element(&region->node);
254 memcpy(region, path_region, sizeof(GpRegion));
255 free(path_region);
256 return Ok;
257 }
258
259 left = malloc(sizeof(region_element));
260 if (left)
261 {
262 *left = region->node;
263 stat = clone_element(&path_region->node, &right);
264 if (stat == Ok)
265 {
266 fuse_region(region, left, right, mode);
267 GdipDeleteRegion(path_region);
268 return Ok;
269 }
270 }
271 else
273
274 free(left);
275 GdipDeleteRegion(path_region);
276 return stat;
277}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
static void fuse_region(GpRegion *region, region_element *left, region_element *right, const CombineMode mode)
Definition: region.c:193
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
Definition: region.c:425
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
Definition: region.c:567
@ CombineModeReplace
Definition: gdiplusenums.h:388
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by GdipEnumerateMetafileSrcRectDestPoints(), GdipSetClipPath(), test_combinereplace(), test_getbounds(), test_getregiondata(), test_incombinedregion(), test_isvisiblepoint(), test_isvisiblerect(), test_transform(), and test_translate().

◆ GdipCombineRegionRect()

GpStatus WINGDIPAPI GdipCombineRegionRect ( GpRegion region,
GDIPCONST GpRectF rect,
CombineMode  mode 
)

Definition at line 282 of file region.c.

284{
285 GpRegion *rect_region;
288
289 TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode);
290
291 if (!(region && rect))
292 return InvalidParameter;
293
294 stat = GdipCreateRegionRect(rect, &rect_region);
295 if (stat != Ok)
296 return stat;
297
298 /* simply replace region data */
300 delete_element(&region->node);
301 memcpy(region, rect_region, sizeof(GpRegion));
302 free(rect_region);
303 return Ok;
304 }
305
306 left = malloc(sizeof(region_element));
307 if (left)
308 {
309 memcpy(left, &region->node, sizeof(region_element));
310 stat = clone_element(&rect_region->node, &right);
311 if (stat == Ok)
312 {
313 fuse_region(region, left, right, mode);
314 GdipDeleteRegion(rect_region);
315 return Ok;
316 }
317 }
318 else
320
321 free(left);
322 GdipDeleteRegion(rect_region);
323 return stat;
324}
RECT rect
Definition: combotst.c:67
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
Definition: region.c:459
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:486

Referenced by GdipCombineRegionRectI(), get_visible_clip_region(), measure_ranges_callback(), SOFTWARE_GdipFillRegion(), test_clipping(), test_clipping_2(), test_combinereplace(), test_excludeinfinite(), test_getbounds(), test_gethrgn(), test_isequal(), test_isvisiblepoint(), test_isvisiblerect(), test_scans(), test_transform(), and test_translate().

◆ GdipCombineRegionRectI()

GpStatus WINGDIPAPI GdipCombineRegionRectI ( GpRegion region,
GDIPCONST GpRect rect,
CombineMode  mode 
)

Definition at line 329 of file region.c.

331{
332 GpRectF rectf;
333
334 TRACE("%p %p %d\n", region, rect, mode);
335
336 if (!rect)
337 return InvalidParameter;
338
339 set_rect(&rectf, rect->X, rect->Y, rect->Width, rect->Height);
340 return GdipCombineRegionRect(region, &rectf, mode);
341}
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode)
Definition: region.c:282
static void set_rect(GpRectF *rect, REAL x, REAL y, REAL width, REAL height)

Referenced by SOFTWARE_GdipDrawThinPath(), and test_getregiondata().

◆ GdipCombineRegionRegion()

GpStatus WINGDIPAPI GdipCombineRegionRegion ( GpRegion region1,
GpRegion region2,
CombineMode  mode 
)

Definition at line 346 of file region.c.

348{
351 GpRegion *reg2copy;
352
353 TRACE("%p %p %d\n", region1, region2, mode);
354
355 if(!(region1 && region2))
356 return InvalidParameter;
357
358 /* simply replace region data */
360 stat = GdipCloneRegion(region2, &reg2copy);
361 if(stat != Ok) return stat;
362
363 delete_element(&region1->node);
364 memcpy(region1, reg2copy, sizeof(GpRegion));
365 free(reg2copy);
366 return Ok;
367 }
368
369 left = malloc(sizeof(region_element));
370 if (!left)
371 return OutOfMemory;
372
373 *left = region1->node;
374 stat = clone_element(&region2->node, &right);
375 if (stat != Ok)
376 {
377 free(left);
378 return OutOfMemory;
379 }
380
381 fuse_region(region1, left, right, mode);
382 region1->num_children += region2->num_children;
383
384 return Ok;
385}
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
Definition: region.c:215

Referenced by GdipPlayMetafileRecord(), GdipSetClipGraphics(), GdipSetClipHrgn(), GdipSetClipRect(), GdipSetClipRegion(), get_visible_clip_region(), METAFILE_PlaybackUpdateClip(), metafile_set_clip_region(), test_combinereplace(), test_getregiondata(), and test_incombinedregion().

◆ GdipCreateRegion()

◆ GdipCreateRegionHrgn()

GpStatus WINGDIPAPI GdipCreateRegionHrgn ( HRGN  hrgn,
GpRegion **  region 
)

Definition at line 502 of file region.c.

503{
504 DWORD size;
506 LPRECT rect;
508 GpPath* path;
510 DWORD i;
511
512 TRACE("(%p, %p)\n", hrgn, region);
513
514 if(!region || !(size = GetRegionData(hrgn, 0, NULL)))
515 return InvalidParameter;
516
517 buf = malloc(size);
518 if(!buf)
519 return OutOfMemory;
520
521 if(!GetRegionData(hrgn, size, buf)){
522 free(buf);
523 return GenericError;
524 }
525
526 if(buf->rdh.nCount == 0){
527 if((stat = GdipCreateRegion(&local)) != Ok){
528 free(buf);
529 return stat;
530 }
531 if((stat = GdipSetEmpty(local)) != Ok){
532 free(buf);
534 return stat;
535 }
536 *region = local;
537 free(buf);
538 return Ok;
539 }
540
542 free(buf);
543 return stat;
544 }
545
546 rect = (LPRECT)buf->Buffer;
547 for(i = 0; i < buf->rdh.nCount; i++){
549 (REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){
550 free(buf);
552 return stat;
553 }
554 rect++;
555 }
556
557 stat = GdipCreateRegionPath(path, region);
558
559 free(buf);
561 return stat;
562}
static HRGN hrgn
float REAL
Definition: types.h:41
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height)
GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *region)
Definition: region.c:1581
GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
Definition: region.c:390
unsigned long DWORD
Definition: ntddk_ex.h:95
#define local
Definition: zutil.h:30
@ FillModeAlternate
Definition: gdiplusenums.h:55
@ GenericError
Definition: gdiplustypes.h:26
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
#define LPRECT
Definition: precomp.h:28
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)

Referenced by GdipSetClipHrgn(), and test_fromhrgn().

◆ GdipCreateRegionPath()

GpStatus WINGDIPAPI GdipCreateRegionPath ( GpPath path,
GpRegion **  region 
)

Definition at line 425 of file region.c.

426{
429
430 TRACE("%p, %p\n", path, region);
431
432 if (!(path && region))
433 return InvalidParameter;
434
435 *region = calloc(1, sizeof(GpRegion));
436 if(!*region)
437 return OutOfMemory;
438 stat = init_region(*region, RegionDataPath);
439 if (stat != Ok)
440 {
441 GdipDeleteRegion(*region);
442 return stat;
443 }
444 element = &(*region)->node;
445
446 stat = GdipClonePath(path, &element->elementdata.path);
447 if (stat != Ok)
448 {
449 GdipDeleteRegion(*region);
450 return stat;
451 }
452
453 return Ok;
454}

Referenced by GdipCombineRegionPath(), GdipCreateRegionHrgn(), GdipIsVisiblePathPoint(), GdipPlayMetafileRecord(), SOFTWARE_GdipDrawThinPath(), SOFTWARE_GdipFillPath(), test_gethrgn(), test_getregiondata(), and transform_region_element().

◆ GdipCreateRegionRect()

GpStatus WINGDIPAPI GdipCreateRegionRect ( GDIPCONST GpRectF rect,
GpRegion **  region 
)

Definition at line 459 of file region.c.

461{
463
464 TRACE("%s, %p\n", debugstr_rectf(rect), region);
465
466 if (!(rect && region))
467 return InvalidParameter;
468
469 *region = calloc(1, sizeof(GpRegion));
470 stat = init_region(*region, RegionDataRect);
471 if(stat != Ok)
472 {
473 GdipDeleteRegion(*region);
474 return stat;
475 }
476
477 (*region)->node.elementdata.rect.X = rect->X;
478 (*region)->node.elementdata.rect.Y = rect->Y;
479 (*region)->node.elementdata.rect.Width = rect->Width;
480 (*region)->node.elementdata.rect.Height = rect->Height;
481
482 return Ok;
483}

Referenced by GdipCombineRegionRect(), GdipCreateRegionRectI(), GdipPlayMetafileRecord(), GdipSetClipRect(), test_clipping(), test_combinereplace(), test_fillregion(), test_get_set_clip(), test_gethrgn(), and test_incombinedregion().

◆ GdipCreateRegionRectI()

GpStatus WINGDIPAPI GdipCreateRegionRectI ( GDIPCONST GpRect rect,
GpRegion **  region 
)

Definition at line 488 of file region.c.

490{
491 GpRectF rectf;
492
493 TRACE("%p, %p\n", rect, region);
494
495 set_rect(&rectf, rect->X, rect->Y, rect->Width, rect->Height);
496 return GdipCreateRegionRect(&rectf, region);
497}

Referenced by test_getregiondata().

◆ GdipCreateRegionRgnData()

GpStatus WINGDIPAPI GdipCreateRegionRgnData ( GDIPCONST BYTE data,
INT  size,
GpRegion **  region 
)

Definition at line 939 of file region.c.

940{
942 struct memory_buffer mbuf;
944 INT count;
945
946 TRACE("(%p, %d, %p)\n", data, size, region);
947
948 if (!data || !size)
949 return InvalidParameter;
950
952
955 return InvalidParameter;
956
957 status = GdipCreateRegion(region);
958 if (status != Ok)
959 return status;
960
961 count = 0;
962 status = read_element(&mbuf, *region, &(*region)->node, &count);
963 if (status == Ok && !count)
965
966 if (status != Ok)
967 {
968 GdipDeleteRegion(*region);
969 *region = NULL;
970 }
971
972 return status;
973}
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
Definition: region.c:768
static void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
static const void * buffer_read(struct memory_buffer *mbuf, INT size)
#define VALID_MAGIC(x)
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct region_header header
Definition: region.c:90
Definition: ps.c:97
int32_t INT
Definition: typedefs.h:58

Referenced by test_GdipCreateRegionRgnData(), and test_region_data().

◆ GdipDeleteRegion()

GpStatus WINGDIPAPI GdipDeleteRegion ( GpRegion region)

◆ GdipGetRegionBounds()

GpStatus WINGDIPAPI GdipGetRegionBounds ( GpRegion region,
GpGraphics graphics,
GpRectF rect 
)

Definition at line 583 of file region.c.

584{
585 REAL min_x, min_y, max_x, max_y;
586 BOOL empty, infinite;
587
588 TRACE("(%p, %p, %p)\n", region, graphics, rect);
589
590 if(!region || !graphics || !rect)
591 return InvalidParameter;
592
593 /* Contrary to MSDN, native ignores the graphics transform. */
594 get_region_bounding_box(&region->node, &min_x, &min_y, &max_x, &max_y, &empty, &infinite);
595
596 /* infinite */
597 if(infinite){
598 rect->X = rect->Y = -(REAL)(1 << 22);
599 rect->Width = rect->Height = (REAL)(1 << 23);
600 TRACE("%p => infinite\n", region);
601 return Ok;
602 }
603
604 if(empty){
605 rect->X = rect->Y = rect->Width = rect->Height = 0.0;
606 TRACE("%p => empty\n", region);
607 return Ok;
608 }
609
610 rect->X = min_x;
611 rect->Y = min_y;
612 rect->Width = max_x - min_x;
613 rect->Height = max_y - min_y;
614 TRACE("%p => %s\n", region, debugstr_rectf(rect));
615
616 return Ok;
617}
static const WCHAR empty[1]
Definition: string.c:47
static void get_region_bounding_box(struct region_element *element, REAL *min_x, REAL *min_y, REAL *max_x, REAL *max_y, BOOL *empty, BOOL *infinite)
Definition: region.c:1330
unsigned int BOOL
Definition: ntddk_ex.h:94

Referenced by GdipGetClipBounds(), GdipGetRegionBoundsI(), GdipGetVisibleClipBounds(), GdipIsEmptyRegion(), test_clipping(), test_font_height_scaling(), test_getbounds(), and test_measure_string().

◆ GdipGetRegionBoundsI()

GpStatus WINGDIPAPI GdipGetRegionBoundsI ( GpRegion region,
GpGraphics graphics,
GpRect rect 
)

Definition at line 622 of file region.c.

623{
624 GpRectF rectf;
626
627 TRACE("(%p, %p, %p)\n", region, graphics, rect);
628
629 if(!rect)
630 return InvalidParameter;
631
632 status = GdipGetRegionBounds(region, graphics, &rectf);
633 if(status == Ok){
634 rect->X = gdip_round(rectf.X);
635 rect->Y = gdip_round(rectf.Y);
636 rect->Width = gdip_round(rectf.Width);
637 rect->Height = gdip_round(rectf.Height);
638 }
639
640 return status;
641}
GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
Definition: region.c:583
static INT gdip_round(REAL x)
REAL Height
Definition: gdiplustypes.h:659
REAL X
Definition: gdiplustypes.h:656
REAL Width
Definition: gdiplustypes.h:658
REAL Y
Definition: gdiplustypes.h:657

◆ GdipGetRegionData()

GpStatus WINGDIPAPI GdipGetRegionData ( GpRegion region,
BYTE buffer,
UINT  size,
UINT needed 
)

Definition at line 740 of file region.c.

742{
744 UINT required;
745
746 TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
747
748 if (!region || !buffer || !size)
749 return InvalidParameter;
750
751 required = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
752 if (size < required)
753 {
754 if (needed) *needed = size;
755 return InsufficientBuffer;
756 }
757
761
762 if (needed)
763 *needed = required;
764
765 return Ok;
766}
DWORD write_region_data(const GpRegion *region, void *data)
Definition: region.c:689
@ InsufficientBuffer
Definition: gdiplustypes.h:30
GLuint buffer
Definition: glext.h:5915
unsigned int UINT
Definition: ndis.h:50
DWORD checksum
Definition: region.c:89
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by get_region_type(), test_clip_xform(), test_combinereplace(), test_fromhrgn(), test_GdipCreateRegionRgnData(), test_getregiondata(), and test_region_data().

◆ GdipGetRegionDataSize()

GpStatus WINGDIPAPI GdipGetRegionDataSize ( GpRegion region,
UINT needed 
)

Definition at line 978 of file region.c.

979{
980 TRACE("%p, %p\n", region, needed);
981
982 if (!(region && needed))
983 return InvalidParameter;
984
985 /* header.size doesn't count header.size and header.checksum */
986 *needed = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
987
988 return Ok;
989}

Referenced by get_region_type(), test_combinereplace(), test_fromhrgn(), test_getregiondata(), and test_region_data().

◆ GdipGetRegionHRgn()

GpStatus WINGDIPAPI GdipGetRegionHRgn ( GpRegion region,
GpGraphics graphics,
HRGN *  hrgn 
)

Definition at line 1201 of file region.c.

1202{
1203 TRACE("(%p, %p, %p)\n", region, graphics, hrgn);
1204
1205 if (!region || !hrgn)
1206 return InvalidParameter;
1207
1208 return get_region_hrgn(&region->node, graphics, hrgn);
1209}
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1062

Referenced by GDI32_GdipFillRegion(), GdipIsEqualRegion(), GdipIsVisiblePathPoint(), GdipIsVisibleRegionPoint(), GdipIsVisibleRegionRect(), get_clip_hrgn(), get_region_scans_data(), SOFTWARE_GdipDrawThinPath(), SOFTWARE_GdipFillRegion(), test_clipping(), test_clipping_2(), and test_gethrgn().

◆ GdipGetRegionScans()

GpStatus WINGDIPAPI GdipGetRegionScans ( GpRegion region,
GpRectF scans,
INT count,
GpMatrix matrix 
)

Definition at line 1878 of file region.c.

1879{
1880 GpStatus stat;
1881 DWORD i;
1883 RECT *rects;
1884
1885 if (!region || !count || !matrix)
1886 return InvalidParameter;
1887
1889
1890 if (stat == Ok)
1891 {
1892 *count = data->rdh.nCount;
1893 rects = (RECT*)data->Buffer;
1894
1895 if (scans)
1896 {
1897 for (i=0; i<data->rdh.nCount; i++)
1898 {
1899 scans[i].X = rects[i].left;
1900 scans[i].Y = rects[i].top;
1901 scans[i].Width = rects[i].right - rects[i].left;
1902 scans[i].Height = rects[i].bottom - rects[i].top;
1903 }
1904 }
1905
1906 free(data);
1907 }
1908
1909 return Ok;
1910}
static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
Definition: region.c:1764
GLuint GLenum matrix
Definition: glext.h:9407
if(dx< 0)
Definition: linetemp.h:194

Referenced by test_excludeinfinite(), and test_scans().

◆ GdipGetRegionScansCount()

GpStatus WINGDIPAPI GdipGetRegionScansCount ( GpRegion region,
UINT count,
GpMatrix matrix 
)

Definition at line 1823 of file region.c.

1824{
1825 GpStatus stat;
1827
1828 TRACE("(%p, %p, %s)\n", region, count, debugstr_matrix(matrix));
1829
1830 if (!region || !count || !matrix)
1831 return InvalidParameter;
1832
1834
1835 if (stat == Ok)
1836 {
1837 *count = data->rdh.nCount;
1838 free(data);
1839 }
1840
1841 return stat;
1842}
const char * debugstr_matrix(const GpMatrix *matrix)
Definition: gdiplus.c:498

Referenced by test_excludeinfinite(), and test_scans().

◆ GdipGetRegionScansI()

GpStatus WINGDIPAPI GdipGetRegionScansI ( GpRegion region,
GpRect scans,
INT count,
GpMatrix matrix 
)

Definition at line 1844 of file region.c.

1845{
1846 GpStatus stat;
1847 DWORD i;
1849 RECT *rects;
1850
1851 if (!region || !count || !matrix)
1852 return InvalidParameter;
1853
1855
1856 if (stat == Ok)
1857 {
1858 *count = data->rdh.nCount;
1859 rects = (RECT*)data->Buffer;
1860
1861 if (scans)
1862 {
1863 for (i=0; i<data->rdh.nCount; i++)
1864 {
1865 scans[i].X = rects[i].left;
1866 scans[i].Y = rects[i].top;
1867 scans[i].Width = rects[i].right - rects[i].left;
1868 scans[i].Height = rects[i].bottom - rects[i].top;
1869 }
1870 }
1871
1872 free(data);
1873 }
1874
1875 return Ok;
1876}
INT Width
Definition: gdiplustypes.h:666
INT Height
Definition: gdiplustypes.h:667
INT X
Definition: gdiplustypes.h:664
INT Y
Definition: gdiplustypes.h:665

Referenced by test_scans().

◆ GdipIsEmptyRegion()

GpStatus WINGDIPAPI GdipIsEmptyRegion ( GpRegion region,
GpGraphics graphics,
BOOL res 
)

Definition at line 1211 of file region.c.

1212{
1214 GpRectF rect;
1215
1216 TRACE("(%p, %p, %p)\n", region, graphics, res);
1217
1218 if(!region || !graphics || !res)
1219 return InvalidParameter;
1220
1221 status = GdipGetRegionBounds(region, graphics, &rect);
1222 if (status != Ok) return status;
1223
1224 *res = rect.Width == 0.0 && rect.Height == 0.0;
1225 TRACE("=> %d\n", *res);
1226
1227 return Ok;
1228}
GLuint res
Definition: glext.h:9613

Referenced by GdipIsClipEmpty(), GdipIsVisibleClipEmpty(), test_fromhrgn(), test_GdipCreateRegionRgnData(), test_get_set_clip(), test_isempty(), and test_string_functions().

◆ GdipIsEqualRegion()

GpStatus WINGDIPAPI GdipIsEqualRegion ( GpRegion region,
GpRegion region2,
GpGraphics graphics,
BOOL res 
)

Definition at line 1233 of file region.c.

1235{
1236 HRGN hrgn1, hrgn2;
1237 GpStatus stat;
1238
1239 TRACE("(%p, %p, %p, %p)\n", region, region2, graphics, res);
1240
1241 if(!region || !region2 || !graphics || !res)
1242 return InvalidParameter;
1243
1244 stat = GdipGetRegionHRgn(region, graphics, &hrgn1);
1245 if(stat != Ok)
1246 return stat;
1247 stat = GdipGetRegionHRgn(region2, graphics, &hrgn2);
1248 if(stat != Ok){
1249 DeleteObject(hrgn1);
1250 return stat;
1251 }
1252
1253 *res = EqualRgn(hrgn1, hrgn2);
1254
1255 /* one of GpRegions is infinite */
1256 if(*res == ERROR)
1257 *res = (!hrgn1 && !hrgn2);
1258
1259 DeleteObject(hrgn1);
1261
1262 return Ok;
1263}
static HRGN hrgn2
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1201
#define ERROR(name)
Definition: error_private.h:53
pKey DeleteObject()
BOOL WINAPI EqualRgn(_In_ HRGN, _In_ HRGN)

Referenced by test_isequal(), test_transform(), and test_translate().

◆ GdipIsInfiniteRegion()

GpStatus WINGDIPAPI GdipIsInfiniteRegion ( GpRegion region,
GpGraphics graphics,
BOOL res 
)

Definition at line 1268 of file region.c.

1269{
1270 /* I think graphics is ignored here */
1271 TRACE("(%p, %p, %p)\n", region, graphics, res);
1272
1273 if(!region || !graphics || !res)
1274 return InvalidParameter;
1275
1276 *res = (region->node.type == RegionDataInfiniteRect);
1277
1278 return Ok;
1279}

Referenced by test_GdipCreateRegionRgnData(), test_get_set_clip(), test_isinfinite(), test_isvisiblepoint(), and test_isvisiblerect().

◆ GdipIsVisibleRegionPoint()

GpStatus WINGDIPAPI GdipIsVisibleRegionPoint ( GpRegion region,
REAL  x,
REAL  y,
GpGraphics graphics,
BOOL res 
)

Definition at line 1529 of file region.c.

1530{
1531 HRGN hrgn;
1532 GpStatus stat;
1533 REAL min_x, min_y, max_x, max_y;
1534 BOOL empty, infinite;
1535
1536 TRACE("(%p, %.2f, %.2f, %p, %p)\n", region, x, y, graphics, res);
1537
1538 if(!region || !res)
1539 return InvalidParameter;
1540
1541 x = gdip_round(x);
1542 y = gdip_round(y);
1543
1544 /* Check for cases where we can skip quantization. */
1545 get_region_bounding_box(&region->node, &min_x, &min_y, &max_x, &max_y, &empty, &infinite);
1546 if (empty || x < min_x || y < min_y || x > max_x || y > max_y)
1547 {
1548 *res = infinite;
1549 return Ok;
1550 }
1551
1552 if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
1553 return stat;
1554
1555 /* infinite */
1556 if(!hrgn){
1557 *res = TRUE;
1558 return Ok;
1559 }
1560
1561 *res = PtInRegion(hrgn, x, y);
1562
1564
1565 return Ok;
1566}
#define TRUE
Definition: types.h:120
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
BOOL WINAPI PtInRegion(_In_ HRGN, _In_ int, _In_ int)

Referenced by GdipIsVisiblePoint(), GdipIsVisibleRegionPointI(), test_incombinedregion(), and test_isvisiblepoint().

◆ GdipIsVisibleRegionPointI()

GpStatus WINGDIPAPI GdipIsVisibleRegionPointI ( GpRegion region,
INT  x,
INT  y,
GpGraphics graphics,
BOOL res 
)

Definition at line 1571 of file region.c.

1572{
1573 TRACE("(%p, %d, %d, %p, %p)\n", region, x, y, graphics, res);
1574
1575 return GdipIsVisibleRegionPoint(region, (REAL)x, (REAL)y, graphics, res);
1576}
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion *region, REAL x, REAL y, GpGraphics *graphics, BOOL *res)
Definition: region.c:1529

Referenced by test_isvisiblepoint().

◆ GdipIsVisibleRegionRect()

GpStatus WINGDIPAPI GdipIsVisibleRegionRect ( GpRegion region,
REAL  x,
REAL  y,
REAL  w,
REAL  h,
GpGraphics graphics,
BOOL res 
)

Definition at line 1284 of file region.c.

1285{
1286 HRGN hrgn;
1287 GpStatus stat;
1288 RECT rect;
1289
1290 TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %p, %p)\n", region, x, y, w, h, graphics, res);
1291
1292 if(!region || !res)
1293 return InvalidParameter;
1294
1295 if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
1296 return stat;
1297
1298 /* infinite */
1299 if(!hrgn){
1300 *res = TRUE;
1301 return Ok;
1302 }
1303
1304 SetRect(&rect, ceilr(x), ceilr(y), ceilr(x + w), ceilr(y + h));
1305 *res = RectInRegion(hrgn, &rect);
1306
1308
1309 return Ok;
1310}
static INT ceilr(REAL x)
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
BOOL WINAPI RectInRegion(_In_ HRGN, _In_ LPCRECT)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)

Referenced by GdipIsVisibleRect(), GdipIsVisibleRegionRectI(), and test_isvisiblerect().

◆ GdipIsVisibleRegionRectI()

GpStatus WINGDIPAPI GdipIsVisibleRegionRectI ( GpRegion region,
INT  x,
INT  y,
INT  w,
INT  h,
GpGraphics graphics,
BOOL res 
)

Definition at line 1315 of file region.c.

1316{
1317 TRACE("(%p, %d, %d, %d, %d, %p, %p)\n", region, x, y, w, h, graphics, res);
1318 if(!region || !res)
1319 return InvalidParameter;
1320
1321 return GdipIsVisibleRegionRect(region, (REAL)x, (REAL)y, (REAL)w, (REAL)h, graphics, res);
1322}
GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion *region, REAL x, REAL y, REAL w, REAL h, GpGraphics *graphics, BOOL *res)
Definition: region.c:1284

Referenced by test_isvisiblerect().

◆ GdipSetEmpty()

◆ GdipSetInfinite()

GpStatus WINGDIPAPI GdipSetInfinite ( GpRegion region)

Definition at line 1596 of file region.c.

1597{
1598 GpStatus stat;
1599
1600 TRACE("%p\n", region);
1601
1602 if (!region)
1603 return InvalidParameter;
1604
1605 delete_element(&region->node);
1607
1608 return stat;
1609}

Referenced by GdipResetClip(), test_gethrgn(), test_getregiondata(), and test_isequal().

◆ GdipTransformRegion()

GpStatus WINGDIPAPI GdipTransformRegion ( GpRegion region,
GpMatrix matrix 
)

Definition at line 1702 of file region.c.

1703{
1704 TRACE("(%p, %s)\n", region, debugstr_matrix(matrix));
1705
1706 if (!region || !matrix)
1707 return InvalidParameter;
1708
1709 return transform_region_element(&region->node, matrix);
1710}
static GpStatus transform_region_element(region_element *element, GpMatrix *matrix)
Definition: region.c:1612

Referenced by GdipGetClip(), GdipGetVisibleClipBounds(), GdipSetClipHrgn(), GdipSetClipRect(), GdipSetClipRegion(), get_clip_hrgn(), get_region_scans_data(), metafile_set_clip_region(), SOFTWARE_GdipFillRegion(), test_clipping(), test_getregiondata(), and test_transform().

◆ GdipTranslateRegion()

GpStatus WINGDIPAPI GdipTranslateRegion ( GpRegion region,
REAL  dx,
REAL  dy 
)

Definition at line 1742 of file region.c.

1743{
1744 TRACE("(%p, %f, %f)\n", region, dx, dy);
1745
1746 if(!region)
1747 return InvalidParameter;
1748
1749 translate_region_element(&region->node, dx, dy);
1750
1751 return Ok;
1752}
static void translate_region_element(region_element *element, REAL dx, REAL dy)
Definition: region.c:1713
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97

Referenced by GdipTranslateClip(), GdipTranslateRegionI(), test_getregiondata(), and test_translate().

◆ GdipTranslateRegionI()

GpStatus WINGDIPAPI GdipTranslateRegionI ( GpRegion region,
INT  dx,
INT  dy 
)

Definition at line 1757 of file region.c.

1758{
1759 TRACE("(%p, %d, %d)\n", region, dx, dy);
1760
1761 return GdipTranslateRegion(region, (REAL)dx, (REAL)dy);
1762}
GpStatus WINGDIPAPI GdipTranslateRegion(GpRegion *region, REAL dx, REAL dy)
Definition: region.c:1742

◆ get_element_size()

static INT get_element_size ( const region_element element)
inlinestatic

Definition at line 110 of file region.c.

111{
112 INT needed = sizeof(DWORD); /* DWORD for the type */
113 switch(element->type)
114 {
115 case RegionDataRect:
116 return needed + sizeof(GpRect);
117 case RegionDataPath:
118 {
119 needed += write_path_data(element->elementdata.path, NULL);
120 needed += sizeof(DWORD); /* Extra DWORD for path size */
121 return needed;
122 }
125 return needed;
126 default:
127 needed += get_element_size(element->elementdata.combine.left);
128 needed += get_element_size(element->elementdata.combine.right);
129 return needed;
130 }
131
132 return 0;
133}
static INT get_element_size(const region_element *element)
Definition: region.c:110
DWORD write_path_data(GpPath *path, void *data)
Rect GpRect
#define DWORD
Definition: nt_native.h:44

Referenced by get_element_size(), and write_region_data().

◆ get_path_hrgn()

static GpStatus get_path_hrgn ( GpPath path,
GpGraphics graphics,
HRGN *  hrgn 
)
static

Definition at line 991 of file region.c.

992{
993 HDC new_hdc=NULL, hdc;
994 GpGraphics *new_graphics=NULL;
996 INT save_state;
997
998 if (!path->pathdata.Count) /* PathToRegion doesn't support empty paths */
999 {
1000 *hrgn = CreateRectRgn( 0, 0, 0, 0 );
1001 return *hrgn ? Ok : OutOfMemory;
1002 }
1003
1004 if (!graphics)
1005 {
1006 hdc = new_hdc = CreateCompatibleDC(0);
1007 if (!new_hdc)
1008 return OutOfMemory;
1009
1010 stat = GdipCreateFromHDC(new_hdc, &new_graphics);
1011 graphics = new_graphics;
1012 if (stat != Ok)
1013 {
1014 DeleteDC(new_hdc);
1015 return stat;
1016 }
1017 }
1018 else if (has_gdi_dc(graphics))
1019 {
1020 stat = gdi_dc_acquire(graphics, &hdc);
1021 if (stat != Ok)
1022 return stat;
1023 }
1024 else
1025 {
1026 graphics->hdc = hdc = new_hdc = CreateCompatibleDC(0);
1027 if (!new_hdc)
1028 return OutOfMemory;
1029 }
1030
1031 save_state = SaveDC(hdc);
1032 EndPath(hdc);
1033
1035
1036 gdi_transform_acquire(graphics);
1037
1038 stat = trace_path(graphics, path);
1039 if (stat == Ok)
1040 {
1041 *hrgn = PathToRegion(hdc);
1042 stat = *hrgn ? Ok : OutOfMemory;
1043 }
1044
1045 gdi_transform_release(graphics);
1046
1047 RestoreDC(hdc, save_state);
1048 if (new_hdc)
1049 {
1050 DeleteDC(new_hdc);
1051 if (new_graphics)
1052 GdipDeleteGraphics(new_graphics);
1053 else
1054 graphics->hdc = NULL;
1055 }
1056 else
1057 gdi_dc_release(graphics, hdc);
1058
1059 return stat;
1060}
#define WINDING
Definition: constants.h:279
#define ALTERNATE
Definition: constants.h:278
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
Definition: graphics.c:2434
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2616
void gdi_dc_release(GpGraphics *graphics, HDC hdc)
Definition: graphics.c:75
GpStatus gdi_dc_acquire(GpGraphics *graphics, HDC *hdc)
Definition: graphics.c:54
GpStatus gdi_transform_acquire(GpGraphics *graphics)
Definition: graphics.c:7228
static BOOL has_gdi_dc(GpGraphics *graphics)
GpStatus gdi_transform_release(GpGraphics *graphics)
Definition: graphics.c:7250
GpStatus trace_path(GpGraphics *graphics, GpPath *path)
Definition: graphics.c:2127
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
HRGN WINAPI PathToRegion(_In_ HDC)
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI EndPath(_In_ HDC)
int WINAPI SaveDC(_In_ HDC)
int WINAPI SetPolyFillMode(_In_ HDC, _In_ int)
Definition: dc.c:1174

Referenced by get_region_hrgn().

◆ get_region_bounding_box()

static void get_region_bounding_box ( struct region_element element,
REAL min_x,
REAL min_y,
REAL max_x,
REAL max_y,
BOOL empty,
BOOL infinite 
)
static

Definition at line 1330 of file region.c.

1332{
1333 REAL left_min_x, left_min_y, left_max_x, left_max_y;
1334 BOOL left_empty, left_infinite;
1335 REAL right_min_x, right_min_y, right_max_x, right_max_y;
1336 BOOL right_empty, right_infinite;
1337 /* For combine modes, we convert the mode to flags as follows to simplify the logic:
1338 * 0x8 = point in combined region if it's in both
1339 * 0x4 = point in combined region if it's in left and not right
1340 * 0x2 = point in combined region if it's not in left and is in right
1341 * 0x1 = point in combined region if it's in neither region */
1342 int flags;
1343 const int combine_mode_flags[] = {
1344 0xa, /* CombineModeReplace - shouldn't be used */
1345 0x8, /* CombineModeIntersect */
1346 0xe, /* CombineModeUnion */
1347 0x6, /* CombineModeXor */
1348 0x4, /* CombineModeExclude */
1349 0x2, /* CombineModeComplement */
1350 };
1351
1352 /* handle unit elements first */
1353 switch (element->type)
1354 {
1356 *min_x = *min_y = *max_x = *max_y = 0.0;
1357 *empty = TRUE;
1358 *infinite = TRUE;
1359 return;
1361 *min_x = *min_y = *max_x = *max_y = 0.0;
1362 *empty = TRUE;
1363 *infinite = FALSE;
1364 return;
1365 case RegionDataPath:
1366 {
1367 GpPath *path = element->elementdata.path;
1368 int i;
1369
1370 if (path->pathdata.Count <= 1) {
1371 *min_x = *min_y = *max_x = *max_y = 0.0;
1372 *empty = TRUE;
1373 *infinite = FALSE;
1374 return;
1375 }
1376
1377 *min_x = *max_x = path->pathdata.Points[0].X;
1378 *min_y = *max_y = path->pathdata.Points[0].Y;
1379 *empty = FALSE;
1380 *infinite = FALSE;
1381
1382 for (i=1; i < path->pathdata.Count; i++)
1383 {
1384 if (path->pathdata.Points[i].X < *min_x)
1385 *min_x = path->pathdata.Points[i].X;
1386 else if (path->pathdata.Points[i].X > *max_x)
1387 *max_x = path->pathdata.Points[i].X;
1388 if (path->pathdata.Points[i].Y < *min_y)
1389 *min_y = path->pathdata.Points[i].Y;
1390 else if (path->pathdata.Points[i].Y > *max_y)
1391 *max_y = path->pathdata.Points[i].Y;
1392 }
1393
1394 return;
1395 }
1396 case RegionDataRect:
1397 *min_x = element->elementdata.rect.X;
1398 *min_y = element->elementdata.rect.Y;
1399 *max_x = element->elementdata.rect.X + element->elementdata.rect.Width;
1400 *max_y = element->elementdata.rect.Y + element->elementdata.rect.Height;
1401 *empty = FALSE;
1402 *infinite = FALSE;
1403 return;
1404 }
1405
1406 /* Should be only combine modes left */
1407 assert(element->type < ARRAY_SIZE(combine_mode_flags));
1408
1409 flags = combine_mode_flags[element->type];
1410
1411 get_region_bounding_box(element->elementdata.combine.left,
1412 &left_min_x, &left_min_y, &left_max_x, &left_max_y, &left_empty, &left_infinite);
1413
1414 if (left_infinite)
1415 {
1416 /* change our function so we can ignore the infinity */
1417 flags = ((flags & 0x3) << 2) | ((flags & 0xc) >> 2);
1418 }
1419
1420 if (left_empty && (flags & 0x3) == 0) {
1421 /* no points in region regardless of right region, return empty */
1422 *empty = TRUE;
1423 *infinite = FALSE;
1424 return;
1425 }
1426
1427 if (left_empty && (flags & 0x3) == 0x3) {
1428 /* all points in region regardless of right region, return infinite */
1429 *empty = TRUE;
1430 *infinite = TRUE;
1431 return;
1432 }
1433
1434 get_region_bounding_box(element->elementdata.combine.right,
1435 &right_min_x, &right_min_y, &right_max_x, &right_max_y, &right_empty, &right_infinite);
1436
1437 if (right_infinite)
1438 {
1439 /* change our function so we can ignore the infinity */
1440 flags = ((flags & 0x5) << 1) | ((flags & 0xa) >> 1);
1441 }
1442
1443 /* result is infinite if points in neither region are in the result */
1444 *infinite = (flags & 0x1);
1445
1446 if (*infinite)
1447 {
1448 /* Again, we modify our function to ignore the infinity.
1449 * The points we care about are the ones that are different from the outside of our box,
1450 * not the points inside the region, so we invert the whole thing.
1451 * From here we can assume 0x1 is not set. */
1452 flags ^= 0xf;
1453 }
1454
1455 if (left_empty)
1456 {
1457 /* We already took care of the cases where the right region doesn't matter,
1458 * so we can just use the right bounding box. */
1459 *min_x = right_min_x;
1460 *min_y = right_min_y;
1461 *max_x = right_max_x;
1462 *max_y = right_max_y;
1463 *empty = right_empty;
1464 return;
1465 }
1466
1467 if (right_empty)
1468 {
1469 /* With no points in right region, and infinities eliminated, we only care
1470 * about flag 0x4, the case where a point is in left region and not right. */
1471 if (flags & 0x4)
1472 {
1473 /* We have a copy of the left region. */
1474 *min_x = left_min_x;
1475 *min_y = left_min_y;
1476 *max_x = left_max_x;
1477 *max_y = left_max_y;
1478 *empty = left_empty;
1479 return;
1480 }
1481 /* otherwise, it's an empty (or infinite) region */
1482 *empty = TRUE;
1483 return;
1484 }
1485
1486 /* From here we know 0x1 isn't set, and we know at least one flag is set.
1487 * We can ignore flag 0x8 because we must assume that any point within the
1488 * intersection of the bounding boxes might be within the region. */
1489 switch (flags & 0x6)
1490 {
1491 case 0x0:
1492 /* intersection */
1493 *min_x = fmaxf(left_min_x, right_min_x);
1494 *min_y = fmaxf(left_min_y, right_min_y);
1495 *max_x = fminf(left_max_x, right_max_x);
1496 *max_y = fminf(left_max_y, right_max_y);
1497 *empty = *min_x > *max_x || *min_y > *max_y;
1498 return;
1499 case 0x2:
1500 /* right (or complement) */
1501 *min_x = right_min_x;
1502 *min_y = right_min_y;
1503 *max_x = right_max_x;
1504 *max_y = right_max_y;
1505 *empty = right_empty;
1506 return;
1507 case 0x4:
1508 /* left (or exclude) */
1509 *min_x = left_min_x;
1510 *min_y = left_min_y;
1511 *max_x = left_max_x;
1512 *max_y = left_max_y;
1513 *empty = left_empty;
1514 return;
1515 case 0x6:
1516 /* union (or xor) */
1517 *min_x = fminf(left_min_x, right_min_x);
1518 *min_y = fminf(left_min_y, right_min_y);
1519 *max_x = fmaxf(left_max_x, right_max_x);
1520 *max_y = fmaxf(left_max_y, right_max_y);
1521 *empty = FALSE;
1522 return;
1523 }
1524}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FALSE
Definition: types.h:117
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP float __cdecl fmaxf(float, float)
_ACRTIMP float __cdecl fminf(float, float)
GLbitfield flags
Definition: glext.h:7161

Referenced by GdipGetRegionBounds(), GdipIsVisibleRegionPoint(), and get_region_bounding_box().

◆ get_region_hrgn()

static GpStatus get_region_hrgn ( struct region_element element,
GpGraphics graphics,
HRGN *  hrgn 
)
static

Definition at line 1062 of file region.c.

1063{
1064 switch (element->type)
1065 {
1067 *hrgn = NULL;
1068 return Ok;
1070 *hrgn = CreateRectRgn(0, 0, 0, 0);
1071 return *hrgn ? Ok : OutOfMemory;
1072 case RegionDataPath:
1073 return get_path_hrgn(element->elementdata.path, graphics, hrgn);
1074 case RegionDataRect:
1075 {
1076 GpPath* path;
1077 GpStatus stat;
1078 GpRectF* rc = &element->elementdata.rect;
1079
1081 if (stat != Ok)
1082 return stat;
1083 stat = GdipAddPathRectangle(path, rc->X, rc->Y, rc->Width, rc->Height);
1084
1085 if (stat == Ok)
1086 stat = get_path_hrgn(path, graphics, hrgn);
1087
1089
1090 return stat;
1091 }
1093 case CombineModeUnion:
1094 case CombineModeXor:
1095 case CombineModeExclude:
1097 {
1098 HRGN left, right;
1099 GpStatus stat;
1100 int ret;
1101
1102 stat = get_region_hrgn(element->elementdata.combine.left, graphics, &left);
1103 if (stat != Ok)
1104 {
1105 *hrgn = NULL;
1106 return stat;
1107 }
1108
1109 if (left == NULL)
1110 {
1111 /* existing region is infinite */
1112 switch (element->type)
1113 {
1115 return get_region_hrgn(element->elementdata.combine.right, graphics, hrgn);
1117 left = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
1118 break;
1120 *hrgn = CreateRectRgn(0, 0, 0, 0);
1121 return *hrgn ? Ok : OutOfMemory;
1122 case CombineModeUnion:
1123 *hrgn = NULL;
1124 return Ok;
1125 }
1126 }
1127
1128 stat = get_region_hrgn(element->elementdata.combine.right, graphics, &right);
1129 if (stat != Ok)
1130 {
1132 *hrgn = NULL;
1133 return stat;
1134 }
1135
1136 if (right == NULL)
1137 {
1138 /* new region is infinite */
1139 switch (element->type)
1140 {
1142 *hrgn = left;
1143 return Ok;
1145 right = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
1146 break;
1147 case CombineModeExclude:
1149 *hrgn = CreateRectRgn(0, 0, 0, 0);
1150 return *hrgn ? Ok : OutOfMemory;
1151 case CombineModeUnion:
1153 *hrgn = NULL;
1154 return Ok;
1155 }
1156 }
1157
1158 switch (element->type)
1159 {
1162 break;
1163 case CombineModeUnion:
1165 break;
1166 case CombineModeXor:
1168 break;
1169 case CombineModeExclude:
1171 break;
1174 break;
1175 default:
1176 ret = ERROR;
1177 }
1178
1180
1181 if (ret == ERROR)
1182 {
1184 *hrgn = NULL;
1185 return GenericError;
1186 }
1187
1188 *hrgn = left;
1189 return Ok;
1190 }
1191 default:
1192 FIXME("GdipGetRegionHRgn unimplemented for region type=%lx\n", element->type);
1193 *hrgn = NULL;
1194 return NotImplemented;
1195 }
1196}
#define FIXME(fmt,...)
Definition: precomp.h:53
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:991
return ret
Definition: mutex.c:146
@ CombineModeUnion
Definition: gdiplusenums.h:390
@ CombineModeComplement
Definition: gdiplusenums.h:393
@ CombineModeIntersect
Definition: gdiplusenums.h:389
@ CombineModeExclude
Definition: gdiplusenums.h:392
@ CombineModeXor
Definition: gdiplusenums.h:391
@ NotImplemented
Definition: gdiplustypes.h:31
#define RGN_DIFF
Definition: wingdi.h:358
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define RGN_AND
Definition: wingdi.h:356
#define RGN_XOR
Definition: wingdi.h:360
#define RGN_OR
Definition: wingdi.h:359

Referenced by GdipGetRegionHRgn(), and get_region_hrgn().

◆ get_region_scans_data()

static GpStatus get_region_scans_data ( GpRegion region,
GpMatrix matrix,
LPRGNDATA data 
)
static

Definition at line 1764 of file region.c.

1765{
1766 GpRegion *region_copy;
1767 GpStatus stat;
1768 HRGN hrgn;
1769 DWORD data_size;
1770
1771 stat = GdipCloneRegion(region, &region_copy);
1772
1773 if (stat == Ok)
1774 {
1775 stat = GdipTransformRegion(region_copy, matrix);
1776
1777 if (stat == Ok)
1778 stat = GdipGetRegionHRgn(region_copy, NULL, &hrgn);
1779
1780 if (stat == Ok)
1781 {
1782 if (hrgn)
1783 {
1784 data_size = GetRegionData(hrgn, 0, NULL);
1785
1786 *data = malloc(data_size);
1787
1788 if (*data)
1789 GetRegionData(hrgn, data_size, *data);
1790 else
1791 stat = OutOfMemory;
1792
1794 }
1795 else
1796 {
1797 data_size = sizeof(RGNDATAHEADER) + sizeof(RECT);
1798
1799 *data = calloc(1, data_size);
1800
1801 if (*data)
1802 {
1803 (*data)->rdh.dwSize = sizeof(RGNDATAHEADER);
1804 (*data)->rdh.iType = RDH_RECTANGLES;
1805 (*data)->rdh.nCount = 1;
1806 (*data)->rdh.nRgnSize = sizeof(RECT);
1807 (*data)->rdh.rcBound.left = (*data)->rdh.rcBound.top = -0x400000;
1808 (*data)->rdh.rcBound.right = (*data)->rdh.rcBound.bottom = 0x400000;
1809
1810 memcpy((*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
1811 }
1812 else
1813 stat = OutOfMemory;
1814 }
1815 }
1816
1817 GdipDeleteRegion(region_copy);
1818 }
1819
1820 return stat;
1821}
struct _RGNDATAHEADER RGNDATAHEADER
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
Definition: region.c:1702
#define RECT
Definition: precomp.h:26
#define RDH_RECTANGLES
Definition: wingdi.h:669

Referenced by GdipGetRegionScans(), GdipGetRegionScansCount(), and GdipGetRegionScansI().

◆ init_region()

static GpStatus init_region ( GpRegion region,
const RegionType  type 
)
inlinestatic

Definition at line 136 of file region.c.

137{
138 region->node.type = type;
139 region->num_children = 0;
140
141 return Ok;
142}
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by GdipCreateRegion(), GdipCreateRegionPath(), GdipCreateRegionRect(), GdipSetEmpty(), and GdipSetInfinite().

◆ read_element()

static GpStatus read_element ( struct memory_buffer mbuf,
GpRegion region,
region_element node,
INT count 
)
static

Definition at line 768 of file region.c.

769{
771 const DWORD *type;
772
773 type = buffer_read(mbuf, sizeof(*type));
774 if (!type) return Ok;
775
776 TRACE("type %#lx\n", *type);
777
778 node->type = *type;
779
780 switch (node->type)
781 {
784 case CombineModeUnion:
785 case CombineModeXor:
788 {
790
791 left = calloc(1, sizeof(region_element));
792 if (!left) return OutOfMemory;
793 right = calloc(1, sizeof(region_element));
794 if (!right)
795 {
796 free(left);
797 return OutOfMemory;
798 }
799
800 status = read_element(mbuf, region, left, count);
801 if (status == Ok)
802 {
803 status = read_element(mbuf, region, right, count);
804 if (status == Ok)
805 {
806 node->elementdata.combine.left = left;
807 node->elementdata.combine.right = right;
808 region->num_children += 2;
809 return Ok;
810 }
811 }
812
813 free(left);
814 free(right);
815 return status;
816 }
817
818 case RegionDataRect:
819 {
820 const GpRectF *rc;
821
822 rc = buffer_read(mbuf, sizeof(*rc));
823 if (!rc)
824 {
825 ERR("failed to read rect data\n");
826 return InvalidParameter;
827 }
828
829 node->elementdata.rect = *rc;
830 *count += 1;
831 return Ok;
832 }
833
834 case RegionDataPath:
835 {
836 GpPath *path;
837 const struct path_header *path_header;
838 const BYTE *types;
839
840 path_header = buffer_read(mbuf, sizeof(*path_header));
841 if (!path_header)
842 {
843 ERR("failed to read path header\n");
844 return InvalidParameter;
845 }
847 {
848 ERR("invalid path header magic %#lx\n", path_header->magic);
849 return InvalidParameter;
850 }
851
852 /* Windows always fails to create an empty path in a region */
853 if (!path_header->count)
854 {
855 TRACE("refusing to create an empty path in a region\n");
856 return GenericError;
857 }
858
860 if (status) return status;
861
862 node->elementdata.path = path;
863
865 return OutOfMemory;
866
867 path->pathdata.Count = path_header->count;
868
870 FIXME("unhandled path flags %#lx\n", path_header->flags);
871
873 {
874 const packed_point *pt;
875 DWORD i;
876
877 pt = buffer_read(mbuf, sizeof(*pt) * path_header->count);
878 if (!pt)
879 {
880 ERR("failed to read packed %lu path points\n", path_header->count);
881 return InvalidParameter;
882 }
883
884 for (i = 0; i < path_header->count; i++)
885 {
886 path->pathdata.Points[i].X = (REAL)pt[i].X;
887 path->pathdata.Points[i].Y = (REAL)pt[i].Y;
888 }
889 }
890 else
891 {
892 const GpPointF *ptf;
893
894 ptf = buffer_read(mbuf, sizeof(*ptf) * path_header->count);
895 if (!ptf)
896 {
897 ERR("failed to read %lu path points\n", path_header->count);
898 return InvalidParameter;
899 }
900 memcpy(path->pathdata.Points, ptf, sizeof(*ptf) * path_header->count);
901 }
902
904 if (!types)
905 {
906 ERR("failed to read %lu path types\n", path_header->count);
907 return InvalidParameter;
908 }
909 memcpy(path->pathdata.Types, types, path_header->count);
910 if (path_header->count & 3)
911 {
912 if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
913 {
914 ERR("failed to read rounding %lu bytes\n", 4 - (path_header->count & 3));
915 return InvalidParameter;
916 }
917 }
918
919 *count += 1;
920 return Ok;
921 }
922
925 *count += 1;
926 return Ok;
927
928 default:
929 FIXME("element type %#lx is not supported\n", *type);
930 break;
931 }
932
933 return InvalidParameter;
934}
#define ERR(fmt,...)
Definition: precomp.h:57
#define Y(I)
#define FLAGS_INTPATH
Definition: region.c:78
#define pt(x, y)
Definition: drawing.c:79
BOOL lengthen_path(GpPath *path, INT len)
Definition: gdiplus.c:415
DWORD magic
Definition: region.c:96
Definition: cmds.c:130
Definition: dlist.c:348
unsigned char BYTE
Definition: xxhash.c:193

Referenced by GdipCreateRegionRgnData(), and read_element().

◆ transform_region_element()

static GpStatus transform_region_element ( region_element element,
GpMatrix matrix 
)
static

Definition at line 1612 of file region.c.

1613{
1614 GpStatus stat;
1615
1616 switch(element->type)
1617 {
1620 return Ok;
1621 case RegionDataRect:
1622 {
1623 GpRegion *new_region;
1624 GpPath *path;
1625
1626 if (matrix->matrix[1] == 0.0 && matrix->matrix[2] == 0.0)
1627 {
1628 GpPointF points[2];
1629
1630 points[0].X = element->elementdata.rect.X;
1631 points[0].Y = element->elementdata.rect.Y;
1632 points[1].X = element->elementdata.rect.X + element->elementdata.rect.Width;
1633 points[1].Y = element->elementdata.rect.Y + element->elementdata.rect.Height;
1634
1636 if (stat != Ok)
1637 return stat;
1638
1639 if (points[0].X > points[1].X)
1640 {
1641 REAL temp;
1642 temp = points[0].X;
1643 points[0].X = points[1].X;
1644 points[1].X = temp;
1645 }
1646
1647 if (points[0].Y > points[1].Y)
1648 {
1649 REAL temp;
1650 temp = points[0].Y;
1651 points[0].Y = points[1].Y;
1652 points[1].Y = temp;
1653 }
1654
1655 element->elementdata.rect.X = points[0].X;
1656 element->elementdata.rect.Y = points[0].Y;
1657 element->elementdata.rect.Width = points[1].X - points[0].X;
1658 element->elementdata.rect.Height = points[1].Y - points[0].Y;
1659 return Ok;
1660 }
1661
1662 /* We can't rotate/shear a rectangle, so convert it to a path. */
1664 if (stat == Ok)
1665 {
1667 element->elementdata.rect.X, element->elementdata.rect.Y,
1668 element->elementdata.rect.Width, element->elementdata.rect.Height);
1669
1670 if (stat == Ok)
1671 stat = GdipCreateRegionPath(path, &new_region);
1672
1674 }
1675
1676 if (stat == Ok)
1677 {
1678 /* Steal the element from the created region. */
1679 memcpy(element, &new_region->node, sizeof(region_element));
1680 free(new_region);
1681 }
1682 else
1683 return stat;
1684 }
1685 /* Fall-through to do the actual conversion. */
1686 case RegionDataPath:
1687 if (!element->elementdata.path->pathdata.Count)
1688 return Ok;
1689
1691 element->elementdata.path->pathdata.Points,
1692 element->elementdata.path->pathdata.Count);
1693 return stat;
1694 default:
1695 stat = transform_region_element(element->elementdata.combine.left, matrix);
1696 if (stat == Ok)
1697 stat = transform_region_element(element->elementdata.combine.right, matrix);
1698 return stat;
1699 }
1700}
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:365
GLsizei const GLfloat * points
Definition: glext.h:8112
static calc_node_t temp
Definition: rpn_ieee.c:38
REAL X
Definition: gdiplustypes.h:643

Referenced by GdipTransformRegion(), and transform_region_element().

◆ translate_region_element()

static void translate_region_element ( region_element element,
REAL  dx,
REAL  dy 
)
static

Definition at line 1713 of file region.c.

1714{
1715 INT i;
1716
1717 switch(element->type)
1718 {
1721 return;
1722 case RegionDataRect:
1723 element->elementdata.rect.X += dx;
1724 element->elementdata.rect.Y += dy;
1725 return;
1726 case RegionDataPath:
1727 for(i = 0; i < element->elementdata.path->pathdata.Count; i++){
1728 element->elementdata.path->pathdata.Points[i].X += dx;
1729 element->elementdata.path->pathdata.Points[i].Y += dy;
1730 }
1731 return;
1732 default:
1733 translate_region_element(element->elementdata.combine.left, dx, dy);
1734 translate_region_element(element->elementdata.combine.right, dx, dy);
1735 return;
1736 }
1737}

Referenced by GdipTranslateRegion(), and translate_region_element().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( gdiplus  )

◆ write_dword()

static void write_dword ( DWORD location,
INT offset,
const DWORD  write 
)
inlinestatic

Definition at line 643 of file region.c.

644{
646 (*offset)++;
647}
#define write
Definition: acwin.h:98
GLintptr offset
Definition: glext.h:5920

Referenced by write_element().

◆ write_element()

static void write_element ( const region_element element,
DWORD buffer,
INT filled 
)
static

Definition at line 655 of file region.c.

657{
658 write_dword(buffer, filled, element->type);
659 switch (element->type)
660 {
663 case CombineModeUnion:
664 case CombineModeXor:
667 write_element(element->elementdata.combine.left, buffer, filled);
668 write_element(element->elementdata.combine.right, buffer, filled);
669 break;
670 case RegionDataRect:
671 write_float(buffer, filled, element->elementdata.rect.X);
672 write_float(buffer, filled, element->elementdata.rect.Y);
673 write_float(buffer, filled, element->elementdata.rect.Width);
674 write_float(buffer, filled, element->elementdata.rect.Height);
675 break;
676 case RegionDataPath:
677 {
678 DWORD size = write_path_data(element->elementdata.path, buffer + *filled + 1);
679 write_dword(buffer, filled, size);
680 *filled += size / sizeof(DWORD);
681 break;
682 }
685 break;
686 }
687}
static void write_element(const region_element *element, DWORD *buffer, INT *filled)
Definition: region.c:655
static void write_float(DWORD *location, INT *offset, const FLOAT write)
Definition: region.c:649
static void write_dword(DWORD *location, INT *offset, const DWORD write)
Definition: region.c:643

Referenced by write_element(), and write_region_data().

◆ write_float()

static void write_float ( DWORD location,
INT offset,
const FLOAT  write 
)
inlinestatic

Definition at line 649 of file region.c.

650{
651 ((FLOAT*)location)[*offset] = write;
652 (*offset)++;
653}
float FLOAT
Definition: typedefs.h:69

Referenced by write_element().

◆ write_region_data()

DWORD write_region_data ( const GpRegion region,
void data 
)

Definition at line 689 of file region.c.

690{
691 struct region_header *header = data;
692 INT filled = 0;
693 DWORD size;
694
695 size = sizeof(struct region_header) + get_element_size(&region->node);
696 if (!data) return size;
697
698 header->magic = VERSION_MAGIC2;
699 header->num_children = region->num_children;
700 filled += 2;
701 /* With few exceptions, everything written is DWORD aligned,
702 * so use that as our base */
703 write_element(&region->node, (DWORD*)data, &filled);
704 return size;
705}
#define VERSION_MAGIC2

Referenced by GdipGetRegionData(), GdipGetRegionDataSize(), and METAFILE_AddRegionObject().