Home | History | Annotate | Download | only in docs
      1 #Topic Region
      2 #Alias Region_Reference ##
      3 #Alias Regions ##
      4 
      5 Region is a compressed one bit mask. Region describes an aliased clipping area
      6 on integer boundaries. Region can also describe an array of integer rectangles.
      7 
      8 Canvas uses Region to reduce the current clip. Region may be drawn to Canvas;
      9 Paint determines if Region is filled or stroked, its Color, and so on.
     10 
     11 Region may be constructed from IRect array or Path. Diagonal lines and curves
     12 in Path become integer rectangle edges. Regions operators compute union,
     13 intersection, difference, and so on. Canvas allows only intersection and
     14 difference; successive clips can only reduce available Canvas area.
     15 
     16 #PhraseDef list_of_op_types
     17 kDifference_Op, kIntersect_Op, kUnion_Op, kXOR_Op, kReverseDifference_Op,
     18 kReplace_Op
     19 ##
     20 
     21 #Class SkRegion
     22 
     23 #Code
     24 #Populate
     25 ##
     26 
     27 SkRegion describes the set of pixels used to clip Canvas. SkRegion is compact,
     28 efficiently storing a single integer rectangle, or a run length encoded array
     29 of rectangles. SkRegion may reduce the current Canvas_Clip, or may be drawn as
     30 one or more integer rectangles. SkRegion iterator returns the scan lines or
     31 rectangles contained by it, optionally intersecting a bounding rectangle.
     32 
     33 # ------------------------------------------------------------------------------
     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 
     52 Returns sequence of rectangles, sorted along y-axis, then x-axis, that make
     53 up Region.
     54 
     55 # ------------------------------------------------------------------------------
     56 
     57 #Method Iterator()
     58 #Line # constructs Region iterator ##
     59 #Populate
     60 
     61 #Example
     62     SkRegion::Iterator iter;
     63     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
     69 rect={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 ##
     81 #Populate
     82 
     83 #Example
     84     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
     90 rect={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 ##
    102 #Populate
    103 
    104 #Example
    105 #Bug 8186
    106     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
    124 #Volatile
    125     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}
    129 after set rect rect={1,2,3,4}
    130   after rewind rewind success=true
    131   after rewind rect={1,2,3,4}
    132 ##
    133 ##
    134 
    135 #SeeAlso reset
    136 
    137 #Method ##
    138 
    139 # ------------------------------------------------------------------------------
    140 
    141 #Method void reset(const SkRegion& region)
    142 #Line # sets Region to iterate ##
    143 #Populate
    144 
    145 #Example
    146     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
    158 after set rect: done=true
    159    after reset: done=false
    160 ##
    161 ##
    162 
    163 #SeeAlso rewind
    164 
    165 #Method ##
    166 
    167 # ------------------------------------------------------------------------------
    168 
    169 #Method bool done() const
    170 #Line # returns if data parsing is complete ##
    171 #Populate
    172 
    173 #Example
    174     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"); 
    180 #StdOut
    181 done=true
    182 done=false
    183 ##
    184 ##
    185 
    186 #SeeAlso next rect
    187 
    188 #Method ##
    189 
    190 # ------------------------------------------------------------------------------
    191 
    192 #Method void next()
    193 #Line # advances to next IRect ##
    194 #Populate
    195 
    196 #Example
    197     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());
    206 #StdOut
    207 rect={1,2,3,4}
    208 rect={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 ##
    220 #Populate
    221 
    222 #Example
    223 #Bug 8186
    224     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();
    231     SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom); 
    232 #StdOut
    233 #Volatile
    234 rect={0,0,0,0}
    235 rect={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 ##
    247 #Populate
    248 
    249 #Example
    250     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();
    257     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 Cliperator {
    273     public:
    274         Cliperator(const SkRegion& region, const SkIRect& clip);
    275         bool done();
    276         void next();
    277         const SkIRect& rect() const;
    278     };
    279 ##
    280 
    281 Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make
    282 up 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 ##
    288 #Populate
    289 
    290 #Example
    291     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
    297 rect={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 ##
    309 #Populate
    310 
    311 #Example
    312     auto debugster = [](const char* label, SkRegion& region) -> void {
    313         SkRegion::Cliperator clipper(region, {0, 0, 5, 5});
    314         SkDebugf("%14s done=%s\n", label, clipper.done() ? "true" : "false"); 
    315     };
    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
    322 after 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 ##
    334 #Populate
    335 
    336 #Example
    337     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();
    345     } while (!clipper.done());
    346 #StdOut
    347 rect={1,3,3,4}
    348 rect={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 ##
    360 #Populate
    361 
    362 #Example
    363 #Bug 8186
    364     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); 
    368     };
    369     SkRegion region;
    370     debugster("empty region", region);
    371     region.setRect({1, 2, 3, 4});
    372     debugster("after set rect", region);
    373 #StdOut
    374 #Volatile
    375   empty region rect={1094713344,1065353216,0,-1}
    376 after set rect rect={1,2,3,3}
    377 ##
    378 ##
    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 
    399 Returns 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 ##
    405 #Populate
    406 
    407 #Example
    408     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);
    414 ##
    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 ##
    424 #Populate
    425 
    426 #Example
    427     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});
    438     debugster("after set rect", region);
    439 #StdOut
    440   empty region: result=false
    441 after 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()
    454 #In Constructors
    455 #Line # constructs with default values ##
    456 #Populate
    457 
    458 #Example
    459 SkRegion region;
    460 SkIRect r = region.getBounds();
    461 SkDebugf("region bounds: {%d, %d, %d, %d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
    462 #StdOut
    463 region bounds: {0, 0, 0, 0}
    464 ##
    465 ##
    466 
    467 #SeeAlso setEmpty
    468 
    469 #Method ##
    470 
    471 # ------------------------------------------------------------------------------
    472 
    473 #Method SkRegion(const SkRegion& region)
    474 #In Constructors
    475 #Line # makes a shallow copy ##
    476 #Populate
    477 
    478 #Example
    479     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);
    482     };
    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
    492  region bounds: {1,2,3,4}
    493 region2 bounds: {1,2,3,4}
    494     after region set empty:
    495  region bounds: {0,0,0,0}
    496 region2 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)
    507 #In Constructors
    508 #Line # constructs Region matching IRect ##
    509 #Populate
    510 
    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()
    525 #In Constructors
    526 #Line # decreases Reference_Count of owned objects ##
    527 #Populate
    528 
    529 #Example
    530 #Description
    531 delete calls Region destructor, but copy of original in region2 is unaffected.
    532 ##
    533     SkRegion* region = new SkRegion({1, 2, 3, 4});
    534     SkRegion region2(*region);
    535     delete region;
    536     auto r = region2.getBounds();
    537     SkDebugf("region2 bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
    538 #StdOut
    539 region2 bounds: {1,2,3,4}
    540 ##
    541 ##
    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)
    550 #In Operators
    551 #Line # makes a shallow copy ##
    552 #Populate
    553 
    554 #Example
    555     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);
    558     };
    559     SkRegion region1({1, 2, 3, 4});
    560     SkRegion region2 = region1;
    561     debugster("region1 bounds", region1);
    562     debugster("region2 bounds", region2);
    563 #StdOut
    564 region1 bounds: {1,2,3,4}
    565 region2 bounds: {1,2,3,4}
    566 ##
    567 ##
    568 
    569 #SeeAlso set swap SkRegion(const SkRegion& region)
    570 
    571 #Method ##
    572 
    573 # ------------------------------------------------------------------------------
    574 
    575 #Method bool operator==(const SkRegion& other) const
    576 #In Operators
    577 #Line # compares Regions for equality ##
    578 #Populate
    579 
    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
    592 empty one == two
    593 set rect one != two
    594 set 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
    605 #In Operators
    606 #Line # compares Regions for inequality ##
    607 #Populate
    608 
    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
    622 empty one == two
    623 set rect one != two
    624 union 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)
    635 #In Constructors
    636 #Line # makes a shallow copy ##
    637 #Populate
    638 
    639 #Example
    640     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);
    643     };
    644     SkRegion region1({1, 2, 3, 4});
    645     SkRegion region2;
    646     region2.set(region1);
    647     debugster("region1 bounds", region1);
    648     debugster("region2 bounds", region2);
    649 #StdOut
    650 region1 bounds: {1,2,3,4}
    651 region2 bounds: {1,2,3,4}
    652 ##
    653 ##
    654 
    655 #SeeAlso operator=(const SkRegion& region) swap SkRegion(const SkRegion& region)
    656 
    657 #Method ##
    658 
    659 # ------------------------------------------------------------------------------
    660 
    661 #Method void swap(SkRegion& other)
    662 #In Operators
    663 #Line # exchanges Region pair ##
    664 #Populate
    665 
    666 #Example
    667     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);
    670     };
    671     SkRegion region1({1, 2, 3, 4});
    672     SkRegion region2;
    673     region1.swap(region2);
    674     debugster("region1 bounds", region1);
    675     debugster("region2 bounds", region2);
    676 #StdOut
    677 region1 bounds: {0,0,0,0}
    678 region2 bounds: {1,2,3,4}
    679 ##
    680 ##
    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 ##
    691 #Populate
    692 
    693 #Example
    694     auto debugster = [](const char* label, SkRegion& region) -> void {
    695         SkDebugf("%14s: region is %s" "empty\n", label, region.isEmpty() ? "" : "not ");
    696     };
    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
    704        initial: region is empty
    705       set rect: region is not empty
    706      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 ##
    719 #Populate
    720 
    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
    732 initial: region is not rect
    733 set rect: region is rect
    734 set 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 ##
    747 #Populate
    748 
    749 #Example
    750     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);
    758     debugster("op rect", region);
    759 #StdOut
    760 initial: region is not complex
    761 set rect: region is not complex
    762 op 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 ##
    775 #Populate
    776 
    777 #Example
    778     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
    783 bounds: {1,2,4,5}
    784 ##
    785 ##
    786 
    787 #SeeAlso isEmpty isRect
    788 
    789 #Method ##
    790 
    791 # ------------------------------------------------------------------------------
    792 
    793 #Method int computeRegionComplexity() const
    794 #In Property
    795 #Line # returns relative complexity ##
    796 #Populate
    797 
    798 #Example
    799     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);
    807     debugster("op rect", region);
    808 #StdOut
    809 initial: region complexity 0
    810 set rect: region complexity 1
    811 op 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 ##
    824 #Populate
    825 
    826 #Example
    827 #Height 100
    828     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);
    835     canvas->drawPath(path, SkPaint());
    836 ##
    837 
    838 #SeeAlso isEmpty isComplex
    839 
    840 #Method ##
    841 
    842 # ------------------------------------------------------------------------------
    843 
    844 #Method bool setEmpty()
    845 #In Constructors
    846 #Line # constructs with default values ##
    847 #Populate
    848 
    849 #Example
    850     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);
    853     };
    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
    860  region bounds: {1,2,3,4}
    861     after region set empty:
    862  region bounds: {0,0,0,0}
    863 ##
    864 ##
    865 
    866 #SeeAlso SkRegion()
    867 
    868 #Method ##
    869 
    870 # ------------------------------------------------------------------------------
    871 
    872 #Method bool setRect(const SkIRect& rect)
    873 #In Constructors
    874 #Line # constructs Region matching IRect ##
    875 #Populate
    876 
    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
    884 region is not empty
    885 region is empty
    886 setEmpty: 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)
    897 #In Constructors
    898 #Line # constructs Region matching bounds ##
    899 #Populate
    900 
    901 #Example
    902     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);
    906     };
    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
    913 set to: 1,2,3,4: success:true {1,2,3,4}
    914 set 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)
    925 #In Constructors
    926 #Line # sets IRect array ##
    927 #Populate
    928 
    929 #Example
    930 #Height 70
    931     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);
    940     canvas->drawRegion(region, SkPaint());
    941 ##
    942 
    943 #SeeAlso setRect op
    944 
    945 #Method ##
    946 
    947 # ------------------------------------------------------------------------------
    948 
    949 #Method bool setRegion(const SkRegion& region)
    950 #In Constructors
    951 #Line # copies Region ##
    952 #Populate
    953 
    954 #Example
    955     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);
    967     debugster("region2 bounds", region2);
    968 #StdOut
    969  region bounds: {1,2,3,4}
    970 region2 bounds: {1,2,3,4}
    971     after region set empty:
    972  region bounds: {1,2,3,4}
    973 region2 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)
    984 #In Constructors
    985 #Line # constructs Region from clipped Path ##
    986 #Populate
    987 
    988 #Example
    989 #Height 120
    990     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());
   1003 ##
   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 ##
   1014 #Populate
   1015 
   1016 #Example
   1017 #Duration 4
   1018 #Height 128
   1019     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);
   1028     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
   1038 #Populate
   1039 
   1040 #Example
   1041 #Duration 4
   1042 #Height 128
   1043     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);
   1053     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 ##
   1065 #Populate
   1066 
   1067 #Example
   1068 #Height 128
   1069     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     }
   1082 ##
   1083 
   1084 #SeeAlso intersects SkRect::contains
   1085 
   1086 #Method ##
   1087 
   1088 # ------------------------------------------------------------------------------
   1089 
   1090 #Method bool contains(const SkIRect& other) const
   1091 #Populate
   1092 
   1093 #Example
   1094 #Height 128
   1095 #Duration 4
   1096     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     }
   1110 ##
   1111 
   1112 #SeeAlso intersects SkRect::contains
   1113 
   1114 #Method ##
   1115 
   1116 # ------------------------------------------------------------------------------
   1117 
   1118 #Method bool contains(const SkRegion& other) const
   1119 #Populate
   1120 
   1121 #Example
   1122 #Height 128
   1123 #Duration 4
   1124     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);
   1138     }
   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 ##
   1150 #Populate
   1151 
   1152 #Example
   1153     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);
   1159     SkDebugf("quickContains 3: %s\n", region.quickContains(test) ? "true" : "false");
   1160 #StdOut
   1161 quickContains 1: true
   1162 quickContains 2: true
   1163 quickContains 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
   1175 #Populate
   1176 
   1177 #Example
   1178     auto debugster = [](const char* label, SkRegion& region) -> void {
   1179         SkDebugf("%s: %s\n", label, region.quickContains(2, 2, 3, 3) ? "true" : "false");
   1180     };
   1181     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);
   1187 #StdOut
   1188 quickContains 1: true
   1189 quickContains 2: true
   1190 quickContains 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 ##
   1203 #Populate
   1204 
   1205 #Example
   1206     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);
   1212     SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
   1213 #StdOut
   1214 quickReject 1: true
   1215 quickReject 2: true
   1216 quickReject 3: false
   1217 ##
   1218 ##
   1219 
   1220 #SeeAlso quickContains contains intersects
   1221 
   1222 #Method ##
   1223 
   1224 # ------------------------------------------------------------------------------
   1225 
   1226 #Method bool quickReject(const SkRegion& rgn) const
   1227 #Populate
   1228 
   1229 #Example
   1230     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);
   1238     SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false");
   1239 #StdOut
   1240 quickReject 1: true
   1241 quickReject 2: true
   1242 quickReject 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 ##
   1255 #Populate
   1256 
   1257 #Example
   1258 #Height 90
   1259     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);
   1267     }
   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
   1277 #Populate
   1278 
   1279 #Example
   1280     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     }
   1292 ##
   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 
   1315 The logical operations that can be performed when combining two Regions.
   1316 
   1317 #Const kDifference_Op 0
   1318 #Line # target minus operand ##
   1319 Subtracts operand Region from target Region.
   1320 ##
   1321 #Const kIntersect_Op 1
   1322 #Line # target intersected with operand ##
   1323 Intersects operand Region and target Region.
   1324 ##
   1325 #Const kUnion_Op 2
   1326 #Line # target unioned with operand ##
   1327 Unions operand Region and target Region.
   1328 ##
   1329 #Const kXOR_Op 3
   1330 #Line # target exclusive or with operand ##
   1331 Replaces target Region with area exclusive to both Regions.
   1332 ##
   1333 #Const kReverseDifference_Op 4
   1334 #Line # operand minus target ##
   1335 Subtracts target Region from operand Region.
   1336 ##
   1337 #Const kReplace_Op 5
   1338 #Line # replace target with operand ##
   1339 Replaces target Region with operand Region.
   1340 ##
   1341 #Const kLastOp 5
   1342 #Line # last operator ##
   1343 ##
   1344 
   1345 #Example
   1346     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     }
   1361 ##
   1362 
   1363 #SeeAlso SkPathOp
   1364 
   1365 #Enum ##
   1366 
   1367 # ------------------------------------------------------------------------------
   1368 
   1369 #Const kOpCnt 6
   1370 #Line # number of operators defined ##
   1371 May 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 ##
   1379 #Populate
   1380 
   1381 #Example
   1382 #Height 128
   1383     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);
   1391     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)
   1401 #Populate
   1402 
   1403 #Example
   1404 #Duration 4
   1405 #Height 128
   1406     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);
   1415     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)
   1425 #Populate
   1426 
   1427 #Example
   1428 #Duration 4
   1429 #Height 128
   1430     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);
   1440     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)
   1450 #Populate
   1451 
   1452 #Example
   1453 #Duration 4
   1454 #Height 128
   1455     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);
   1467     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)
   1477 #Populate
   1478 
   1479 #Example
   1480 #Duration 4
   1481 #Height 128
   1482     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);
   1494     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)
   1504 #Populate
   1505 
   1506 #Example
   1507 #Duration 4
   1508 #Height 128
   1509     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);
   1524     canvas->drawRegion(xRegion, paint);
   1525 ##
   1526 
   1527 #SeeAlso setRects Op
   1528 
   1529 #Method ##
   1530 
   1531 # ------------------------------------------------------------------------------
   1532 
   1533 #Method size_t writeToMemory(void* buffer) const
   1534 #In Utility
   1535 #Line # writes to buffer ##
   1536 #Populate
   1537 
   1538 #Example
   1539 #Height 128
   1540     SkPaint paint;
   1541     paint.setTextSize(128);
   1542     SkPath xPath;
   1543     paint.getTextPath("X", 1, 20, 110, &xPath);
   1544     SkIRect drawBounds = {0, 0, 128, 128};
   1545     SkRegion xRegion;
   1546     xRegion.setPath(xPath, SkRegion(drawBounds));
   1547     size_t size = xRegion.writeToMemory(nullptr);
   1548     sk_sp<SkData> data = SkData::MakeUninitialized(size);
   1549     xRegion.writeToMemory(data->writable_data());
   1550     SkRegion copy;
   1551     copy.readFromMemory(data->data(), data->size());
   1552     canvas->drawRegion(copy, paint);
   1553 ##
   1554 
   1555 #SeeAlso readFromMemory
   1556 
   1557 #Method ##
   1558 
   1559 # ------------------------------------------------------------------------------
   1560 
   1561 #Method size_t readFromMemory(const void* buffer, size_t length)
   1562 #In Utility
   1563 #Line # reads from buffer ##
   1564 #Populate
   1565 
   1566 #Example
   1567 #Height 100
   1568     SkRegion region({20, 20, 80, 80});
   1569     size_t size = region.writeToMemory(nullptr);
   1570     sk_sp<SkData> data = SkData::MakeUninitialized(size);
   1571     region.writeToMemory(data->writable_data());
   1572     SkRegion copy;
   1573     copy.readFromMemory(data->data(), data->size());
   1574     canvas->drawRegion(copy, SkPaint());
   1575 ##
   1576 
   1577 #SeeAlso writeToMemory
   1578 
   1579 #Method ##
   1580 
   1581 #Class SkRegion ##
   1582 
   1583 #Topic Region ##
   1584