SkRegion.h 24 KB

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