ReactOS 0.4.15-dev-8434-g155a7c7
region.c File Reference
#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 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 77 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 140 of file region.c.

142{
144
145 /* root node is allocated with GpRegion */
146 if(!*element2){
147 *element2 = heap_alloc_zero(sizeof(region_element));
148 if (!*element2)
149 return OutOfMemory;
150 }
151
152 (*element2)->type = element->type;
153
154 switch (element->type)
155 {
156 case RegionDataRect:
157 (*element2)->elementdata.rect = element->elementdata.rect;
158 return Ok;
161 return Ok;
162 case RegionDataPath:
163 stat = GdipClonePath(element->elementdata.path, &(*element2)->elementdata.path);
164 if (stat == Ok) return Ok;
165 break;
166 default:
167 (*element2)->elementdata.combine.left = NULL;
168 (*element2)->elementdata.combine.right = NULL;
169
170 stat = clone_element(element->elementdata.combine.left,
171 &(*element2)->elementdata.combine.left);
172 if (stat == Ok)
173 {
174 stat = clone_element(element->elementdata.combine.right,
175 &(*element2)->elementdata.combine.right);
176 if (stat == Ok) return Ok;
177 }
178 break;
179 }
180
181 delete_element(*element2);
182 *element2 = NULL;
183 return stat;
184}
#define stat
Definition: acwin.h:99
#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:140
void delete_element(region_element *element)
Definition: gdiplus.c:455
@ RegionDataEmptyRect
@ RegionDataRect
@ RegionDataInfiniteRect
@ RegionDataPath
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
@ OutOfMemory
Definition: gdiplustypes.h:29
Definition: stat.h:55

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 189 of file region.c.

191{
192 region->node.type = mode;
193 region->node.elementdata.combine.left = left;
194 region->node.elementdata.combine.right = right;
195 region->num_children += 2;
196}
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
union region_element::@410 elementdata
struct region_element::@410::@411 combine

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

◆ GdipCloneRegion()

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

Definition at line 211 of file region.c.

212{
214
215 TRACE("%p %p\n", region, clone);
216
217 if (!(region && clone))
218 return InvalidParameter;
219
220 *clone = heap_alloc_zero(sizeof(GpRegion));
221 if (!*clone)
222 return OutOfMemory;
223 element = &(*clone)->node;
224
225 (*clone)->num_children = region->num_children;
226 return clone_element(&region->node, &element);
227}
@ InvalidParameter
Definition: gdiplustypes.h:28
#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 232 of file region.c.

233{
234 GpRegion *path_region;
237
238 TRACE("%p %p %d\n", region, path, mode);
239
240 if (!(region && path))
241 return InvalidParameter;
242
243 stat = GdipCreateRegionPath(path, &path_region);
244 if (stat != Ok)
245 return stat;
246
247 /* simply replace region data */
249 delete_element(&region->node);
250 memcpy(region, path_region, sizeof(GpRegion));
251 heap_free(path_region);
252 return Ok;
253 }
254
255 left = heap_alloc_zero(sizeof(region_element));
256 if (left)
257 {
258 *left = region->node;
259 stat = clone_element(&path_region->node, &right);
260 if (stat == Ok)
261 {
262 fuse_region(region, left, right, mode);
263 GdipDeleteRegion(path_region);
264 return Ok;
265 }
266 }
267 else
269
271 GdipDeleteRegion(path_region);
272 return stat;
273}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void fuse_region(GpRegion *region, region_element *left, region_element *right, const CombineMode mode)
Definition: region.c:189
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
Definition: region.c:425
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
Definition: region.c:571
@ CombineModeReplace
Definition: gdiplusenums.h:351
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

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

◆ GdipCombineRegionRect()

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

Definition at line 278 of file region.c.

280{
281 GpRegion *rect_region;
284
285 TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode);
286
287 if (!(region && rect))
288 return InvalidParameter;
289
290 stat = GdipCreateRegionRect(rect, &rect_region);
291 if (stat != Ok)
292 return stat;
293
294 /* simply replace region data */
296 delete_element(&region->node);
297 memcpy(region, rect_region, sizeof(GpRegion));
298 heap_free(rect_region);
299 return Ok;
300 }
301
302 left = heap_alloc_zero(sizeof(region_element));
303 if (left)
304 {
305 memcpy(left, &region->node, sizeof(region_element));
306 stat = clone_element(&rect_region->node, &right);
307 if (stat == Ok)
308 {
309 fuse_region(region, left, right, mode);
310 GdipDeleteRegion(rect_region);
311 return Ok;
312 }
313 }
314 else
316
318 GdipDeleteRegion(rect_region);
319 return stat;
320}
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
Definition: region.c:459
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:476
& rect
Definition: startmenu.cpp:1413

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 325 of file region.c.

327{
328 GpRectF rectf;
329
330 TRACE("%p %p %d\n", region, rect, mode);
331
332 if (!rect)
333 return InvalidParameter;
334
335 rectf.X = (REAL)rect->X;
336 rectf.Y = (REAL)rect->Y;
337 rectf.Height = (REAL)rect->Height;
338 rectf.Width = (REAL)rect->Width;
339
340 return GdipCombineRegionRect(region, &rectf, mode);
341}
float REAL
Definition: types.h:41
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode)
Definition: region.c:278
REAL Height
Definition: gdiplustypes.h:664
REAL X
Definition: gdiplustypes.h:661
REAL Width
Definition: gdiplustypes.h:663
REAL Y
Definition: gdiplustypes.h:662

Referenced by 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 heap_free(reg2copy);
366 return Ok;
367 }
368
369 left = heap_alloc_zero(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 {
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:211

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

◆ GdipCreateRegion()

◆ GdipCreateRegionHrgn()

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

Definition at line 506 of file region.c.

507{
508 DWORD size;
510 LPRECT rect;
512 GpPath* path;
514 DWORD i;
515
516 TRACE("(%p, %p)\n", hrgn, region);
517
518 if(!region || !(size = GetRegionData(hrgn, 0, NULL)))
519 return InvalidParameter;
520
521 buf = heap_alloc_zero(size);
522 if(!buf)
523 return OutOfMemory;
524
525 if(!GetRegionData(hrgn, size, buf)){
526 heap_free(buf);
527 return GenericError;
528 }
529
530 if(buf->rdh.nCount == 0){
531 if((stat = GdipCreateRegion(&local)) != Ok){
532 heap_free(buf);
533 return stat;
534 }
535 if((stat = GdipSetEmpty(local)) != Ok){
536 heap_free(buf);
538 return stat;
539 }
540 *region = local;
541 heap_free(buf);
542 return Ok;
543 }
544
546 heap_free(buf);
547 return stat;
548 }
549
550 rect = (LPRECT)buf->Buffer;
551 for(i = 0; i < buf->rdh.nCount; i++){
552 if((stat = GdipAddPathRectangle(path, (REAL)rect->left, (REAL)rect->top,
553 (REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){
554 heap_free(buf);
556 return stat;
557 }
558 rect++;
559 }
560
561 stat = GdipCreateRegionPath(path, region);
562
563 heap_free(buf);
565 return stat;
566}
static HRGN hrgn
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:1359
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:27
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
#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 = heap_alloc_zero(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_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("%p, %p\n", rect, region);
465
466 if (!(rect && region))
467 return InvalidParameter;
468
469 *region = heap_alloc_zero(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_get_set_clip(), and test_gethrgn().

◆ 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 rectf.X = (REAL)rect->X;
496 rectf.Y = (REAL)rect->Y;
497 rectf.Width = (REAL)rect->Width;
498 rectf.Height = (REAL)rect->Height;
499
500 return GdipCreateRegionRect(&rectf, region);
501}

Referenced by test_getregiondata().

◆ GdipCreateRegionRgnData()

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

Definition at line 946 of file region.c.

947{
949 struct memory_buffer mbuf;
951 INT count;
952
953 TRACE("(%p, %d, %p)\n", data, size, region);
954
955 if (!data || !size)
956 return InvalidParameter;
957
959
962 return InvalidParameter;
963
964 status = GdipCreateRegion(region);
965 if (status != Ok)
966 return status;
967
968 count = 0;
969 status = read_element(&mbuf, *region, &(*region)->node, &count);
970 if (status == Ok && !count)
972
973 if (status != Ok)
974 {
975 GdipDeleteRegion(*region);
976 *region = NULL;
977 }
978
979 return status;
980}
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
Definition: region.c:775
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:89
Definition: ps.c:97
int32_t INT
Definition: typedefs.h:58

Referenced by test_GdipCreateRegionRgnData(), and test_region_data().

◆ GdipDeleteRegion()

◆ GdipGetRegionBounds()

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

Definition at line 587 of file region.c.

588{
589 HRGN hrgn;
590 RECT r;
592
593 TRACE("(%p, %p, %p)\n", region, graphics, rect);
594
595 if(!region || !graphics || !rect)
596 return InvalidParameter;
597
598 /* Contrary to MSDN, native ignores the graphics transform. */
599 status = GdipGetRegionHRgn(region, NULL, &hrgn);
600 if(status != Ok)
601 return status;
602
603 /* infinite */
604 if(!hrgn){
605 rect->X = rect->Y = -(REAL)(1 << 22);
606 rect->Width = rect->Height = (REAL)(1 << 23);
607 TRACE("%p => infinite\n", region);
608 return Ok;
609 }
610
611 if(GetRgnBox(hrgn, &r)){
612 rect->X = r.left;
613 rect->Y = r.top;
614 rect->Width = r.right - r.left;
615 rect->Height = r.bottom - r.top;
616 TRACE("%p => %s\n", region, debugstr_rectf(rect));
617 }
618 else
620
622
623 return status;
624}
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1194
pKey DeleteObject()
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
int WINAPI GetRgnBox(_In_ HRGN, _Out_ LPRECT)

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 629 of file region.c.

630{
631 GpRectF rectf;
633
634 TRACE("(%p, %p, %p)\n", region, graphics, rect);
635
636 if(!rect)
637 return InvalidParameter;
638
639 status = GdipGetRegionBounds(region, graphics, &rectf);
640 if(status == Ok){
641 rect->X = gdip_round(rectf.X);
642 rect->Y = gdip_round(rectf.Y);
643 rect->Width = gdip_round(rectf.Width);
644 rect->Height = gdip_round(rectf.Height);
645 }
646
647 return status;
648}
GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
Definition: region.c:587
static INT gdip_round(REAL x)

Referenced by GdipGetClipBoundsI().

◆ GdipGetRegionData()

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

Definition at line 747 of file region.c.

749{
751 UINT required;
752
753 TRACE("%p, %p, %d, %p\n", region, buffer, size, needed);
754
755 if (!region || !buffer || !size)
756 return InvalidParameter;
757
758 required = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
759 if (size < required)
760 {
761 if (needed) *needed = size;
762 return InsufficientBuffer;
763 }
764
768
769 if (needed)
770 *needed = required;
771
772 return Ok;
773}
DWORD write_region_data(const GpRegion *region, void *data)
Definition: region.c:696
@ InsufficientBuffer
Definition: gdiplustypes.h:31
GLuint buffer
Definition: glext.h:5915
unsigned int UINT
Definition: ndis.h:50
DWORD checksum
Definition: region.c:88
#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 985 of file region.c.

986{
987 TRACE("%p, %p\n", region, needed);
988
989 if (!(region && needed))
990 return InvalidParameter;
991
992 /* header.size doesn't count header.size and header.checksum */
993 *needed = FIELD_OFFSET(struct region_data_header, header) + write_region_data(region, NULL);
994
995 return Ok;
996}

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 1194 of file region.c.

1195{
1196 TRACE("(%p, %p, %p)\n", region, graphics, hrgn);
1197
1198 if (!region || !hrgn)
1199 return InvalidParameter;
1200
1201 return get_region_hrgn(&region->node, graphics, hrgn);
1202}
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1062

Referenced by GDI32_GdipFillRegion(), GdipGetRegionBounds(), GdipIsEqualRegion(), GdipIsVisiblePathPoint(), GdipIsVisibleRegionPoint(), GdipIsVisibleRegionRect(), get_clip_hrgn(), get_region_scans_data(), 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 1656 of file region.c.

1657{
1658 GpStatus stat;
1659 DWORD i;
1661 RECT *rects;
1662
1663 if (!region || !count || !matrix)
1664 return InvalidParameter;
1665
1667
1668 if (stat == Ok)
1669 {
1670 *count = data->rdh.nCount;
1671 rects = (RECT*)data->Buffer;
1672
1673 if (scans)
1674 {
1675 for (i=0; i<data->rdh.nCount; i++)
1676 {
1677 scans[i].X = rects[i].left;
1678 scans[i].Y = rects[i].top;
1679 scans[i].Width = rects[i].right - rects[i].left;
1680 scans[i].Height = rects[i].bottom - rects[i].top;
1681 }
1682 }
1683
1684 heap_free(data);
1685 }
1686
1687 return Ok;
1688}
static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
Definition: region.c:1542
GLuint GLenum matrix
Definition: glext.h:9407
if(dx< 0)
Definition: linetemp.h:194
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306

Referenced by test_excludeinfinite(), and test_scans().

◆ GdipGetRegionScansCount()

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

Definition at line 1601 of file region.c.

1602{
1603 GpStatus stat;
1605
1606 TRACE("(%p, %p, %p)\n", region, count, matrix);
1607
1608 if (!region || !count || !matrix)
1609 return InvalidParameter;
1610
1612
1613 if (stat == Ok)
1614 {
1615 *count = data->rdh.nCount;
1616 heap_free(data);
1617 }
1618
1619 return stat;
1620}

Referenced by test_excludeinfinite(), and test_scans().

◆ GdipGetRegionScansI()

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

Definition at line 1622 of file region.c.

1623{
1624 GpStatus stat;
1625 DWORD i;
1627 RECT *rects;
1628
1629 if (!region || !count || !matrix)
1630 return InvalidParameter;
1631
1633
1634 if (stat == Ok)
1635 {
1636 *count = data->rdh.nCount;
1637 rects = (RECT*)data->Buffer;
1638
1639 if (scans)
1640 {
1641 for (i=0; i<data->rdh.nCount; i++)
1642 {
1643 scans[i].X = rects[i].left;
1644 scans[i].Y = rects[i].top;
1645 scans[i].Width = rects[i].right - rects[i].left;
1646 scans[i].Height = rects[i].bottom - rects[i].top;
1647 }
1648 }
1649
1650 heap_free(data);
1651 }
1652
1653 return Ok;
1654}
INT Width
Definition: gdiplustypes.h:671
INT Height
Definition: gdiplustypes.h:672
INT X
Definition: gdiplustypes.h:669
INT Y
Definition: gdiplustypes.h:670

Referenced by test_scans().

◆ GdipIsEmptyRegion()

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

Definition at line 1204 of file region.c.

1205{
1207 GpRectF rect;
1208
1209 TRACE("(%p, %p, %p)\n", region, graphics, res);
1210
1211 if(!region || !graphics || !res)
1212 return InvalidParameter;
1213
1214 status = GdipGetRegionBounds(region, graphics, &rect);
1215 if (status != Ok) return status;
1216
1217 *res = rect.Width == 0.0 && rect.Height == 0.0;
1218 TRACE("=> %d\n", *res);
1219
1220 return Ok;
1221}
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 1226 of file region.c.

1228{
1229 HRGN hrgn1, hrgn2;
1230 GpStatus stat;
1231
1232 TRACE("(%p, %p, %p, %p)\n", region, region2, graphics, res);
1233
1234 if(!region || !region2 || !graphics || !res)
1235 return InvalidParameter;
1236
1237 stat = GdipGetRegionHRgn(region, graphics, &hrgn1);
1238 if(stat != Ok)
1239 return stat;
1240 stat = GdipGetRegionHRgn(region2, graphics, &hrgn2);
1241 if(stat != Ok){
1242 DeleteObject(hrgn1);
1243 return stat;
1244 }
1245
1246 *res = EqualRgn(hrgn1, hrgn2);
1247
1248 /* one of GpRegions is infinite */
1249 if(*res == ERROR)
1250 *res = (!hrgn1 && !hrgn2);
1251
1252 DeleteObject(hrgn1);
1254
1255 return Ok;
1256}
static HRGN hrgn2
#define ERROR(name)
Definition: error_private.h:53
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 1261 of file region.c.

1262{
1263 /* I think graphics is ignored here */
1264 TRACE("(%p, %p, %p)\n", region, graphics, res);
1265
1266 if(!region || !graphics || !res)
1267 return InvalidParameter;
1268
1269 *res = (region->node.type == RegionDataInfiniteRect);
1270
1271 return Ok;
1272}

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 1320 of file region.c.

1321{
1322 HRGN hrgn;
1323 GpStatus stat;
1324
1325 TRACE("(%p, %.2f, %.2f, %p, %p)\n", region, x, y, graphics, res);
1326
1327 if(!region || !res)
1328 return InvalidParameter;
1329
1330 if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
1331 return stat;
1332
1333 /* infinite */
1334 if(!hrgn){
1335 *res = TRUE;
1336 return Ok;
1337 }
1338
1340
1342
1343 return Ok;
1344}
#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(), and test_isvisiblepoint().

◆ GdipIsVisibleRegionPointI()

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

Definition at line 1349 of file region.c.

1350{
1351 TRACE("(%p, %d, %d, %p, %p)\n", region, x, y, graphics, res);
1352
1353 return GdipIsVisibleRegionPoint(region, (REAL)x, (REAL)y, graphics, res);
1354}
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion *region, REAL x, REAL y, GpGraphics *graphics, BOOL *res)
Definition: region.c:1320

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 1277 of file region.c.

1278{
1279 HRGN hrgn;
1280 GpStatus stat;
1281 RECT rect;
1282
1283 TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %p, %p)\n", region, x, y, w, h, graphics, res);
1284
1285 if(!region || !res)
1286 return InvalidParameter;
1287
1288 if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
1289 return stat;
1290
1291 /* infinite */
1292 if(!hrgn){
1293 *res = TRUE;
1294 return Ok;
1295 }
1296
1297 SetRect(&rect, ceilr(x), ceilr(y), ceilr(x + w), ceilr(y + h));
1298 *res = RectInRegion(hrgn, &rect);
1299
1301
1302 return Ok;
1303}
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 1308 of file region.c.

1309{
1310 TRACE("(%p, %d, %d, %d, %d, %p, %p)\n", region, x, y, w, h, graphics, res);
1311 if(!region || !res)
1312 return InvalidParameter;
1313
1314 return GdipIsVisibleRegionRect(region, (REAL)x, (REAL)y, (REAL)w, (REAL)h, graphics, res);
1315}
GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion *region, REAL x, REAL y, REAL w, REAL h, GpGraphics *graphics, BOOL *res)
Definition: region.c:1277

Referenced by test_isvisiblerect().

◆ GdipSetEmpty()

◆ GdipSetInfinite()

GpStatus WINGDIPAPI GdipSetInfinite ( GpRegion region)

Definition at line 1374 of file region.c.

1375{
1376 GpStatus stat;
1377
1378 TRACE("%p\n", region);
1379
1380 if (!region)
1381 return InvalidParameter;
1382
1383 delete_element(&region->node);
1385
1386 return stat;
1387}

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

◆ GdipTransformRegion()

GpStatus WINGDIPAPI GdipTransformRegion ( GpRegion region,
GpMatrix matrix 
)

Definition at line 1480 of file region.c.

1481{
1482 TRACE("(%p, %p)\n", region, matrix);
1483
1484 if (!region || !matrix)
1485 return InvalidParameter;
1486
1487 return transform_region_element(&region->node, matrix);
1488}
static GpStatus transform_region_element(region_element *element, GpMatrix *matrix)
Definition: region.c:1390

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 1520 of file region.c.

1521{
1522 TRACE("(%p, %f, %f)\n", region, dx, dy);
1523
1524 if(!region)
1525 return InvalidParameter;
1526
1527 translate_region_element(&region->node, dx, dy);
1528
1529 return Ok;
1530}
static void translate_region_element(region_element *element, REAL dx, REAL dy)
Definition: region.c:1491
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97

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

◆ GdipTranslateRegionI()

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

Definition at line 1535 of file region.c.

1536{
1537 TRACE("(%p, %d, %d)\n", region, dx, dy);
1538
1539 return GdipTranslateRegion(region, (REAL)dx, (REAL)dy);
1540}
GpStatus WINGDIPAPI GdipTranslateRegion(GpRegion *region, REAL dx, REAL dy)
Definition: region.c:1520

◆ get_element_size()

static INT get_element_size ( const region_element element)
inlinestatic

Definition at line 106 of file region.c.

107{
108 INT needed = sizeof(DWORD); /* DWORD for the type */
109 switch(element->type)
110 {
111 case RegionDataRect:
112 return needed + sizeof(GpRect);
113 case RegionDataPath:
114 {
115 needed += write_path_data(element->elementdata.path, NULL);
116 needed += sizeof(DWORD); /* Extra DWORD for path size */
117 return needed;
118 }
121 return needed;
122 default:
123 needed += get_element_size(element->elementdata.combine.left);
124 needed += get_element_size(element->elementdata.combine.right);
125 return needed;
126 }
127
128 return 0;
129}
static INT get_element_size(const region_element *element)
Definition: region.c:106
DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN
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 998 of file region.c.

999{
1000 HDC new_hdc=NULL;
1001 GpGraphics *new_graphics=NULL;
1002 GpStatus stat;
1003 INT save_state;
1004
1005 if (!path->pathdata.Count) /* PathToRegion doesn't support empty paths */
1006 {
1007 *hrgn = CreateRectRgn( 0, 0, 0, 0 );
1008 return *hrgn ? Ok : OutOfMemory;
1009 }
1010
1011 if (!graphics)
1012 {
1013 new_hdc = CreateCompatibleDC(0);
1014 if (!new_hdc)
1015 return OutOfMemory;
1016
1017 stat = GdipCreateFromHDC(new_hdc, &new_graphics);
1018 graphics = new_graphics;
1019 if (stat != Ok)
1020 {
1021 DeleteDC(new_hdc);
1022 return stat;
1023 }
1024 }
1025 else if (!graphics->hdc)
1026 {
1027 graphics->hdc = new_hdc = CreateCompatibleDC(0);
1028 if (!new_hdc)
1029 return OutOfMemory;
1030 }
1031
1032 save_state = SaveDC(graphics->hdc);
1033 EndPath(graphics->hdc);
1034
1035 SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE
1036 : WINDING));
1037
1038 gdi_transform_acquire(graphics);
1039
1040 stat = trace_path(graphics, path);
1041 if (stat == Ok)
1042 {
1043 *hrgn = PathToRegion(graphics->hdc);
1044 stat = *hrgn ? Ok : OutOfMemory;
1045 }
1046
1047 gdi_transform_release(graphics);
1048
1049 RestoreDC(graphics->hdc, save_state);
1050 if (new_hdc)
1051 {
1052 DeleteDC(new_hdc);
1053 if (new_graphics)
1054 GdipDeleteGraphics(new_graphics);
1055 else
1056 graphics->hdc = NULL;
1057 }
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:2395
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2581
GpStatus gdi_transform_acquire(GpGraphics *graphics)
Definition: graphics.c:6842
GpStatus gdi_transform_release(GpGraphics *graphics)
Definition: graphics.c:6856
GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN
Definition: graphics.c:2087
static HDC
Definition: imagelist.c:92
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_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 = NULL;
1121 return Ok;
1122 }
1123 }
1124
1125 stat = get_region_hrgn(element->elementdata.combine.right, graphics, &right);
1126 if (stat != Ok)
1127 {
1129 *hrgn = NULL;
1130 return stat;
1131 }
1132
1133 if (right == NULL)
1134 {
1135 /* new region is infinite */
1136 switch (element->type)
1137 {
1139 *hrgn = left;
1140 return Ok;
1142 right = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
1143 break;
1146 *hrgn = NULL;
1147 return Ok;
1148 }
1149 }
1150
1151 switch (element->type)
1152 {
1155 break;
1156 case CombineModeUnion:
1158 break;
1159 case CombineModeXor:
1161 break;
1162 case CombineModeExclude:
1164 break;
1167 break;
1168 default:
1169 ret = ERROR;
1170 }
1171
1173
1174 if (ret == ERROR)
1175 {
1177 *hrgn = NULL;
1178 return GenericError;
1179 }
1180
1181 *hrgn = left;
1182 return Ok;
1183 }
1184 default:
1185 FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type);
1186 *hrgn = NULL;
1187 return NotImplemented;
1188 }
1189}
#define FIXME(fmt,...)
Definition: precomp.h:53
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:998
@ CombineModeUnion
Definition: gdiplusenums.h:353
@ CombineModeComplement
Definition: gdiplusenums.h:356
@ CombineModeIntersect
Definition: gdiplusenums.h:352
@ CombineModeExclude
Definition: gdiplusenums.h:355
@ CombineModeXor
Definition: gdiplusenums.h:354
@ NotImplemented
Definition: gdiplustypes.h:32
int ret
#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 1542 of file region.c.

1543{
1544 GpRegion *region_copy;
1545 GpStatus stat;
1546 HRGN hrgn;
1547 DWORD data_size;
1548
1549 stat = GdipCloneRegion(region, &region_copy);
1550
1551 if (stat == Ok)
1552 {
1553 stat = GdipTransformRegion(region_copy, matrix);
1554
1555 if (stat == Ok)
1556 stat = GdipGetRegionHRgn(region_copy, NULL, &hrgn);
1557
1558 if (stat == Ok)
1559 {
1560 if (hrgn)
1561 {
1562 data_size = GetRegionData(hrgn, 0, NULL);
1563
1564 *data = heap_alloc_zero(data_size);
1565
1566 if (*data)
1567 GetRegionData(hrgn, data_size, *data);
1568 else
1569 stat = OutOfMemory;
1570
1572 }
1573 else
1574 {
1575 data_size = sizeof(RGNDATAHEADER) + sizeof(RECT);
1576
1577 *data = heap_alloc_zero(data_size);
1578
1579 if (*data)
1580 {
1581 (*data)->rdh.dwSize = sizeof(RGNDATAHEADER);
1582 (*data)->rdh.iType = RDH_RECTANGLES;
1583 (*data)->rdh.nCount = 1;
1584 (*data)->rdh.nRgnSize = sizeof(RECT);
1585 (*data)->rdh.rcBound.left = (*data)->rdh.rcBound.top = -0x400000;
1586 (*data)->rdh.rcBound.right = (*data)->rdh.rcBound.bottom = 0x400000;
1587
1588 memcpy((*data)->Buffer, &(*data)->rdh.rcBound, sizeof(RECT));
1589 }
1590 else
1591 stat = OutOfMemory;
1592 }
1593 }
1594
1595 GdipDeleteRegion(region_copy);
1596 }
1597
1598 return stat;
1599}
struct _RGNDATAHEADER RGNDATAHEADER
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
Definition: region.c:1480
#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 132 of file region.c.

133{
134 region->node.type = type;
135 region->num_children = 0;
136
137 return Ok;
138}
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 775 of file region.c.

776{
778 const DWORD *type;
779
780 type = buffer_read(mbuf, sizeof(*type));
781 if (!type) return Ok;
782
783 TRACE("type %#x\n", *type);
784
785 node->type = *type;
786
787 switch (node->type)
788 {
791 case CombineModeUnion:
792 case CombineModeXor:
795 {
797
798 left = heap_alloc_zero(sizeof(region_element));
799 if (!left) return OutOfMemory;
800 right = heap_alloc_zero(sizeof(region_element));
801 if (!right)
802 {
804 return OutOfMemory;
805 }
806
807 status = read_element(mbuf, region, left, count);
808 if (status == Ok)
809 {
810 status = read_element(mbuf, region, right, count);
811 if (status == Ok)
812 {
813 node->elementdata.combine.left = left;
814 node->elementdata.combine.right = right;
815 region->num_children += 2;
816 return Ok;
817 }
818 }
819
822 return status;
823 }
824
825 case RegionDataRect:
826 {
827 const GpRectF *rc;
828
829 rc = buffer_read(mbuf, sizeof(*rc));
830 if (!rc)
831 {
832 ERR("failed to read rect data\n");
833 return InvalidParameter;
834 }
835
836 node->elementdata.rect = *rc;
837 *count += 1;
838 return Ok;
839 }
840
841 case RegionDataPath:
842 {
843 GpPath *path;
844 const struct path_header *path_header;
845 const BYTE *types;
846
847 path_header = buffer_read(mbuf, sizeof(*path_header));
848 if (!path_header)
849 {
850 ERR("failed to read path header\n");
851 return InvalidParameter;
852 }
854 {
855 ERR("invalid path header magic %#x\n", path_header->magic);
856 return InvalidParameter;
857 }
858
859 /* Windows always fails to create an empty path in a region */
860 if (!path_header->count)
861 {
862 TRACE("refusing to create an empty path in a region\n");
863 return GenericError;
864 }
865
867 if (status) return status;
868
869 node->elementdata.path = path;
870
872 return OutOfMemory;
873
874 path->pathdata.Count = path_header->count;
875
877 FIXME("unhandled path flags %#x\n", path_header->flags);
878
880 {
881 const packed_point *pt;
882 DWORD i;
883
884 pt = buffer_read(mbuf, sizeof(*pt) * path_header->count);
885 if (!pt)
886 {
887 ERR("failed to read packed %u path points\n", path_header->count);
888 return InvalidParameter;
889 }
890
891 for (i = 0; i < path_header->count; i++)
892 {
893 path->pathdata.Points[i].X = (REAL)pt[i].X;
894 path->pathdata.Points[i].Y = (REAL)pt[i].Y;
895 }
896 }
897 else
898 {
899 const GpPointF *ptf;
900
901 ptf = buffer_read(mbuf, sizeof(*ptf) * path_header->count);
902 if (!ptf)
903 {
904 ERR("failed to read %u path points\n", path_header->count);
905 return InvalidParameter;
906 }
907 memcpy(path->pathdata.Points, ptf, sizeof(*ptf) * path_header->count);
908 }
909
911 if (!types)
912 {
913 ERR("failed to read %u path types\n", path_header->count);
914 return InvalidParameter;
915 }
916 memcpy(path->pathdata.Types, types, path_header->count);
917 if (path_header->count & 3)
918 {
919 if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
920 {
921 ERR("failed to read rounding %u bytes\n", 4 - (path_header->count & 3));
922 return InvalidParameter;
923 }
924 }
925
926 *count += 1;
927 return Ok;
928 }
929
932 *count += 1;
933 return Ok;
934
935 default:
936 FIXME("element type %#x is not supported\n", *type);
937 break;
938 }
939
940 return InvalidParameter;
941}
#define ERR(fmt,...)
Definition: precomp.h:57
#define Y(I)
#define FLAGS_INTPATH
Definition: region.c:77
#define pt(x, y)
Definition: drawing.c:79
BOOL lengthen_path(GpPath *path, INT len)
Definition: gdiplus.c:405
DWORD magic
Definition: region.c:95
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 1390 of file region.c.

1391{
1392 GpStatus stat;
1393
1394 switch(element->type)
1395 {
1398 return Ok;
1399 case RegionDataRect:
1400 {
1401 GpRegion *new_region;
1402 GpPath *path;
1403
1404 if (matrix->matrix[1] == 0.0 && matrix->matrix[2] == 0.0)
1405 {
1406 GpPointF points[2];
1407
1408 points[0].X = element->elementdata.rect.X;
1409 points[0].Y = element->elementdata.rect.Y;
1410 points[1].X = element->elementdata.rect.X + element->elementdata.rect.Width;
1411 points[1].Y = element->elementdata.rect.Y + element->elementdata.rect.Height;
1412
1414 if (stat != Ok)
1415 return stat;
1416
1417 if (points[0].X > points[1].X)
1418 {
1419 REAL temp;
1420 temp = points[0].X;
1421 points[0].X = points[1].X;
1422 points[1].X = temp;
1423 }
1424
1425 if (points[0].Y > points[1].Y)
1426 {
1427 REAL temp;
1428 temp = points[0].Y;
1429 points[0].Y = points[1].Y;
1430 points[1].Y = temp;
1431 }
1432
1433 element->elementdata.rect.X = points[0].X;
1434 element->elementdata.rect.Y = points[0].Y;
1435 element->elementdata.rect.Width = points[1].X - points[0].X;
1436 element->elementdata.rect.Height = points[1].Y - points[0].Y;
1437 return Ok;
1438 }
1439
1440 /* We can't rotate/shear a rectangle, so convert it to a path. */
1442 if (stat == Ok)
1443 {
1445 element->elementdata.rect.X, element->elementdata.rect.Y,
1446 element->elementdata.rect.Width, element->elementdata.rect.Height);
1447
1448 if (stat == Ok)
1449 stat = GdipCreateRegionPath(path, &new_region);
1450
1452 }
1453
1454 if (stat == Ok)
1455 {
1456 /* Steal the element from the created region. */
1457 memcpy(element, &new_region->node, sizeof(region_element));
1458 heap_free(new_region);
1459 }
1460 else
1461 return stat;
1462 }
1463 /* Fall-through to do the actual conversion. */
1464 case RegionDataPath:
1465 if (!element->elementdata.path->pathdata.Count)
1466 return Ok;
1467
1469 element->elementdata.path->pathdata.Points,
1470 element->elementdata.path->pathdata.Count);
1471 return stat;
1472 default:
1473 stat = transform_region_element(element->elementdata.combine.left, matrix);
1474 if (stat == Ok)
1475 stat = transform_region_element(element->elementdata.combine.right, matrix);
1476 return stat;
1477 }
1478}
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:363
GLsizei const GLfloat * points
Definition: glext.h:8112
static calc_node_t temp
Definition: rpn_ieee.c:38
REAL X
Definition: gdiplustypes.h:648

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 1491 of file region.c.

1492{
1493 INT i;
1494
1495 switch(element->type)
1496 {
1499 return;
1500 case RegionDataRect:
1501 element->elementdata.rect.X += dx;
1502 element->elementdata.rect.Y += dy;
1503 return;
1504 case RegionDataPath:
1505 for(i = 0; i < element->elementdata.path->pathdata.Count; i++){
1506 element->elementdata.path->pathdata.Points[i].X += dx;
1507 element->elementdata.path->pathdata.Points[i].Y += dy;
1508 }
1509 return;
1510 default:
1511 translate_region_element(element->elementdata.combine.left, dx, dy);
1512 translate_region_element(element->elementdata.combine.right, dx, dy);
1513 return;
1514 }
1515}

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 650 of file region.c.

651{
653 (*offset)++;
654}
#define write
Definition: acwin.h:97
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 662 of file region.c.

664{
665 write_dword(buffer, filled, element->type);
666 switch (element->type)
667 {
670 case CombineModeUnion:
671 case CombineModeXor:
674 write_element(element->elementdata.combine.left, buffer, filled);
675 write_element(element->elementdata.combine.right, buffer, filled);
676 break;
677 case RegionDataRect:
678 write_float(buffer, filled, element->elementdata.rect.X);
679 write_float(buffer, filled, element->elementdata.rect.Y);
680 write_float(buffer, filled, element->elementdata.rect.Width);
681 write_float(buffer, filled, element->elementdata.rect.Height);
682 break;
683 case RegionDataPath:
684 {
685 DWORD size = write_path_data(element->elementdata.path, buffer + *filled + 1);
686 write_dword(buffer, filled, size);
687 *filled += size / sizeof(DWORD);
688 break;
689 }
692 break;
693 }
694}
static void write_element(const region_element *element, DWORD *buffer, INT *filled)
Definition: region.c:662
static void write_float(DWORD *location, INT *offset, const FLOAT write)
Definition: region.c:656
static void write_dword(DWORD *location, INT *offset, const DWORD write)
Definition: region.c:650

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 656 of file region.c.

657{
658 ((FLOAT*)location)[*offset] = write;
659 (*offset)++;
660}
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 696 of file region.c.

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

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