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