ReactOS  0.4.14-dev-49-gfb4591c
region.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Google (Lei Zhang)
3  * Copyright (C) 2013 Dmitry Timoshkov
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <stdarg.h>
21 
22 #include "windef.h"
23 #include "winbase.h"
24 #include "wingdi.h"
25 
26 #include "objbase.h"
27 
28 #include "gdiplus.h"
29 #include "gdiplus_private.h"
30 #include "wine/debug.h"
31 
33 
34 /**********************************************************
35  *
36  * Data returned by GdipGetRegionData looks something like this:
37  *
38  * struct region_data_header
39  * {
40  * DWORD size; size in bytes of the data - 8.
41  * DWORD magic1; probably a checksum.
42  * DWORD magic2; always seems to be 0xdbc01001 - version?
43  * DWORD num_ops; number of combining ops * 2
44  * };
45  *
46  * Then follows a sequence of combining ops and region elements.
47  *
48  * A region element is either a RECTF or some path data.
49  *
50  * Combining ops are just stored as their CombineMode value.
51  *
52  * Each RECTF is preceded by the DWORD 0x10000000. An empty rect is
53  * stored as 0x10000002 (with no following RECTF) and an infinite rect
54  * is stored as 0x10000003 (again with no following RECTF).
55  *
56  * Path data is preceded by the DWORD 0x10000001. Then follows a
57  * DWORD size and then size bytes of data.
58  *
59  * The combining ops are stored in the reverse order to the region
60  * elements and in the reverse order to which the region was
61  * constructed.
62  *
63  * When two or more complex regions (ie those with more than one
64  * element) are combined, the combining op for the two regions comes
65  * first, then the combining ops for the region elements in region 1,
66  * followed by the region elements for region 1, then follows the
67  * combining ops for region 2 and finally region 2's region elements.
68  * Presumably you're supposed to use the 0x1000000x header to find the
69  * end of the op list (the count of the elements in each region is not
70  * stored).
71  *
72  * When a simple region (1 element) is combined, it's treated as if a
73  * single rect/path is being combined.
74  *
75  */
76 
77 #define FLAGS_INTPATH 0x4000
78 
80 {
83 };
84 
86 {
90 };
91 
92 struct path_header
93 {
96  DWORD count;
97  DWORD flags;
98 };
99 
100 typedef struct packed_point
101 {
102  short X;
103  short Y;
104 } packed_point;
105 
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  }
119  case RegionDataEmptyRect:
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 }
130 
131 /* Does not check parameters, caller must do that */
132 static inline GpStatus init_region(GpRegion* region, const RegionType type)
133 {
134  region->node.type = type;
135  region->num_children = 0;
136 
137  return Ok;
138 }
139 
141  region_element** element2)
142 {
143  GpStatus stat;
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;
159  case RegionDataEmptyRect:
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 }
185 
186 /* Common code for CombineRegion*
187  * All the caller has to do is get its format into an element
188  */
189 static inline void fuse_region(GpRegion* region, region_element* left,
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 }
197 
198 /*****************************************************************************
199  * GdipCloneRegion [GDIPLUS.@]
200  *
201  * Creates a deep copy of the region
202  *
203  * PARAMS
204  * region [I] source region
205  * clone [O] resulting clone
206  *
207  * RETURNS
208  * SUCCESS: Ok
209  * FAILURE: InvalidParameter or OutOfMemory
210  */
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 }
228 
229 /*****************************************************************************
230  * GdipCombineRegionPath [GDIPLUS.@]
231  */
233 {
234  GpRegion *path_region;
236  GpStatus stat;
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 */
248  if(mode == CombineModeReplace){
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
268  stat = OutOfMemory;
269 
270  heap_free(left);
271  GdipDeleteRegion(path_region);
272  return stat;
273 }
274 
275 /*****************************************************************************
276  * GdipCombineRegionRect [GDIPLUS.@]
277  */
280 {
281  GpRegion *rect_region;
283  GpStatus stat;
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 */
295  if(mode == CombineModeReplace){
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
315  stat = OutOfMemory;
316 
317  heap_free(left);
318  GdipDeleteRegion(rect_region);
319  return stat;
320 }
321 
322 /*****************************************************************************
323  * GdipCombineRegionRectI [GDIPLUS.@]
324  */
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 }
342 
343 /*****************************************************************************
344  * GdipCombineRegionRegion [GDIPLUS.@]
345  */
347  GpRegion *region2, CombineMode mode)
348 {
350  GpStatus stat;
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 */
359  if(mode == CombineModeReplace){
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  {
377  heap_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 }
386 
387 /*****************************************************************************
388  * GdipCreateRegion [GDIPLUS.@]
389  */
391 {
392  TRACE("%p\n", region);
393 
394  if(!region)
395  return InvalidParameter;
396 
397  *region = heap_alloc_zero(sizeof(GpRegion));
398  if(!*region)
399  return OutOfMemory;
400 
401  TRACE("=> %p\n", *region);
402 
403  return init_region(*region, RegionDataInfiniteRect);
404 }
405 
406 /*****************************************************************************
407  * GdipCreateRegionPath [GDIPLUS.@]
408  *
409  * Creates a GpRegion from a GpPath
410  *
411  * PARAMS
412  * path [I] path to base the region on
413  * region [O] pointer to the newly allocated region
414  *
415  * RETURNS
416  * SUCCESS: Ok
417  * FAILURE: InvalidParameter
418  *
419  * NOTES
420  * If a path has no floating point points, its points will be stored as shorts
421  * (INTPATH)
422  *
423  * If a path is empty, it is considered to be an INTPATH
424  */
426 {
428  GpStatus stat;
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 }
455 
456 /*****************************************************************************
457  * GdipCreateRegionRect [GDIPLUS.@]
458  */
460  GpRegion **region)
461 {
462  GpStatus stat;
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 }
484 
485 /*****************************************************************************
486  * GdipCreateRegionRectI [GDIPLUS.@]
487  */
489  GpRegion **region)
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 }
502 
503 /******************************************************************************
504  * GdipCreateRegionHrgn [GDIPLUS.@]
505  */
507 {
508  DWORD size;
509  LPRGNDATA buf;
510  LPRECT rect;
511  GpStatus stat;
512  GpPath* path;
513  GpRegion* local;
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 }
567 
568 /*****************************************************************************
569  * GdipDeleteRegion [GDIPLUS.@]
570  */
572 {
573  TRACE("%p\n", region);
574 
575  if (!region)
576  return InvalidParameter;
577 
578  delete_element(&region->node);
579  heap_free(region);
580 
581  return Ok;
582 }
583 
584 /*****************************************************************************
585  * GdipGetRegionBounds [GDIPLUS.@]
586  */
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 }
625 
626 /*****************************************************************************
627  * GdipGetRegionBoundsI [GDIPLUS.@]
628  */
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 }
649 
650 static inline void write_dword(DWORD* location, INT* offset, const DWORD write)
651 {
652  location[*offset] = write;
653  (*offset)++;
654 }
655 
656 static inline void write_float(DWORD* location, INT* offset, const FLOAT write)
657 {
658  ((FLOAT*)location)[*offset] = write;
659  (*offset)++;
660 }
661 
663  INT* filled)
664 {
665  write_dword(buffer, filled, element->type);
666  switch (element->type)
667  {
668  case CombineModeReplace:
670  case CombineModeUnion:
671  case CombineModeXor:
672  case CombineModeExclude:
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  }
690  case RegionDataEmptyRect:
692  break;
693  }
694 }
695 
696 DWORD write_region_data(const GpRegion *region, void *data)
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 }
713 
714 /*****************************************************************************
715  * GdipGetRegionData [GDIPLUS.@]
716  *
717  * Returns the header, followed by combining ops and region elements.
718  *
719  * PARAMS
720  * region [I] region to retrieve from
721  * buffer [O] buffer to hold the resulting data
722  * size [I] size of the buffer
723  * needed [O] (optional) how much data was written
724  *
725  * RETURNS
726  * SUCCESS: Ok
727  * FAILURE: InvalidParameter
728  *
729  * NOTES
730  * The header contains the size, a checksum, a version string, and the number
731  * of children. The size does not count itself or the checksum.
732  * Version is always something like 0xdbc01001 or 0xdbc01002
733  *
734  * An element is a RECT, or PATH; Combining ops are stored as their
735  * CombineMode value. Special regions (infinite, empty) emit just their
736  * op-code; GpRectFs emit their code followed by their points; GpPaths emit
737  * their code followed by a second header for the path followed by the actual
738  * path data. Followed by the flags for each point. The pathheader contains
739  * the size of the data to follow, a version number again, followed by a count
740  * of how many points, and any special flags which may apply. 0x4000 means it's
741  * a path of shorts instead of FLOAT.
742  *
743  * Combining Ops are stored in reverse order from when they were constructed;
744  * the output is a tree where the left side combining area is always taken
745  * first.
746  */
748  UINT *needed)
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 }
774 
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  {
789  case CombineModeReplace:
791  case CombineModeUnion:
792  case CombineModeXor:
793  case CombineModeExclude:
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  {
803  heap_free(left);
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 
820  heap_free(left);
821  heap_free(right);
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 
930  case RegionDataEmptyRect:
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 }
942 
943 /*****************************************************************************
944  * GdipCreateRegionRgnData [GDIPLUS.@]
945  */
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 
958  init_memory_buffer(&mbuf, data, size);
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 }
981 
982 /*****************************************************************************
983  * GdipGetRegionDataSize [GDIPLUS.@]
984  */
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 }
997 
998 static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
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 }
1061 
1063 {
1064  switch (element->type)
1065  {
1067  *hrgn = NULL;
1068  return Ok;
1069  case RegionDataEmptyRect:
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  }
1092  case CombineModeIntersect:
1093  case CombineModeUnion:
1094  case CombineModeXor:
1095  case CombineModeExclude:
1096  case CombineModeComplement:
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  {
1114  case CombineModeIntersect:
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  {
1128  DeleteObject(left);
1129  *hrgn = NULL;
1130  return stat;
1131  }
1132 
1133  if (right == NULL)
1134  {
1135  /* new region is infinite */
1136  switch (element->type)
1137  {
1138  case CombineModeIntersect:
1139  *hrgn = left;
1140  return Ok;
1142  right = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22);
1143  break;
1145  DeleteObject(left);
1146  *hrgn = NULL;
1147  return Ok;
1148  }
1149  }
1150 
1151  switch (element->type)
1152  {
1153  case CombineModeIntersect:
1155  break;
1156  case CombineModeUnion:
1158  break;
1159  case CombineModeXor:
1161  break;
1162  case CombineModeExclude:
1164  break;
1165  case CombineModeComplement:
1167  break;
1168  default:
1169  ret = ERROR;
1170  }
1171 
1173 
1174  if (ret == ERROR)
1175  {
1176  DeleteObject(left);
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 }
1190 
1191 /*****************************************************************************
1192  * GdipGetRegionHRgn [GDIPLUS.@]
1193  */
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 }
1203 
1205 {
1206  GpStatus status;
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 }
1222 
1223 /*****************************************************************************
1224  * GdipIsEqualRegion [GDIPLUS.@]
1225  */
1227  BOOL *res)
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 }
1257 
1258 /*****************************************************************************
1259  * GdipIsInfiniteRegion [GDIPLUS.@]
1260  */
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 }
1273 
1274 /*****************************************************************************
1275  * GdipIsVisibleRegionRect [GDIPLUS.@]
1276  */
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 
1300  DeleteObject(hrgn);
1301 
1302  return Ok;
1303 }
1304 
1305 /*****************************************************************************
1306  * GdipIsVisibleRegionRectI [GDIPLUS.@]
1307  */
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 }
1316 
1317 /*****************************************************************************
1318  * GdipIsVisibleRegionPoint [GDIPLUS.@]
1319  */
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 
1341  DeleteObject(hrgn);
1342 
1343  return Ok;
1344 }
1345 
1346 /*****************************************************************************
1347  * GdipIsVisibleRegionPointI [GDIPLUS.@]
1348  */
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 }
1355 
1356 /*****************************************************************************
1357  * GdipSetEmpty [GDIPLUS.@]
1358  */
1360 {
1361  GpStatus stat;
1362 
1363  TRACE("%p\n", region);
1364 
1365  if (!region)
1366  return InvalidParameter;
1367 
1368  delete_element(&region->node);
1370 
1371  return stat;
1372 }
1373 
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 }
1388 
1389 /* Transforms GpRegion elements with given matrix */
1391 {
1392  GpStatus stat;
1393 
1394  switch(element->type)
1395  {
1396  case RegionDataEmptyRect:
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 }
1479 
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 }
1489 
1490 /* Translates GpRegion elements with specified offsets */
1492 {
1493  INT i;
1494 
1495  switch(element->type)
1496  {
1497  case RegionDataEmptyRect:
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 }
1516 
1517 /*****************************************************************************
1518  * GdipTranslateRegion [GDIPLUS.@]
1519  */
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 }
1531 
1532 /*****************************************************************************
1533  * GdipTranslateRegionI [GDIPLUS.@]
1534  */
1536 {
1537  TRACE("(%p, %d, %d)\n", region, dx, dy);
1538 
1539  return GdipTranslateRegion(region, (REAL)dx, (REAL)dy);
1540 }
1541 
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 
1571  DeleteObject(hrgn);
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 }
1600 
1602 {
1603  GpStatus stat;
1604  LPRGNDATA data;
1605 
1606  TRACE("(%p, %p, %p)\n", region, count, matrix);
1607 
1608  if (!region || !count || !matrix)
1609  return InvalidParameter;
1610 
1611  stat = get_region_scans_data(region, matrix, &data);
1612 
1613  if (stat == Ok)
1614  {
1615  *count = data->rdh.nCount;
1616  heap_free(data);
1617  }
1618 
1619  return stat;
1620 }
1621 
1623 {
1624  GpStatus stat;
1625  DWORD i;
1626  LPRGNDATA data;
1627  RECT *rects;
1628 
1629  if (!region || !count || !matrix)
1630  return InvalidParameter;
1631 
1632  stat = get_region_scans_data(region, matrix, &data);
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 }
1655 
1657 {
1658  GpStatus stat;
1659  DWORD i;
1660  LPRGNDATA data;
1661  RECT *rects;
1662 
1663  if (!region || !count || !matrix)
1664  return InvalidParameter;
1665 
1666  stat = get_region_scans_data(region, matrix, &data);
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 }
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
Definition: region.c:1204
GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode)
Definition: region.c:278
HRGN WINAPI PathToRegion(_In_ HDC)
struct _RGNDATAHEADER RGNDATAHEADER
#define WINDING
Definition: constants.h:279
short X
Definition: region.c:102
#define TRUE
Definition: types.h:120
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GpStatus WINGDIPAPI GdipCombineRegionRectI(GpRegion *region, GDIPCONST GpRect *rect, CombineMode mode)
Definition: region.c:325
region_element node
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size, UINT *needed)
Definition: region.c:747
static void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
#define Y(I)
struct packed_point packed_point
Rect GpRect
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define pt(x, y)
Definition: drawing.c:79
GLsizei const GLchar ** path
Definition: glext.h:7234
GLuint GLenum matrix
Definition: glext.h:9407
INT Width
Definition: gdiplustypes.h:271
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *region, GpRect *scans, INT *count, GpMatrix *matrix)
Definition: region.c:1622
#define ERROR(name)
Definition: error_private.h:53
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1194
static void fuse_region(GpRegion *region, region_element *left, region_element *right, const CombineMode mode)
Definition: region.c:189
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
static HRGN hrgn2
BOOL WINAPI EndPath(_In_ HDC)
DWORD checksum
Definition: region.c:88
static HDC
Definition: imagelist.c:92
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum GLenum * types
Definition: glext.h:7753
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion *region, REAL x, REAL y, GpGraphics *graphics, BOOL *res)
Definition: region.c:1320
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count)
Definition: region.c:775
LONG top
Definition: windef.h:292
GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *region, GpRegion *region2, GpGraphics *graphics, BOOL *res)
Definition: region.c:1226
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region)
Definition: region.c:506
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
DWORD num_children
void delete_element(region_element *element)
Definition: gdiplus.c:455
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GpStatus WINGDIPAPI GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode mode)
Definition: region.c:232
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
GpStatus gdi_transform_acquire(GpGraphics *graphics)
Definition: graphics.c:6842
static GpStatus transform_region_element(region_element *element, GpMatrix *matrix)
Definition: region.c:1390
LONG left
Definition: windef.h:291
GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN
Definition: graphics.c:2087
LONG right
Definition: windef.h:293
#define GDIPCONST
Definition: gdiplusflat.h:24
GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *region)
Definition: region.c:1374
DWORD size
Definition: region.c:94
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
#define VERSION_MAGIC2
GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *region)
Definition: region.c:1359
GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics, GpRect *rect)
Definition: region.c:629
& rect
Definition: startmenu.cpp:1413
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
union region_element::@392 elementdata
DWORD magic
Definition: region.c:95
GpStatus WINGDIPAPI GdipCloneRegion(GpRegion *region, GpRegion **clone)
Definition: region.c:211
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
struct tagRECT RECT
GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics, BOOL *res)
Definition: region.c:1261
BOOL WINAPI RectInRegion(HRGN hrgn, LPCRECT prcl)
Definition: region.c:964
#define RGN_AND
Definition: wingdi.h:355
CombineMode
Definition: gdiplusenums.h:347
#define write
Definition: acwin.h:97
GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *region, UINT *count, GpMatrix *matrix)
Definition: region.c:1601
static INT ceilr(REAL x)
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
DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN
GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region)
Definition: region.c:488
#define ALTERNATE
Definition: constants.h:278
static void write_element(const region_element *element, DWORD *buffer, INT *filled)
Definition: region.c:662
unsigned int BOOL
Definition: ntddk_ex.h:94
#define RGN_XOR
Definition: wingdi.h:359
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2581
INT X
Definition: gdiplustypes.h:269
#define FIXME(fmt,...)
Definition: debug.h:110
static GpStatus init_region(GpRegion *region, const RegionType type)
Definition: region.c:132
#define WINGDIPAPI
Definition: gdiplusflat.h:22
smooth NULL
Definition: ftsmooth.c:416
#define RGN_OR
Definition: wingdi.h:358
struct region_element::@392::@393 combine
#define LPRECT
Definition: precomp.h:28
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1062
REAL Height
Definition: gdiplustypes.h:264
static INT gdip_round(REAL x)
BOOL WINAPI EqualRgn(_In_ HRGN, _In_ HRGN)
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus)
GpStatus WINGDIPAPI GdipCreateRegion(GpRegion **region)
Definition: region.c:390
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
GpStatus WINGDIPAPI GdipIsVisibleRegionPointI(GpRegion *region, INT x, INT y, GpGraphics *graphics, BOOL *res)
Definition: region.c:1349
if(!(yy_init))
Definition: macro.lex.yy.c:714
Definition: cmds.c:130
#define RDH_RECTANGLES
Definition: wingdi.h:668
static void write_dword(DWORD *location, INT *offset, const DWORD write)
Definition: region.c:650
int WINAPI SetPolyFillMode(_In_ HDC, _In_ int)
Definition: dc.c:1143
DWORD magic
Definition: region.c:81
GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
Definition: region.c:985
REAL X
Definition: gdiplustypes.h:261
const char * debugstr_rectf(const RectF *rc)
Definition: gdiplus.c:476
#define VALID_MAGIC(x)
static void write_float(DWORD *location, INT *offset, const FLOAT write)
Definition: region.c:656
BOOL WINAPI PtInRegion(IN HRGN hrgn, int x, int y)
Definition: region.c:941
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height)
DWORD num_children
Definition: region.c:82
GLdouble GLdouble right
Definition: glext.h:10859
GpStatus WINGDIPAPI GdipIsVisibleRegionRectI(GpRegion *region, INT x, INT y, INT w, INT h, GpGraphics *graphics, BOOL *res)
Definition: region.c:1308
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static GpStatus clone_element(const region_element *element, region_element **element2)
Definition: region.c:140
GLsizei const GLfloat * points
Definition: glext.h:8112
int ret
GpStatus WINGDIPAPI GdipTranslateRegion(GpRegion *region, REAL dx, REAL dy)
Definition: region.c:1520
short Y
Definition: region.c:103
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *region, GpMatrix *matrix)
Definition: region.c:1480
HRGN WINAPI CreateRectRgn(int x1, int y1, int x2, int y2)
Definition: region.c:556
static HRGN hrgn
Definition: win.c:55
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:998
GpStatus WINGDIPAPI GdipCreatePath(GpFillMode fill, GpPath **path)
Definition: stat.h:55
REAL X
Definition: gdiplustypes.h:248
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
static void translate_region_element(region_element *element, REAL dx, REAL dy)
Definition: region.c:1491
GLenum mode
Definition: glext.h:6217
GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics, GpRectF *rect)
Definition: region.c:587
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:363
static INT get_element_size(const region_element *element)
Definition: region.c:106
Status
Definition: gdiplustypes.h:24
REAL Width
Definition: gdiplustypes.h:263
#define local
Definition: zutil.h:30
#define ERR(fmt,...)
Definition: debug.h:109
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define FLAGS_INTPATH
Definition: region.c:77
BOOL WINAPI DeleteDC(_In_ HDC)
#define RGN_DIFF
Definition: wingdi.h:357
static GpStatus get_region_scans_data(GpRegion *region, GpMatrix *matrix, LPRGNDATA *data)
Definition: region.c:1542
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion **region)
Definition: region.c:946
INT WINAPI GetRgnBox(HRGN hrgn, LPRECT prcOut)
Definition: region.c:816
static calc_node_t temp
Definition: rpn_ieee.c:38
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
Definition: region.c:425
Definition: services.c:325
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
DWORD WINAPI GetRegionData(HRGN hrgn, DWORD nCount, LPRGNDATA lpRgnData)
Definition: region.c:798
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
Definition: graphics.c:2395
unsigned int UINT
Definition: ndis.h:50
GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion *region, REAL x, REAL y, REAL w, REAL h, GpGraphics *graphics, BOOL *res)
Definition: region.c:1277
int WINAPI SaveDC(_In_ HDC)
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
INT Height
Definition: gdiplustypes.h:272
GpStatus gdi_transform_release(GpGraphics *graphics)
Definition: graphics.c:6856
GLuint res
Definition: glext.h:9613
GpStatus WINGDIPAPI GdipCombineRegionRegion(GpRegion *region1, GpRegion *region2, CombineMode mode)
Definition: region.c:346
float FLOAT
Definition: typedefs.h:67
GpStatus WINGDIPAPI GdipTranslateRegionI(GpRegion *region, INT dx, INT dy)
Definition: region.c:1535
LONG bottom
Definition: windef.h:294
GpStatus WINGDIPAPI GdipClonePath(GpPath *path, GpPath **clone)
INT Y
Definition: gdiplustypes.h:270
RegionType
static const void * buffer_read(struct memory_buffer *mbuf, INT size)
float REAL
Definition: types.h:41
REAL Y
Definition: gdiplustypes.h:262
BOOL lengthen_path(GpPath *path, INT len)
Definition: gdiplus.c:405
GpStatus WINGDIPAPI GdipGetRegionScans(GpRegion *region, GpRectF *scans, INT *count, GpMatrix *matrix)
Definition: region.c:1656
static SERVICE_STATUS status
Definition: service.c:31
struct region_header header
Definition: region.c:89
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
INT WINAPI CombineRgn(_In_ HRGN hrgnDest, _In_ HRGN hrgnSrc1, _In_ HRGN hrgnSrc2, _In_ INT iCombineMode)
Definition: region.c:194
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
Definition: region.c:571
struct CFHEADER header
Definition: fdi.c:109
GpStatus WINGDIPAPI GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region)
Definition: region.c:459
DWORD write_region_data(const GpRegion *region, void *data)
Definition: region.c:696
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: dlist.c:348
Definition: ps.c:97