|  | #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 | 
|  |  | 
|  | 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. | 
|  |  | 
|  | #Subtopic Overview | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | #Subtopic Constant | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | #Subtopic Class | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | #Subtopic Constructor | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | #Subtopic Operator | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | #Subtopic Member_Function | 
|  | #Populate | 
|  | ## | 
|  |  | 
|  | # ------------------------------------------------------------------------------ | 
|  |  | 
|  | #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 ## | 
|  | Initializes Iterator with an empty Region. done() on Iterator returns true. | 
|  | Call reset() to initialized Iterator at a later time. | 
|  |  | 
|  | #Return empty Region ierator ## | 
|  |  | 
|  | #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 ## | 
|  | Sets Iterator to return elements of IRect array in region. | 
|  | #Param region  Region to iterate ## | 
|  |  | 
|  | #Return Region iterator ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Points Iterator to start of Region. | 
|  | Returns true if Region was set; otherwise, returns false. | 
|  |  | 
|  | #Return true if Region was set ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Resets iterator, using the new Region. | 
|  |  | 
|  | #Param region  Region to iterate ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Iterator is pointing to final IRect in Region. | 
|  |  | 
|  | #Return true if data parsing is complete ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Advances Iterator to next IRect in Region if it is not done. | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns IRect element in Region. Does not return predictable results if Region | 
|  | is empty. | 
|  |  | 
|  | #Return part of Region as IRect ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns Region if set; otherwise, returns nullptr. | 
|  |  | 
|  | #Return iterated Region ## | 
|  |  | 
|  | #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 SK_API Cliperator { | 
|  | public: | 
|  | Cliperator(const SkRegion&, 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 ## | 
|  |  | 
|  | Sets Cliperator to return elements of IRect array in Region within clip. | 
|  |  | 
|  | #Param region  Region to iterate ## | 
|  | #Param clip  bounds of iteration ## | 
|  |  | 
|  | #Return Region iterator ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Cliperator is pointing to final IRect in Region. | 
|  |  | 
|  | #Return true if data parsing is complete ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Advances iterator to next IRect in Region contained by clip. | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns IRect element in Region, intersected with clip passed to Cliperator | 
|  | constructor. Does not return predictable results if Region | 
|  | is empty. | 
|  |  | 
|  | #Return part of Region inside clip as IRect  ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Sets Spanerator to return line segments in Region on scan line. | 
|  |  | 
|  |  | 
|  | #Param region  Region to iterate ## | 
|  | #Param y  horizontal line to intersect ## | 
|  | #Param left  bounds of iteration ## | 
|  | #Param right  bounds of iteration ## | 
|  |  | 
|  | #Return Region iterator ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Advances iterator to next span intersecting Region within line segment provided | 
|  | in constructor. Returns true if interval was found. | 
|  |  | 
|  | #Param left  pointer to span start; may be nullptr ## | 
|  | #Param right  pointer to span end; may be nullptr ## | 
|  |  | 
|  | #Return true if interval was found ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs with default values ## | 
|  |  | 
|  | Constructs an empty Region. Region is set to empty bounds | 
|  | at (0, 0) with zero width and height. | 
|  |  | 
|  | #Return empty Region ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # makes a shallow copy ## | 
|  | Constructs a copy of an existing region. | 
|  | Copy constructor makes two regions identical by value. Internally, region and | 
|  | the returned result share pointer values. The underlying Rect array is | 
|  | copied when modified. | 
|  |  | 
|  | Creating a Region copy is very efficient and never allocates memory. | 
|  | Regions are always copied by value from the interface; the underlying shared | 
|  | pointers are not exposed. | 
|  |  | 
|  | #Param region  Region to copy by value ## | 
|  |  | 
|  | #Return copy of Region ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs Region matching IRect ## | 
|  | Constructs a rectangular Region matching the bounds of rect. | 
|  |  | 
|  | #Param rect  bounds of constructed Region ## | 
|  |  | 
|  | #Return rectangular Region ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # decreases Reference_Count of owned objects ## | 
|  | Releases ownership of any shared data and deletes data if Region is sole owner. | 
|  |  | 
|  | #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 Operator | 
|  | #Line # makes a shallow copy ## | 
|  | Constructs a copy of an existing region. | 
|  | Makes two regions identical by value. Internally, region and | 
|  | the returned result share pointer values. The underlying Rect array is | 
|  | copied when modified. | 
|  |  | 
|  | Creating a Region copy is very efficient and never allocates memory. | 
|  | Regions are always copied by value from the interface; the underlying shared | 
|  | pointers are not exposed. | 
|  |  | 
|  | #Param region  Region to copy by value ## | 
|  |  | 
|  | #Return Region to copy by value ## | 
|  |  | 
|  | #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 Operator | 
|  | #Line # compares Regions for equality ## | 
|  |  | 
|  | Compares Region and other; returns true if they enclose exactly | 
|  | the same area. | 
|  |  | 
|  | #Param other  Region to compare ## | 
|  |  | 
|  | #Return true if Region pair are equivalent ## | 
|  |  | 
|  | #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 Operator | 
|  | #Line # compares Regions for inequality ## | 
|  |  | 
|  | Compares Region and other; returns true if they do not enclose the same area. | 
|  |  | 
|  | #Param other  Region to compare ## | 
|  |  | 
|  | #Return true if Region pair are not equivalent ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # makes a shallow copy ## | 
|  |  | 
|  | Sets Region to src, and returns true if src bounds is not empty. | 
|  | This makes Region and src identical by value. Internally, | 
|  | Region and src share pointer values. The underlying Rect array is | 
|  | copied when modified. | 
|  |  | 
|  | Creating a Region copy is very efficient and never allocates memory. | 
|  | Regions are always copied by value from the interface; the underlying shared | 
|  | pointers are not exposed. | 
|  |  | 
|  | #Param src  Region to copy ## | 
|  |  | 
|  | #Return copy of src ## | 
|  |  | 
|  | #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 Operator | 
|  | #Line # exchanges Region pair ## | 
|  |  | 
|  | Exchanges IRect array of Region and other. swap() internally exchanges pointers, | 
|  | so it is lightweight and does not allocate memory. | 
|  |  | 
|  | swap() usage has largely been replaced by operator=(const SkRegion& region). | 
|  | Paths do not copy their content on assignment until they are written to, | 
|  | making assignment as efficient as swap(). | 
|  |  | 
|  | #Param other  operator=(const SkRegion& region) set ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region is empty. | 
|  | Empty Region has bounds width or height less than or equal to zero. | 
|  | SkRegion() constructs empty Region; setEmpty | 
|  | and setRect with dimensionless data make Region empty. | 
|  |  | 
|  | #Return true if bounds has no width or height ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region is one IRect with positive dimensions. | 
|  |  | 
|  | #Return true if Region contains one IRect ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region is described by more than one rectangle. | 
|  |  | 
|  | #Return true if Region contains more than one IRect ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns minimum and maximum axes values of IRect array. | 
|  | Returns (0, 0, 0, 0) if Region is empty. | 
|  |  | 
|  | #Return combined bounds of all IRect elements ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns a value that increases with the number of | 
|  | elements in Region. Returns zero if Region is empty. | 
|  | Returns one if Region equals IRect; otherwise, returns | 
|  | value greater than one indicating that Region is complex. | 
|  |  | 
|  | Call to compare Regions for relative complexity. | 
|  |  | 
|  | #Return relative complexity ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Appends outline of Region to path. | 
|  | Returns true if Region is not empty; otherwise, returns false, and leaves path | 
|  | unmodified. | 
|  |  | 
|  | #Param path  Path to append to ## | 
|  |  | 
|  | #Return true if path changed ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs with default values ## | 
|  |  | 
|  | Constructs an empty Region. Region is set to empty bounds | 
|  | at (0, 0) with zero width and height. Always returns false. | 
|  |  | 
|  | #Return false ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs Region matching IRect ## | 
|  |  | 
|  | Constructs a rectangular Region matching the bounds of rect. | 
|  | If rect is empty, constructs empty and returns false. | 
|  |  | 
|  | #Param rect  bounds of constructed Region ## | 
|  |  | 
|  | #Return true if rect is not empty ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs Region matching bounds ## | 
|  |  | 
|  | Constructs Region with bounds (left, top, right, bottom). | 
|  | Returns true if left is less than right and top is less than bottom; otherwise, | 
|  | constructs empty Region and returns false. | 
|  |  | 
|  | #Param left edge of bounds on x-axis ## | 
|  | #Param top  edge of bounds on y-axis ## | 
|  | #Param right  edge of bounds on x-axis ## | 
|  | #Param bottom  edge of bounds on y-axis ## | 
|  |  | 
|  | #Return rectangular Region ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # sets IRect array ## | 
|  |  | 
|  | Constructs Region as the union of IRect in rects array. If count is | 
|  | zero, constructs empty Region. Returns false if constructed Region is empty. | 
|  |  | 
|  | May be faster than repeated calls to op(). | 
|  |  | 
|  | #Param rects  array of IRects ## | 
|  | #Param count  array size ## | 
|  |  | 
|  | #Return  true if constructed Region is not empty ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # copies Region ## | 
|  |  | 
|  | Constructs a copy of an existing region. | 
|  | Makes two regions identical by value. Internally, region and | 
|  | the returned result share pointer values. The underlying Rect array is | 
|  | copied when modified. | 
|  |  | 
|  | Creating a Region copy is very efficient and never allocates memory. | 
|  | Regions are always copied by value from the interface; the underlying shared | 
|  | pointers are not exposed. | 
|  |  | 
|  | #Param region  Region to copy by value ## | 
|  |  | 
|  | #Return Region to copy by value ## | 
|  |  | 
|  | #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 Constructor | 
|  | #Line # constructs Region from clipped Path ## | 
|  |  | 
|  | Constructs Region to match outline of path within clip. | 
|  | Returns false if constructed Region is empty. | 
|  |  | 
|  | Constructed Region draws the same pixels as path through clip when | 
|  | Anti_Aliasing is disabled. | 
|  |  | 
|  | #Param path  Path providing outline ## | 
|  | #Param clip  Region containing path ## | 
|  |  | 
|  | #Return true if constructed Region is not empty ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region intersects rect. | 
|  | Returns false if either rect or Region is empty, or do not intersect. | 
|  |  | 
|  | #Param rect  IRect to intersect ## | 
|  |  | 
|  | #Return true if rect and Region have area in common ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Returns true if Region intersects other. | 
|  | Returns false if either other or Region is empty, or do not intersect. | 
|  |  | 
|  | #Param other  Region to intersect ## | 
|  |  | 
|  | #Return true if other and Region have area in common ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if IPoint (x, y) is inside Region. | 
|  | Returns false if Region is empty. | 
|  |  | 
|  | #Param x  test IPoint x-coordinate ## | 
|  | #Param y  test IPoint y-coordinate ## | 
|  |  | 
|  | #Return true if (x, y) is inside Region ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Returns true if other is completely inside Region. | 
|  | Returns false if Region or other is empty. | 
|  |  | 
|  | #Param other IRect to contain ## | 
|  |  | 
|  | #Return true if other is inside Region ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Returns true if other is completely inside Region. | 
|  | Returns false if Region or other is empty. | 
|  |  | 
|  | #Param other  Region to contain ## | 
|  |  | 
|  | #Return true if other is inside Region ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region is a single rectangle and contains r. | 
|  | May return false even though Region contains r. | 
|  |  | 
|  | #Param r  IRect to contain ## | 
|  |  | 
|  | #Return true quickly if r points are equal or inside ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Returns true if Region is a single rectangle and contains IRect | 
|  | (left, top, right, bottom). | 
|  | Returns false if Region is empty or IRect (left, top, right, bottom) is empty. | 
|  | May return false even though Region contains (left, top, right, bottom). | 
|  |  | 
|  | #Param left edge of bounds on x-axis ## | 
|  | #Param top  edge of bounds on y-axis ## | 
|  | #Param right  edge of bounds on x-axis ## | 
|  | #Param bottom  edge of bounds on y-axis ## | 
|  |  | 
|  | #Return true quickly if IRect are equal or inside ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Returns true if Region does not intersect rect. | 
|  | Returns true if rect is empty or Region is empty. | 
|  | May return false even though Region does not intersect rect. | 
|  |  | 
|  | #Param rect  IRect to intersect ## | 
|  |  | 
|  | #Return true if rect does not intersect ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Returns true if Region does not intersect rgn. | 
|  | Returns true if rgn is empty or Region is empty. | 
|  | May return false even though Region does not intersect rgn. | 
|  |  | 
|  | #Param rgn  Region to intersect ## | 
|  |  | 
|  | #Return true if rgn does not intersect ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Offsets Region by IVector (dx, dy). Has no effect if Region is empty. | 
|  |  | 
|  | #Param dx  x-axis offset ## | 
|  | #Param dy  y-axis offset ## | 
|  |  | 
|  | #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 | 
|  |  | 
|  | Offsets Region by IVector (dx, dy), writing result to dst. Region may be passed | 
|  | as dst parameter, translating Region in place. Has no effect if dst is nullptr. | 
|  | If Region is empty, sets dst to empty. | 
|  |  | 
|  | #Param dx  x-axis offset ## | 
|  | #Param dy  y-axis offset ## | 
|  | #Param dst  translated result ## | 
|  |  | 
|  | #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; | 
|  | paint.setTextAlign(SkPaint::kCenter_Align); | 
|  | 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 ## | 
|  |  | 
|  | Replaces Region with the result of Region op rect. | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param rect IRect operand ## | 
|  | #Param op   operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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) | 
|  |  | 
|  | Replaces Region with the result of Region op IRect (left, top, right, bottom). | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param left edge of bounds on x-axis ## | 
|  | #Param top  edge of bounds on y-axis ## | 
|  | #Param right  edge of bounds on x-axis ## | 
|  | #Param bottom  edge of bounds on y-axis ## | 
|  | #Param op   operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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) | 
|  |  | 
|  | Replaces Region with the result of Region op rgn. | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param rgn  Region operand ## | 
|  | #Param op   operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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) | 
|  |  | 
|  | Replaces Region with the result of rect op rgn. | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param rect  IRect operand ## | 
|  | #Param rgn  Region operand ## | 
|  | #Param op   operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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) | 
|  |  | 
|  | Replaces Region with the result of rgn op rect. | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param rgn  Region operand ## | 
|  | #Param rect  IRect operand ## | 
|  | #Param op   operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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) | 
|  |  | 
|  | Replaces Region with the result of rgna op rgnb. | 
|  | Returns true if replaced Region is not empty. | 
|  |  | 
|  | #Param rgna  Region operand ## | 
|  | #Param rgnb  Region operand ## | 
|  | #Param op  operator, one of: #list_of_op_types# | 
|  | ## | 
|  |  | 
|  | #Return false if result is empty ## | 
|  |  | 
|  | #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 char* toString() | 
|  | #In Utility | 
|  | #Line # exists for Android framework only ## | 
|  | #Private | 
|  | Android framework only. | 
|  | ## | 
|  | #Return string representation of Region ## | 
|  |  | 
|  | #Method ## | 
|  |  | 
|  | # ------------------------------------------------------------------------------ | 
|  |  | 
|  | #Method size_t writeToMemory(void* buffer) const | 
|  | #In Utility | 
|  | #Line # writes to buffer ## | 
|  |  | 
|  | Writes Region to buffer, and returns number of bytes written. | 
|  | If buffer is nullptr, returns number number of bytes that would be written. | 
|  |  | 
|  | #Param buffer  storage for binary data ## | 
|  |  | 
|  | #Return size of Region ## | 
|  |  | 
|  | #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 ## | 
|  |  | 
|  | Constructs Region from buffer of size length. Returns bytes read. | 
|  | Returned value will be multiple of four or zero if length was too small. | 
|  |  | 
|  | #Param buffer  storage for binary data ## | 
|  | #Param length  size of buffer ## | 
|  |  | 
|  | #Return  bytes read ## | 
|  |  | 
|  | #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 ## |