#Topic Region #Alias Region_Reference ## #Alias Regions ## Region is a compressed one bit mask. Region describes an aliased clipping area on integer boundaries. Region can also describe an array of integer rectangles. Canvas uses Region to reduce the current clip. Region may be drawn to Canvas; Paint determines if Region is filled or stroked, its Color, and so on. Region may be constructed from IRect array or Path. Diagonal lines and curves in Path become integer rectangle edges. Regions operators compute union, intersection, difference, and so on. Canvas allows only intersection and difference; successive clips can only reduce available Canvas area. #PhraseDef list_of_op_types kDifference_Op, kIntersect_Op, kUnion_Op, kXOR_Op, kReverseDifference_Op, kReplace_Op ## #Class SkRegion #Code #Populate ## SkRegion describes the set of pixels used to clip Canvas. SkRegion is compact, efficiently storing a single integer rectangle, or a run length encoded array of rectangles. SkRegion may reduce the current Canvas_Clip, or may be drawn as one or more integer rectangles. SkRegion iterator returns the scan lines or rectangles contained by it, optionally intersecting a bounding rectangle. # ------------------------------------------------------------------------------ #Class Iterator #Line # iterator returning IRect ## #Code class Iterator { public: Iterator(); Iterator(const SkRegion& region); bool rewind(); void reset(const SkRegion& region); bool done() const; void next(); const SkIRect& rect(); const SkRegion* rgn(); }; ## Returns sequence of rectangles, sorted along y-axis, then x-axis, that make up Region. # ------------------------------------------------------------------------------ #Method Iterator() #Line # constructs Region iterator ## #Populate #Example SkRegion::Iterator iter; SkRegion region; region.setRect({1, 2, 3, 4}); iter.reset(region); auto r = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut rect={1,2,3,4} ## ## #SeeAlso reset SkRegion #Method ## # ------------------------------------------------------------------------------ #Method Iterator(const SkRegion& region) #Line # constructs Region iterator ## #Populate #Example SkRegion region; region.setRect({1, 2, 3, 4}); SkRegion::Iterator iter(region); auto r = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut rect={1,2,3,4} ## ## #SeeAlso reset SkRegion Cliperator Spanerator #Method ## # ------------------------------------------------------------------------------ #Method bool rewind() #Line # points Iterator to start ## #Populate #Example #Bug 8186 auto debugster = [](const char* label, SkRegion::Iterator& iter, bool addRewind) -> void { if (addRewind) { bool success = iter.rewind(); SkDebugf("%14s rewind success=%s\n", label, success ? "true" : "false"); } auto r = iter.rect(); SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion::Iterator iter; debugster("empty iter", iter, true); SkRegion region; iter.reset(region); debugster("empty region", iter, true); region.setRect({1, 2, 3, 4}); iter.reset(region); debugster("after set rect", iter, false); debugster("after rewind", iter, true); #StdOut #Volatile empty iter rewind success=false empty iter rect={0,0,0,0} empty region rewind success=true empty region rect={0,0,0,0} after set rect rect={1,2,3,4} after rewind rewind success=true after rewind rect={1,2,3,4} ## ## #SeeAlso reset #Method ## # ------------------------------------------------------------------------------ #Method void reset(const SkRegion& region) #Line # sets Region to iterate ## #Populate #Example auto debugster = [](const char* label, SkRegion::Iterator& iter) -> void { SkDebugf("%14s: done=%s\n", label, iter.done() ? "true" : "false"); }; SkRegion region; SkRegion::Iterator iter(region); debugster("empty region", iter); region.setRect({1, 2, 3, 4}); debugster("after set rect", iter); iter.reset(region); debugster("after reset", iter); #StdOut empty region: done=true after set rect: done=true after reset: done=false ## ## #SeeAlso rewind #Method ## # ------------------------------------------------------------------------------ #Method bool done() const #Line # returns if data parsing is complete ## #Populate #Example SkRegion region; SkRegion::Iterator iter(region); SkDebugf("done=%s\n", iter.done() ? "true" : "false"); region.setRect({1, 2, 3, 4}); iter.rewind(); SkDebugf("done=%s\n", iter.done() ? "true" : "false"); #StdOut done=true done=false ## ## #SeeAlso next rect #Method ## # ------------------------------------------------------------------------------ #Method void next() #Line # advances to next IRect ## #Populate #Example SkRegion region; SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; region.setRects(rects, SK_ARRAY_COUNT(rects)); SkRegion::Iterator iter(region); do { auto r2 = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom); iter.next(); } while (!iter.done()); #StdOut rect={1,2,3,4} rect={5,6,7,8} ## ## #SeeAlso done rect #Method ## # ------------------------------------------------------------------------------ #Method const SkIRect& rect() const #Line # returns part of Region as IRect ## #Populate #Example #Bug 8186 SkRegion region; SkRegion::Iterator iter(region); auto r1 = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r1.fLeft, r1.fTop, r1.fRight, r1.fBottom); region.setRect({1, 2, 3, 4}); iter.rewind(); auto r2 = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom); #StdOut #Volatile rect={0,0,0,0} rect={1,2,3,4} ## ## #SeeAlso next done #Method ## # ------------------------------------------------------------------------------ #Method const SkRegion* rgn() const #Line # returns original Region ## #Populate #Example SkRegion region; SkIRect rects[] = {{1, 2, 3, 4}, {3, 4, 5, 6}}; region.setRects(rects, SK_ARRAY_COUNT(rects)); SkRegion::Iterator iter(region); auto r = iter.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); auto b = iter.rgn()->getBounds(); SkDebugf("bounds={%d,%d,%d,%d}\n", b.fLeft, b.fTop, b.fRight, b.fBottom); ## #SeeAlso Iterator reset #Method ## #Class Iterator ## # ------------------------------------------------------------------------------ #Class Cliperator #Line # iterator returning IRect within clip ## #Code class Cliperator { public: Cliperator(const SkRegion& region, const SkIRect& clip); bool done(); void next(); const SkIRect& rect() const; }; ## Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make up Region intersected with the specified clip rectangle. # ------------------------------------------------------------------------------ #Method Cliperator(const SkRegion& region, const SkIRect& clip) #Line # constructs Region iterator with clip ## #Populate #Example SkRegion region; region.setRect({1, 2, 3, 4}); SkRegion::Cliperator clipper(region, {0, 0, 2, 3}); auto r = clipper.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut rect={1,2,2,3} ## ## #SeeAlso SkRegion Iterator Spanerator #Method ## # ------------------------------------------------------------------------------ #Method bool done() #Line # returns if data parsing is complete ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { SkRegion::Cliperator clipper(region, {0, 0, 5, 5}); SkDebugf("%14s done=%s\n", label, clipper.done() ? "true" : "false"); }; SkRegion region; debugster("empty region", region); region.setRect({1, 2, 3, 4}); debugster("after add rect", region); #StdOut empty region done=true after add rect done=false ## ## #SeeAlso next rect #Method ## # ------------------------------------------------------------------------------ #Method void next() #Line # advances to next IRect within clip ## #Populate #Example SkRegion region; SkIRect rects[] = {{1, 2, 3, 4}, {5, 6, 7, 8}}; region.setRects(rects, SK_ARRAY_COUNT(rects)); SkRegion::Cliperator clipper(region, {0, 3, 8, 7}); do { auto r2 = clipper.rect(); SkDebugf("rect={%d,%d,%d,%d}\n", r2.fLeft, r2.fTop, r2.fRight, r2.fBottom); clipper.next(); } while (!clipper.done()); #StdOut rect={1,3,3,4} rect={5,6,7,7} ## ## #SeeAlso done #Method ## # ------------------------------------------------------------------------------ #Method const SkIRect& rect() const #Line # returns part of Region as IRect intersected with clip ## #Populate #Example #Bug 8186 auto debugster = [](const char* label, SkRegion& region) -> void { SkRegion::Cliperator clipper(region, {0, 0, 5, 3}); auto r = clipper.rect(); SkDebugf("%14s rect={%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region; debugster("empty region", region); region.setRect({1, 2, 3, 4}); debugster("after set rect", region); #StdOut #Volatile empty region rect={1094713344,1065353216,0,-1} after set rect rect={1,2,3,3} ## ## #SeeAlso next done #Method ## #Class Cliperator ## # ------------------------------------------------------------------------------ #Class Spanerator #Line # horizontal line segment iterator ## #Code class Spanerator { public: Spanerator(const SkRegion& region, int y, int left, int right); bool next(int* left, int* right); }; ## Returns the line segment ends within Region that intersect a horizontal line. # ------------------------------------------------------------------------------ #Method Spanerator(const SkRegion& region, int y, int left, int right) #Line # constructs Region iterator on scan line ## #Populate #Example SkRegion region; region.setRect({1, 2, 3, 4}); SkRegion::Spanerator spanner(region, 3, 2, 4); int left, right; bool result = spanner.next(&left, &right); SkDebugf("result=%s left=%d right=%d\n", result ? "true" : "false", left, right); ## #SeeAlso SkRegion Iterator Cliperator #Method ## # ------------------------------------------------------------------------------ #Method bool next(int* left, int* right) #Line # advances to next span on horizontal line ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { SkRegion::Spanerator spanner(region, 3, 2, 4); int left, right; bool result = spanner.next(&left, &right); SkDebugf("%14s: result=%s", label, result ? "true" : "false"); if (result) SkDebugf(" left=%d right=%d", left, right); SkDebugf("\n"); }; SkRegion region; debugster("empty region", region); region.setRect({1, 2, 3, 4}); debugster("after set rect", region); #StdOut empty region: result=false after set rect: result=true left=2 right=3 ## ## #SeeAlso done #Method ## #Class Spanerator ## # ------------------------------------------------------------------------------ #Method SkRegion() #In Constructors #Line # constructs with default values ## #Populate #Example SkRegion region; SkIRect r = region.getBounds(); SkDebugf("region bounds: {%d, %d, %d, %d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut region bounds: {0, 0, 0, 0} ## ## #SeeAlso setEmpty #Method ## # ------------------------------------------------------------------------------ #Method SkRegion(const SkRegion& region) #In Constructors #Line # makes a shallow copy ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region({1, 2, 3, 4}); SkRegion region2(region); debugster("region bounds", region); debugster("region2 bounds", region2); region.setEmpty(); SkDebugf(" after region set empty:\n"); debugster("region bounds", region); debugster("region2 bounds", region2); #StdOut region bounds: {1,2,3,4} region2 bounds: {1,2,3,4} after region set empty: region bounds: {0,0,0,0} region2 bounds: {1,2,3,4} ## ## #SeeAlso setRegion operator=(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method explicit SkRegion(const SkIRect& rect) #In Constructors #Line # constructs Region matching IRect ## #Populate #Example SkRegion region({1, 2, 3, 4}); SkRegion region2; region2.setRect({1, 2, 3, 4}); SkDebugf("region %c= region2\n", region == region2 ? '=' : '!'); ## #SeeAlso setRect setRegion #Method ## # ------------------------------------------------------------------------------ #Method ~SkRegion() #In Constructors #Line # decreases Reference_Count of owned objects ## #Populate #Example #Description delete calls Region destructor, but copy of original in region2 is unaffected. ## SkRegion* region = new SkRegion({1, 2, 3, 4}); SkRegion region2(*region); delete region; auto r = region2.getBounds(); SkDebugf("region2 bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut region2 bounds: {1,2,3,4} ## ## #SeeAlso SkRegion() SkRegion(const SkRegion& region) SkRegion(const SkIRect& rect) operator=(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method SkRegion& operator=(const SkRegion& region) #In Operators #Line # makes a shallow copy ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region1({1, 2, 3, 4}); SkRegion region2 = region1; debugster("region1 bounds", region1); debugster("region2 bounds", region2); #StdOut region1 bounds: {1,2,3,4} region2 bounds: {1,2,3,4} ## ## #SeeAlso set swap SkRegion(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method bool operator==(const SkRegion& other) const #In Operators #Line # compares Regions for equality ## #Populate #Example auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void { SkDebugf("%s one %c= two\n", prefix, a == b ? '=' : '!'); }; SkRegion one; SkRegion two; debugster("empty", one, two); one.setRect({1, 2, 3, 4}); debugster("set rect", one, two); one.setEmpty(); debugster("set empty", one, two); #StdOut empty one == two set rect one != two set empty one == two ## ## #SeeAlso operator!=(const SkRegion& other) const operator=(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method bool operator!=(const SkRegion& other) const #In Operators #Line # compares Regions for inequality ## #Populate #Example auto debugster = [](const char* prefix, const SkRegion& a, const SkRegion& b) -> void { SkDebugf("%s one %c= two\n", prefix, a != b ? '!' : '='); }; SkRegion one; SkRegion two; debugster("empty", one, two); one.setRect({1, 2, 3, 4}); two.setRect({1, 2, 3, 3}); debugster("set rect", one, two); two.op({1, 3, 3, 4}, SkRegion::kUnion_Op); debugster("union rect", one, two); #StdOut empty one == two set rect one != two union rect one == two ## ## #SeeAlso operator==(const SkRegion& other) const operator=(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method bool set(const SkRegion& src) #In Constructors #Line # makes a shallow copy ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region1({1, 2, 3, 4}); SkRegion region2; region2.set(region1); debugster("region1 bounds", region1); debugster("region2 bounds", region2); #StdOut region1 bounds: {1,2,3,4} region2 bounds: {1,2,3,4} ## ## #SeeAlso operator=(const SkRegion& region) swap SkRegion(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method void swap(SkRegion& other) #In Operators #Line # exchanges Region pair ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region1({1, 2, 3, 4}); SkRegion region2; region1.swap(region2); debugster("region1 bounds", region1); debugster("region2 bounds", region2); #StdOut region1 bounds: {0,0,0,0} region2 bounds: {1,2,3,4} ## ## #SeeAlso operator=(const SkRegion& region) set SkRegion(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method bool isEmpty() const #In Property #Line # returns if bounds has no width or height ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { SkDebugf("%14s: region is %s" "empty\n", label, region.isEmpty() ? "" : "not "); }; SkRegion region; debugster("initial", region); region.setRect({1, 2, 3, 4}); debugster("set rect", region); region.setEmpty(); debugster("set empty", region); #StdOut initial: region is empty set rect: region is not empty set empty: region is empty ## ## #SeeAlso isRect isComplex operator==(const SkRegion& other) const #Method ## # ------------------------------------------------------------------------------ #Method bool isRect() const #In Property #Line # returns if Region contains one IRect ## #Populate #Example auto debugster = [](const char* label, const SkRegion& region) -> void { SkDebugf("%s: region is %s" "rect\n", label, region.isRect() ? "" : "not "); }; SkRegion region; debugster("initial", region); region.setRect({1, 2, 3, 4}); debugster("set rect", region); region.setEmpty(); debugster("set empty", region); #StdOut initial: region is not rect set rect: region is rect set empty: region is not rect ## ## #SeeAlso isEmpty isComplex #Method ## # ------------------------------------------------------------------------------ #Method bool isComplex() const #In Property #Line # returns true if Region contains more than one IRect ## #Populate #Example auto debugster = [](const char* label, const SkRegion& region) -> void { SkDebugf("%s: region is %s" "complex\n", label, region.isComplex() ? "" : "not "); }; SkRegion region; debugster("initial", region); region.setRect({1, 2, 3, 4}); debugster("set rect", region); region.op({2, 3, 4, 5}, SkRegion::kUnion_Op); debugster("op rect", region); #StdOut initial: region is not complex set rect: region is not complex op rect: region is complex ## ## #SeeAlso isEmpty isRect #Method ## # ------------------------------------------------------------------------------ #Method const SkIRect& getBounds() const #In Property #Line # returns maximum and minimum of IRect array ## #Populate #Example SkRegion region({1, 2, 3, 4}); region.op({2, 3, 4, 5}, SkRegion::kUnion_Op); auto r = region.getBounds(); SkDebugf("bounds: {%d,%d,%d,%d}\n", r.fLeft, r.fTop, r.fRight, r.fBottom); #StdOut bounds: {1,2,4,5} ## ## #SeeAlso isEmpty isRect #Method ## # ------------------------------------------------------------------------------ #Method int computeRegionComplexity() const #In Property #Line # returns relative complexity ## #Populate #Example auto debugster = [](const char* label, const SkRegion& region) -> void { SkDebugf("%s: region complexity %d\n", label, region.computeRegionComplexity()); }; SkRegion region; debugster("initial", region); region.setRect({1, 2, 3, 4}); debugster("set rect", region); region.op({2, 3, 4, 5}, SkRegion::kUnion_Op); debugster("op rect", region); #StdOut initial: region complexity 0 set rect: region complexity 1 op rect: region complexity 3 ## ## #SeeAlso isRect isComplex #Method ## # ------------------------------------------------------------------------------ #Method bool getBoundaryPath(SkPath* path) const #In Property #Line # appends Region outline to Path ## #Populate #Example #Height 100 SkRegion region; region.setRect({10, 20, 90, 60}); region.op({30, 40, 60, 80}, SkRegion::kXOR_Op); canvas->drawRegion(region, SkPaint()); SkPath path; region.getBoundaryPath(&path); path.offset(100, 0); canvas->drawPath(path, SkPaint()); ## #SeeAlso isEmpty isComplex #Method ## # ------------------------------------------------------------------------------ #Method bool setEmpty() #In Constructors #Line # constructs with default values ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region({1, 2, 3, 4}); debugster("region bounds", region); region.setEmpty(); SkDebugf(" after region set empty:\n"); debugster("region bounds", region); #StdOut region bounds: {1,2,3,4} after region set empty: region bounds: {0,0,0,0} ## ## #SeeAlso SkRegion() #Method ## # ------------------------------------------------------------------------------ #Method bool setRect(const SkIRect& rect) #In Constructors #Line # constructs Region matching IRect ## #Populate #Example SkRegion region({1, 2, 3, 4}); SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not "); bool setEmpty = region.setRect({1, 2, 1, 4}); SkDebugf("region is %s" "empty\n", region.isEmpty() ? "" : "not "); SkDebugf("setEmpty: %s\n", setEmpty ? "true" : "false"); #StdOut region is not empty region is empty setEmpty: false ## ## #SeeAlso SkRegion(const SkIRect& rect) #Method ## # ------------------------------------------------------------------------------ #Method bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom) #In Constructors #Line # constructs Region matching bounds ## #Populate #Example auto debugster = [](const char* label, bool success, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: success:%s {%d,%d,%d,%d}\n", label, success ? "true" : "false", r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region; bool success = region.setRect(1, 2, 3, 4); debugster("set to: 1,2,3,4", success, region); success = region.setRect(3, 2, 1, 4); debugster("set to: 3,2,1,4", success, region); #StdOut set to: 1,2,3,4: success:true {1,2,3,4} set to: 3,2,1,4: success:false {0,0,0,0} ## ## #SeeAlso SkRegion(const SkIRect& rect) #Method ## # ------------------------------------------------------------------------------ #Method bool setRects(const SkIRect rects[], int count) #In Constructors #Line # sets IRect array ## #Populate #Example #Height 70 SkIRect rects[] = { {10, 10, 40, 40}, {20, 20, 50, 50}, {30, 30, 60, 60} }; SkRegion region; region.setRects(rects, SK_ARRAY_COUNT(rects)); canvas->drawRegion(region, SkPaint()); region.setEmpty(); for (auto add : rects) { region.op(add, SkRegion::kUnion_Op); } region.translate(100, 0); canvas->drawRegion(region, SkPaint()); ## #SeeAlso setRect op #Method ## # ------------------------------------------------------------------------------ #Method bool setRegion(const SkRegion& region) #In Constructors #Line # copies Region ## #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { auto r = region.getBounds(); SkDebugf("%14s: {%d,%d,%d,%d}\n", label, r.fLeft, r.fTop, r.fRight, r.fBottom); }; SkRegion region({1, 2, 3, 4}); SkRegion region2; region2.setRegion(region); debugster("region bounds", region); debugster("region2 bounds", region2); region2.setEmpty(); SkDebugf(" after region set empty:\n"); debugster("region bounds", region); debugster("region2 bounds", region2); #StdOut region bounds: {1,2,3,4} region2 bounds: {1,2,3,4} after region set empty: region bounds: {1,2,3,4} region2 bounds: {0,0,0,0} ## ## #SeeAlso SkRegion(const SkRegion& region) #Method ## # ------------------------------------------------------------------------------ #Method bool setPath(const SkPath& path, const SkRegion& clip) #In Constructors #Line # constructs Region from clipped Path ## #Populate #Example #Height 120 SkPaint paint; paint.setTextSize(128); SkPath textPath; paint.getTextPath("Q", 1, 0, 110, &textPath); SkIRect clipRect = {20, 20, 100, 120}; SkRegion clipRegion(clipRect); SkRegion region; region.setPath(textPath, clipRegion); canvas->drawRegion(region, SkPaint()); clipRect.offset(100, 0); textPath.offset(100, 0); canvas->clipRect(SkRect::Make(clipRect), false); canvas->drawPath(textPath, SkPaint()); ## #SeeAlso setRects op #Method ## # ------------------------------------------------------------------------------ #Method bool intersects(const SkIRect& rect) const #In Intersection #Line # returns true if areas overlap ## #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath textPath; paint.getTextPath("W", 1, 20, 110, &textPath); SkRegion region; region.setPath(textPath, SkRegion({0, 0, 256, 256})); canvas->drawRegion(region, SkPaint()); SkIRect iRect = SkIRect::MakeXYWH(frame * 160, 55, 10, 10); paint.setColor(region.intersects(iRect) ? SK_ColorBLUE : SK_ColorRED); canvas->drawRect(SkRect::Make(iRect), paint); ## #SeeAlso contains SkRect::intersects #Method ## # ------------------------------------------------------------------------------ #Method bool intersects(const SkRegion& other) const #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath hPath, dotPath; paint.getTextPath("H", 1, 40, 110, &hPath); paint.getTextPath(",", 1, frame * 180, 95, &dotPath); SkRegion hRegion, dotRegion; hRegion.setPath(hPath, SkRegion({0, 0, 256, 256})); dotRegion.setPath(dotPath, SkRegion({0, 0, 256, 256})); canvas->drawRegion(hRegion, paint); paint.setColor(hRegion.intersects(dotRegion) ? SK_ColorBLUE : SK_ColorRED); canvas->drawRegion(dotRegion, paint); ## #SeeAlso contains SkRect::intersects #Method ## # ------------------------------------------------------------------------------ #Method bool contains(int32_t x, int32_t y) const #In Intersection #Line # returns true if points are equal or inside ## #Populate #Example #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath; paint.getTextPath("X", 1, 20, 110, &xPath); SkRegion xRegion; xRegion.setPath(xPath, SkRegion({0, 0, 256, 256})); canvas->drawRegion(xRegion, paint); for (int y = 0; y < 128; y += 8) { for (int x = 0; x < 128; x += 8) { paint.setColor(xRegion.contains(x, y) ? SK_ColorWHITE : SK_ColorRED); canvas->drawPoint(x, y, paint); } } ## #SeeAlso intersects SkRect::contains #Method ## # ------------------------------------------------------------------------------ #Method bool contains(const SkIRect& other) const #Populate #Example #Height 128 #Duration 4 SkPaint paint; paint.setTextSize(128); SkPath xPath; paint.getTextPath("X", 1, 20, 110, &xPath); SkRegion xRegion; SkIRect drawBounds = {0, 0, 128, 128}; xRegion.setPath(xPath, SkRegion(drawBounds)); xRegion.op(drawBounds, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); SkIRect test = SkIRect::MakeXYWH(frame* 128, 64, 5, 5); if (xRegion.contains(test)) { paint.setColor(SK_ColorYELLOW); canvas->drawRect(SkRect::Make(test), paint); } ## #SeeAlso intersects SkRect::contains #Method ## # ------------------------------------------------------------------------------ #Method bool contains(const SkRegion& other) const #Populate #Example #Height 128 #Duration 4 SkPaint paint; paint.setTextSize(128); SkPath xPath, testPath; paint.getTextPath("X", 1, 20, 110, &xPath); paint.getTextPath("`", 1, frame * 150 - 40, 150, &testPath); SkRegion xRegion, testRegion; SkIRect drawBounds = {0, 0, 128, 128}; xRegion.setPath(xPath, SkRegion(drawBounds)); testRegion.setPath(testPath, SkRegion(drawBounds)); xRegion.op(drawBounds, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); if (xRegion.contains(testRegion)) { paint.setColor(SK_ColorYELLOW); canvas->drawRegion(testRegion, paint); } ## #SeeAlso intersects SkRect::contains #Method ## # ------------------------------------------------------------------------------ #Method bool quickContains(const SkIRect& r) const #In Intersection #Line # returns true quickly if points are equal or inside ## #Populate #Example SkRegion region({1, 2, 3, 4}); SkIRect test = {2, 2, 3, 3}; SkDebugf("quickContains 1: %s\n", region.quickContains(test) ? "true" : "false"); region.op({1, 4, 3, 6}, SkRegion::kUnion_Op); SkDebugf("quickContains 2: %s\n", region.quickContains(test) ? "true" : "false"); region.op({1, 7, 3, 8}, SkRegion::kUnion_Op); SkDebugf("quickContains 3: %s\n", region.quickContains(test) ? "true" : "false"); #StdOut quickContains 1: true quickContains 2: true quickContains 3: false ## ## #SeeAlso contains quickReject intersects #Method ## # ------------------------------------------------------------------------------ #Method bool quickContains(int32_t left, int32_t top, int32_t right, int32_t bottom) const #Populate #Example auto debugster = [](const char* label, SkRegion& region) -> void { SkDebugf("%s: %s\n", label, region.quickContains(2, 2, 3, 3) ? "true" : "false"); }; SkRegion region({1, 2, 3, 4}); debugster("quickContains 1", region); region.op({1, 4, 3, 6}, SkRegion::kUnion_Op); debugster("quickContains 2", region); region.op({1, 7, 3, 8}, SkRegion::kUnion_Op); debugster("quickContains 3", region); #StdOut quickContains 1: true quickContains 2: true quickContains 3: false ## ## #SeeAlso contains quickReject intersects #Method ## # ------------------------------------------------------------------------------ #Method bool quickReject(const SkIRect& rect) const #In Intersection #Line # returns true quickly if points are outside ## #Populate #Example SkRegion region({1, 2, 3, 4}); SkIRect test = {4, 2, 5, 3}; SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false"); region.op({1, 4, 3, 6}, SkRegion::kUnion_Op); SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false"); region.op({4, 7, 5, 8}, SkRegion::kUnion_Op); SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false"); #StdOut quickReject 1: true quickReject 2: true quickReject 3: false ## ## #SeeAlso quickContains contains intersects #Method ## # ------------------------------------------------------------------------------ #Method bool quickReject(const SkRegion& rgn) const #Populate #Example SkRegion region({1, 2, 3, 4}); SkRegion test; SkIRect rects[] = {{4, 2, 5, 3}, {7, 2, 8, 3}}; test.setRects(rects, SK_ARRAY_COUNT(rects)); SkDebugf("quickReject 1: %s\n", region.quickReject(test) ? "true" : "false"); region.op({1, 4, 3, 6}, SkRegion::kUnion_Op); SkDebugf("quickReject 2: %s\n", region.quickReject(test) ? "true" : "false"); region.op({4, 7, 5, 8}, SkRegion::kUnion_Op); SkDebugf("quickReject 3: %s\n", region.quickReject(test) ? "true" : "false"); #StdOut quickReject 1: true quickReject 2: true quickReject 3: false ## ## #SeeAlso quickContains contains intersects #Method ## # ------------------------------------------------------------------------------ #Method void translate(int dx, int dy) #In Transform #Line # translates IPoints in Region ## #Populate #Example #Height 90 SkRegion test; SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}}; test.setRects(rects, SK_ARRAY_COUNT(rects)); SkPaint paint; for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) { paint.setColor(color); canvas->drawRegion(test, paint); test.translate(10, 10); } ## #SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset #Method ## # ------------------------------------------------------------------------------ #Method void translate(int dx, int dy, SkRegion* dst) const #Populate #Example SkRegion test; SkIRect rects[] = {{40, 20, 50, 30}, {70, 40, 80, 50}, { 60, 10, 70, 20}}; test.setRects(rects, SK_ARRAY_COUNT(rects)); SkPaint paint; for (auto color : { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorMAGENTA } ) { paint.setColor(color); canvas->drawRegion(test, paint); SkRegion second; test.translate(10, test.getBounds().fBottom, &second); test.op(second, SkRegion::kXOR_Op); test.translate(30, 0); } ## #SeeAlso SkCanvas::translate SkIRect::offset SkPath::offset #Method ## # ------------------------------------------------------------------------------ #Enum Op #Line # binary operator combining Regions ## #Code enum Op { kDifference_Op, kIntersect_Op, kUnion_Op, kXOR_Op, kReverseDifference_Op, kReplace_Op, kLastOp = kReplace_Op, }; ## The logical operations that can be performed when combining two Regions. #Const kDifference_Op 0 #Line # target minus operand ## Subtracts operand Region from target Region. ## #Const kIntersect_Op 1 #Line # target intersected with operand ## Intersects operand Region and target Region. ## #Const kUnion_Op 2 #Line # target unioned with operand ## Unions operand Region and target Region. ## #Const kXOR_Op 3 #Line # target exclusive or with operand ## Replaces target Region with area exclusive to both Regions. ## #Const kReverseDifference_Op 4 #Line # operand minus target ## Subtracts target Region from operand Region. ## #Const kReplace_Op 5 #Line # replace target with operand ## Replaces target Region with operand Region. ## #Const kLastOp 5 #Line # last operator ## ## #Example SkRegion operand({35, 35, 85, 85}); const char* labels[] = {"difference", "intersect", "union", "xor", "reverse diff", "replace"}; int index = 0; SkPaint paint; for (auto op : { SkRegion::kDifference_Op, SkRegion::kIntersect_Op, SkRegion::kUnion_Op, SkRegion::kXOR_Op, SkRegion::kReverseDifference_Op, SkRegion::kReplace_Op } ) { SkRegion target({10, 10, 60, 60}); target.op(operand, op); canvas->drawRegion(target, paint); canvas->drawString(labels[index++], 40, 100, paint); canvas->translate(80, 0); if (SkRegion::kUnion_Op == op) { canvas->translate(-240, 120); } } ## #SeeAlso SkPathOp #Enum ## # ------------------------------------------------------------------------------ #Const kOpCnt 6 #Line # number of operators defined ## May be used to verify that Op is a legal value. #Const ## # ------------------------------------------------------------------------------ #Method bool op(const SkIRect& rect, Op op) #In Transform #Line # applies binary operator ## #Populate #Example #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath; paint.getTextPath("X", 1, 20, 110, &xPath); SkRegion xRegion; SkIRect drawBounds = {0, 0, 128, 128}; xRegion.setPath(xPath, SkRegion(drawBounds)); xRegion.op(drawBounds, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method bool op(int left, int top, int right, int bottom, Op op) #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath; paint.getTextPath("X", 1, 20, 110, &xPath); SkRegion xRegion; SkIRect drawBounds = {0, 0, 128, 128}; xRegion.setPath(xPath, SkRegion(drawBounds)); xRegion.op(drawBounds.fLeft + frame * drawBounds.width(), drawBounds.fTop, drawBounds.fRight, drawBounds.fBottom, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method bool op(const SkRegion& rgn, Op op) #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath, opPath; paint.getTextPath("X", 1, 20, 110, &xPath); opPath.addCircle(64, 64, frame * 64); SkRegion xRegion, opRegion; SkIRect drawBounds = {0, 0, 128, 128}; opRegion.setPath(opPath, SkRegion(drawBounds)); xRegion.setPath(xPath, SkRegion(drawBounds)); xRegion.op(opRegion, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method bool op(const SkIRect& rect, const SkRegion& rgn, Op op) #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath, opPath; paint.getTextPath("X", 1, 20, 110, &xPath); opPath.addCircle(64, 64, frame * 64); SkRegion xRegion, opRegion, rectRegion; SkIRect drawBounds = {0, 0, 128, 128}; opRegion.setPath(opPath, SkRegion(drawBounds)); xRegion.setPath(xPath, SkRegion(drawBounds)); drawBounds.inset(frame * drawBounds.width() / 2, 0); rectRegion.op(drawBounds, opRegion, SkRegion::kIntersect_Op); xRegion.op(rectRegion, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method bool op(const SkRegion& rgn, const SkIRect& rect, Op op) #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath, opPath; paint.getTextPath("X", 1, 20, 110, &xPath); opPath.addCircle(64, 64, frame * 64); SkRegion xRegion, opRegion, rectRegion; SkIRect drawBounds = {0, 0, 128, 128}; opRegion.setPath(opPath, SkRegion(drawBounds)); xRegion.setPath(xPath, SkRegion(drawBounds)); drawBounds.inset(frame * drawBounds.width() / 2, 0); rectRegion.op(opRegion, drawBounds, SkRegion::kUnion_Op); xRegion.op(rectRegion, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op) #Populate #Example #Duration 4 #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath, opPath; paint.getTextPath("X", 1, 20, 110, &xPath); xPath.setFillType(SkPath::kInverseWinding_FillType); opPath.addCircle(64, 64, frame * 64); opPath.setFillType(SkPath::kInverseWinding_FillType); SkRegion xRegion, opRegion, rectRegion; SkIRect drawBounds = {0, 0, 128, 128}; opRegion.setPath(opPath, SkRegion(drawBounds)); xRegion.setPath(xPath, SkRegion(drawBounds)); drawBounds.inset(frame * drawBounds.width() / 2, 0); rectRegion.setRect(drawBounds); rectRegion.op(xRegion, SkRegion::kIntersect_Op); xRegion.op(rectRegion, opRegion, SkRegion::kReverseDifference_Op); canvas->drawRegion(xRegion, paint); ## #SeeAlso setRects Op #Method ## # ------------------------------------------------------------------------------ #Method size_t writeToMemory(void* buffer) const #In Utility #Line # writes to buffer ## #Populate #Example #Height 128 SkPaint paint; paint.setTextSize(128); SkPath xPath; paint.getTextPath("X", 1, 20, 110, &xPath); SkIRect drawBounds = {0, 0, 128, 128}; SkRegion xRegion; xRegion.setPath(xPath, SkRegion(drawBounds)); size_t size = xRegion.writeToMemory(nullptr); sk_sp<SkData> data = SkData::MakeUninitialized(size); xRegion.writeToMemory(data->writable_data()); SkRegion copy; copy.readFromMemory(data->data(), data->size()); canvas->drawRegion(copy, paint); ## #SeeAlso readFromMemory #Method ## # ------------------------------------------------------------------------------ #Method size_t readFromMemory(const void* buffer, size_t length) #In Utility #Line # reads from buffer ## #Populate #Example #Height 100 SkRegion region({20, 20, 80, 80}); size_t size = region.writeToMemory(nullptr); sk_sp<SkData> data = SkData::MakeUninitialized(size); region.writeToMemory(data->writable_data()); SkRegion copy; copy.readFromMemory(data->data(), data->size()); canvas->drawRegion(copy, SkPaint()); ## #SeeAlso writeToMemory #Method ## #Class SkRegion ## #Topic Region ##