blob: 7e72f6ae2f8465e51be96fa2a1b3e39f23a6fb51 [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
Cary Clark61313f32018-10-08 14:57:48 -040023#Code
24#Populate
25##
26
Cary Clarkd2ca79c2018-08-10 13:09:13 -040027SkRegion describes the set of pixels used to clip Canvas. SkRegion is compact,
28efficiently storing a single integer rectangle, or a run length encoded array
29of rectangles. SkRegion may reduce the current Canvas_Clip, or may be drawn as
30one or more integer rectangles. SkRegion iterator returns the scan lines or
31rectangles contained by it, optionally intersecting a bounding rectangle.
32
Cary Clarkd2ca79c2018-08-10 13:09:13 -040033# ------------------------------------------------------------------------------
34
35#Class Iterator
36#Line # iterator returning IRect ##
37
38#Code
39 class Iterator {
40 public:
41 Iterator();
42 Iterator(const SkRegion& region);
43 bool rewind();
44 void reset(const SkRegion& region);
45 bool done() const;
46 void next();
47 const SkIRect& rect();
48 const SkRegion* rgn();
49 };
50##
51
52Returns sequence of rectangles, sorted along y-axis, then x-axis, that make
53up Region.
54
55# ------------------------------------------------------------------------------
56
57#Method Iterator()
58#Line # constructs Region iterator ##
Cary Clark09d80c02018-10-31 12:14:03 -040059#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -040060
61#Example
62 SkRegion::Iterator iter;
Cary Clark09d80c02018-10-31 12:14:03 -040063 SkRegion region;
64 region.setRect({1, 2, 3, 4});
65 iter.reset(region);
66 auto r = iter.rect();
67 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
68#StdOut
Cary Clarkd2ca79c2018-08-10 13:09:13 -040069rect={1,2,3,4}
70##
71##
72
73#SeeAlso reset SkRegion
74
75#Method ##
76
77# ------------------------------------------------------------------------------
78
79#Method Iterator(const SkRegion& region)
80#Line # constructs Region iterator ##
Cary Clark09d80c02018-10-31 12:14:03 -040081#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -040082
83#Example
Cary Clark09d80c02018-10-31 12:14:03 -040084 SkRegion region;
85 region.setRect({1, 2, 3, 4});
86 SkRegion::Iterator iter(region);
87 auto r = iter.rect();
88 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
89#StdOut
Cary Clarkd2ca79c2018-08-10 13:09:13 -040090rect={1,2,3,4}
91##
92##
93
94#SeeAlso reset SkRegion Cliperator Spanerator
95
96#Method ##
97
98# ------------------------------------------------------------------------------
99
100#Method bool rewind()
101#Line # points Iterator to start ##
Cary Clark09d80c02018-10-31 12:14:03 -0400102#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400103
104#Example
105#Bug 8186
Cary Clark09d80c02018-10-31 12:14:03 -0400106 auto debugster = [](const char* label, SkRegion::Iterator& iter, bool addRewind) -> void {
107 if (addRewind) {
108 bool success = iter.rewind();
109 SkDebugf("%14s rewind success=%s\n", label, success ? "true" : "false");
110 }
111 auto r = iter.rect();
112 SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
113 };
114 SkRegion::Iterator iter;
115 debugster("empty iter", iter, true);
116 SkRegion region;
117 iter.reset(region);
118 debugster("empty region", iter, true);
119 region.setRect({1, 2, 3, 4});
120 iter.reset(region);
121 debugster("after set rect", iter, false);
122 debugster("after rewind", iter, true);
123#StdOut
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400124#Volatile
Cary Clark09d80c02018-10-31 12:14:03 -0400125 empty iter rewind success=false
126 empty iter rect={0,0,0,0}
127 empty region rewind success=true
128 empty region rect={0,0,0,0}
129after set rect rect={1,2,3,4}
130 after rewind rewind success=true
131 after rewind rect={1,2,3,4}
132##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400133##
134
135#SeeAlso reset
136
137#Method ##
138
139# ------------------------------------------------------------------------------
140
141#Method void reset(const SkRegion& region)
142#Line # sets Region to iterate ##
Cary Clark09d80c02018-10-31 12:14:03 -0400143#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400144
145#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400146 auto debugster = [](const char* label, SkRegion::Iterator& iter) -> void {
147 SkDebugf("%14s: done=%s\n", label, iter.done() ? "true" : "false");
148 };
149 SkRegion region;
150 SkRegion::Iterator iter(region);
151 debugster("empty region", iter);
152 region.setRect({1, 2, 3, 4});
153 debugster("after set rect", iter);
154 iter.reset(region);
155 debugster("after reset", iter);
156#StdOut
157 empty region: done=true
158after set rect: done=true
159 after reset: done=false
160##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400161##
162
163#SeeAlso rewind
164
165#Method ##
166
167# ------------------------------------------------------------------------------
168
169#Method bool done() const
170#Line # returns if data parsing is complete ##
Cary Clark09d80c02018-10-31 12:14:03 -0400171#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400172
173#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400174 SkRegion region;
175 SkRegion::Iterator iter(region);
176 SkDebugf("done=%s\n", iter.done() ? "true" : "false");
177 region.setRect({1, 2, 3, 4});
178 iter.rewind();
179 SkDebugf("done=%s\n", iter.done() ? "true" : "false");
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400180#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400181done=true
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400182done=false
183##
184##
185
186#SeeAlso next rect
187
188#Method ##
189
190# ------------------------------------------------------------------------------
191
192#Method void next()
193#Line # advances to next IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400194#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400195
196#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400197 SkRegion region;
198 SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
199 region.setRects(rects, SK_ARRAY_COUNT(rects));
200 SkRegion::Iterator iter(region);
201 do {
202 auto r2 = iter.rect();
203 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
204 iter.next();
205 } while (!iter.done());
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400206#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400207rect={1,2,3,4}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400208rect={5,6,7,8}
209##
210##
211
212#SeeAlso done rect
213
214#Method ##
215
216# ------------------------------------------------------------------------------
217
218#Method const SkIRect& rect() const
219#Line # returns part of Region as IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400220#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400221
222#Example
223#Bug 8186
Cary Clark09d80c02018-10-31 12:14:03 -0400224 SkRegion region;
225 SkRegion::Iterator iter(region);
226 auto r1 = iter.rect();
227 SkDebugf("rect={%d,%d,%d,%d}\n", r1.fLeft, r1.fTop, r1.fRight, r1.fBottom);
228 region.setRect({1, 2, 3, 4});
229 iter.rewind();
230 auto r2 = iter.rect();
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400231 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
232#StdOut
233#Volatile
Cary Clark09d80c02018-10-31 12:14:03 -0400234rect={0,0,0,0}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400235rect={1,2,3,4}
236##
237##
238
239#SeeAlso next done
240
241#Method ##
242
243# ------------------------------------------------------------------------------
244
245#Method const SkRegion* rgn() const
246#Line # returns original Region ##
Cary Clark09d80c02018-10-31 12:14:03 -0400247#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400248
249#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400250 SkRegion region;
251 SkIRect rects[] = {{1, 2, 3, 4}, {3, 4, 5, 6}};
252 region.setRects(rects, SK_ARRAY_COUNT(rects));
253 SkRegion::Iterator iter(region);
254 auto r = iter.rect();
255 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
256 auto b = iter.rgn()->getBounds();
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400257 SkDebugf("bounds={%d,%d,%d,%d}\n", b.fLeft, b.fTop, b.fRight, b.fBottom);
258##
259
260#SeeAlso Iterator reset
261
262#Method ##
263
264#Class Iterator ##
265
266# ------------------------------------------------------------------------------
267
268#Class Cliperator
269#Line # iterator returning IRect within clip ##
270
271#Code
272 class SK_API Cliperator {
273 public:
Cary Clarka8cdc172018-09-07 14:17:08 -0400274 Cliperator(const SkRegion& region, const SkIRect& clip);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400275 bool done();
276 void next();
277 const SkIRect& rect() const;
278 };
279##
280
281Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make
282up Region intersected with the specified clip rectangle.
283
284# ------------------------------------------------------------------------------
285
286#Method Cliperator(const SkRegion& region, const SkIRect& clip)
287#Line # constructs Region iterator with clip ##
Cary Clark09d80c02018-10-31 12:14:03 -0400288#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400289
290#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400291 SkRegion region;
292 region.setRect({1, 2, 3, 4});
293 SkRegion::Cliperator clipper(region, {0, 0, 2, 3});
294 auto r = clipper.rect();
295 SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
296#StdOut
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400297rect={1,2,2,3}
298##
299##
300
301#SeeAlso SkRegion Iterator Spanerator
302
303#Method ##
304
305# ------------------------------------------------------------------------------
306
307#Method bool done()
308#Line # returns if data parsing is complete ##
Cary Clark09d80c02018-10-31 12:14:03 -0400309#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400310
311#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400312 auto debugster = [](const char* label, SkRegion& region) -> void {
313 SkRegion::Cliperator clipper(region, {0, 0, 5, 5});
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400314 SkDebugf("%14s done=%s\n", label, clipper.done() ? "true" : "false");
Cary Clark09d80c02018-10-31 12:14:03 -0400315 };
316 SkRegion region;
317 debugster("empty region", region);
318 region.setRect({1, 2, 3, 4});
319 debugster("after add rect", region);
320#StdOut
321 empty region done=true
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400322after add rect done=false
323##
324##
325
326#SeeAlso next rect
327
328#Method ##
329
330# ------------------------------------------------------------------------------
331
332#Method void next()
333#Line # advances to next IRect within clip ##
Cary Clark09d80c02018-10-31 12:14:03 -0400334#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400335
336#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400337 SkRegion region;
338 SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
339 region.setRects(rects, SK_ARRAY_COUNT(rects));
340 SkRegion::Cliperator clipper(region, {0, 3, 8, 7});
341 do {
342 auto r2 = clipper.rect();
343 SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom);
344 clipper.next();
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400345 } while (!clipper.done());
346#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400347rect={1,3,3,4}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400348rect={5,6,7,7}
349##
350##
351
352#SeeAlso done
353
354#Method ##
355
356# ------------------------------------------------------------------------------
357
358#Method const SkIRect& rect() const
359#Line # returns part of Region as IRect intersected with clip ##
Cary Clark09d80c02018-10-31 12:14:03 -0400360#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400361
362#Example
363#Bug 8186
Cary Clark09d80c02018-10-31 12:14:03 -0400364 auto debugster = [](const char* label, SkRegion& region) -> void {
365 SkRegion::Cliperator clipper(region, {0, 0, 5, 3});
366 auto r = clipper.rect();
367 SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400368 };
Cary Clark09d80c02018-10-31 12:14:03 -0400369 SkRegion region;
370 debugster("empty region", region);
371 region.setRect({1, 2, 3, 4});
372 debugster("after set rect", region);
373#StdOut
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400374#Volatile
Cary Clark09d80c02018-10-31 12:14:03 -0400375 empty region rect={1094713344,1065353216,0,-1}
376after set rect rect={1,2,3,3}
377##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400378##
379
380#SeeAlso next done
381
382#Method ##
383
384#Class Cliperator ##
385
386# ------------------------------------------------------------------------------
387
388#Class Spanerator
389#Line # horizontal line segment iterator ##
390
391#Code
392 class Spanerator {
393 public:
394 Spanerator(const SkRegion& region, int y, int left, int right);
395 bool next(int* left, int* right);
396 };
397##
398
399Returns the line segment ends within Region that intersect a horizontal line.
400
401# ------------------------------------------------------------------------------
402
403#Method Spanerator(const SkRegion& region, int y, int left, int right)
404#Line # constructs Region iterator on scan line ##
Cary Clark09d80c02018-10-31 12:14:03 -0400405#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400406
407#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400408 SkRegion region;
409 region.setRect({1, 2, 3, 4});
410 SkRegion::Spanerator spanner(region, 3, 2, 4);
411 int left, right;
412 bool result = spanner.next(&left, &right);
413 SkDebugf("result=%s left=%d right=%d\n", result ? "true" : "false", left, right);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400414##
415
416#SeeAlso SkRegion Iterator Cliperator
417
418#Method ##
419
420# ------------------------------------------------------------------------------
421
422#Method bool next(int* left, int* right)
423#Line # advances to next span on horizontal line ##
Cary Clark09d80c02018-10-31 12:14:03 -0400424#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400425
426#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400427 auto debugster = [](const char* label, SkRegion& region) -> void {
428 SkRegion::Spanerator spanner(region, 3, 2, 4);
429 int left, right;
430 bool result = spanner.next(&left, &right);
431 SkDebugf("%14s: result=%s", label, result ? "true" : "false");
432 if (result) SkDebugf(" left=%d right=%d", left, right);
433 SkDebugf("\n");
434 };
435 SkRegion region;
436 debugster("empty region", region);
437 region.setRect({1, 2, 3, 4});
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400438 debugster("after set rect", region);
439#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400440 empty region: result=false
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400441after set rect: result=true left=2 right=3
442##
443##
444
445#SeeAlso done
446
447#Method ##
448
449#Class Spanerator ##
450
451# ------------------------------------------------------------------------------
452
453#Method SkRegion()
Cary Clark61313f32018-10-08 14:57:48 -0400454#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400455#Line # constructs with default values ##
Cary Clark09d80c02018-10-31 12:14:03 -0400456#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400457
458#Example
459SkRegion region;
460SkIRect r = region.getBounds();
461SkDebugf("region bounds: {%d, %d, %d, %d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
462#StdOut
463region bounds: {0, 0, 0, 0}
464##
465##
466
467#SeeAlso setEmpty
468
469#Method ##
470
471# ------------------------------------------------------------------------------
472
473#Method SkRegion(const SkRegion& region)
Cary Clark61313f32018-10-08 14:57:48 -0400474#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400475#Line # makes a shallow copy ##
Cary Clark09d80c02018-10-31 12:14:03 -0400476#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400477
478#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400479 auto debugster = [](const char* label, SkRegion& region) -> void {
480 auto r = region.getBounds();
481 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400482 };
483 SkRegion region({1, 2, 3, 4});
484 SkRegion region2(region);
485 debugster("region bounds", region);
486 debugster("region2 bounds", region2);
487 region.setEmpty();
488 SkDebugf(" after region set empty:\n");
489 debugster("region bounds", region);
490 debugster("region2 bounds", region2);
491#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400492 region bounds: {1,2,3,4}
493region2 bounds: {1,2,3,4}
494 after region set empty:
495 region bounds: {0,0,0,0}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400496region2 bounds: {1,2,3,4}
497##
498##
499
500#SeeAlso setRegion operator=(const SkRegion& region)
501
502#Method ##
503
504# ------------------------------------------------------------------------------
505
506#Method explicit SkRegion(const SkIRect& rect)
Cary Clark61313f32018-10-08 14:57:48 -0400507#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400508#Line # constructs Region matching IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400509#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400510
511#Example
512 SkRegion region({1, 2, 3, 4});
513 SkRegion region2;
514 region2.setRect({1, 2, 3, 4});
515 SkDebugf("region %c= region2\n", region == region2 ? '=' : '!');
516##
517
518#SeeAlso setRect setRegion
519
520#Method ##
521
522# ------------------------------------------------------------------------------
523
524#Method ~SkRegion()
Cary Clark61313f32018-10-08 14:57:48 -0400525#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400526#Line # decreases Reference_Count of owned objects ##
Cary Clark09d80c02018-10-31 12:14:03 -0400527#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400528
529#Example
530#Description
Cary Clark09d80c02018-10-31 12:14:03 -0400531delete calls Region destructor, but copy of original in region2 is unaffected.
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400532##
533 SkRegion* region = new SkRegion({1, 2, 3, 4});
534 SkRegion region2(*region);
535 delete region;
Cary Clark09d80c02018-10-31 12:14:03 -0400536 auto r = region2.getBounds();
537 SkDebugf("region2 bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
538#StdOut
539region2 bounds: {1,2,3,4}
540##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400541##
542
543#SeeAlso SkRegion() SkRegion(const SkRegion& region) SkRegion(const SkIRect& rect) operator=(const SkRegion& region)
544
545#Method ##
546
547# ------------------------------------------------------------------------------
548
549#Method SkRegion& operator=(const SkRegion& region)
Cary Clark61313f32018-10-08 14:57:48 -0400550#In Operators
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400551#Line # makes a shallow copy ##
Cary Clark09d80c02018-10-31 12:14:03 -0400552#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400553
554#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400555 auto debugster = [](const char* label, SkRegion& region) -> void {
556 auto r = region.getBounds();
557 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400558 };
559 SkRegion region1({1, 2, 3, 4});
560 SkRegion region2 = region1;
561 debugster("region1 bounds", region1);
562 debugster("region2 bounds", region2);
Cary Clark09d80c02018-10-31 12:14:03 -0400563#StdOut
564region1 bounds: {1,2,3,4}
565region2 bounds: {1,2,3,4}
566##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400567##
568
569#SeeAlso set swap SkRegion(const SkRegion& region)
570
571#Method ##
572
573# ------------------------------------------------------------------------------
574
575#Method bool operator==(const SkRegion& other)_const
Cary Clark61313f32018-10-08 14:57:48 -0400576#In Operators
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400577#Line # compares Regions for equality ##
Cary Clark09d80c02018-10-31 12:14:03 -0400578#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400579
580#Example
581 auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void {
582 SkDebugf("%s one %c= two\n", prefix, a == b ? '=' : '!');
583 };
584 SkRegion one;
585 SkRegion two;
586 debugster("empty", one, two);
587 one.setRect({1, 2, 3, 4});
588 debugster("set rect", one, two);
589 one.setEmpty();
590 debugster("set empty", one, two);
591#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400592empty one == two
593set rect one != two
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400594set empty one == two
595##
596##
597
598#SeeAlso operator!=(const SkRegion& other)_const operator=(const SkRegion& region)
599
600#Method ##
601
602# ------------------------------------------------------------------------------
603
604#Method bool operator!=(const SkRegion& other)_const
Cary Clark61313f32018-10-08 14:57:48 -0400605#In Operators
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400606#Line # compares Regions for inequality ##
Cary Clark09d80c02018-10-31 12:14:03 -0400607#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400608
609#Example
610 auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void {
611 SkDebugf("%s one %c= two\n", prefix, a != b ? '!' : '=');
612 };
613 SkRegion one;
614 SkRegion two;
615 debugster("empty", one, two);
616 one.setRect({1, 2, 3, 4});
617 two.setRect({1, 2, 3, 3});
618 debugster("set rect", one, two);
619 two.op({1, 3, 3, 4}, SkRegion::kUnion_Op);
620 debugster("union rect", one, two);
621#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400622empty one == two
623set rect one != two
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400624union rect one == two
625##
626##
627
628#SeeAlso operator==(const SkRegion& other)_const operator=(const SkRegion& region)
629
630#Method ##
631
632# ------------------------------------------------------------------------------
633
634#Method bool set(const SkRegion& src)
Cary Clark61313f32018-10-08 14:57:48 -0400635#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400636#Line # makes a shallow copy ##
Cary Clark09d80c02018-10-31 12:14:03 -0400637#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400638
639#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400640 auto debugster = [](const char* label, SkRegion& region) -> void {
641 auto r = region.getBounds();
642 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400643 };
644 SkRegion region1({1, 2, 3, 4});
645 SkRegion region2;
646 region2.set(region1);
647 debugster("region1 bounds", region1);
648 debugster("region2 bounds", region2);
Cary Clark09d80c02018-10-31 12:14:03 -0400649#StdOut
650region1 bounds: {1,2,3,4}
651region2 bounds: {1,2,3,4}
652##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400653##
654
655#SeeAlso operator=(const SkRegion& region) swap SkRegion(const SkRegion& region)
656
657#Method ##
658
659# ------------------------------------------------------------------------------
660
661#Method void swap(SkRegion& other)
Cary Clark61313f32018-10-08 14:57:48 -0400662#In Operators
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400663#Line # exchanges Region pair ##
Cary Clark09d80c02018-10-31 12:14:03 -0400664#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400665
666#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400667 auto debugster = [](const char* label, SkRegion& region) -> void {
668 auto r = region.getBounds();
669 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400670 };
671 SkRegion region1({1, 2, 3, 4});
672 SkRegion region2;
673 region1.swap(region2);
674 debugster("region1 bounds", region1);
675 debugster("region2 bounds", region2);
Cary Clark09d80c02018-10-31 12:14:03 -0400676#StdOut
677region1 bounds: {0,0,0,0}
678region2 bounds: {1,2,3,4}
679##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400680##
681
682#SeeAlso operator=(const SkRegion& region) set SkRegion(const SkRegion& region)
683
684#Method ##
685
686# ------------------------------------------------------------------------------
687
688#Method bool isEmpty() const
689#In Property
690#Line # returns if bounds has no width or height ##
Cary Clark09d80c02018-10-31 12:14:03 -0400691#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400692
693#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400694 auto debugster = [](const char* label, SkRegion& region) -> void {
695 SkDebugf("%14s: region is %s" "empty\n", label, region.isEmpty() ? "" : "not ");
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400696 };
697 SkRegion region;
698 debugster("initial", region);
699 region.setRect({1, 2, 3, 4});
700 debugster("set rect", region);
701 region.setEmpty();
702 debugster("set empty", region);
703#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400704 initial: region is empty
705 set rect: region is not empty
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400706 set empty: region is empty
707##
708##
709
710#SeeAlso isRect isComplex operator==(const SkRegion& other)_const
711
712#Method ##
713
714# ------------------------------------------------------------------------------
715
716#Method bool isRect() const
717#In Property
718#Line # returns if Region contains one IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400719#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400720
721#Example
722 auto debugster = [](const char* label, const SkRegion& region) -> void {
723 SkDebugf("%s: region is %s" "rect\n", label, region.isRect() ? "" : "not ");
724 };
725 SkRegion region;
726 debugster("initial", region);
727 region.setRect({1, 2, 3, 4});
728 debugster("set rect", region);
729 region.setEmpty();
730 debugster("set empty", region);
731#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400732initial: region is not rect
733set rect: region is rect
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400734set empty: region is not rect
735##
736##
737
738#SeeAlso isEmpty isComplex
739
740#Method ##
741
742# ------------------------------------------------------------------------------
743
744#Method bool isComplex() const
745#In Property
746#Line # returns true if Region contains more than one IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400747#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400748
749#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400750 auto debugster = [](const char* label, const SkRegion& region) -> void {
751 SkDebugf("%s: region is %s" "complex\n", label, region.isComplex() ? "" : "not ");
752 };
753 SkRegion region;
754 debugster("initial", region);
755 region.setRect({1, 2, 3, 4});
756 debugster("set rect", region);
757 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400758 debugster("op rect", region);
759#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400760initial: region is not complex
761set rect: region is not complex
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400762op rect: region is complex
763##
764##
765
766#SeeAlso isEmpty isRect
767
768#Method ##
769
770# ------------------------------------------------------------------------------
771
772#Method const SkIRect& getBounds() const
773#In Property
774#Line # returns maximum and minimum of IRect array ##
Cary Clark09d80c02018-10-31 12:14:03 -0400775#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400776
777#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400778 SkRegion region({1, 2, 3, 4});
779 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
780 auto r = region.getBounds();
781 SkDebugf("bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
782#StdOut
783bounds: {1,2,4,5}
784##
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400785##
786
787#SeeAlso isEmpty isRect
788
789#Method ##
790
791# ------------------------------------------------------------------------------
792
793#Method int computeRegionComplexity() const
794#In Property
795#Line # returns relative complexity ##
Cary Clark09d80c02018-10-31 12:14:03 -0400796#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400797
798#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400799 auto debugster = [](const char* label, const SkRegion& region) -> void {
800 SkDebugf("%s: region complexity %d\n", label, region.computeRegionComplexity());
801 };
802 SkRegion region;
803 debugster("initial", region);
804 region.setRect({1, 2, 3, 4});
805 debugster("set rect", region);
806 region.op({2, 3, 4, 5}, SkRegion::kUnion_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400807 debugster("op rect", region);
808#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400809initial: region complexity 0
810set rect: region complexity 1
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400811op rect: region complexity 3
812##
813##
814
815#SeeAlso isRect isComplex
816
817#Method ##
818
819# ------------------------------------------------------------------------------
820
821#Method bool getBoundaryPath(SkPath* path) const
822#In Property
823#Line # appends Region outline to Path ##
Cary Clark09d80c02018-10-31 12:14:03 -0400824#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400825
826#Example
827#Height 100
Cary Clark09d80c02018-10-31 12:14:03 -0400828 SkRegion region;
829 region.setRect({10, 20, 90, 60});
830 region.op({30, 40, 60, 80}, SkRegion::kXOR_Op);
831 canvas->drawRegion(region, SkPaint());
832 SkPath path;
833 region.getBoundaryPath(&path);
834 path.offset(100, 0);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400835 canvas->drawPath(path, SkPaint());
836##
837
838#SeeAlso isEmpty isComplex
839
840#Method ##
841
842# ------------------------------------------------------------------------------
843
844#Method bool setEmpty()
Cary Clark61313f32018-10-08 14:57:48 -0400845#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400846#Line # constructs with default values ##
Cary Clark09d80c02018-10-31 12:14:03 -0400847#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400848
849#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400850 auto debugster = [](const char* label, SkRegion& region) -> void {
851 auto r = region.getBounds();
852 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400853 };
854 SkRegion region({1, 2, 3, 4});
855 debugster("region bounds", region);
856 region.setEmpty();
857 SkDebugf(" after region set empty:\n");
858 debugster("region bounds", region);
859#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400860 region bounds: {1,2,3,4}
861 after region set empty:
862 region bounds: {0,0,0,0}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400863##
864##
865
866#SeeAlso SkRegion()
867
868#Method ##
869
870# ------------------------------------------------------------------------------
871
872#Method bool setRect(const SkIRect& rect)
Cary Clark61313f32018-10-08 14:57:48 -0400873#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400874#Line # constructs Region matching IRect ##
Cary Clark09d80c02018-10-31 12:14:03 -0400875#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400876
877#Example
878 SkRegion region({1, 2, 3, 4});
879 SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not ");
880 bool setEmpty = region.setRect({1, 2, 1, 4});
881 SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not ");
882 SkDebugf("setEmpty: %s\n", setEmpty ? "true" : "false");
883#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400884region is not empty
885region is empty
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400886setEmpty: false
887##
888##
889
890#SeeAlso SkRegion(const SkIRect& rect)
891
892#Method ##
893
894# ------------------------------------------------------------------------------
895
896#Method bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom)
Cary Clark61313f32018-10-08 14:57:48 -0400897#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400898#Line # constructs Region matching bounds ##
Cary Clark09d80c02018-10-31 12:14:03 -0400899#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400900
901#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400902 auto debugster = [](const char* label, bool success, SkRegion& region) -> void {
903 auto r = region.getBounds();
904 SkDebugf("%14s: success:%s {%d,%d,%d,%d}\n", label, success ? "true" : "false",
905 r.fLeft, r.fTop, r.fRight, r.fBottom);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400906 };
907 SkRegion region;
908 bool success = region.setRect(1, 2, 3, 4);
909 debugster("set to: 1,2,3,4", success, region);
910 success = region.setRect(3, 2, 1, 4);
911 debugster("set to: 3,2,1,4", success, region);
912#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400913set to: 1,2,3,4: success:true {1,2,3,4}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400914set to: 3,2,1,4: success:false {0,0,0,0}
915##
916##
917
918#SeeAlso SkRegion(const SkIRect& rect)
919
920#Method ##
921
922# ------------------------------------------------------------------------------
923
924#Method bool setRects(const SkIRect rects[], int count)
Cary Clark61313f32018-10-08 14:57:48 -0400925#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400926#Line # sets IRect array ##
Cary Clark09d80c02018-10-31 12:14:03 -0400927#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400928
929#Example
930#Height 70
Cary Clark09d80c02018-10-31 12:14:03 -0400931 SkIRect rects[] = { {10, 10, 40, 40}, {20, 20, 50, 50}, {30, 30, 60, 60} };
932 SkRegion region;
933 region.setRects(rects, SK_ARRAY_COUNT(rects));
934 canvas->drawRegion(region, SkPaint());
935 region.setEmpty();
936 for (auto add : rects) {
937 region.op(add, SkRegion::kUnion_Op);
938 }
939 region.translate(100, 0);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400940 canvas->drawRegion(region, SkPaint());
941##
942
943#SeeAlso setRect op
944
945#Method ##
946
947# ------------------------------------------------------------------------------
948
949#Method bool setRegion(const SkRegion& region)
Cary Clark61313f32018-10-08 14:57:48 -0400950#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400951#Line # copies Region ##
Cary Clark09d80c02018-10-31 12:14:03 -0400952#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400953
954#Example
Cary Clark09d80c02018-10-31 12:14:03 -0400955 auto debugster = [](const char* label, SkRegion& region) -> void {
956 auto r = region.getBounds();
957 SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom);
958 };
959 SkRegion region({1, 2, 3, 4});
960 SkRegion region2;
961 region2.setRegion(region);
962 debugster("region bounds", region);
963 debugster("region2 bounds", region2);
964 region2.setEmpty();
965 SkDebugf(" after region set empty:\n");
966 debugster("region bounds", region);
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400967 debugster("region2 bounds", region2);
968#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -0400969 region bounds: {1,2,3,4}
970region2 bounds: {1,2,3,4}
971 after region set empty:
972 region bounds: {1,2,3,4}
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400973region2 bounds: {0,0,0,0}
974##
975##
976
977#SeeAlso SkRegion(const SkRegion& region)
978
979#Method ##
980
981# ------------------------------------------------------------------------------
982
983#Method bool setPath(const SkPath& path, const SkRegion& clip)
Cary Clark61313f32018-10-08 14:57:48 -0400984#In Constructors
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400985#Line # constructs Region from clipped Path ##
Cary Clark09d80c02018-10-31 12:14:03 -0400986#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -0400987
988#Example
989#Height 120
Cary Clark09d80c02018-10-31 12:14:03 -0400990 SkPaint paint;
991 paint.setTextSize(128);
992 SkPath textPath;
993 paint.getTextPath("Q", 1, 0, 110, &textPath);
994 SkIRect clipRect = {20, 20, 100, 120};
995 SkRegion clipRegion(clipRect);
996 SkRegion region;
997 region.setPath(textPath, clipRegion);
998 canvas->drawRegion(region, SkPaint());
999 clipRect.offset(100, 0);
1000 textPath.offset(100, 0);
1001 canvas->clipRect(SkRect::Make(clipRect), false);
1002 canvas->drawPath(textPath, SkPaint());
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001003##
1004
1005#SeeAlso setRects op
1006
1007#Method ##
1008
1009# ------------------------------------------------------------------------------
1010
1011#Method bool intersects(const SkIRect& rect) const
1012#In Intersection
1013#Line # returns true if areas overlap ##
Cary Clark09d80c02018-10-31 12:14:03 -04001014#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001015
1016#Example
1017#Duration 4
1018#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001019 SkPaint paint;
1020 paint.setTextSize(128);
1021 SkPath textPath;
1022 paint.getTextPath("W", 1, 20, 110, &textPath);
1023 SkRegion region;
1024 region.setPath(textPath, SkRegion({0, 0, 256, 256}));
1025 canvas->drawRegion(region, SkPaint());
1026 SkIRect iRect = SkIRect::MakeXYWH(frame * 160, 55, 10, 10);
1027 paint.setColor(region.intersects(iRect) ? SK_ColorBLUE : SK_ColorRED);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001028 canvas->drawRect(SkRect::Make(iRect), paint);
1029##
1030
1031#SeeAlso contains SkRect::intersects
1032
1033#Method ##
1034
1035# ------------------------------------------------------------------------------
1036
1037#Method bool intersects(const SkRegion& other) const
Cary Clark09d80c02018-10-31 12:14:03 -04001038#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001039
1040#Example
1041#Duration 4
1042#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001043 SkPaint paint;
1044 paint.setTextSize(128);
1045 SkPath hPath, dotPath;
1046 paint.getTextPath("H", 1, 40, 110, &hPath);
1047 paint.getTextPath(",", 1, frame * 180, 95, &dotPath);
1048 SkRegion hRegion, dotRegion;
1049 hRegion.setPath(hPath, SkRegion({0, 0, 256, 256}));
1050 dotRegion.setPath(dotPath, SkRegion({0, 0, 256, 256}));
1051 canvas->drawRegion(hRegion, paint);
1052 paint.setColor(hRegion.intersects(dotRegion) ? SK_ColorBLUE : SK_ColorRED);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001053 canvas->drawRegion(dotRegion, paint);
1054##
1055
1056#SeeAlso contains SkRect::intersects
1057
1058#Method ##
1059
1060# ------------------------------------------------------------------------------
1061
1062#Method bool contains(int32_t x, int32_t y) const
1063#In Intersection
1064#Line # returns true if points are equal or inside ##
Cary Clark09d80c02018-10-31 12:14:03 -04001065#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001066
1067#Example
1068#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001069 SkPaint paint;
1070 paint.setTextSize(128);
1071 SkPath xPath;
1072 paint.getTextPath("X", 1, 20, 110, &xPath);
1073 SkRegion xRegion;
1074 xRegion.setPath(xPath, SkRegion({0, 0, 256, 256}));
1075 canvas->drawRegion(xRegion, paint);
1076 for (int y = 0; y < 128; y += 8) {
1077 for (int x = 0; x < 128; x += 8) {
1078 paint.setColor(xRegion.contains(x, y) ? SK_ColorWHITE : SK_ColorRED);
1079 canvas->drawPoint(x, y, paint);
1080 }
1081 }
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001082##
1083
1084#SeeAlso intersects SkRect::contains
1085
1086#Method ##
1087
1088# ------------------------------------------------------------------------------
1089
1090#Method bool contains(const SkIRect& other) const
Cary Clark09d80c02018-10-31 12:14:03 -04001091#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001092
1093#Example
1094#Height 128
1095#Duration 4
Cary Clark09d80c02018-10-31 12:14:03 -04001096 SkPaint paint;
1097 paint.setTextSize(128);
1098 SkPath xPath;
1099 paint.getTextPath("X", 1, 20, 110, &xPath);
1100 SkRegion xRegion;
1101 SkIRect drawBounds = {0, 0, 128, 128};
1102 xRegion.setPath(xPath, SkRegion(drawBounds));
1103 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
1104 canvas->drawRegion(xRegion, paint);
1105 SkIRect test = SkIRect::MakeXYWH(frame* 128, 64, 5, 5);
1106 if (xRegion.contains(test)) {
1107 paint.setColor(SK_ColorYELLOW);
1108 canvas->drawRect(SkRect::Make(test), paint);
1109 }
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001110##
1111
1112#SeeAlso intersects SkRect::contains
1113
1114#Method ##
1115
1116# ------------------------------------------------------------------------------
1117
1118#Method bool contains(const SkRegion& other) const
Cary Clark09d80c02018-10-31 12:14:03 -04001119#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001120
1121#Example
1122#Height 128
1123#Duration 4
Cary Clark09d80c02018-10-31 12:14:03 -04001124 SkPaint paint;
1125 paint.setTextSize(128);
1126 SkPath xPath, testPath;
1127 paint.getTextPath("X", 1, 20, 110, &xPath);
1128 paint.getTextPath("`", 1, frame * 150 - 40, 150, &testPath);
1129 SkRegion xRegion, testRegion;
1130 SkIRect drawBounds = {0, 0, 128, 128};
1131 xRegion.setPath(xPath, SkRegion(drawBounds));
1132 testRegion.setPath(testPath, SkRegion(drawBounds));
1133 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
1134 canvas->drawRegion(xRegion, paint);
1135 if (xRegion.contains(testRegion)) {
1136 paint.setColor(SK_ColorYELLOW);
1137 canvas->drawRegion(testRegion, paint);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001138 }
1139##
1140
1141#SeeAlso intersects SkRect::contains
1142
1143#Method ##
1144
1145# ------------------------------------------------------------------------------
1146
1147#Method bool quickContains(const SkIRect& r) const
1148#In Intersection
1149#Line # returns true quickly if points are equal or inside ##
Cary Clark09d80c02018-10-31 12:14:03 -04001150#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001151
1152#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001153 SkRegion region({1, 2, 3, 4});
1154 SkIRect test = {2, 2, 3, 3};
1155 SkDebugf("quickContains 1: %s\n", region.quickContains(test) ? "true" : "false");
1156 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1157 SkDebugf("quickContains 2: %s\n", region.quickContains(test) ? "true" : "false");
1158 region.op({1, 7, 3, 8}, SkRegion::kUnion_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001159 SkDebugf("quickContains 3: %s\n", region.quickContains(test) ? "true" : "false");
1160#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -04001161quickContains 1: true
1162quickContains 2: true
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001163quickContains 3: false
1164##
1165##
1166
1167#SeeAlso contains quickReject intersects
1168
1169#Method ##
1170
1171# ------------------------------------------------------------------------------
1172
1173#Method bool quickContains(int32_t left, int32_t top, int32_t right,
1174 int32_t bottom) const
Cary Clark09d80c02018-10-31 12:14:03 -04001175#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001176
1177#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001178 auto debugster = [](const char* label, SkRegion& region) -> void {
1179 SkDebugf("%s: %s\n", label, region.quickContains(2, 2, 3, 3) ? "true" : "false");
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001180 };
Cary Clark09d80c02018-10-31 12:14:03 -04001181 SkRegion region({1, 2, 3, 4});
1182 debugster("quickContains 1", region);
1183 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1184 debugster("quickContains 2", region);
1185 region.op({1, 7, 3, 8}, SkRegion::kUnion_Op);
1186 debugster("quickContains 3", region);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001187#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -04001188quickContains 1: true
1189quickContains 2: true
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001190quickContains 3: false
1191##
1192##
1193
1194#SeeAlso contains quickReject intersects
1195
1196#Method ##
1197
1198# ------------------------------------------------------------------------------
1199
1200#Method bool quickReject(const SkIRect& rect) const
1201#In Intersection
1202#Line # returns true quickly if points are outside ##
Cary Clark09d80c02018-10-31 12:14:03 -04001203#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001204
1205#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001206 SkRegion region({1, 2, 3, 4});
1207 SkIRect test = {4, 2, 5, 3};
1208 SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false");
1209 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1210 SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false");
1211 region.op({4, 7, 5, 8}, SkRegion::kUnion_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001212 SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
1213#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -04001214quickReject 1: true
1215quickReject 2: true
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001216quickReject 3: false
1217##
1218##
1219
1220#SeeAlso quickContains contains intersects
1221
1222#Method ##
1223
1224# ------------------------------------------------------------------------------
1225
1226#Method bool quickReject(const SkRegion& rgn) const
Cary Clark09d80c02018-10-31 12:14:03 -04001227#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001228
1229#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001230 SkRegion region({1, 2, 3, 4});
1231 SkRegion test;
1232 SkIRect rects[] = {{4, 2, 5, 3}, {7, 2, 8, 3}};
1233 test.setRects(rects, SK_ARRAY_COUNT(rects));
1234 SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false");
1235 region.op({1, 4, 3, 6}, SkRegion::kUnion_Op);
1236 SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false");
1237 region.op({4, 7, 5, 8}, SkRegion::kUnion_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001238 SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
1239#StdOut
Cary Clark09d80c02018-10-31 12:14:03 -04001240quickReject 1: true
1241quickReject 2: true
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001242quickReject 3: false
1243##
1244##
1245
1246#SeeAlso quickContains contains intersects
1247
1248#Method ##
1249
1250# ------------------------------------------------------------------------------
1251
1252#Method void translate(int dx, int dy)
1253#In Transform
1254#Line # translates IPoints in Region ##
Cary Clark09d80c02018-10-31 12:14:03 -04001255#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001256
1257#Example
1258#Height 90
Cary Clark09d80c02018-10-31 12:14:03 -04001259 SkRegion test;
1260 SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}};
1261 test.setRects(rects, SK_ARRAY_COUNT(rects));
1262 SkPaint paint;
1263 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) {
1264 paint.setColor(color);
1265 canvas->drawRegion(test, paint);
1266 test.translate(10, 10);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001267 }
1268##
1269
1270#SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset
1271
1272#Method ##
1273
1274# ------------------------------------------------------------------------------
1275
1276#Method void translate(int dx, int dy, SkRegion* dst) const
Cary Clark09d80c02018-10-31 12:14:03 -04001277#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001278
1279#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001280 SkRegion test;
1281 SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}};
1282 test.setRects(rects, SK_ARRAY_COUNT(rects));
1283 SkPaint paint;
1284 for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) {
1285 paint.setColor(color);
1286 canvas->drawRegion(test, paint);
1287 SkRegion second;
1288 test.translate(10, test.getBounds().fBottom, &second);
1289 test.op(second, SkRegion::kXOR_Op);
1290 test.translate(30, 0);
1291 }
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001292##
1293
1294#SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset
1295
1296#Method ##
1297
1298# ------------------------------------------------------------------------------
1299
1300#Enum Op
1301#Line # binary operator combining Regions ##
1302
1303#Code
1304 enum Op {
1305 kDifference_Op,
1306 kIntersect_Op,
1307 kUnion_Op,
1308 kXOR_Op,
1309 kReverseDifference_Op,
1310 kReplace_Op,
1311 kLastOp = kReplace_Op,
1312 };
1313##
1314
1315The logical operations that can be performed when combining two Regions.
1316
1317#Const kDifference_Op 0
1318#Line # target minus operand ##
1319Subtracts operand Region from target Region.
1320##
1321#Const kIntersect_Op 1
1322#Line # target intersected with operand ##
1323Intersects operand Region and target Region.
1324##
1325#Const kUnion_Op 2
1326#Line # target unioned with operand ##
1327Unions operand Region and target Region.
1328##
1329#Const kXOR_Op 3
1330#Line # target exclusive or with operand ##
1331Replaces target Region with area exclusive to both Regions.
1332##
1333#Const kReverseDifference_Op 4
1334#Line # operand minus target ##
1335Subtracts target Region from operand Region.
1336##
1337#Const kReplace_Op 5
1338#Line # replace target with operand ##
1339Replaces target Region with operand Region.
1340##
1341#Const kLastOp 5
1342#Line # last operator ##
1343##
1344
1345#Example
Cary Clark09d80c02018-10-31 12:14:03 -04001346 SkRegion operand({35, 35, 85, 85});
1347 const char* labels[] = {"difference", "intersect", "union", "xor", "reverse diff", "replace"};
1348 int index = 0;
1349 SkPaint paint;
1350 for (auto op : { SkRegion::kDifference_Op, SkRegion::kIntersect_Op, SkRegion::kUnion_Op,
1351 SkRegion::kXOR_Op, SkRegion::kReverseDifference_Op, SkRegion::kReplace_Op } ) {
1352 SkRegion target({10, 10, 60, 60});
1353 target.op(operand, op);
1354 canvas->drawRegion(target, paint);
1355 canvas->drawString(labels[index++], 40, 100, paint);
1356 canvas->translate(80, 0);
1357 if (SkRegion::kUnion_Op == op) {
1358 canvas->translate(-240, 120);
1359 }
1360 }
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001361##
1362
1363#SeeAlso SkPathOp
1364
1365#Enum ##
1366
1367# ------------------------------------------------------------------------------
1368
1369#Const kOpCnt 6
1370#Line # number of operators defined ##
1371May be used to verify that Op is a legal value.
1372#Const ##
1373
1374# ------------------------------------------------------------------------------
1375
1376#Method bool op(const SkIRect& rect, Op op)
1377#In Transform
1378#Line # applies binary operator ##
Cary Clark09d80c02018-10-31 12:14:03 -04001379#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001380
1381#Example
1382#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001383 SkPaint paint;
1384 paint.setTextSize(128);
1385 SkPath xPath;
1386 paint.getTextPath("X", 1, 20, 110, &xPath);
1387 SkRegion xRegion;
1388 SkIRect drawBounds = {0, 0, 128, 128};
1389 xRegion.setPath(xPath, SkRegion(drawBounds));
1390 xRegion.op(drawBounds, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001391 canvas->drawRegion(xRegion, paint);
1392##
1393
1394#SeeAlso setRects Op
1395
1396#Method ##
1397
1398# ------------------------------------------------------------------------------
1399
1400#Method bool op(int left, int top, int right, int bottom, Op op)
Cary Clark09d80c02018-10-31 12:14:03 -04001401#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001402
1403#Example
1404#Duration 4
1405#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001406 SkPaint paint;
1407 paint.setTextSize(128);
1408 SkPath xPath;
1409 paint.getTextPath("X", 1, 20, 110, &xPath);
1410 SkRegion xRegion;
1411 SkIRect drawBounds = {0, 0, 128, 128};
1412 xRegion.setPath(xPath, SkRegion(drawBounds));
1413 xRegion.op(drawBounds.fLeft + frame * drawBounds.width(), drawBounds.fTop,
1414 drawBounds.fRight, drawBounds.fBottom, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001415 canvas->drawRegion(xRegion, paint);
1416##
1417
1418#SeeAlso setRects Op
1419
1420#Method ##
1421
1422# ------------------------------------------------------------------------------
1423
1424#Method bool op(const SkRegion& rgn, Op op)
Cary Clark09d80c02018-10-31 12:14:03 -04001425#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001426
1427#Example
1428#Duration 4
1429#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001430 SkPaint paint;
1431 paint.setTextSize(128);
1432 SkPath xPath, opPath;
1433 paint.getTextPath("X", 1, 20, 110, &xPath);
1434 opPath.addCircle(64, 64, frame * 64);
1435 SkRegion xRegion, opRegion;
1436 SkIRect drawBounds = {0, 0, 128, 128};
1437 opRegion.setPath(opPath, SkRegion(drawBounds));
1438 xRegion.setPath(xPath, SkRegion(drawBounds));
1439 xRegion.op(opRegion, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001440 canvas->drawRegion(xRegion, paint);
1441##
1442
1443#SeeAlso setRects Op
1444
1445#Method ##
1446
1447# ------------------------------------------------------------------------------
1448
1449#Method bool op(const SkIRect& rect, const SkRegion& rgn, Op op)
Cary Clark09d80c02018-10-31 12:14:03 -04001450#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001451
1452#Example
1453#Duration 4
1454#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001455 SkPaint paint;
1456 paint.setTextSize(128);
1457 SkPath xPath, opPath;
1458 paint.getTextPath("X", 1, 20, 110, &xPath);
1459 opPath.addCircle(64, 64, frame * 64);
1460 SkRegion xRegion, opRegion, rectRegion;
1461 SkIRect drawBounds = {0, 0, 128, 128};
1462 opRegion.setPath(opPath, SkRegion(drawBounds));
1463 xRegion.setPath(xPath, SkRegion(drawBounds));
1464 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1465 rectRegion.op(drawBounds, opRegion, SkRegion::kIntersect_Op);
1466 xRegion.op(rectRegion, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001467 canvas->drawRegion(xRegion, paint);
1468##
1469
1470#SeeAlso setRects Op
1471
1472#Method ##
1473
1474# ------------------------------------------------------------------------------
1475
1476#Method bool op(const SkRegion& rgn, const SkIRect& rect, Op op)
Cary Clark09d80c02018-10-31 12:14:03 -04001477#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001478
1479#Example
1480#Duration 4
1481#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001482 SkPaint paint;
1483 paint.setTextSize(128);
1484 SkPath xPath, opPath;
1485 paint.getTextPath("X", 1, 20, 110, &xPath);
1486 opPath.addCircle(64, 64, frame * 64);
1487 SkRegion xRegion, opRegion, rectRegion;
1488 SkIRect drawBounds = {0, 0, 128, 128};
1489 opRegion.setPath(opPath, SkRegion(drawBounds));
1490 xRegion.setPath(xPath, SkRegion(drawBounds));
1491 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1492 rectRegion.op(opRegion, drawBounds, SkRegion::kUnion_Op);
1493 xRegion.op(rectRegion, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001494 canvas->drawRegion(xRegion, paint);
1495##
1496
1497#SeeAlso setRects Op
1498
1499#Method ##
1500
1501# ------------------------------------------------------------------------------
1502
1503#Method bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op)
Cary Clark09d80c02018-10-31 12:14:03 -04001504#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001505
1506#Example
1507#Duration 4
1508#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001509 SkPaint paint;
1510 paint.setTextSize(128);
1511 SkPath xPath, opPath;
1512 paint.getTextPath("X", 1, 20, 110, &xPath);
1513 xPath.setFillType(SkPath::kInverseWinding_FillType);
1514 opPath.addCircle(64, 64, frame * 64);
1515 opPath.setFillType(SkPath::kInverseWinding_FillType);
1516 SkRegion xRegion, opRegion, rectRegion;
1517 SkIRect drawBounds = {0, 0, 128, 128};
1518 opRegion.setPath(opPath, SkRegion(drawBounds));
1519 xRegion.setPath(xPath, SkRegion(drawBounds));
1520 drawBounds.inset(frame * drawBounds.width() / 2, 0);
1521 rectRegion.setRect(drawBounds);
1522 rectRegion.op(xRegion, SkRegion::kIntersect_Op);
1523 xRegion.op(rectRegion, opRegion, SkRegion::kReverseDifference_Op);
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001524 canvas->drawRegion(xRegion, paint);
1525##
1526
1527#SeeAlso setRects Op
1528
1529#Method ##
1530
1531# ------------------------------------------------------------------------------
1532
1533#Method char* toString()
1534#In Utility
1535#Line # exists for Android framework only ##
1536#Private
1537Android framework only.
1538##
1539#Return string representation of Region ##
1540
1541#Method ##
1542
1543# ------------------------------------------------------------------------------
1544
1545#Method size_t writeToMemory(void* buffer) const
1546#In Utility
1547#Line # writes to buffer ##
Cary Clark09d80c02018-10-31 12:14:03 -04001548#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001549
1550#Example
1551#Height 128
Cary Clark09d80c02018-10-31 12:14:03 -04001552 SkPaint paint;
1553 paint.setTextSize(128);
1554 SkPath xPath;
1555 paint.getTextPath("X", 1, 20, 110, &xPath);
1556 SkIRect drawBounds = {0, 0, 128, 128};
1557 SkRegion xRegion;
1558 xRegion.setPath(xPath, SkRegion(drawBounds));
1559 size_t size = xRegion.writeToMemory(nullptr);
1560 sk_sp<SkData> data = SkData::MakeUninitialized(size);
1561 xRegion.writeToMemory(data->writable_data());
1562 SkRegion copy;
1563 copy.readFromMemory(data->data(), data->size());
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001564 canvas->drawRegion(copy, paint);
1565##
1566
1567#SeeAlso readFromMemory
1568
1569#Method ##
1570
1571# ------------------------------------------------------------------------------
1572
1573#Method size_t readFromMemory(const void* buffer, size_t length)
1574#In Utility
1575#Line # reads from buffer ##
Cary Clark09d80c02018-10-31 12:14:03 -04001576#Populate
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001577
1578#Example
1579#Height 100
Cary Clark09d80c02018-10-31 12:14:03 -04001580 SkRegion region({20, 20, 80, 80});
1581 size_t size = region.writeToMemory(nullptr);
1582 sk_sp<SkData> data = SkData::MakeUninitialized(size);
1583 region.writeToMemory(data->writable_data());
1584 SkRegion copy;
1585 copy.readFromMemory(data->data(), data->size());
Cary Clarkd2ca79c2018-08-10 13:09:13 -04001586 canvas->drawRegion(copy, SkPaint());
1587##
1588
1589#SeeAlso writeToMemory
1590
1591#Method ##
1592
1593#Class SkRegion ##
1594
1595#Topic Region ##