1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2005 The Android Open Source Project 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SkRegion_DEFINED 9cb93a386Sopenharmony_ci#define SkRegion_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ciclass SkPath; 14cb93a386Sopenharmony_ciclass SkRgnBuilder; 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci/** \class SkRegion 17cb93a386Sopenharmony_ci SkRegion describes the set of pixels used to clip SkCanvas. SkRegion is compact, 18cb93a386Sopenharmony_ci efficiently storing a single integer rectangle, or a run length encoded array 19cb93a386Sopenharmony_ci of rectangles. SkRegion may reduce the current SkCanvas clip, or may be drawn as 20cb93a386Sopenharmony_ci one or more integer rectangles. SkRegion iterator returns the scan lines or 21cb93a386Sopenharmony_ci rectangles contained by it, optionally intersecting a bounding rectangle. 22cb93a386Sopenharmony_ci*/ 23cb93a386Sopenharmony_ciclass SK_API SkRegion { 24cb93a386Sopenharmony_ci typedef int32_t RunType; 25cb93a386Sopenharmony_cipublic: 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci /** Constructs an empty SkRegion. SkRegion is set to empty bounds 28cb93a386Sopenharmony_ci at (0, 0) with zero width and height. 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci @return empty SkRegion 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_empty_constructor 33cb93a386Sopenharmony_ci */ 34cb93a386Sopenharmony_ci SkRegion(); 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci /** Constructs a copy of an existing region. 37cb93a386Sopenharmony_ci Copy constructor makes two regions identical by value. Internally, region and 38cb93a386Sopenharmony_ci the returned result share pointer values. The underlying SkRect array is 39cb93a386Sopenharmony_ci copied when modified. 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci Creating a SkRegion copy is very efficient and never allocates memory. 42cb93a386Sopenharmony_ci SkRegion are always copied by value from the interface; the underlying shared 43cb93a386Sopenharmony_ci pointers are not exposed. 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci @param region SkRegion to copy by value 46cb93a386Sopenharmony_ci @return copy of SkRegion 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_copy_const_SkRegion 49cb93a386Sopenharmony_ci */ 50cb93a386Sopenharmony_ci SkRegion(const SkRegion& region); 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci /** Constructs a rectangular SkRegion matching the bounds of rect. 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci @param rect bounds of constructed SkRegion 55cb93a386Sopenharmony_ci @return rectangular SkRegion 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_copy_const_SkIRect 58cb93a386Sopenharmony_ci */ 59cb93a386Sopenharmony_ci explicit SkRegion(const SkIRect& rect); 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci /** Releases ownership of any shared data and deletes data if SkRegion is sole owner. 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_destructor 64cb93a386Sopenharmony_ci */ 65cb93a386Sopenharmony_ci ~SkRegion(); 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci /** Constructs a copy of an existing region. 68cb93a386Sopenharmony_ci Makes two regions identical by value. Internally, region and 69cb93a386Sopenharmony_ci the returned result share pointer values. The underlying SkRect array is 70cb93a386Sopenharmony_ci copied when modified. 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci Creating a SkRegion copy is very efficient and never allocates memory. 73cb93a386Sopenharmony_ci SkRegion are always copied by value from the interface; the underlying shared 74cb93a386Sopenharmony_ci pointers are not exposed. 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci @param region SkRegion to copy by value 77cb93a386Sopenharmony_ci @return SkRegion to copy by value 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_copy_operator 80cb93a386Sopenharmony_ci */ 81cb93a386Sopenharmony_ci SkRegion& operator=(const SkRegion& region); 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci /** Compares SkRegion and other; returns true if they enclose exactly 84cb93a386Sopenharmony_ci the same area. 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci @param other SkRegion to compare 87cb93a386Sopenharmony_ci @return true if SkRegion pair are equivalent 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_equal1_operator 90cb93a386Sopenharmony_ci */ 91cb93a386Sopenharmony_ci bool operator==(const SkRegion& other) const; 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci /** Compares SkRegion and other; returns true if they do not enclose the same area. 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci @param other SkRegion to compare 96cb93a386Sopenharmony_ci @return true if SkRegion pair are not equivalent 97cb93a386Sopenharmony_ci */ 98cb93a386Sopenharmony_ci bool operator!=(const SkRegion& other) const { 99cb93a386Sopenharmony_ci return !(*this == other); 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci /** Sets SkRegion to src, and returns true if src bounds is not empty. 103cb93a386Sopenharmony_ci This makes SkRegion and src identical by value. Internally, 104cb93a386Sopenharmony_ci SkRegion and src share pointer values. The underlying SkRect array is 105cb93a386Sopenharmony_ci copied when modified. 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci Creating a SkRegion copy is very efficient and never allocates memory. 108cb93a386Sopenharmony_ci SkRegion are always copied by value from the interface; the underlying shared 109cb93a386Sopenharmony_ci pointers are not exposed. 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci @param src SkRegion to copy 112cb93a386Sopenharmony_ci @return copy of src 113cb93a386Sopenharmony_ci */ 114cb93a386Sopenharmony_ci bool set(const SkRegion& src) { 115cb93a386Sopenharmony_ci *this = src; 116cb93a386Sopenharmony_ci return !this->isEmpty(); 117cb93a386Sopenharmony_ci } 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ci /** Exchanges SkIRect array of SkRegion and other. swap() internally exchanges pointers, 120cb93a386Sopenharmony_ci so it is lightweight and does not allocate memory. 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci swap() usage has largely been replaced by operator=(const SkRegion& region). 123cb93a386Sopenharmony_ci SkPath do not copy their content on assignment until they are written to, 124cb93a386Sopenharmony_ci making assignment as efficient as swap(). 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci @param other operator=(const SkRegion& region) set 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_swap 129cb93a386Sopenharmony_ci */ 130cb93a386Sopenharmony_ci void swap(SkRegion& other); 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci /** Returns true if SkRegion is empty. 133cb93a386Sopenharmony_ci Empty SkRegion has bounds width or height less than or equal to zero. 134cb93a386Sopenharmony_ci SkRegion() constructs empty SkRegion; setEmpty() 135cb93a386Sopenharmony_ci and setRect() with dimensionless data make SkRegion empty. 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci @return true if bounds has no width or height 138cb93a386Sopenharmony_ci */ 139cb93a386Sopenharmony_ci bool isEmpty() const { return fRunHead == emptyRunHeadPtr(); } 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci /** Returns true if SkRegion is one SkIRect with positive dimensions. 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci @return true if SkRegion contains one SkIRect 144cb93a386Sopenharmony_ci */ 145cb93a386Sopenharmony_ci bool isRect() const { return fRunHead == kRectRunHeadPtr; } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci /** Returns true if SkRegion is described by more than one rectangle. 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci @return true if SkRegion contains more than one SkIRect 150cb93a386Sopenharmony_ci */ 151cb93a386Sopenharmony_ci bool isComplex() const { return !this->isEmpty() && !this->isRect(); } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci /** Returns minimum and maximum axes values of SkIRect array. 154cb93a386Sopenharmony_ci Returns (0, 0, 0, 0) if SkRegion is empty. 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci @return combined bounds of all SkIRect elements 157cb93a386Sopenharmony_ci */ 158cb93a386Sopenharmony_ci const SkIRect& getBounds() const { return fBounds; } 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci /** Returns a value that increases with the number of 161cb93a386Sopenharmony_ci elements in SkRegion. Returns zero if SkRegion is empty. 162cb93a386Sopenharmony_ci Returns one if SkRegion equals SkIRect; otherwise, returns 163cb93a386Sopenharmony_ci value greater than one indicating that SkRegion is complex. 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci Call to compare SkRegion for relative complexity. 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci @return relative complexity 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_computeRegionComplexity 170cb93a386Sopenharmony_ci */ 171cb93a386Sopenharmony_ci int computeRegionComplexity() const; 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci /** Appends outline of SkRegion to path. 174cb93a386Sopenharmony_ci Returns true if SkRegion is not empty; otherwise, returns false, and leaves path 175cb93a386Sopenharmony_ci unmodified. 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci @param path SkPath to append to 178cb93a386Sopenharmony_ci @return true if path changed 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_getBoundaryPath 181cb93a386Sopenharmony_ci */ 182cb93a386Sopenharmony_ci bool getBoundaryPath(SkPath* path) const; 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci /** Constructs an empty SkRegion. SkRegion is set to empty bounds 185cb93a386Sopenharmony_ci at (0, 0) with zero width and height. Always returns false. 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci @return false 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_setEmpty 190cb93a386Sopenharmony_ci */ 191cb93a386Sopenharmony_ci bool setEmpty(); 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci /** Constructs a rectangular SkRegion matching the bounds of rect. 194cb93a386Sopenharmony_ci If rect is empty, constructs empty and returns false. 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci @param rect bounds of constructed SkRegion 197cb93a386Sopenharmony_ci @return true if rect is not empty 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_setRect 200cb93a386Sopenharmony_ci */ 201cb93a386Sopenharmony_ci bool setRect(const SkIRect& rect); 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ci /** Constructs SkRegion as the union of SkIRect in rects array. If count is 204cb93a386Sopenharmony_ci zero, constructs empty SkRegion. Returns false if constructed SkRegion is empty. 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci May be faster than repeated calls to op(). 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ci @param rects array of SkIRect 209cb93a386Sopenharmony_ci @param count array size 210cb93a386Sopenharmony_ci @return true if constructed SkRegion is not empty 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_setRects 213cb93a386Sopenharmony_ci */ 214cb93a386Sopenharmony_ci bool setRects(const SkIRect rects[], int count); 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ci /** Constructs a copy of an existing region. 217cb93a386Sopenharmony_ci Makes two regions identical by value. Internally, region and 218cb93a386Sopenharmony_ci the returned result share pointer values. The underlying SkRect array is 219cb93a386Sopenharmony_ci copied when modified. 220cb93a386Sopenharmony_ci 221cb93a386Sopenharmony_ci Creating a SkRegion copy is very efficient and never allocates memory. 222cb93a386Sopenharmony_ci SkRegion are always copied by value from the interface; the underlying shared 223cb93a386Sopenharmony_ci pointers are not exposed. 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_ci @param region SkRegion to copy by value 226cb93a386Sopenharmony_ci @return SkRegion to copy by value 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_setRegion 229cb93a386Sopenharmony_ci */ 230cb93a386Sopenharmony_ci bool setRegion(const SkRegion& region); 231cb93a386Sopenharmony_ci 232cb93a386Sopenharmony_ci /** Constructs SkRegion to match outline of path within clip. 233cb93a386Sopenharmony_ci Returns false if constructed SkRegion is empty. 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci Constructed SkRegion draws the same pixels as path through clip when 236cb93a386Sopenharmony_ci anti-aliasing is disabled. 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_ci @param path SkPath providing outline 239cb93a386Sopenharmony_ci @param clip SkRegion containing path 240cb93a386Sopenharmony_ci @return true if constructed SkRegion is not empty 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_setPath 243cb93a386Sopenharmony_ci */ 244cb93a386Sopenharmony_ci bool setPath(const SkPath& path, const SkRegion& clip); 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ci /** Returns true if SkRegion intersects rect. 247cb93a386Sopenharmony_ci Returns false if either rect or SkRegion is empty, or do not intersect. 248cb93a386Sopenharmony_ci 249cb93a386Sopenharmony_ci @param rect SkIRect to intersect 250cb93a386Sopenharmony_ci @return true if rect and SkRegion have area in common 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_intersects 253cb93a386Sopenharmony_ci */ 254cb93a386Sopenharmony_ci bool intersects(const SkIRect& rect) const; 255cb93a386Sopenharmony_ci 256cb93a386Sopenharmony_ci /** Returns true if SkRegion intersects other. 257cb93a386Sopenharmony_ci Returns false if either other or SkRegion is empty, or do not intersect. 258cb93a386Sopenharmony_ci 259cb93a386Sopenharmony_ci @param other SkRegion to intersect 260cb93a386Sopenharmony_ci @return true if other and SkRegion have area in common 261cb93a386Sopenharmony_ci 262cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_intersects_2 263cb93a386Sopenharmony_ci */ 264cb93a386Sopenharmony_ci bool intersects(const SkRegion& other) const; 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci /** Returns true if SkIPoint (x, y) is inside SkRegion. 267cb93a386Sopenharmony_ci Returns false if SkRegion is empty. 268cb93a386Sopenharmony_ci 269cb93a386Sopenharmony_ci @param x test SkIPoint x-coordinate 270cb93a386Sopenharmony_ci @param y test SkIPoint y-coordinate 271cb93a386Sopenharmony_ci @return true if (x, y) is inside SkRegion 272cb93a386Sopenharmony_ci 273cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_contains 274cb93a386Sopenharmony_ci */ 275cb93a386Sopenharmony_ci bool contains(int32_t x, int32_t y) const; 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_ci /** Returns true if other is completely inside SkRegion. 278cb93a386Sopenharmony_ci Returns false if SkRegion or other is empty. 279cb93a386Sopenharmony_ci 280cb93a386Sopenharmony_ci @param other SkIRect to contain 281cb93a386Sopenharmony_ci @return true if other is inside SkRegion 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_contains_2 284cb93a386Sopenharmony_ci */ 285cb93a386Sopenharmony_ci bool contains(const SkIRect& other) const; 286cb93a386Sopenharmony_ci 287cb93a386Sopenharmony_ci /** Returns true if other is completely inside SkRegion. 288cb93a386Sopenharmony_ci Returns false if SkRegion or other is empty. 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci @param other SkRegion to contain 291cb93a386Sopenharmony_ci @return true if other is inside SkRegion 292cb93a386Sopenharmony_ci 293cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_contains_3 294cb93a386Sopenharmony_ci */ 295cb93a386Sopenharmony_ci bool contains(const SkRegion& other) const; 296cb93a386Sopenharmony_ci 297cb93a386Sopenharmony_ci /** Returns true if SkRegion is a single rectangle and contains r. 298cb93a386Sopenharmony_ci May return false even though SkRegion contains r. 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci @param r SkIRect to contain 301cb93a386Sopenharmony_ci @return true quickly if r points are equal or inside 302cb93a386Sopenharmony_ci */ 303cb93a386Sopenharmony_ci bool quickContains(const SkIRect& r) const { 304cb93a386Sopenharmony_ci SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region 305cb93a386Sopenharmony_ci 306cb93a386Sopenharmony_ci return r.fLeft < r.fRight && r.fTop < r.fBottom && 307cb93a386Sopenharmony_ci fRunHead == kRectRunHeadPtr && // this->isRect() 308cb93a386Sopenharmony_ci /* fBounds.contains(left, top, right, bottom); */ 309cb93a386Sopenharmony_ci fBounds.fLeft <= r.fLeft && fBounds.fTop <= r.fTop && 310cb93a386Sopenharmony_ci fBounds.fRight >= r.fRight && fBounds.fBottom >= r.fBottom; 311cb93a386Sopenharmony_ci } 312cb93a386Sopenharmony_ci 313cb93a386Sopenharmony_ci /** Returns true if SkRegion does not intersect rect. 314cb93a386Sopenharmony_ci Returns true if rect is empty or SkRegion is empty. 315cb93a386Sopenharmony_ci May return false even though SkRegion does not intersect rect. 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_ci @param rect SkIRect to intersect 318cb93a386Sopenharmony_ci @return true if rect does not intersect 319cb93a386Sopenharmony_ci */ 320cb93a386Sopenharmony_ci bool quickReject(const SkIRect& rect) const { 321cb93a386Sopenharmony_ci return this->isEmpty() || rect.isEmpty() || 322cb93a386Sopenharmony_ci !SkIRect::Intersects(fBounds, rect); 323cb93a386Sopenharmony_ci } 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_ci /** Returns true if SkRegion does not intersect rgn. 326cb93a386Sopenharmony_ci Returns true if rgn is empty or SkRegion is empty. 327cb93a386Sopenharmony_ci May return false even though SkRegion does not intersect rgn. 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci @param rgn SkRegion to intersect 330cb93a386Sopenharmony_ci @return true if rgn does not intersect 331cb93a386Sopenharmony_ci */ 332cb93a386Sopenharmony_ci bool quickReject(const SkRegion& rgn) const { 333cb93a386Sopenharmony_ci return this->isEmpty() || rgn.isEmpty() || 334cb93a386Sopenharmony_ci !SkIRect::Intersects(fBounds, rgn.fBounds); 335cb93a386Sopenharmony_ci } 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci /** Offsets SkRegion by ivector (dx, dy). Has no effect if SkRegion is empty. 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci @param dx x-axis offset 340cb93a386Sopenharmony_ci @param dy y-axis offset 341cb93a386Sopenharmony_ci */ 342cb93a386Sopenharmony_ci void translate(int dx, int dy) { this->translate(dx, dy, this); } 343cb93a386Sopenharmony_ci 344cb93a386Sopenharmony_ci /** Offsets SkRegion by ivector (dx, dy), writing result to dst. SkRegion may be passed 345cb93a386Sopenharmony_ci as dst parameter, translating SkRegion in place. Has no effect if dst is nullptr. 346cb93a386Sopenharmony_ci If SkRegion is empty, sets dst to empty. 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_ci @param dx x-axis offset 349cb93a386Sopenharmony_ci @param dy y-axis offset 350cb93a386Sopenharmony_ci @param dst translated result 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_translate_2 353cb93a386Sopenharmony_ci */ 354cb93a386Sopenharmony_ci void translate(int dx, int dy, SkRegion* dst) const; 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci /** \enum SkRegion::Op 357cb93a386Sopenharmony_ci The logical operations that can be performed when combining two SkRegion. 358cb93a386Sopenharmony_ci */ 359cb93a386Sopenharmony_ci enum Op { 360cb93a386Sopenharmony_ci kDifference_Op, //!< target minus operand 361cb93a386Sopenharmony_ci kIntersect_Op, //!< target intersected with operand 362cb93a386Sopenharmony_ci kUnion_Op, //!< target unioned with operand 363cb93a386Sopenharmony_ci kXOR_Op, //!< target exclusive or with operand 364cb93a386Sopenharmony_ci kReverseDifference_Op, //!< operand minus target 365cb93a386Sopenharmony_ci kReplace_Op, //!< replace target with operand 366cb93a386Sopenharmony_ci kLastOp = kReplace_Op, //!< last operator 367cb93a386Sopenharmony_ci }; 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_ci static const int kOpCnt = kLastOp + 1; 370cb93a386Sopenharmony_ci 371cb93a386Sopenharmony_ci /** Replaces SkRegion with the result of SkRegion op rect. 372cb93a386Sopenharmony_ci Returns true if replaced SkRegion is not empty. 373cb93a386Sopenharmony_ci 374cb93a386Sopenharmony_ci @param rect SkIRect operand 375cb93a386Sopenharmony_ci @return false if result is empty 376cb93a386Sopenharmony_ci */ 377cb93a386Sopenharmony_ci bool op(const SkIRect& rect, Op op) { 378cb93a386Sopenharmony_ci if (this->isRect() && kIntersect_Op == op) { 379cb93a386Sopenharmony_ci if (!fBounds.intersect(rect)) { 380cb93a386Sopenharmony_ci return this->setEmpty(); 381cb93a386Sopenharmony_ci } 382cb93a386Sopenharmony_ci return true; 383cb93a386Sopenharmony_ci } 384cb93a386Sopenharmony_ci return this->op(*this, rect, op); 385cb93a386Sopenharmony_ci } 386cb93a386Sopenharmony_ci 387cb93a386Sopenharmony_ci /** Replaces SkRegion with the result of SkRegion op rgn. 388cb93a386Sopenharmony_ci Returns true if replaced SkRegion is not empty. 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci @param rgn SkRegion operand 391cb93a386Sopenharmony_ci @return false if result is empty 392cb93a386Sopenharmony_ci */ 393cb93a386Sopenharmony_ci bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); } 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci /** Replaces SkRegion with the result of rect op rgn. 396cb93a386Sopenharmony_ci Returns true if replaced SkRegion is not empty. 397cb93a386Sopenharmony_ci 398cb93a386Sopenharmony_ci @param rect SkIRect operand 399cb93a386Sopenharmony_ci @param rgn SkRegion operand 400cb93a386Sopenharmony_ci @return false if result is empty 401cb93a386Sopenharmony_ci 402cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_op_4 403cb93a386Sopenharmony_ci */ 404cb93a386Sopenharmony_ci bool op(const SkIRect& rect, const SkRegion& rgn, Op op); 405cb93a386Sopenharmony_ci 406cb93a386Sopenharmony_ci /** Replaces SkRegion with the result of rgn op rect. 407cb93a386Sopenharmony_ci Returns true if replaced SkRegion is not empty. 408cb93a386Sopenharmony_ci 409cb93a386Sopenharmony_ci @param rgn SkRegion operand 410cb93a386Sopenharmony_ci @param rect SkIRect operand 411cb93a386Sopenharmony_ci @return false if result is empty 412cb93a386Sopenharmony_ci 413cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_op_5 414cb93a386Sopenharmony_ci */ 415cb93a386Sopenharmony_ci bool op(const SkRegion& rgn, const SkIRect& rect, Op op); 416cb93a386Sopenharmony_ci 417cb93a386Sopenharmony_ci /** Replaces SkRegion with the result of rgna op rgnb. 418cb93a386Sopenharmony_ci Returns true if replaced SkRegion is not empty. 419cb93a386Sopenharmony_ci 420cb93a386Sopenharmony_ci @param rgna SkRegion operand 421cb93a386Sopenharmony_ci @param rgnb SkRegion operand 422cb93a386Sopenharmony_ci @return false if result is empty 423cb93a386Sopenharmony_ci 424cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_op_6 425cb93a386Sopenharmony_ci */ 426cb93a386Sopenharmony_ci bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op); 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 429cb93a386Sopenharmony_ci /** Private. Android framework only. 430cb93a386Sopenharmony_ci 431cb93a386Sopenharmony_ci @return string representation of SkRegion 432cb93a386Sopenharmony_ci */ 433cb93a386Sopenharmony_ci char* toString(); 434cb93a386Sopenharmony_ci#endif 435cb93a386Sopenharmony_ci 436cb93a386Sopenharmony_ci /** \class SkRegion::Iterator 437cb93a386Sopenharmony_ci Returns sequence of rectangles, sorted along y-axis, then x-axis, that make 438cb93a386Sopenharmony_ci up SkRegion. 439cb93a386Sopenharmony_ci */ 440cb93a386Sopenharmony_ci class SK_API Iterator { 441cb93a386Sopenharmony_ci public: 442cb93a386Sopenharmony_ci 443cb93a386Sopenharmony_ci /** Initializes SkRegion::Iterator with an empty SkRegion. done() on SkRegion::Iterator 444cb93a386Sopenharmony_ci returns true. 445cb93a386Sopenharmony_ci Call reset() to initialized SkRegion::Iterator at a later time. 446cb93a386Sopenharmony_ci 447cb93a386Sopenharmony_ci @return empty SkRegion iterator 448cb93a386Sopenharmony_ci */ 449cb93a386Sopenharmony_ci Iterator() : fRgn(nullptr), fDone(true) {} 450cb93a386Sopenharmony_ci 451cb93a386Sopenharmony_ci /** Sets SkRegion::Iterator to return elements of SkIRect array in region. 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_ci @param region SkRegion to iterate 454cb93a386Sopenharmony_ci @return SkRegion iterator 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Iterator_copy_const_SkRegion 457cb93a386Sopenharmony_ci */ 458cb93a386Sopenharmony_ci Iterator(const SkRegion& region); 459cb93a386Sopenharmony_ci 460cb93a386Sopenharmony_ci /** SkPoint SkRegion::Iterator to start of SkRegion. 461cb93a386Sopenharmony_ci Returns true if SkRegion was set; otherwise, returns false. 462cb93a386Sopenharmony_ci 463cb93a386Sopenharmony_ci @return true if SkRegion was set 464cb93a386Sopenharmony_ci 465cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Iterator_rewind 466cb93a386Sopenharmony_ci */ 467cb93a386Sopenharmony_ci bool rewind(); 468cb93a386Sopenharmony_ci 469cb93a386Sopenharmony_ci /** Resets iterator, using the new SkRegion. 470cb93a386Sopenharmony_ci 471cb93a386Sopenharmony_ci @param region SkRegion to iterate 472cb93a386Sopenharmony_ci 473cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Iterator_reset 474cb93a386Sopenharmony_ci */ 475cb93a386Sopenharmony_ci void reset(const SkRegion& region); 476cb93a386Sopenharmony_ci 477cb93a386Sopenharmony_ci /** Returns true if SkRegion::Iterator is pointing to final SkIRect in SkRegion. 478cb93a386Sopenharmony_ci 479cb93a386Sopenharmony_ci @return true if data parsing is complete 480cb93a386Sopenharmony_ci */ 481cb93a386Sopenharmony_ci bool done() const { return fDone; } 482cb93a386Sopenharmony_ci 483cb93a386Sopenharmony_ci /** Advances SkRegion::Iterator to next SkIRect in SkRegion if it is not done. 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Iterator_next 486cb93a386Sopenharmony_ci */ 487cb93a386Sopenharmony_ci void next(); 488cb93a386Sopenharmony_ci 489cb93a386Sopenharmony_ci /** Returns SkIRect element in SkRegion. Does not return predictable results if SkRegion 490cb93a386Sopenharmony_ci is empty. 491cb93a386Sopenharmony_ci 492cb93a386Sopenharmony_ci @return part of SkRegion as SkIRect 493cb93a386Sopenharmony_ci */ 494cb93a386Sopenharmony_ci const SkIRect& rect() const { return fRect; } 495cb93a386Sopenharmony_ci 496cb93a386Sopenharmony_ci /** Returns SkRegion if set; otherwise, returns nullptr. 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ci @return iterated SkRegion 499cb93a386Sopenharmony_ci */ 500cb93a386Sopenharmony_ci const SkRegion* rgn() const { return fRgn; } 501cb93a386Sopenharmony_ci 502cb93a386Sopenharmony_ci private: 503cb93a386Sopenharmony_ci const SkRegion* fRgn; 504cb93a386Sopenharmony_ci const SkRegion::RunType* fRuns; 505cb93a386Sopenharmony_ci SkIRect fRect = {0, 0, 0, 0}; 506cb93a386Sopenharmony_ci bool fDone; 507cb93a386Sopenharmony_ci }; 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_ci /** \class SkRegion::Cliperator 510cb93a386Sopenharmony_ci Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make 511cb93a386Sopenharmony_ci up SkRegion intersected with the specified clip rectangle. 512cb93a386Sopenharmony_ci */ 513cb93a386Sopenharmony_ci class SK_API Cliperator { 514cb93a386Sopenharmony_ci public: 515cb93a386Sopenharmony_ci 516cb93a386Sopenharmony_ci /** Sets SkRegion::Cliperator to return elements of SkIRect array in SkRegion within clip. 517cb93a386Sopenharmony_ci 518cb93a386Sopenharmony_ci @param region SkRegion to iterate 519cb93a386Sopenharmony_ci @param clip bounds of iteration 520cb93a386Sopenharmony_ci @return SkRegion iterator 521cb93a386Sopenharmony_ci 522cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Cliperator_const_SkRegion_const_SkIRect 523cb93a386Sopenharmony_ci */ 524cb93a386Sopenharmony_ci Cliperator(const SkRegion& region, const SkIRect& clip); 525cb93a386Sopenharmony_ci 526cb93a386Sopenharmony_ci /** Returns true if SkRegion::Cliperator is pointing to final SkIRect in SkRegion. 527cb93a386Sopenharmony_ci 528cb93a386Sopenharmony_ci @return true if data parsing is complete 529cb93a386Sopenharmony_ci */ 530cb93a386Sopenharmony_ci bool done() { return fDone; } 531cb93a386Sopenharmony_ci 532cb93a386Sopenharmony_ci /** Advances iterator to next SkIRect in SkRegion contained by clip. 533cb93a386Sopenharmony_ci 534cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Cliperator_next 535cb93a386Sopenharmony_ci */ 536cb93a386Sopenharmony_ci void next(); 537cb93a386Sopenharmony_ci 538cb93a386Sopenharmony_ci /** Returns SkIRect element in SkRegion, intersected with clip passed to 539cb93a386Sopenharmony_ci SkRegion::Cliperator constructor. Does not return predictable results if SkRegion 540cb93a386Sopenharmony_ci is empty. 541cb93a386Sopenharmony_ci 542cb93a386Sopenharmony_ci @return part of SkRegion inside clip as SkIRect 543cb93a386Sopenharmony_ci */ 544cb93a386Sopenharmony_ci const SkIRect& rect() const { return fRect; } 545cb93a386Sopenharmony_ci 546cb93a386Sopenharmony_ci private: 547cb93a386Sopenharmony_ci Iterator fIter; 548cb93a386Sopenharmony_ci SkIRect fClip; 549cb93a386Sopenharmony_ci SkIRect fRect = {0, 0, 0, 0}; 550cb93a386Sopenharmony_ci bool fDone; 551cb93a386Sopenharmony_ci }; 552cb93a386Sopenharmony_ci 553cb93a386Sopenharmony_ci /** \class SkRegion::Spanerator 554cb93a386Sopenharmony_ci Returns the line segment ends within SkRegion that intersect a horizontal line. 555cb93a386Sopenharmony_ci */ 556cb93a386Sopenharmony_ci class Spanerator { 557cb93a386Sopenharmony_ci public: 558cb93a386Sopenharmony_ci 559cb93a386Sopenharmony_ci /** Sets SkRegion::Spanerator to return line segments in SkRegion on scan line. 560cb93a386Sopenharmony_ci 561cb93a386Sopenharmony_ci @param region SkRegion to iterate 562cb93a386Sopenharmony_ci @param y horizontal line to intersect 563cb93a386Sopenharmony_ci @param left bounds of iteration 564cb93a386Sopenharmony_ci @param right bounds of iteration 565cb93a386Sopenharmony_ci @return SkRegion iterator 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Spanerator_const_SkRegion_int_int_int 568cb93a386Sopenharmony_ci */ 569cb93a386Sopenharmony_ci Spanerator(const SkRegion& region, int y, int left, int right); 570cb93a386Sopenharmony_ci 571cb93a386Sopenharmony_ci /** Advances iterator to next span intersecting SkRegion within line segment provided 572cb93a386Sopenharmony_ci in constructor. Returns true if interval was found. 573cb93a386Sopenharmony_ci 574cb93a386Sopenharmony_ci @param left pointer to span start; may be nullptr 575cb93a386Sopenharmony_ci @param right pointer to span end; may be nullptr 576cb93a386Sopenharmony_ci @return true if interval was found 577cb93a386Sopenharmony_ci 578cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_Spanerator_next 579cb93a386Sopenharmony_ci */ 580cb93a386Sopenharmony_ci bool next(int* left, int* right); 581cb93a386Sopenharmony_ci 582cb93a386Sopenharmony_ci private: 583cb93a386Sopenharmony_ci const SkRegion::RunType* fRuns; 584cb93a386Sopenharmony_ci int fLeft, fRight; 585cb93a386Sopenharmony_ci bool fDone; 586cb93a386Sopenharmony_ci }; 587cb93a386Sopenharmony_ci 588cb93a386Sopenharmony_ci /** Writes SkRegion to buffer, and returns number of bytes written. 589cb93a386Sopenharmony_ci If buffer is nullptr, returns number number of bytes that would be written. 590cb93a386Sopenharmony_ci 591cb93a386Sopenharmony_ci @param buffer storage for binary data 592cb93a386Sopenharmony_ci @return size of SkRegion 593cb93a386Sopenharmony_ci 594cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_writeToMemory 595cb93a386Sopenharmony_ci */ 596cb93a386Sopenharmony_ci size_t writeToMemory(void* buffer) const; 597cb93a386Sopenharmony_ci 598cb93a386Sopenharmony_ci /** Constructs SkRegion from buffer of size length. Returns bytes read. 599cb93a386Sopenharmony_ci Returned value will be multiple of four or zero if length was too small. 600cb93a386Sopenharmony_ci 601cb93a386Sopenharmony_ci @param buffer storage for binary data 602cb93a386Sopenharmony_ci @param length size of buffer 603cb93a386Sopenharmony_ci @return bytes read 604cb93a386Sopenharmony_ci 605cb93a386Sopenharmony_ci example: https://fiddle.skia.org/c/@Region_readFromMemory 606cb93a386Sopenharmony_ci */ 607cb93a386Sopenharmony_ci size_t readFromMemory(const void* buffer, size_t length); 608cb93a386Sopenharmony_ci 609cb93a386Sopenharmony_ci /** Writes text representation of SkRegion to string. 610cb93a386Sopenharmony_ci 611cb93a386Sopenharmony_ci @param desc the string storing a description of parameters. 612cb93a386Sopenharmony_ci @param depth the number of tabs preceding each line. 613cb93a386Sopenharmony_ci */ 614cb93a386Sopenharmony_ci void dump(std::string& desc, int depth) const; 615cb93a386Sopenharmony_ci 616cb93a386Sopenharmony_ciprivate: 617cb93a386Sopenharmony_ci static constexpr int kOpCount = kReplace_Op + 1; 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ci // T 620cb93a386Sopenharmony_ci // [B N L R S] 621cb93a386Sopenharmony_ci // S 622cb93a386Sopenharmony_ci static constexpr int kRectRegionRuns = 7; 623cb93a386Sopenharmony_ci 624cb93a386Sopenharmony_ci struct RunHead; 625cb93a386Sopenharmony_ci 626cb93a386Sopenharmony_ci static RunHead* emptyRunHeadPtr() { return (SkRegion::RunHead*) -1; } 627cb93a386Sopenharmony_ci static constexpr RunHead* kRectRunHeadPtr = nullptr; 628cb93a386Sopenharmony_ci 629cb93a386Sopenharmony_ci // allocate space for count runs 630cb93a386Sopenharmony_ci void allocateRuns(int count); 631cb93a386Sopenharmony_ci void allocateRuns(int count, int ySpanCount, int intervalCount); 632cb93a386Sopenharmony_ci void allocateRuns(const RunHead& src); 633cb93a386Sopenharmony_ci 634cb93a386Sopenharmony_ci SkDEBUGCODE(void dump() const;) 635cb93a386Sopenharmony_ci 636cb93a386Sopenharmony_ci SkIRect fBounds; 637cb93a386Sopenharmony_ci RunHead* fRunHead; 638cb93a386Sopenharmony_ci 639cb93a386Sopenharmony_ci void freeRuns(); 640cb93a386Sopenharmony_ci 641cb93a386Sopenharmony_ci /** 642cb93a386Sopenharmony_ci * Return the runs from this region, consing up fake runs if the region 643cb93a386Sopenharmony_ci * is empty or a rect. In those 2 cases, we use tmpStorage to hold the 644cb93a386Sopenharmony_ci * run data. 645cb93a386Sopenharmony_ci */ 646cb93a386Sopenharmony_ci const RunType* getRuns(RunType tmpStorage[], int* intervals) const; 647cb93a386Sopenharmony_ci 648cb93a386Sopenharmony_ci // This is called with runs[] that do not yet have their interval-count 649cb93a386Sopenharmony_ci // field set on each scanline. That is computed as part of this call 650cb93a386Sopenharmony_ci // (inside ComputeRunBounds). 651cb93a386Sopenharmony_ci bool setRuns(RunType runs[], int count); 652cb93a386Sopenharmony_ci 653cb93a386Sopenharmony_ci int count_runtype_values(int* itop, int* ibot) const; 654cb93a386Sopenharmony_ci 655cb93a386Sopenharmony_ci bool isValid() const; 656cb93a386Sopenharmony_ci 657cb93a386Sopenharmony_ci static void BuildRectRuns(const SkIRect& bounds, 658cb93a386Sopenharmony_ci RunType runs[kRectRegionRuns]); 659cb93a386Sopenharmony_ci 660cb93a386Sopenharmony_ci // If the runs define a simple rect, return true and set bounds to that 661cb93a386Sopenharmony_ci // rect. If not, return false and ignore bounds. 662cb93a386Sopenharmony_ci static bool RunsAreARect(const SkRegion::RunType runs[], int count, 663cb93a386Sopenharmony_ci SkIRect* bounds); 664cb93a386Sopenharmony_ci 665cb93a386Sopenharmony_ci /** 666cb93a386Sopenharmony_ci * If the last arg is null, just return if the result is non-empty, 667cb93a386Sopenharmony_ci * else store the result in the last arg. 668cb93a386Sopenharmony_ci */ 669cb93a386Sopenharmony_ci static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*); 670cb93a386Sopenharmony_ci 671cb93a386Sopenharmony_ci friend struct RunHead; 672cb93a386Sopenharmony_ci friend class Iterator; 673cb93a386Sopenharmony_ci friend class Spanerator; 674cb93a386Sopenharmony_ci friend class SkRegionPriv; 675cb93a386Sopenharmony_ci friend class SkRgnBuilder; 676cb93a386Sopenharmony_ci friend class SkFlatRegion; 677cb93a386Sopenharmony_ci}; 678cb93a386Sopenharmony_ci 679cb93a386Sopenharmony_ci#endif 680