blob: 4ca2fddaa5a468a2ecefa59d0e6ce25a3e7da165 [file] [log] [blame]
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001#Topic Region
2#Alias Region_Reference ##
3#Alias Regions ##
4
5Region is a compressed one bit mask. Region describes an aliased clipping area
6on integer boundaries. Region can also describe an array of integer rectangles.
7
8Canvas uses Region to reduce the current clip. Region may be drawn to Canvas;
9Paint determines if Region is filled or stroked, its Color, and so on.
10
11Region may be constructed from IRect array or Path. Diagonal lines and curves
12in Path become integer rectangle edges. Regions operators compute union,
13intersection, difference, and so on. Canvas allows only intersection and
14difference; successive clips can only reduce available Canvas area.
15
16#PhraseDef list_of_op_types
17kDifference_Op, kIntersect_Op, kUnion_Op, kXOR_Op, kReverseDifference_Op,
18kReplace_Op
19##
20
21#Class SkRegion
22
23SkRegion describes the set of pixels used to clip Canvas. SkRegion is compact,
24efficiently storing a single integer rectangle, or a run length encoded array
25of rectangles. SkRegion may reduce the current Canvas_Clip, or may be drawn as
26one or more integer rectangles. SkRegion iterator returns the scan lines or
27rectangles contained by it, optionally intersecting a bounding rectangle.
28
29#Subtopic Overview
30#Populate
31##
32
33#Subtopic Constant
34#Populate
35##
36
37#Subtopic Class
38#Populate
39##
40
41#Subtopic Constructor
42#Populate
43##
44
45#Subtopic Operator
46#Populate
47##
48
49#Subtopic Member_Function
50#Populate
51##
52
53# ------------------------------------------------------------------------------
54
55#Class Iterator
56#Line # iterator returning IRect ##
57
58#Code
59 class Iterator {
60 public:
61 Iterator();
62 Iterator(const SkRegion& region);
63 bool rewind();
64 void reset(const SkRegion& region);
65 bool done() const;
66 void next();
67 const SkIRect& rect();
68 const SkRegion* rgn();
69 };
70##
71
72Returns sequence of rectangles, sorted along y-axis, then x-axis, that make
73up Region.
74
75# ------------------------------------------------------------------------------
76
77#Method Iterator()
78#Line # constructs Region iterator ##
79Initializes Iterator with an empty Region. done() on Iterator returns true.
80Call reset() to initialized Iterator at a later time.
81
82#Return empty Region ierator ##
83
84#Example
85 SkRegion::Iterator iter;
86 SkRegion region;
87 region.setRect({1, 2, 3, 4});
88 iter.reset(region);
89 auto r = iter.rect();
90 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
91#StdOut
92rect={1,2,3,4}
93##
94##
95
96#SeeAlso reset SkRegion
97
98#Method ##
99
100# ------------------------------------------------------------------------------
101
102#Method Iterator(const SkRegion& region)
103#Line # constructs Region iterator ##
104Sets Iterator to return elements of IRect array in region.
105#Param region Region to iterate ##
106
107#Return Region iterator ##
108
109#Example
110 SkRegion region;
111 region.setRect({1, 2, 3, 4});
112 SkRegion::Iterator iter(region);
113 auto r = iter.rect();
114 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
115#StdOut
116rect={1,2,3,4}
117##
118##
119
120#SeeAlso reset SkRegion Cliperator Spanerator
121
122#Method ##
123
124# ------------------------------------------------------------------------------
125
126#Method bool rewind()
127#Line # points Iterator to start ##
128
129Points Iterator to start of Region.
130Returns true if Region was set; otherwise, returns false.
131
132#Return true if Region was set ##
133
134#Example
135#Bug 8186
136 auto debugster = [](const char* label, SkRegion::Iterator& iter, bool addRewind) -> void {
137 if (addRewind) {
138 bool success = iter.rewind();
139 SkDebugf("%14s rewind success=%s\n", label, success ? "true" : "false");
140 }
141 auto r = iter.rect();
142 SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
143 };
144 SkRegion::Iterator iter;
145 debugster("empty iter", iter, true);
146 SkRegion region;
147 iter.reset(region);
148 debugster("empty region", iter, true);
149 region.setRect({1, 2, 3, 4});
150 iter.reset(region);
151 debugster("after set rect", iter, false);
152 debugster("after rewind", iter, true);
153#StdOut
154#Volatile
155 empty iter rewind success=false
156 empty iter rect={0,0,0,0}
157 empty region rewind success=true
158 empty region rect={0,0,0,0}
159after set rect rect={1,2,3,4}
160 after rewind rewind success=true
161 after rewind rect={1,2,3,4}
162##
163##
164
165#SeeAlso reset
166
167#Method ##
168
169# ------------------------------------------------------------------------------
170
171#Method void reset(const SkRegion& region)
172#Line # sets Region to iterate ##
173
174Resets iterator, using the new Region.
175
176#Param region Region to iterate ##
177
178#Example
179 auto debugster = [](const char* label, SkRegion::Iterator& iter) -> void {
180 SkDebugf("%14s: done=%s\n", label, iter.done() ? "true" : "false");
181 };
182 SkRegion region;
183 SkRegion::Iterator iter(region);
184 debugster("empty region", iter);
185 region.setRect({1, 2, 3, 4});
186 debugster("after set rect", iter);
187 iter.reset(region);
188 debugster("after reset", iter);
189#StdOut
190 empty region: done=true
191after set rect: done=true
192 after reset: done=false
193##
194##
195
196#SeeAlso rewind
197
198#Method ##
199
200# ------------------------------------------------------------------------------
201
202#Method bool done() const
203#Line # returns if data parsing is complete ##
204
205Returns true if Iterator is pointing to final IRect in Region.
206
207#Return true if data parsing is complete ##
208
209#Example
210 SkRegion region;
211 SkRegion::Iterator iter(region);
212 SkDebugf("done=%s\n", iter.done() ? "true" : "false");
213 region.setRect({1, 2, 3, 4});
214 iter.rewind();
215 SkDebugf("done=%s\n", iter.done() ? "true" : "false");
216#StdOut
217done=true
218done=false
219##
220##
221
222#SeeAlso next rect
223
224#Method ##
225
226# ------------------------------------------------------------------------------
227
228#Method void next()
229#Line # advances to next IRect ##
230
231Advances Iterator to next IRect in Region if it is not done.
232
233#Example
234 SkRegion region;
235 SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
236 region.setRects(rects, SK_ARRAY_COUNT(rects));
237 SkRegion::Iterator iter(region);
238 do {
239 auto r2 = iter.rect();
240 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
241 iter.next();
242 } while (!iter.done());
243#StdOut
244rect={1,2,3,4}
245rect={5,6,7,8}
246##
247##
248
249#SeeAlso done rect
250
251#Method ##
252
253# ------------------------------------------------------------------------------
254
255#Method const SkIRect& rect() const
256#Line # returns part of Region as IRect ##
257
258Returns IRect element in Region. Does not return predictable results if Region
259is empty.
260
261#Return part of Region as IRect ##
262
263#Example
264#Bug 8186
265 SkRegion region;
266 SkRegion::Iterator iter(region);
267 auto r1 = iter.rect();
268 SkDebugf("rect={%d,%d,%d,%d}\n", r1.fLeft, r1.fTop, r1.fRight, r1.fBottom);
269 region.setRect({1, 2, 3, 4});
270 iter.rewind();
271 auto r2 = iter.rect();
272 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
273#StdOut
274#Volatile
275rect={0,0,0,0}
276rect={1,2,3,4}
277##
278##
279
280#SeeAlso next done
281
282#Method ##
283
284# ------------------------------------------------------------------------------
285
286#Method const SkRegion* rgn() const
287#Line # returns original Region ##
288
289Returns Region if set; otherwise, returns nullptr.
290
291#Return iterated Region ##
292
293#Example
294 SkRegion region;
295 SkIRect rects[] = {{1, 2, 3, 4}, {3, 4, 5, 6}};
296 region.setRects(rects, SK_ARRAY_COUNT(rects));
297 SkRegion::Iterator iter(region);
298 auto r = iter.rect();
299 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
300 auto b = iter.rgn()->getBounds();
301 SkDebugf("bounds={%d,%d,%d,%d}\n", b.fLeft, b.fTop, b.fRight, b.fBottom);
302##
303
304#SeeAlso Iterator reset
305
306#Method ##
307
308#Class Iterator ##
309
310# ------------------------------------------------------------------------------
311
312#Class Cliperator
313#Line # iterator returning IRect within clip ##
314
315#Code
316 class SK_API Cliperator {
317 public:
Cary Clarka8cdc172018-09-07 14:17:08 -0400318 Cliperator(const SkRegion& region, const SkIRect& clip);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400319 bool done();
320 void next();
321 const SkIRect& rect() const;
322 };
323##
324
325Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make
326up Region intersected with the specified clip rectangle.
327
328# ------------------------------------------------------------------------------
329
330#Method Cliperator(const SkRegion& region, const SkIRect& clip)
331#Line # constructs Region iterator with clip ##
332
333Sets Cliperator to return elements of IRect array in Region within clip.
334
335#Param region Region to iterate ##
336#Param clip bounds of iteration ##
337
338#Return Region iterator ##
339
340#Example
341 SkRegion region;
342 region.setRect({1, 2, 3, 4});
343 SkRegion::Cliperator clipper(region, {0, 0, 2, 3});
344 auto r = clipper.rect();
345 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
346#StdOut
347rect={1,2,2,3}
348##
349##
350
351#SeeAlso SkRegion Iterator Spanerator
352
353#Method ##
354
355# ------------------------------------------------------------------------------
356
357#Method bool done()
358#Line # returns if data parsing is complete ##
359
360Returns true if Cliperator is pointing to final IRect in Region.
361
362#Return true if data parsing is complete ##
363
364#Example
365 auto debugster = [](const char* label, SkRegion& region) -> void {
366 SkRegion::Cliperator clipper(region, {0, 0, 5, 5});
367 SkDebugf("%14s done=%s\n", label, clipper.done() ? "true" : "false");
368 };
369 SkRegion region;
370 debugster("empty region", region);
371 region.setRect({1, 2, 3, 4});
372 debugster("after add rect", region);
373#StdOut
374 empty region done=true
375after add rect done=false
376##
377##
378
379#SeeAlso next rect
380
381#Method ##
382
383# ------------------------------------------------------------------------------
384
385#Method void next()
386#Line # advances to next IRect within clip ##
387
388Advances iterator to next IRect in Region contained by clip.
389
390#Example
391 SkRegion region;
392 SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
393 region.setRects(rects, SK_ARRAY_COUNT(rects));
394 SkRegion::Cliperator clipper(region, {0, 3, 8, 7});
395 do {
396 auto r2 = clipper.rect();
397 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
398 clipper.next();
399 } while (!clipper.done());
400#StdOut
401rect={1,3,3,4}
402rect={5,6,7,7}
403##
404##
405
406#SeeAlso done
407
408#Method ##
409
410# ------------------------------------------------------------------------------
411
412#Method const SkIRect& rect() const
413#Line # returns part of Region as IRect intersected with clip ##
414
415Returns IRect element in Region, intersected with clip passed to Cliperator
416constructor. Does not return predictable results if Region
417is empty.
418
419#Return part of Region inside clip as IRect ##
420
421#Example
422#Bug 8186
423 auto debugster = [](const char* label, SkRegion& region) -> void {
424 SkRegion::Cliperator clipper(region, {0, 0, 5, 3});
425 auto r = clipper.rect();
426 SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
427 };
428 SkRegion region;
429 debugster("empty region", region);
430 region.setRect({1, 2, 3, 4});
431 debugster("after set rect", region);
432#StdOut
433#Volatile
434 empty region rect={1094713344,1065353216,0,-1}
435after set rect rect={1,2,3,3}
436##
437##
438
439#SeeAlso next done
440
441#Method ##
442
443#Class Cliperator ##
444
445# ------------------------------------------------------------------------------
446
447#Class Spanerator
448#Line # horizontal line segment iterator ##
449
450#Code
451 class Spanerator {
452 public:
453 Spanerator(const SkRegion& region, int y, int left, int right);
454 bool next(int* left, int* right);
455 };
456##
457
458Returns the line segment ends within Region that intersect a horizontal line.
459
460# ------------------------------------------------------------------------------
461
462#Method Spanerator(const SkRegion& region, int y, int left, int right)
463#Line # constructs Region iterator on scan line ##
464
465Sets Spanerator to return line segments in Region on scan line.
466
467
468#Param region Region to iterate ##
469#Param y horizontal line to intersect ##
470#Param left bounds of iteration ##
471#Param right bounds of iteration ##
472
473#Return Region iterator ##
474
475#Example
476 SkRegion region;
477 region.setRect({1, 2, 3, 4});
478 SkRegion::Spanerator spanner(region, 3, 2, 4);
479 int left, right;
480 bool result = spanner.next(&left, &right);
481 SkDebugf("result=%s left=%d right=%d\n", result ? "true" : "false", left, right);
482##
483
484#SeeAlso SkRegion Iterator Cliperator
485
486#Method ##
487
488# ------------------------------------------------------------------------------
489
490#Method bool next(int* left, int* right)
491#Line # advances to next span on horizontal line ##
492
493Advances iterator to next span intersecting Region within line segment provided
494in constructor. Returns true if interval was found.
495
496#Param left pointer to span start; may be nullptr ##
497#Param right pointer to span end; may be nullptr ##
498
499#Return true if interval was found ##
500
501#Example
502 auto debugster = [](const char* label, SkRegion& region) -> void {
503 SkRegion::Spanerator spanner(region, 3, 2, 4);
504 int left, right;
505 bool result = spanner.next(&left, &right);
506 SkDebugf("%14s: result=%s", label, result ? "true" : "false");
507 if (result) SkDebugf(" left=%d right=%d", left, right);
508 SkDebugf("\n");
509 };
510 SkRegion region;
511 debugster("empty region", region);
512 region.setRect({1, 2, 3, 4});
513 debugster("after set rect", region);
514#StdOut
515 empty region: result=false
516after set rect: result=true left=2 right=3
517##
518##
519
520#SeeAlso done
521
522#Method ##
523
524#Class Spanerator ##
525
526# ------------------------------------------------------------------------------
527
528#Method SkRegion()
529#In Constructor
530#Line # constructs with default values ##
531
532Constructs an empty Region. Region is set to empty bounds
533at (0, 0) with zero width and height.
534
535#Return empty Region ##
536
537#Example
538SkRegion region;
539SkIRect r = region.getBounds();
540SkDebugf("region bounds: {%d, %d, %d, %d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
541#StdOut
542region bounds: {0, 0, 0, 0}
543##
544##
545
546#SeeAlso setEmpty
547
548#Method ##
549
550# ------------------------------------------------------------------------------
551
552#Method SkRegion(const SkRegion& region)
553#In Constructor
554#Line # makes a shallow copy ##
555Constructs a copy of an existing region.
556Copy constructor makes two regions identical by value. Internally, region and
557the returned result share pointer values. The underlying Rect array is
558copied when modified.
559
560Creating a Region copy is very efficient and never allocates memory.
561Regions are always copied by value from the interface; the underlying shared
562pointers are not exposed.
563
564#Param region Region to copy by value ##
565
566#Return copy of Region ##
567
568#Example
569 auto debugster = [](const char* label, SkRegion& region) -> void {
570 auto r = region.getBounds();
571 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
572 };
573 SkRegion region({1, 2, 3, 4});
574 SkRegion region2(region);
575 debugster("region bounds", region);
576 debugster("region2 bounds", region2);
577 region.setEmpty();
578 SkDebugf(" after region set empty:\n");
579 debugster("region bounds", region);
580 debugster("region2 bounds", region2);
581#StdOut
582 region bounds: {1,2,3,4}
583region2 bounds: {1,2,3,4}
584 after region set empty:
585 region bounds: {0,0,0,0}
586region2 bounds: {1,2,3,4}
587##
588##
589
590#SeeAlso setRegion operator=(const SkRegion& region)
591
592#Method ##
593
594# ------------------------------------------------------------------------------
595
596#Method explicit SkRegion(const SkIRect& rect)
597#In Constructor
598#Line # constructs Region matching IRect ##
599Constructs a rectangular Region matching the bounds of rect.
600
601#Param rect bounds of constructed Region ##
602
603#Return rectangular Region ##
604
605#Example
606 SkRegion region({1, 2, 3, 4});
607 SkRegion region2;
608 region2.setRect({1, 2, 3, 4});
609 SkDebugf("region %c= region2\n", region == region2 ? '=' : '!');
610##
611
612#SeeAlso setRect setRegion
613
614#Method ##
615
616# ------------------------------------------------------------------------------
617
618#Method ~SkRegion()
619#In Constructor
620#Line # decreases Reference_Count of owned objects ##
621Releases ownership of any shared data and deletes data if Region is sole owner.
622
623#Example
624#Description
625delete calls Region Destructor, but copy of original in region2 is unaffected.
626##
627 SkRegion* region = new SkRegion({1, 2, 3, 4});
628 SkRegion region2(*region);
629 delete region;
630 auto r = region2.getBounds();
631 SkDebugf("region2 bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
632#StdOut
633region2 bounds: {1,2,3,4}
634##
635##
636
637#SeeAlso SkRegion() SkRegion(const SkRegion& region) SkRegion(const SkIRect& rect) operator=(const SkRegion& region)
638
639#Method ##
640
641# ------------------------------------------------------------------------------
642
643#Method SkRegion& operator=(const SkRegion& region)
644#In Operator
645#Line # makes a shallow copy ##
646Constructs a copy of an existing region.
647Makes two regions identical by value. Internally, region and
648the returned result share pointer values. The underlying Rect array is
649copied when modified.
650
651Creating a Region copy is very efficient and never allocates memory.
652Regions are always copied by value from the interface; the underlying shared
653pointers are not exposed.
654
655#Param region Region to copy by value ##
656
657#Return Region to copy by value ##
658
659#Example
660 auto debugster = [](const char* label, SkRegion& region) -> void {
661 auto r = region.getBounds();
662 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
663 };
664 SkRegion region1({1, 2, 3, 4});
665 SkRegion region2 = region1;
666 debugster("region1 bounds", region1);
667 debugster("region2 bounds", region2);
668#StdOut
669region1 bounds: {1,2,3,4}
670region2 bounds: {1,2,3,4}
671##
672##
673
674#SeeAlso set swap SkRegion(const SkRegion& region)
675
676#Method ##
677
678# ------------------------------------------------------------------------------
679
680#Method bool operator==(const SkRegion& other)_const
681#In Operator
682#Line # compares Regions for equality ##
683
684Compares Region and other; returns true if they enclose exactly
685the same area.
686
687#Param other Region to compare ##
688
689#Return true if Region pair are equivalent ##
690
691#Example
692 auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void {
693 SkDebugf("%s one %c= two\n", prefix, a == b ? '=' : '!');
694 };
695 SkRegion one;
696 SkRegion two;
697 debugster("empty", one, two);
698 one.setRect({1, 2, 3, 4});
699 debugster("set rect", one, two);
700 one.setEmpty();
701 debugster("set empty", one, two);
702#StdOut
703empty one == two
704set rect one != two
705set empty one == two
706##
707##
708
709#SeeAlso operator!=(const SkRegion& other)_const operator=(const SkRegion& region)
710
711#Method ##
712
713# ------------------------------------------------------------------------------
714
715#Method bool operator!=(const SkRegion& other)_const
716#In Operator
717#Line # compares Regions for inequality ##
718
719Compares Region and other; returns true if they do not enclose the same area.
720
721#Param other Region to compare ##
722
723#Return true if Region pair are not equivalent ##
724
725#Example
726 auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void {
727 SkDebugf("%s one %c= two\n", prefix, a != b ? '!' : '=');
728 };
729 SkRegion one;
730 SkRegion two;
731 debugster("empty", one, two);
732 one.setRect({1, 2, 3, 4});
733 two.setRect({1, 2, 3, 3});
734 debugster("set rect", one, two);
735 two.op({1, 3, 3, 4}, SkRegion::kUnion_Op);
736 debugster("union rect", one, two);
737#StdOut
738empty one == two
739set rect one != two
740union rect one == two
741##
742##
743
744#SeeAlso operator==(const SkRegion& other)_const operator=(const SkRegion& region)
745
746#Method ##
747
748# ------------------------------------------------------------------------------
749
750#Method bool set(const SkRegion& src)
751#In Constructor
752#Line # makes a shallow copy ##
753
754Sets Region to src, and returns true if src bounds is not empty.
755This makes Region and src identical by value. Internally,
756Region and src share pointer values. The underlying Rect array is
757copied when modified.
758
759Creating a Region copy is very efficient and never allocates memory.
760Regions are always copied by value from the interface; the underlying shared
761pointers are not exposed.
762
763#Param src Region to copy ##
764
765#Return copy of src ##
766
767#Example
768 auto debugster = [](const char* label, SkRegion& region) -> void {
769 auto r = region.getBounds();
770 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
771 };
772 SkRegion region1({1, 2, 3, 4});
773 SkRegion region2;
774 region2.set(region1);
775 debugster("region1 bounds", region1);
776 debugster("region2 bounds", region2);
777#StdOut
778region1 bounds: {1,2,3,4}
779region2 bounds: {1,2,3,4}
780##
781##
782
783#SeeAlso operator=(const SkRegion& region) swap SkRegion(const SkRegion& region)
784
785#Method ##
786
787# ------------------------------------------------------------------------------
788
789#Method void swap(SkRegion& other)
790#In Operator
791#Line # exchanges Region pair ##
792
793Exchanges IRect array of Region and other. swap() internally exchanges pointers,
794so it is lightweight and does not allocate memory.
795
796swap() usage has largely been replaced by operator=(const SkRegion& region).
797Paths do not copy their content on assignment until they are written to,
798making assignment as efficient as swap().
799
800#Param other operator=(const SkRegion& region) set ##
801
802#Example
803 auto debugster = [](const char* label, SkRegion& region) -> void {
804 auto r = region.getBounds();
805 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
806 };
807 SkRegion region1({1, 2, 3, 4});
808 SkRegion region2;
809 region1.swap(region2);
810 debugster("region1 bounds", region1);
811 debugster("region2 bounds", region2);
812#StdOut
813region1 bounds: {0,0,0,0}
814region2 bounds: {1,2,3,4}
815##
816##
817
818#SeeAlso operator=(const SkRegion& region) set SkRegion(const SkRegion& region)
819
820#Method ##
821
822# ------------------------------------------------------------------------------
823
824#Method bool isEmpty() const
825#In Property
826#Line # returns if bounds has no width or height ##
827
828Returns true if Region is empty.
829Empty Region has bounds width or height less than or equal to zero.
830SkRegion() constructs empty Region; setEmpty
831and setRect with dimensionless data make Region empty.
832
833#Return true if bounds has no width or height ##
834
835#Example
836 auto debugster = [](const char* label, SkRegion& region) -> void {
837 SkDebugf("%14s: region is %s" "empty\n", label, region.isEmpty() ? "" : "not ");
838 };
839 SkRegion region;
840 debugster("initial", region);
841 region.setRect({1, 2, 3, 4});
842 debugster("set rect", region);
843 region.setEmpty();
844 debugster("set empty", region);
845#StdOut
846 initial: region is empty
847 set rect: region is not empty
848 set empty: region is empty
849##
850##
851
852#SeeAlso isRect isComplex operator==(const SkRegion& other)_const
853
854#Method ##
855
856# ------------------------------------------------------------------------------
857
858#Method bool isRect() const
859#In Property
860#Line # returns if Region contains one IRect ##
861
862Returns true if Region is one IRect with positive dimensions.
863
864#Return true if Region contains one IRect ##
865
866#Example
867 auto debugster = [](const char* label, const SkRegion& region) -> void {
868 SkDebugf("%s: region is %s" "rect\n", label, region.isRect() ? "" : "not ");
869 };
870 SkRegion region;
871 debugster("initial", region);
872 region.setRect({1, 2, 3, 4});
873 debugster("set rect", region);
874 region.setEmpty();
875 debugster("set empty", region);
876#StdOut
877initial: region is not rect
878set rect: region is rect
879set empty: region is not rect
880##
881##
882
883#SeeAlso isEmpty isComplex
884
885#Method ##
886
887# ------------------------------------------------------------------------------
888
889#Method bool isComplex() const
890#In Property
891#Line # returns true if Region contains more than one IRect ##
892
893Returns true if Region is described by more than one rectangle.
894
895#Return true if Region contains more than one IRect ##
896
897#Example
898 auto debugster = [](const char* label, const SkRegion& region) -> void {
899 SkDebugf("%s: region is %s" "complex\n", label, region.isComplex() ? "" : "not ");
900 };
901 SkRegion region;
902 debugster("initial", region);
903 region.setRect({1, 2, 3, 4});
904 debugster("set rect", region);
905 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
906 debugster("op rect", region);
907#StdOut
908initial: region is not complex
909set rect: region is not complex
910op rect: region is complex
911##
912##
913
914#SeeAlso isEmpty isRect
915
916#Method ##
917
918# ------------------------------------------------------------------------------
919
920#Method const SkIRect& getBounds() const
921#In Property
922#Line # returns maximum and minimum of IRect array ##
923
924Returns minimum and maximum axes values of IRect array.
925Returns (0, 0, 0, 0) if Region is empty.
926
927#Return combined bounds of all IRect elements ##
928
929#Example
930 SkRegion region({1, 2, 3, 4});
931 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
932 auto r = region.getBounds();
933 SkDebugf("bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
934#StdOut
935bounds: {1,2,4,5}
936##
937##
938
939#SeeAlso isEmpty isRect
940
941#Method ##
942
943# ------------------------------------------------------------------------------
944
945#Method int computeRegionComplexity() const
946#In Property
947#Line # returns relative complexity ##
948
949Returns a value that increases with the number of
950elements in Region. Returns zero if Region is empty.
951Returns one if Region equals IRect; otherwise, returns
952value greater than one indicating that Region is complex.
953
954Call to compare Regions for relative complexity.
955
956#Return relative complexity ##
957
958#Example
959 auto debugster = [](const char* label, const SkRegion& region) -> void {
960 SkDebugf("%s: region complexity %d\n", label, region.computeRegionComplexity());
961 };
962 SkRegion region;
963 debugster("initial", region);
964 region.setRect({1, 2, 3, 4});
965 debugster("set rect", region);
966 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
967 debugster("op rect", region);
968#StdOut
969initial: region complexity 0
970set rect: region complexity 1
971op rect: region complexity 3
972##
973##
974
975#SeeAlso isRect isComplex
976
977#Method ##
978
979# ------------------------------------------------------------------------------
980
981#Method bool getBoundaryPath(SkPath* path) const
982#In Property
983#Line # appends Region outline to Path ##
984
985Appends outline of Region to path.
986Returns true if Region is not empty; otherwise, returns false, and leaves path
987unmodified.
988
989#Param path Path to append to ##
990
991#Return true if path changed ##
992
993#Example
994#Height 100
995 SkRegion region;
996 region.setRect({10, 20, 90, 60});
997 region.op({30, 40, 60, 80}, SkRegion::kXOR_Op);
998 canvas->drawRegion(region, SkPaint());
999 SkPath path;
1000 region.getBoundaryPath(&path);
1001 path.offset(100, 0);
1002 canvas->drawPath(path, SkPaint());
1003##
1004
1005#SeeAlso isEmpty isComplex
1006
1007#Method ##
1008
1009# ------------------------------------------------------------------------------
1010
1011#Method bool setEmpty()
1012#In Constructor
1013#Line # constructs with default values ##
1014
1015Constructs an empty Region. Region is set to empty bounds
1016at (0, 0) with zero width and height. Always returns false.
1017
1018#Return false ##
1019
1020#Example
1021 auto debugster = [](const char* label, SkRegion& region) -> void {
1022 auto r = region.getBounds();
1023 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
1024 };
1025 SkRegion region({1, 2, 3, 4});
1026 debugster("region bounds", region);
1027 region.setEmpty();
1028 SkDebugf(" after region set empty:\n");
1029 debugster("region bounds", region);
1030#StdOut
1031 region bounds: {1,2,3,4}
1032 after region set empty:
1033 region bounds: {0,0,0,0}
1034##
1035##
1036
1037#SeeAlso SkRegion()
1038
1039#Method ##
1040
1041# ------------------------------------------------------------------------------
1042
1043#Method bool setRect(const SkIRect& rect)
1044#In Constructor
1045#Line # constructs Region matching IRect ##
1046
1047Constructs a rectangular Region matching the bounds of rect.
1048If rect is empty, constructs empty and returns false.
1049
1050#Param rect bounds of constructed Region ##
1051
1052#Return true if rect is not empty ##
1053
1054#Example
1055 SkRegion region({1, 2, 3, 4});
1056 SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not ");
1057 bool setEmpty = region.setRect({1, 2, 1, 4});
1058 SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not ");
1059 SkDebugf("setEmpty: %s\n", setEmpty ? "true" : "false");
1060#StdOut
1061region is not empty
1062region is empty
1063setEmpty: false
1064##
1065##
1066
1067#SeeAlso SkRegion(const SkIRect& rect)
1068
1069#Method ##
1070
1071# ------------------------------------------------------------------------------
1072
1073#Method bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom)
1074#In Constructor
1075#Line # constructs Region matching bounds ##
1076
1077Constructs Region with bounds (left, top, right, bottom).
1078Returns true if left is less than right and top is less than bottom; otherwise,
1079constructs empty Region and returns false.
1080
1081#Param left edge of bounds on x-axis ##
1082#Param top edge of bounds on y-axis ##
1083#Param right edge of bounds on x-axis ##
1084#Param bottom edge of bounds on y-axis ##
1085
1086#Return rectangular Region ##
1087
1088#Example
1089 auto debugster = [](const char* label, bool success, SkRegion& region) -> void {
1090 auto r = region.getBounds();
1091 SkDebugf("%14s: success:%s {%d,%d,%d,%d}\n", label, success ? "true" : "false",
1092 r.fLeft, r.fTop, r.fRight, r.fBottom);
1093 };
1094 SkRegion region;
1095 bool success = region.setRect(1, 2, 3, 4);
1096 debugster("set to: 1,2,3,4", success, region);
1097 success = region.setRect(3, 2, 1, 4);
1098 debugster("set to: 3,2,1,4", success, region);
1099#StdOut
1100set to: 1,2,3,4: success:true {1,2,3,4}
1101set to: 3,2,1,4: success:false {0,0,0,0}
1102##
1103##
1104
1105#SeeAlso SkRegion(const SkIRect& rect)
1106
1107#Method ##
1108
1109# ------------------------------------------------------------------------------
1110
1111#Method bool setRects(const SkIRect rects[], int count)
1112#In Constructor
1113#Line # sets IRect array ##
1114
1115Constructs Region as the union of IRect in rects array. If count is
1116zero, constructs empty Region. Returns false if constructed Region is empty.
1117
1118May be faster than repeated calls to op().
1119
1120#Param rects array of IRects ##
1121#Param count array size ##
1122
1123#Return true if constructed Region is not empty ##
1124
1125#Example
1126#Height 70
1127 SkIRect rects[] = { {10, 10, 40, 40}, {20, 20, 50, 50}, {30, 30, 60, 60} };
1128 SkRegion region;
1129 region.setRects(rects, SK_ARRAY_COUNT(rects));
1130 canvas->drawRegion(region, SkPaint());
1131 region.setEmpty();
1132 for (auto add : rects) {
1133 region.op(add, SkRegion::kUnion_Op);
1134 }
1135 region.translate(100, 0);
1136 canvas->drawRegion(region, SkPaint());
1137##
1138
1139#SeeAlso setRect op
1140
1141#Method ##
1142
1143# ------------------------------------------------------------------------------
1144
1145#Method bool setRegion(const SkRegion& region)
1146#In Constructor
1147#Line # copies Region ##
1148
1149Constructs a copy of an existing region.
1150Makes two regions identical by value. Internally, region and
1151the returned result share pointer values. The underlying Rect array is
1152copied when modified.
1153
1154Creating a Region copy is very efficient and never allocates memory.
1155Regions are always copied by value from the interface; the underlying shared
1156pointers are not exposed.
1157
1158#Param region Region to copy by value ##
1159
1160#Return Region to copy by value ##
1161
1162#Example
1163 auto debugster = [](const char* label, SkRegion& region) -> void {
1164 auto r = region.getBounds();
1165 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
1166 };
1167 SkRegion region({1, 2, 3, 4});
1168 SkRegion region2;
1169 region2.setRegion(region);
1170 debugster("region bounds", region);
1171 debugster("region2 bounds", region2);
1172 region2.setEmpty();
1173 SkDebugf(" after region set empty:\n");
1174 debugster("region bounds", region);
1175 debugster("region2 bounds", region2);
1176#StdOut
1177 region bounds: {1,2,3,4}
1178region2 bounds: {1,2,3,4}
1179 after region set empty:
1180 region bounds: {1,2,3,4}
1181region2 bounds: {0,0,0,0}
1182##
1183##
1184
1185#SeeAlso SkRegion(const SkRegion& region)
1186
1187#Method ##
1188
1189# ------------------------------------------------------------------------------
1190
1191#Method bool setPath(const SkPath& path, const SkRegion& clip)
1192#In Constructor
1193#Line # constructs Region from clipped Path ##
1194
1195Constructs Region to match outline of path within clip.
1196Returns false if constructed Region is empty.
1197
1198Constructed Region draws the same pixels as path through clip when
1199Anti_Aliasing is disabled.
1200
1201#Param path Path providing outline ##
1202#Param clip Region containing path ##
1203
1204#Return true if constructed Region is not empty ##
1205
1206#Example
1207#Height 120
1208 SkPaint paint;
1209 paint.setTextSize(128);
1210 SkPath textPath;
1211 paint.getTextPath("Q", 1, 0, 110, &textPath);
1212 SkIRect clipRect = {20, 20, 100, 120};
1213 SkRegion clipRegion(clipRect);
1214 SkRegion region;
1215 region.setPath(textPath, clipRegion);
1216 canvas->drawRegion(region, SkPaint());
1217 clipRect.offset(100, 0);
1218 textPath.offset(100, 0);
1219 canvas->clipRect(SkRect::Make(clipRect), false);
1220 canvas->drawPath(textPath, SkPaint());
1221##
1222
1223#SeeAlso setRects op
1224
1225#Method ##
1226
1227# ------------------------------------------------------------------------------
1228
1229#Method bool intersects(const SkIRect& rect) const
1230#In Intersection
1231#Line # returns true if areas overlap ##
1232
1233Returns true if Region intersects rect.
1234Returns false if either rect or Region is empty, or do not intersect.
1235
1236#Param rect IRect to intersect ##
1237
1238#Return true if rect and Region have area in common ##
1239
1240#Example
1241#Duration 4
1242#Height 128
1243 SkPaint paint;
1244 paint.setTextSize(128);
1245 SkPath textPath;
1246 paint.getTextPath("W", 1, 20, 110, &textPath);
1247 SkRegion region;
1248 region.setPath(textPath, SkRegion({0, 0, 256, 256}));
1249 canvas->drawRegion(region, SkPaint());
1250 SkIRect iRect = SkIRect::MakeXYWH(frame * 160, 55, 10, 10);
1251 paint.setColor(region.intersects(iRect) ? SK_ColorBLUE : SK_ColorRED);
1252 canvas->drawRect(SkRect::Make(iRect), paint);
1253##
1254
1255#SeeAlso contains SkRect::intersects
1256
1257#Method ##
1258
1259# ------------------------------------------------------------------------------
1260
1261#Method bool intersects(const SkRegion& other) const
1262
1263Returns true if Region intersects other.
1264Returns false if either other or Region is empty, or do not intersect.
1265
1266#Param other Region to intersect ##
1267
1268#Return true if other and Region have area in common ##
1269
1270#Example
1271#Duration 4
1272#Height 128
1273 SkPaint paint;
1274 paint.setTextSize(128);
1275 SkPath hPath, dotPath;
1276 paint.getTextPath("H", 1, 40, 110, &hPath);
1277 paint.getTextPath(",", 1, frame * 180, 95, &dotPath);
1278 SkRegion hRegion, dotRegion;
1279 hRegion.setPath(hPath, SkRegion({0, 0, 256, 256}));
1280 dotRegion.setPath(dotPath, SkRegion({0, 0, 256, 256}));
1281 canvas->drawRegion(hRegion, paint);
1282 paint.setColor(hRegion.intersects(dotRegion) ? SK_ColorBLUE : SK_ColorRED);
1283 canvas->drawRegion(dotRegion, paint);
1284##
1285
1286#SeeAlso contains SkRect::intersects
1287
1288#Method ##
1289
1290# ------------------------------------------------------------------------------
1291
1292#Method bool contains(int32_t x, int32_t y) const
1293#In Intersection
1294#Line # returns true if points are equal or inside ##
1295
1296Returns true if IPoint (x, y) is inside Region.
1297Returns false if Region is empty.
1298
1299#Param x test IPoint x-coordinate ##
1300#Param y test IPoint y-coordinate ##
1301
1302#Return true if (x, y) is inside Region ##
1303
1304#Example
1305#Height 128
1306 SkPaint paint;
1307 paint.setTextSize(128);
1308 SkPath xPath;
1309 paint.getTextPath("X", 1, 20, 110, &xPath);
1310 SkRegion xRegion;
1311 xRegion.setPath(xPath, SkRegion({0, 0, 256, 256}));
1312 canvas->drawRegion(xRegion, paint);
1313 for (int y = 0; y < 128; y += 8) {
1314 for (int x = 0; x < 128; x += 8) {
1315 paint.setColor(xRegion.contains(x, y) ? SK_ColorWHITE : SK_ColorRED);
1316 canvas->drawPoint(x, y, paint);
1317 }
1318 }
1319##
1320
1321#SeeAlso intersects SkRect::contains
1322
1323#Method ##
1324
1325# ------------------------------------------------------------------------------
1326
1327#Method bool contains(const SkIRect& other) const
1328
1329Returns true if other is completely inside Region.
1330Returns false if Region or other is empty.
1331
1332#Param other IRect to contain ##
1333
1334#Return true if other is inside Region ##
1335
1336#Example
1337#Height 128
1338#Duration 4
1339 SkPaint paint;
1340 paint.setTextSize(128);
1341 SkPath xPath;
1342 paint.getTextPath("X", 1, 20, 110, &xPath);
1343 SkRegion xRegion;
1344 SkIRect drawBounds = {0, 0, 128, 128};
1345 xRegion.setPath(xPath, SkRegion(drawBounds));
1346 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
1347 canvas->drawRegion(xRegion, paint);
1348 SkIRect test = SkIRect::MakeXYWH(frame* 128, 64, 5, 5);
1349 if (xRegion.contains(test)) {
1350 paint.setColor(SK_ColorYELLOW);
1351 canvas->drawRect(SkRect::Make(test), paint);
1352 }
1353##
1354
1355#SeeAlso intersects SkRect::contains
1356
1357#Method ##
1358
1359# ------------------------------------------------------------------------------
1360
1361#Method bool contains(const SkRegion& other) const
1362
1363Returns true if other is completely inside Region.
1364Returns false if Region or other is empty.
1365
1366#Param other Region to contain ##
1367
1368#Return true if other is inside Region ##
1369
1370#Example
1371#Height 128
1372#Duration 4
1373 SkPaint paint;
1374 paint.setTextSize(128);
1375 SkPath xPath, testPath;
1376 paint.getTextPath("X", 1, 20, 110, &xPath);
1377 paint.getTextPath("`", 1, frame * 150 - 40, 150, &testPath);
1378 SkRegion xRegion, testRegion;
1379 SkIRect drawBounds = {0, 0, 128, 128};
1380 xRegion.setPath(xPath, SkRegion(drawBounds));
1381 testRegion.setPath(testPath, SkRegion(drawBounds));
1382 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
1383 canvas->drawRegion(xRegion, paint);
1384 if (xRegion.contains(testRegion)) {
1385 paint.setColor(SK_ColorYELLOW);
1386 canvas->drawRegion(testRegion, paint);
1387 }
1388##
1389
1390#SeeAlso intersects SkRect::contains
1391
1392#Method ##
1393
1394# ------------------------------------------------------------------------------
1395
1396#Method bool quickContains(const SkIRect& r) const
1397#In Intersection
1398#Line # returns true quickly if points are equal or inside ##
1399
1400Returns true if Region is a single rectangle and contains r.
1401May return false even though Region contains r.
1402
1403#Param r IRect to contain ##
1404
1405#Return true quickly if r points are equal or inside ##
1406
1407#Example
1408 SkRegion region({1, 2, 3, 4});
1409 SkIRect test = {2, 2, 3, 3};
1410 SkDebugf("quickContains 1: %s\n", region.quickContains(test) ? "true" : "false");
1411 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1412 SkDebugf("quickContains 2: %s\n", region.quickContains(test) ? "true" : "false");
1413 region.op({1, 7, 3, 8}, SkRegion::kUnion_Op);
1414 SkDebugf("quickContains 3: %s\n", region.quickContains(test) ? "true" : "false");
1415#StdOut
1416quickContains 1: true
1417quickContains 2: true
1418quickContains 3: false
1419##
1420##
1421
1422#SeeAlso contains quickReject intersects
1423
1424#Method ##
1425
1426# ------------------------------------------------------------------------------
1427
1428#Method bool quickContains(int32_t left, int32_t top, int32_t right,
1429 int32_t bottom) const
1430
1431Returns true if Region is a single rectangle and contains IRect
1432(left, top, right, bottom).
1433Returns false if Region is empty or IRect (left, top, right, bottom) is empty.
1434May return false even though Region contains (left, top, right, bottom).
1435
1436#Param left edge of bounds on x-axis ##
1437#Param top edge of bounds on y-axis ##
1438#Param right edge of bounds on x-axis ##
1439#Param bottom edge of bounds on y-axis ##
1440
1441#Return true quickly if IRect are equal or inside ##
1442
1443#Example
1444 auto debugster = [](const char* label, SkRegion& region) -> void {
1445 SkDebugf("%s: %s\n", label, region.quickContains(2, 2, 3, 3) ? "true" : "false");
1446 };
1447 SkRegion region({1, 2, 3, 4});
1448 debugster("quickContains 1", region);
1449 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1450 debugster("quickContains 2", region);
1451 region.op({1, 7, 3, 8}, SkRegion::kUnion_Op);
1452 debugster("quickContains 3", region);
1453#StdOut
1454quickContains 1: true
1455quickContains 2: true
1456quickContains 3: false
1457##
1458##
1459
1460#SeeAlso contains quickReject intersects
1461
1462#Method ##
1463
1464# ------------------------------------------------------------------------------
1465
1466#Method bool quickReject(const SkIRect& rect) const
1467#In Intersection
1468#Line # returns true quickly if points are outside ##
1469
1470Returns true if Region does not intersect rect.
1471Returns true if rect is empty or Region is empty.
1472May return false even though Region does not intersect rect.
1473
1474#Param rect IRect to intersect ##
1475
1476#Return true if rect does not intersect ##
1477
1478#Example
1479 SkRegion region({1, 2, 3, 4});
1480 SkIRect test = {4, 2, 5, 3};
1481 SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false");
1482 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1483 SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false");
1484 region.op({4, 7, 5, 8}, SkRegion::kUnion_Op);
1485 SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
1486#StdOut
1487quickReject 1: true
1488quickReject 2: true
1489quickReject 3: false
1490##
1491##
1492
1493#SeeAlso quickContains contains intersects
1494
1495#Method ##
1496
1497# ------------------------------------------------------------------------------
1498
1499#Method bool quickReject(const SkRegion& rgn) const
1500
1501Returns true if Region does not intersect rgn.
1502Returns true if rgn is empty or Region is empty.
1503May return false even though Region does not intersect rgn.
1504
1505#Param rgn Region to intersect ##
1506
1507#Return true if rgn does not intersect ##
1508
1509#Example
1510 SkRegion region({1, 2, 3, 4});
1511 SkRegion test;
1512 SkIRect rects[] = {{4, 2, 5, 3}, {7, 2, 8, 3}};
1513 test.setRects(rects, SK_ARRAY_COUNT(rects));
1514 SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false");
1515 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1516 SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false");
1517 region.op({4, 7, 5, 8}, SkRegion::kUnion_Op);
1518 SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
1519#StdOut
1520quickReject 1: true
1521quickReject 2: true
1522quickReject 3: false
1523##
1524##
1525
1526#SeeAlso quickContains contains intersects
1527
1528#Method ##
1529
1530# ------------------------------------------------------------------------------
1531
1532#Method void translate(int dx, int dy)
1533#In Transform
1534#Line # translates IPoints in Region ##
1535
1536Offsets Region by IVector (dx, dy). Has no effect if Region is empty.
1537
1538#Param dx x-axis offset ##
1539#Param dy y-axis offset ##
1540
1541#Example
1542#Height 90
1543 SkRegion test;
1544 SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}};
1545 test.setRects(rects, SK_ARRAY_COUNT(rects));
1546 SkPaint paint;
1547 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) {
1548 paint.setColor(color);
1549 canvas->drawRegion(test, paint);
1550 test.translate(10, 10);
1551 }
1552##
1553
1554#SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset
1555
1556#Method ##
1557
1558# ------------------------------------------------------------------------------
1559
1560#Method void translate(int dx, int dy, SkRegion* dst) const
1561
1562Offsets Region by IVector (dx, dy), writing result to dst. Region may be passed
1563as dst parameter, translating Region in place. Has no effect if dst is nullptr.
1564If Region is empty, sets dst to empty.
1565
1566#Param dx x-axis offset ##
1567#Param dy y-axis offset ##
1568#Param dst translated result ##
1569
1570#Example
1571 SkRegion test;
1572 SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}};
1573 test.setRects(rects, SK_ARRAY_COUNT(rects));
1574 SkPaint paint;
1575 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) {
1576 paint.setColor(color);
1577 canvas->drawRegion(test, paint);
1578 SkRegion second;
1579 test.translate(10, test.getBounds().fBottom, &second);
1580 test.op(second, SkRegion::kXOR_Op);
1581 test.translate(30, 0);
1582 }
1583##
1584
1585#SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset
1586
1587#Method ##
1588
1589# ------------------------------------------------------------------------------
1590
1591#Enum Op
1592#Line # binary operator combining Regions ##
1593
1594#Code
1595 enum Op {
1596 kDifference_Op,
1597 kIntersect_Op,
1598 kUnion_Op,
1599 kXOR_Op,
1600 kReverseDifference_Op,
1601 kReplace_Op,
1602 kLastOp = kReplace_Op,
1603 };
1604##
1605
1606The logical operations that can be performed when combining two Regions.
1607
1608#Const kDifference_Op 0
1609#Line # target minus operand ##
1610Subtracts operand Region from target Region.
1611##
1612#Const kIntersect_Op 1
1613#Line # target intersected with operand ##
1614Intersects operand Region and target Region.
1615##
1616#Const kUnion_Op 2
1617#Line # target unioned with operand ##
1618Unions operand Region and target Region.
1619##
1620#Const kXOR_Op 3
1621#Line # target exclusive or with operand ##
1622Replaces target Region with area exclusive to both Regions.
1623##
1624#Const kReverseDifference_Op 4
1625#Line # operand minus target ##
1626Subtracts target Region from operand Region.
1627##
1628#Const kReplace_Op 5
1629#Line # replace target with operand ##
1630Replaces target Region with operand Region.
1631##
1632#Const kLastOp 5
1633#Line # last operator ##
1634##
1635
1636#Example
1637 SkRegion operand({35, 35, 85, 85});
1638 const char* labels[] = {"difference", "intersect", "union", "xor", "reverse diff", "replace"};
1639 int index = 0;
1640 SkPaint paint;
1641 paint.setTextAlign(SkPaint::kCenter_Align);
1642 for (auto op : { SkRegion::kDifference_Op, SkRegion::kIntersect_Op, SkRegion::kUnion_Op,
1643 SkRegion::kXOR_Op, SkRegion::kReverseDifference_Op, SkRegion::kReplace_Op } ) {
1644 SkRegion target({10, 10, 60, 60});
1645 target.op(operand, op);
1646 canvas->drawRegion(target, paint);
1647 canvas->drawString(labels[index++], 40, 100, paint);
1648 canvas->translate(80, 0);
1649 if (SkRegion::kUnion_Op == op) {
1650 canvas->translate(-240, 120);
1651 }
1652 }
1653##
1654
1655#SeeAlso SkPathOp
1656
1657#Enum ##
1658
1659# ------------------------------------------------------------------------------
1660
1661#Const kOpCnt 6
1662#Line # number of operators defined ##
1663May be used to verify that Op is a legal value.
1664#Const ##
1665
1666# ------------------------------------------------------------------------------
1667
1668#Method bool op(const SkIRect& rect, Op op)
1669#In Transform
1670#Line # applies binary operator ##
1671
1672Replaces Region with the result of Region op rect.
1673Returns true if replaced Region is not empty.
1674
1675#Param rect IRect operand ##
1676#Param op operator, one of: #list_of_op_types#
1677##
1678
1679#Return false if result is empty ##
1680
1681#Example
1682#Height 128
1683 SkPaint paint;
1684 paint.setTextSize(128);
1685 SkPath xPath;
1686 paint.getTextPath("X", 1, 20, 110, &xPath);
1687 SkRegion xRegion;
1688 SkIRect drawBounds = {0, 0, 128, 128};
1689 xRegion.setPath(xPath, SkRegion(drawBounds));
1690 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
1691 canvas->drawRegion(xRegion, paint);
1692##
1693
1694#SeeAlso setRects Op
1695
1696#Method ##
1697
1698# ------------------------------------------------------------------------------
1699
1700#Method bool op(int left, int top, int right, int bottom, Op op)
1701
1702Replaces Region with the result of Region op IRect (left, top, right, bottom).
1703Returns true if replaced Region is not empty.
1704
1705#Param left edge of bounds on x-axis ##
1706#Param top edge of bounds on y-axis ##
1707#Param right edge of bounds on x-axis ##
1708#Param bottom edge of bounds on y-axis ##
1709#Param op operator, one of: #list_of_op_types#
1710##
1711
1712#Return false if result is empty ##
1713
1714#Example
1715#Duration 4
1716#Height 128
1717 SkPaint paint;
1718 paint.setTextSize(128);
1719 SkPath xPath;
1720 paint.getTextPath("X", 1, 20, 110, &xPath);
1721 SkRegion xRegion;
1722 SkIRect drawBounds = {0, 0, 128, 128};
1723 xRegion.setPath(xPath, SkRegion(drawBounds));
1724 xRegion.op(drawBounds.fLeft + frame * drawBounds.width(), drawBounds.fTop,
1725 drawBounds.fRight, drawBounds.fBottom, SkRegion::kReverseDifference_Op);
1726 canvas->drawRegion(xRegion, paint);
1727##
1728
1729#SeeAlso setRects Op
1730
1731#Method ##
1732
1733# ------------------------------------------------------------------------------
1734
1735#Method bool op(const SkRegion& rgn, Op op)
1736
1737Replaces Region with the result of Region op rgn.
1738Returns true if replaced Region is not empty.
1739
1740#Param rgn Region operand ##
1741#Param op operator, one of: #list_of_op_types#
1742##
1743
1744#Return false if result is empty ##
1745
1746#Example
1747#Duration 4
1748#Height 128
1749 SkPaint paint;
1750 paint.setTextSize(128);
1751 SkPath xPath, opPath;
1752 paint.getTextPath("X", 1, 20, 110, &xPath);
1753 opPath.addCircle(64, 64, frame * 64);
1754 SkRegion xRegion, opRegion;
1755 SkIRect drawBounds = {0, 0, 128, 128};
1756 opRegion.setPath(opPath, SkRegion(drawBounds));
1757 xRegion.setPath(xPath, SkRegion(drawBounds));
1758 xRegion.op(opRegion, SkRegion::kReverseDifference_Op);
1759 canvas->drawRegion(xRegion, paint);
1760##
1761
1762#SeeAlso setRects Op
1763
1764#Method ##
1765
1766# ------------------------------------------------------------------------------
1767
1768#Method bool op(const SkIRect& rect, const SkRegion& rgn, Op op)
1769
1770Replaces Region with the result of rect op rgn.
1771Returns true if replaced Region is not empty.
1772
1773#Param rect IRect operand ##
1774#Param rgn Region operand ##
1775#Param op operator, one of: #list_of_op_types#
1776##
1777
1778#Return false if result is empty ##
1779
1780#Example
1781#Duration 4
1782#Height 128
1783 SkPaint paint;
1784 paint.setTextSize(128);
1785 SkPath xPath, opPath;
1786 paint.getTextPath("X", 1, 20, 110, &xPath);
1787 opPath.addCircle(64, 64, frame * 64);
1788 SkRegion xRegion, opRegion, rectRegion;
1789 SkIRect drawBounds = {0, 0, 128, 128};
1790 opRegion.setPath(opPath, SkRegion(drawBounds));
1791 xRegion.setPath(xPath, SkRegion(drawBounds));
1792 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1793 rectRegion.op(drawBounds, opRegion, SkRegion::kIntersect_Op);
1794 xRegion.op(rectRegion, SkRegion::kReverseDifference_Op);
1795 canvas->drawRegion(xRegion, paint);
1796##
1797
1798#SeeAlso setRects Op
1799
1800#Method ##
1801
1802# ------------------------------------------------------------------------------
1803
1804#Method bool op(const SkRegion& rgn, const SkIRect& rect, Op op)
1805
1806Replaces Region with the result of rgn op rect.
1807Returns true if replaced Region is not empty.
1808
1809#Param rgn Region operand ##
1810#Param rect IRect operand ##
1811#Param op operator, one of: #list_of_op_types#
1812##
1813
1814#Return false if result is empty ##
1815
1816#Example
1817#Duration 4
1818#Height 128
1819 SkPaint paint;
1820 paint.setTextSize(128);
1821 SkPath xPath, opPath;
1822 paint.getTextPath("X", 1, 20, 110, &xPath);
1823 opPath.addCircle(64, 64, frame * 64);
1824 SkRegion xRegion, opRegion, rectRegion;
1825 SkIRect drawBounds = {0, 0, 128, 128};
1826 opRegion.setPath(opPath, SkRegion(drawBounds));
1827 xRegion.setPath(xPath, SkRegion(drawBounds));
1828 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1829 rectRegion.op(opRegion, drawBounds, SkRegion::kUnion_Op);
1830 xRegion.op(rectRegion, SkRegion::kReverseDifference_Op);
1831 canvas->drawRegion(xRegion, paint);
1832##
1833
1834#SeeAlso setRects Op
1835
1836#Method ##
1837
1838# ------------------------------------------------------------------------------
1839
1840#Method bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op)
1841
1842Replaces Region with the result of rgna op rgnb.
1843Returns true if replaced Region is not empty.
1844
1845#Param rgna Region operand ##
1846#Param rgnb Region operand ##
1847#Param op operator, one of: #list_of_op_types#
1848##
1849
1850#Return false if result is empty ##
1851
1852#Example
1853#Duration 4
1854#Height 128
1855 SkPaint paint;
1856 paint.setTextSize(128);
1857 SkPath xPath, opPath;
1858 paint.getTextPath("X", 1, 20, 110, &xPath);
1859 xPath.setFillType(SkPath::kInverseWinding_FillType);
1860 opPath.addCircle(64, 64, frame * 64);
1861 opPath.setFillType(SkPath::kInverseWinding_FillType);
1862 SkRegion xRegion, opRegion, rectRegion;
1863 SkIRect drawBounds = {0, 0, 128, 128};
1864 opRegion.setPath(opPath, SkRegion(drawBounds));
1865 xRegion.setPath(xPath, SkRegion(drawBounds));
1866 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1867 rectRegion.setRect(drawBounds);
1868 rectRegion.op(xRegion, SkRegion::kIntersect_Op);
1869 xRegion.op(rectRegion, opRegion, SkRegion::kReverseDifference_Op);
1870 canvas->drawRegion(xRegion, paint);
1871##
1872
1873#SeeAlso setRects Op
1874
1875#Method ##
1876
1877# ------------------------------------------------------------------------------
1878
1879#Method char* toString()
1880#In Utility
1881#Line # exists for Android framework only ##
1882#Private
1883Android framework only.
1884##
1885#Return string representation of Region ##
1886
1887#Method ##
1888
1889# ------------------------------------------------------------------------------
1890
1891#Method size_t writeToMemory(void* buffer) const
1892#In Utility
1893#Line # writes to buffer ##
1894
1895Writes Region to buffer, and returns number of bytes written.
1896If buffer is nullptr, returns number number of bytes that would be written.
1897
1898#Param buffer storage for binary data ##
1899
1900#Return size of Region ##
1901
1902#Example
1903#Height 128
1904 SkPaint paint;
1905 paint.setTextSize(128);
1906 SkPath xPath;
1907 paint.getTextPath("X", 1, 20, 110, &xPath);
1908 SkIRect drawBounds = {0, 0, 128, 128};
1909 SkRegion xRegion;
1910 xRegion.setPath(xPath, SkRegion(drawBounds));
1911 size_t size = xRegion.writeToMemory(nullptr);
1912 sk_sp<SkData> data = SkData::MakeUninitialized(size);
1913 xRegion.writeToMemory(data->writable_data());
1914 SkRegion copy;
1915 copy.readFromMemory(data->data(), data->size());
1916 canvas->drawRegion(copy, paint);
1917##
1918
1919#SeeAlso readFromMemory
1920
1921#Method ##
1922
1923# ------------------------------------------------------------------------------
1924
1925#Method size_t readFromMemory(const void* buffer, size_t length)
1926#In Utility
1927#Line # reads from buffer ##
1928
1929Constructs Region from buffer of size length. Returns bytes read.
1930Returned value will be multiple of four or zero if length was too small.
1931
1932#Param buffer storage for binary data ##
1933#Param length size of buffer ##
1934
1935#Return bytes read ##
1936
1937#Example
1938#Height 100
1939 SkRegion region({20, 20, 80, 80});
1940 size_t size = region.writeToMemory(nullptr);
1941 sk_sp<SkData> data = SkData::MakeUninitialized(size);
1942 region.writeToMemory(data->writable_data());
1943 SkRegion copy;
1944 copy.readFromMemory(data->data(), data->size());
1945 canvas->drawRegion(copy, SkPaint());
1946##
1947
1948#SeeAlso writeToMemory
1949
1950#Method ##
1951
1952#Class SkRegion ##
1953
1954#Topic Region ##