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