clean up includes
Prepare SkRegion.h, SkShader.h, SkStream.h for documentation. Name params, add trailing commas to enum member list, move or remove some public SkRegion.h stuff. SkRegion gets a minor overhaul to move some pieces to private: or SkRegionPriv. The intent is to preserve the current code so that the fixes for documentation do not impact performance or code size. R=djsollen@google.com,reed@google.com Docs-Preview: https://skia.org/?cl=141284 Bug: skia:6818 Change-Id: I0d82794081b8739a9e8af0d1cd4a0e5d32d04f04 Reviewed-on: https://skia-review.googlesource.com/141284 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
98d3375b36
commit
6943689ab4
@ -8,7 +8,7 @@
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkRegionPriv.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
bool FuzzRegionDeserialize(sk_sp<SkData> bytes) {
|
||||
@ -30,7 +30,7 @@ bool FuzzRegionDeserialize(sk_sp<SkData> bytes) {
|
||||
return false;
|
||||
}
|
||||
s->getCanvas()->drawRegion(region, SkPaint());
|
||||
SkDEBUGCODE(region.validate());
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(region));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -15,29 +15,20 @@
|
||||
class SkPath;
|
||||
class SkRgnBuilder;
|
||||
|
||||
namespace android {
|
||||
class Region;
|
||||
}
|
||||
|
||||
#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1)
|
||||
#define SkRegion_gRectRunHeadPtr nullptr
|
||||
|
||||
/** \class SkRegion
|
||||
|
||||
The SkRegion class encapsulates the geometric region used to specify
|
||||
clipping areas for drawing.
|
||||
*/
|
||||
class SK_API SkRegion {
|
||||
public:
|
||||
typedef int32_t RunType;
|
||||
static constexpr int kRunTypeSentinel = 0x7FFFFFFF;
|
||||
|
||||
public:
|
||||
SkRegion();
|
||||
SkRegion(const SkRegion&);
|
||||
explicit SkRegion(const SkIRect&);
|
||||
SkRegion(const SkRegion& region);
|
||||
explicit SkRegion(const SkIRect& region);
|
||||
~SkRegion();
|
||||
|
||||
SkRegion& operator=(const SkRegion&);
|
||||
SkRegion& operator=(const SkRegion& region);
|
||||
|
||||
/**
|
||||
* Return true if the two regions are equal. i.e. The enclose exactly
|
||||
@ -65,13 +56,13 @@ public:
|
||||
* Swap the contents of this and the specified region. This operation
|
||||
* is gauarenteed to never fail.
|
||||
*/
|
||||
void swap(SkRegion&);
|
||||
void swap(SkRegion& other);
|
||||
|
||||
/** Return true if this region is empty */
|
||||
bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
|
||||
bool isEmpty() const { return fRunHead == emptyRunHeadPtr(); }
|
||||
|
||||
/** Return true if this region is a single, non-empty rectangle */
|
||||
bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
|
||||
bool isRect() const { return fRunHead == kRectRunHeadPtr; }
|
||||
|
||||
/** Return true if this region consists of more than 1 rectangular area */
|
||||
bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
|
||||
@ -109,7 +100,7 @@ public:
|
||||
* If rect is non-empty, set this region to that rectangle and return true,
|
||||
* otherwise set this region to empty and return false.
|
||||
*/
|
||||
bool setRect(const SkIRect&);
|
||||
bool setRect(const SkIRect& rect);
|
||||
|
||||
/**
|
||||
* If left < right and top < bottom, set this region to that rectangle and
|
||||
@ -131,7 +122,7 @@ public:
|
||||
* Set this region to the specified region, and return true if it is
|
||||
* non-empty.
|
||||
*/
|
||||
bool setRegion(const SkRegion&);
|
||||
bool setRegion(const SkRegion& region);
|
||||
|
||||
/**
|
||||
* Set this region to the area described by the path, clipped.
|
||||
@ -139,19 +130,19 @@ public:
|
||||
* This produces a region that is identical to the pixels that would be
|
||||
* drawn by the path (with no antialiasing) with the specified clip.
|
||||
*/
|
||||
bool setPath(const SkPath&, const SkRegion& clip);
|
||||
bool setPath(const SkPath& path, const SkRegion& clip);
|
||||
|
||||
/**
|
||||
* Returns true if the specified rectangle has a non-empty intersection
|
||||
* with this region.
|
||||
*/
|
||||
bool intersects(const SkIRect&) const;
|
||||
bool intersects(const SkIRect& rect) const;
|
||||
|
||||
/**
|
||||
* Returns true if the specified region has a non-empty intersection
|
||||
* with this region.
|
||||
*/
|
||||
bool intersects(const SkRegion&) const;
|
||||
bool intersects(const SkRegion& other) const;
|
||||
|
||||
/**
|
||||
* Return true if the specified x,y coordinate is inside the region.
|
||||
@ -164,7 +155,7 @@ public:
|
||||
* returns the correct result. Note: if either this region or the rectangle
|
||||
* is empty, contains() returns false.
|
||||
*/
|
||||
bool contains(const SkIRect&) const;
|
||||
bool contains(const SkIRect& other) const;
|
||||
|
||||
/**
|
||||
* Return true if the specified region is completely inside the region.
|
||||
@ -172,7 +163,7 @@ public:
|
||||
* returns the correct result. Note: if either region is empty, contains()
|
||||
* returns false.
|
||||
*/
|
||||
bool contains(const SkRegion&) const;
|
||||
bool contains(const SkRegion& other) const;
|
||||
|
||||
/**
|
||||
* Return true if this region is a single rectangle (not complex) and the
|
||||
@ -196,7 +187,7 @@ public:
|
||||
SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
|
||||
|
||||
return left < right && top < bottom &&
|
||||
fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect()
|
||||
fRunHead == kRectRunHeadPtr && // this->isRect()
|
||||
/* fBounds.contains(left, top, right, bottom); */
|
||||
fBounds.fLeft <= left && fBounds.fTop <= top &&
|
||||
fBounds.fRight >= right && fBounds.fBottom >= bottom;
|
||||
@ -245,7 +236,7 @@ public:
|
||||
kReverseDifference_Op,
|
||||
kReplace_Op, //!< replace the dst region with the op region
|
||||
|
||||
kLastOp = kReplace_Op
|
||||
kLastOp = kReplace_Op,
|
||||
};
|
||||
|
||||
static const int kOpCnt = kLastOp + 1;
|
||||
@ -317,11 +308,11 @@ public:
|
||||
class SK_API Iterator {
|
||||
public:
|
||||
Iterator() : fRgn(nullptr), fDone(true) {}
|
||||
Iterator(const SkRegion&);
|
||||
Iterator(const SkRegion& region);
|
||||
// if we have a region, reset to it and return true, else return false
|
||||
bool rewind();
|
||||
// reset the iterator, using the new region
|
||||
void reset(const SkRegion&);
|
||||
void reset(const SkRegion& region);
|
||||
bool done() const { return fDone; }
|
||||
void next();
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
@ -330,7 +321,7 @@ public:
|
||||
|
||||
private:
|
||||
const SkRegion* fRgn;
|
||||
const RunType* fRuns;
|
||||
const SkRegion::RunType* fRuns;
|
||||
SkIRect fRect;
|
||||
bool fDone;
|
||||
};
|
||||
@ -341,7 +332,7 @@ public:
|
||||
*/
|
||||
class SK_API Cliperator {
|
||||
public:
|
||||
Cliperator(const SkRegion&, const SkIRect& clip);
|
||||
Cliperator(const SkRegion& region, const SkIRect& clip);
|
||||
bool done() { return fDone; }
|
||||
void next();
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
@ -359,7 +350,7 @@ public:
|
||||
*/
|
||||
class Spanerator {
|
||||
public:
|
||||
Spanerator(const SkRegion&, int y, int left, int right);
|
||||
Spanerator(const SkRegion& region, int y, int left, int right);
|
||||
bool next(int* left, int* right);
|
||||
|
||||
private:
|
||||
@ -383,19 +374,6 @@ public:
|
||||
*/
|
||||
size_t readFromMemory(const void* buffer, size_t length);
|
||||
|
||||
/**
|
||||
* Returns a reference to a global empty region. Just a convenience for
|
||||
* callers that need a const empty region.
|
||||
*/
|
||||
static const SkRegion& GetEmptyRegion();
|
||||
|
||||
SkDEBUGCODE(void dump() const;)
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
SkDEBUGCODE(static void UnitTest();)
|
||||
|
||||
// expose this to allow for regression test on complex regions
|
||||
SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
|
||||
|
||||
private:
|
||||
static constexpr int kOpCount = kReplace_Op + 1;
|
||||
|
||||
@ -404,15 +382,18 @@ private:
|
||||
// S
|
||||
static constexpr int kRectRegionRuns = 7;
|
||||
|
||||
friend class android::Region; // needed for marshalling efficiently
|
||||
|
||||
struct RunHead;
|
||||
|
||||
static RunHead* emptyRunHeadPtr() { return (SkRegion::RunHead*) -1; }
|
||||
static constexpr RunHead* kRectRunHeadPtr = nullptr;
|
||||
|
||||
// allocate space for count runs
|
||||
void allocateRuns(int count);
|
||||
void allocateRuns(int count, int ySpanCount, int intervalCount);
|
||||
void allocateRuns(const RunHead& src);
|
||||
|
||||
SkDEBUGCODE(void dump() const;)
|
||||
|
||||
SkIRect fBounds;
|
||||
RunHead* fRunHead;
|
||||
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
*/
|
||||
kDecal_TileMode,
|
||||
|
||||
kLast_TileMode = kDecal_TileMode
|
||||
kLast_TileMode = kDecal_TileMode,
|
||||
};
|
||||
|
||||
static constexpr int kTileModeCount = kLast_TileMode + 1;
|
||||
@ -139,7 +139,7 @@ public:
|
||||
kRadial_GradientType,
|
||||
kSweep_GradientType,
|
||||
kConical_GradientType,
|
||||
kLast_GradientType = kConical_GradientType
|
||||
kLast_GradientType = kConical_GradientType,
|
||||
};
|
||||
|
||||
struct GradientInfo {
|
||||
|
@ -288,7 +288,7 @@ class SK_API SkNullWStream : public SkWStream {
|
||||
public:
|
||||
SkNullWStream() : fBytesWritten(0) {}
|
||||
|
||||
bool write(const void*, size_t n) override { fBytesWritten += n; return true; }
|
||||
bool write(const void* , size_t n) override { fBytesWritten += n; return true; }
|
||||
void flush() override {}
|
||||
size_t bytesWritten() const override { return fBytesWritten; }
|
||||
|
||||
@ -373,7 +373,7 @@ public:
|
||||
SkMemoryStream(const void* data, size_t length, bool copyData = false);
|
||||
|
||||
/** Creates the stream to read from the specified data */
|
||||
SkMemoryStream(sk_sp<SkData>);
|
||||
SkMemoryStream(sk_sp<SkData> data);
|
||||
|
||||
/** Returns a stream with a copy of the input data. */
|
||||
static std::unique_ptr<SkMemoryStream> MakeCopy(const void* data, size_t length);
|
||||
@ -397,7 +397,7 @@ public:
|
||||
void setMemoryOwned(const void* data, size_t length);
|
||||
|
||||
sk_sp<SkData> asData() const { return fData; }
|
||||
void setData(sk_sp<SkData>);
|
||||
void setData(sk_sp<SkData> data);
|
||||
|
||||
void skipToAlign4();
|
||||
const void* getAtPos();
|
||||
|
@ -114,46 +114,6 @@ static void test_text(SkCanvas* canvas) {
|
||||
drawFadingText(canvas, str, len, x, y, paint);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static void make_rgn(SkRegion* rgn, int left, int top, int right, int bottom,
|
||||
int count, int32_t runs[]) {
|
||||
SkIRect r;
|
||||
r.set(left, top, right, bottom);
|
||||
|
||||
rgn->debugSetRuns(runs, count);
|
||||
SkASSERT(rgn->getBounds() == r);
|
||||
}
|
||||
|
||||
static void test_union_bug_1505668(SkRegion* ra, SkRegion* rb, SkRegion* rc) {
|
||||
static int32_t dataA[] = {
|
||||
0x00000001,
|
||||
0x000001dd, 2, 0x00000001, 0x0000000c, 0x0000000d, 0x00000025, 0x7fffffff,
|
||||
0x000001de, 1, 0x00000001, 0x00000025, 0x7fffffff,
|
||||
0x000004b3, 1, 0x00000001, 0x00000026, 0x7fffffff,
|
||||
0x000004b4, 1, 0x0000000c, 0x00000026, 0x7fffffff,
|
||||
0x00000579, 1, 0x00000000, 0x0000013a, 0x7fffffff,
|
||||
0x000005d8, 1, 0x00000000, 0x0000013b, 0x7fffffff,
|
||||
0x7fffffff
|
||||
};
|
||||
make_rgn(ra, 0, 1, 315, 1496, SK_ARRAY_COUNT(dataA), dataA);
|
||||
|
||||
static int32_t dataB[] = {
|
||||
0x000000b6,
|
||||
0x000000c4, 1, 0x000000a1, 0x000000f0, 0x7fffffff,
|
||||
0x000000d6, 0, 0x7fffffff,
|
||||
0x000000e4, 2, 0x00000070, 0x00000079, 0x000000a1, 0x000000b0, 0x7fffffff,
|
||||
0x000000e6, 0, 0x7fffffff,
|
||||
0x000000f4, 2, 0x00000070, 0x00000079, 0x000000a1, 0x000000b0, 0x7fffffff,
|
||||
0x000000f6, 0, 0x7fffffff,
|
||||
0x00000104, 1, 0x000000a1, 0x000000b0, 0x7fffffff,
|
||||
0x7fffffff
|
||||
};
|
||||
make_rgn(rb, 112, 182, 240, 260, SK_ARRAY_COUNT(dataB), dataB);
|
||||
|
||||
rc->op(*ra, *rb, SkRegion::kUnion_Op);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
|
||||
dst->fLeft = (int)::roundf(src.fLeft * scale);
|
||||
dst->fTop = (int)::roundf(src.fTop * scale);
|
||||
@ -324,26 +284,7 @@ protected:
|
||||
test_text(canvas);
|
||||
return;
|
||||
}
|
||||
#ifdef SK_DEBUG
|
||||
if (true) {
|
||||
SkRegion a, b, c;
|
||||
test_union_bug_1505668(&a, &b, &c);
|
||||
|
||||
if (false) { // draw the result of the test
|
||||
SkPaint paint;
|
||||
|
||||
canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
|
||||
paint.setColor(SK_ColorRED);
|
||||
paint_rgn(canvas, a, paint);
|
||||
paint.setColor(0x800000FF);
|
||||
paint_rgn(canvas, b, paint);
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
// paint_rgn(canvas, c, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
const SkPoint origins[] = {
|
||||
{ 30*SK_Scalar1, 50*SK_Scalar1 },
|
||||
{ 150*SK_Scalar1, 50*SK_Scalar1 },
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegionPriv.h"
|
||||
|
||||
enum MutateResult {
|
||||
kDoNothing_MutateResult,
|
||||
@ -459,7 +460,7 @@ void SkRasterClip::validate() const {
|
||||
SkASSERT(fAA.isEmpty());
|
||||
}
|
||||
|
||||
fBW.validate();
|
||||
SkRegionPriv::Validate(fBW);
|
||||
fAA.validate();
|
||||
|
||||
SkASSERT(this->computeIsEmpty() == fIsEmpty);
|
||||
|
@ -31,7 +31,11 @@ SkDEBUGCODE(int32_t gRgnAllocCounter;)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SkRegion_gEmptyRunHeadPtr ((SkRegionPriv::RunHead*)-1)
|
||||
#define SkRegion_gRectRunHeadPtr nullptr
|
||||
|
||||
constexpr int kRunArrayStackCount = 256;
|
||||
|
||||
// This is a simple data structure which is like a SkSTArray<N,T,true>, except that:
|
||||
// - It does not initialize memory.
|
||||
// - It does not distinguish between reserved space and initialized space.
|
||||
@ -45,7 +49,7 @@ public:
|
||||
#ifdef SK_DEBUG
|
||||
int count() const { return fCount; }
|
||||
#endif
|
||||
SkRegion::RunType& operator[](int i) {
|
||||
SkRegionPriv::RunType& operator[](int i) {
|
||||
SkASSERT((unsigned)i < (unsigned)fCount);
|
||||
return fPtr[i];
|
||||
}
|
||||
@ -56,36 +60,36 @@ public:
|
||||
count += count >> 1;
|
||||
fMalloc.realloc(count);
|
||||
if (fPtr == fStack) {
|
||||
memcpy(fMalloc.get(), fStack, fCount * sizeof(SkRegion::RunType));
|
||||
memcpy(fMalloc.get(), fStack, fCount * sizeof(SkRegionPriv::RunType));
|
||||
}
|
||||
fPtr = fMalloc.get();
|
||||
fCount = count;
|
||||
}
|
||||
}
|
||||
private:
|
||||
SkRegion::RunType fStack[kRunArrayStackCount];
|
||||
SkAutoTMalloc<SkRegion::RunType> fMalloc;
|
||||
SkRegionPriv::RunType fStack[kRunArrayStackCount];
|
||||
SkAutoTMalloc<SkRegionPriv::RunType> fMalloc;
|
||||
int fCount = kRunArrayStackCount;
|
||||
SkRegion::RunType* fPtr; // non-owning pointer
|
||||
SkRegionPriv::RunType* fPtr; // non-owning pointer
|
||||
};
|
||||
|
||||
/* Pass in the beginning with the intervals.
|
||||
* We back up 1 to read the interval-count.
|
||||
* Return the beginning of the next scanline (i.e. the next Y-value)
|
||||
*/
|
||||
static SkRegion::RunType* skip_intervals(const SkRegion::RunType runs[]) {
|
||||
static SkRegionPriv::RunType* skip_intervals(const SkRegionPriv::RunType runs[]) {
|
||||
int intervals = runs[-1];
|
||||
#ifdef SK_DEBUG
|
||||
if (intervals > 0) {
|
||||
SkASSERT(runs[0] < runs[1]);
|
||||
SkASSERT(runs[1] < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(runs[1] < SkRegion_kRunTypeSentinel);
|
||||
} else {
|
||||
SkASSERT(0 == intervals);
|
||||
SkASSERT(SkRegion::kRunTypeSentinel == runs[0]);
|
||||
SkASSERT(SkRegion_kRunTypeSentinel == runs[0]);
|
||||
}
|
||||
#endif
|
||||
runs += intervals * 2 + 1;
|
||||
return const_cast<SkRegion::RunType*>(runs);
|
||||
return const_cast<SkRegionPriv::RunType*>(runs);
|
||||
}
|
||||
|
||||
bool SkRegion::RunsAreARect(const SkRegion::RunType runs[], int count,
|
||||
@ -189,10 +193,10 @@ bool SkRegion::setRect(const SkIRect& r) {
|
||||
return this->setEmpty();
|
||||
}
|
||||
this->freeRuns();
|
||||
SkASSERT(r.left() != SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(r.top() != SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(r.right() != SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(r.bottom() != SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(r.left() != SkRegion_kRunTypeSentinel);
|
||||
SkASSERT(r.top() != SkRegion_kRunTypeSentinel);
|
||||
SkASSERT(r.right() != SkRegion_kRunTypeSentinel);
|
||||
SkASSERT(r.bottom() != SkRegion_kRunTypeSentinel);
|
||||
fBounds = r;
|
||||
fRunHead = SkRegion_gRectRunHeadPtr;
|
||||
return true;
|
||||
@ -274,7 +278,7 @@ static bool isRunCountEmpty(int count) {
|
||||
}
|
||||
|
||||
bool SkRegion::setRuns(RunType runs[], int count) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
SkASSERT(count > 0);
|
||||
|
||||
if (isRunCountEmpty(count)) {
|
||||
@ -291,7 +295,7 @@ bool SkRegion::setRuns(RunType runs[], int count) {
|
||||
assert_sentinel(runs[1], false); // bottom
|
||||
// runs[2] is uncomputed intervalCount
|
||||
|
||||
if (runs[3] == SkRegion::kRunTypeSentinel) { // should be first left...
|
||||
if (runs[3] == SkRegion_kRunTypeSentinel) { // should be first left...
|
||||
runs += 3; // skip empty initial span
|
||||
runs[0] = runs[-2]; // set new top to prev bottom
|
||||
assert_sentinel(runs[1], false); // bot: a sentinal would mean two in a row
|
||||
@ -304,8 +308,8 @@ bool SkRegion::setRuns(RunType runs[], int count) {
|
||||
assert_sentinel(stop[-2], true);
|
||||
|
||||
// now check for a trailing empty span
|
||||
if (stop[-5] == SkRegion::kRunTypeSentinel) { // eek, stop[-4] was a bottom with no x-runs
|
||||
stop[-4] = SkRegion::kRunTypeSentinel; // kill empty last span
|
||||
if (stop[-5] == SkRegion_kRunTypeSentinel) { // eek, stop[-4] was a bottom with no x-runs
|
||||
stop[-4] = SkRegion_kRunTypeSentinel; // kill empty last span
|
||||
stop -= 3;
|
||||
assert_sentinel(stop[-1], true); // last y-sentinel
|
||||
assert_sentinel(stop[-2], true); // last x-sentinel
|
||||
@ -342,7 +346,7 @@ bool SkRegion::setRuns(RunType runs[], int count) {
|
||||
return this->setEmpty();
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -354,12 +358,12 @@ void SkRegion::BuildRectRuns(const SkIRect& bounds,
|
||||
runs[2] = 1; // 1 interval for this scanline
|
||||
runs[3] = bounds.fLeft;
|
||||
runs[4] = bounds.fRight;
|
||||
runs[5] = kRunTypeSentinel;
|
||||
runs[6] = kRunTypeSentinel;
|
||||
runs[5] = SkRegion_kRunTypeSentinel;
|
||||
runs[6] = SkRegion_kRunTypeSentinel;
|
||||
}
|
||||
|
||||
bool SkRegion::contains(int32_t x, int32_t y) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
if (!fBounds.contains(x, y)) {
|
||||
return false;
|
||||
@ -392,17 +396,17 @@ bool SkRegion::contains(int32_t x, int32_t y) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
static SkRegion::RunType scanline_bottom(const SkRegion::RunType runs[]) {
|
||||
static SkRegionPriv::RunType scanline_bottom(const SkRegionPriv::RunType runs[]) {
|
||||
return runs[0];
|
||||
}
|
||||
|
||||
static const SkRegion::RunType* scanline_next(const SkRegion::RunType runs[]) {
|
||||
static const SkRegionPriv::RunType* scanline_next(const SkRegionPriv::RunType runs[]) {
|
||||
// skip [B N [L R]... S]
|
||||
return runs + 2 + runs[1] * 2 + 1;
|
||||
}
|
||||
|
||||
static bool scanline_contains(const SkRegion::RunType runs[],
|
||||
SkRegion::RunType L, SkRegion::RunType R) {
|
||||
static bool scanline_contains(const SkRegionPriv::RunType runs[],
|
||||
SkRegionPriv::RunType L, SkRegionPriv::RunType R) {
|
||||
runs += 2; // skip Bottom and IntervalCount
|
||||
for (;;) {
|
||||
if (L < runs[0]) {
|
||||
@ -417,7 +421,7 @@ static bool scanline_contains(const SkRegion::RunType runs[],
|
||||
}
|
||||
|
||||
bool SkRegion::contains(const SkIRect& r) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
if (!fBounds.contains(r)) {
|
||||
return false;
|
||||
@ -441,8 +445,8 @@ bool SkRegion::contains(const SkIRect& r) const {
|
||||
}
|
||||
|
||||
bool SkRegion::contains(const SkRegion& rgn) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(rgn.validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(rgn));
|
||||
|
||||
if (this->isEmpty() || rgn.isEmpty() || !fBounds.contains(rgn.fBounds)) {
|
||||
return false;
|
||||
@ -467,7 +471,7 @@ const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[],
|
||||
const RunType* runs = tmpStorage;
|
||||
|
||||
if (this->isEmpty()) {
|
||||
tmpStorage[0] = kRunTypeSentinel;
|
||||
tmpStorage[0] = SkRegion_kRunTypeSentinel;
|
||||
*intervals = 0;
|
||||
} else if (this->isRect()) {
|
||||
BuildRectRuns(fBounds, tmpStorage);
|
||||
@ -481,8 +485,8 @@ const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[],
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool scanline_intersects(const SkRegion::RunType runs[],
|
||||
SkRegion::RunType L, SkRegion::RunType R) {
|
||||
static bool scanline_intersects(const SkRegionPriv::RunType runs[],
|
||||
SkRegionPriv::RunType L, SkRegionPriv::RunType R) {
|
||||
runs += 2; // skip Bottom and IntervalCount
|
||||
for (;;) {
|
||||
if (R <= runs[0]) {
|
||||
@ -497,7 +501,7 @@ static bool scanline_intersects(const SkRegion::RunType runs[],
|
||||
}
|
||||
|
||||
bool SkRegion::intersects(const SkIRect& r) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
if (this->isEmpty() || r.isEmpty()) {
|
||||
return false;
|
||||
@ -554,8 +558,8 @@ bool SkRegion::intersects(const SkRegion& rgn) const {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkRegion::operator==(const SkRegion& b) const {
|
||||
SkDEBUGCODE(validate();)
|
||||
SkDEBUGCODE(b.validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(b));
|
||||
|
||||
if (this == &b) {
|
||||
return true;
|
||||
@ -591,7 +595,7 @@ static int32_t pin_offset_s32(int32_t min, int32_t max, int32_t offset) {
|
||||
}
|
||||
|
||||
void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
if (nullptr == dst) {
|
||||
return;
|
||||
@ -625,28 +629,28 @@ void SkRegion::translate(int dx, int dy, SkRegion* dst) const {
|
||||
*druns++ = (SkRegion::RunType)(*sruns++ + dy); // top
|
||||
for (;;) {
|
||||
int bottom = *sruns++;
|
||||
if (bottom == kRunTypeSentinel) {
|
||||
if (bottom == SkRegion_kRunTypeSentinel) {
|
||||
break;
|
||||
}
|
||||
*druns++ = (SkRegion::RunType)(bottom + dy); // bottom;
|
||||
*druns++ = *sruns++; // copy intervalCount;
|
||||
for (;;) {
|
||||
int x = *sruns++;
|
||||
if (x == kRunTypeSentinel) {
|
||||
if (x == SkRegion_kRunTypeSentinel) {
|
||||
break;
|
||||
}
|
||||
*druns++ = (SkRegion::RunType)(x + dx);
|
||||
*druns++ = (SkRegion::RunType)(*sruns++ + dx);
|
||||
}
|
||||
*druns++ = kRunTypeSentinel; // x sentinel
|
||||
*druns++ = SkRegion_kRunTypeSentinel; // x sentinel
|
||||
}
|
||||
*druns++ = kRunTypeSentinel; // y sentinel
|
||||
*druns++ = SkRegion_kRunTypeSentinel; // y sentinel
|
||||
|
||||
SkASSERT(sruns - fRunHead->readonly_runs() == fRunHead->fRunCount);
|
||||
SkASSERT(druns - dst->fRunHead->readonly_runs() == dst->fRunHead->fRunCount);
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -673,20 +677,20 @@ bool SkRegion::setRects(const SkIRect rects[], int count) {
|
||||
#ifdef SK_DEBUG
|
||||
static void assert_valid_pair(int left, int rite)
|
||||
{
|
||||
SkASSERT(left == SkRegion::kRunTypeSentinel || left < rite);
|
||||
SkASSERT(left == SkRegion_kRunTypeSentinel || left < rite);
|
||||
}
|
||||
#else
|
||||
#define assert_valid_pair(left, rite)
|
||||
#endif
|
||||
|
||||
struct spanRec {
|
||||
const SkRegion::RunType* fA_runs;
|
||||
const SkRegion::RunType* fB_runs;
|
||||
const SkRegionPriv::RunType* fA_runs;
|
||||
const SkRegionPriv::RunType* fB_runs;
|
||||
int fA_left, fA_rite, fB_left, fB_rite;
|
||||
int fLeft, fRite, fInside;
|
||||
|
||||
void init(const SkRegion::RunType a_runs[],
|
||||
const SkRegion::RunType b_runs[]) {
|
||||
void init(const SkRegionPriv::RunType a_runs[],
|
||||
const SkRegionPriv::RunType b_runs[]) {
|
||||
fA_left = *a_runs++;
|
||||
fA_rite = *a_runs++;
|
||||
fB_left = *b_runs++;
|
||||
@ -697,10 +701,10 @@ struct spanRec {
|
||||
}
|
||||
|
||||
bool done() const {
|
||||
SkASSERT(fA_left <= SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(fB_left <= SkRegion::kRunTypeSentinel);
|
||||
return fA_left == SkRegion::kRunTypeSentinel &&
|
||||
fB_left == SkRegion::kRunTypeSentinel;
|
||||
SkASSERT(fA_left <= SkRegion_kRunTypeSentinel);
|
||||
SkASSERT(fB_left <= SkRegion_kRunTypeSentinel);
|
||||
return fA_left == SkRegion_kRunTypeSentinel &&
|
||||
fB_left == SkRegion_kRunTypeSentinel;
|
||||
}
|
||||
|
||||
void next() {
|
||||
@ -770,20 +774,20 @@ struct spanRec {
|
||||
}
|
||||
};
|
||||
|
||||
static int distance_to_sentinel(const SkRegion::RunType* runs) {
|
||||
const SkRegion::RunType* ptr = runs;
|
||||
while (*ptr != SkRegion::kRunTypeSentinel) { ptr += 2; }
|
||||
static int distance_to_sentinel(const SkRegionPriv::RunType* runs) {
|
||||
const SkRegionPriv::RunType* ptr = runs;
|
||||
while (*ptr != SkRegion_kRunTypeSentinel) { ptr += 2; }
|
||||
return ptr - runs;
|
||||
}
|
||||
|
||||
static int operate_on_span(const SkRegion::RunType a_runs[],
|
||||
const SkRegion::RunType b_runs[],
|
||||
static int operate_on_span(const SkRegionPriv::RunType a_runs[],
|
||||
const SkRegionPriv::RunType b_runs[],
|
||||
RunArray* array, int dstOffset,
|
||||
int min, int max) {
|
||||
// This is a worst-case for this span plus two for TWO terminating sentinels.
|
||||
array->resizeToAtLeast(
|
||||
dstOffset + distance_to_sentinel(a_runs) + distance_to_sentinel(b_runs) + 2);
|
||||
SkRegion::RunType* dst = &(*array)[dstOffset]; // get pointer AFTER resizing.
|
||||
SkRegionPriv::RunType* dst = &(*array)[dstOffset]; // get pointer AFTER resizing.
|
||||
|
||||
spanRec rec;
|
||||
bool firstInterval = true;
|
||||
@ -800,17 +804,17 @@ static int operate_on_span(const SkRegion::RunType a_runs[],
|
||||
if ((unsigned)(rec.fInside - min) <= (unsigned)(max - min) &&
|
||||
left < rite) { // skip if equal
|
||||
if (firstInterval || *(dst - 1) < left) {
|
||||
*dst++ = (SkRegion::RunType)(left);
|
||||
*dst++ = (SkRegion::RunType)(rite);
|
||||
*dst++ = (SkRegionPriv::RunType)(left);
|
||||
*dst++ = (SkRegionPriv::RunType)(rite);
|
||||
firstInterval = false;
|
||||
} else {
|
||||
// update the right edge
|
||||
*(dst - 1) = (SkRegion::RunType)(rite);
|
||||
*(dst - 1) = (SkRegionPriv::RunType)(rite);
|
||||
}
|
||||
}
|
||||
}
|
||||
SkASSERT(dst < &(*array)[array->count() - 1]);
|
||||
*dst++ = SkRegion::kRunTypeSentinel;
|
||||
*dst++ = SkRegion_kRunTypeSentinel;
|
||||
return dst - &(*array)[0];
|
||||
}
|
||||
|
||||
@ -839,32 +843,32 @@ public:
|
||||
: fMin(gOpMinMax[op].fMin)
|
||||
, fMax(gOpMinMax[op].fMax)
|
||||
, fArray(array)
|
||||
, fTop((SkRegion::RunType)top) // just a first guess, we might update this
|
||||
, fTop((SkRegionPriv::RunType)top) // just a first guess, we might update this
|
||||
{ SkASSERT((unsigned)op <= 3); }
|
||||
|
||||
void addSpan(int bottom, const SkRegion::RunType a_runs[],
|
||||
const SkRegion::RunType b_runs[]) {
|
||||
void addSpan(int bottom, const SkRegionPriv::RunType a_runs[],
|
||||
const SkRegionPriv::RunType b_runs[]) {
|
||||
// skip X values and slots for the next Y+intervalCount
|
||||
int start = fPrevDst + fPrevLen + 2;
|
||||
// start points to beginning of dst interval
|
||||
int stop = operate_on_span(a_runs, b_runs, fArray, start, fMin, fMax);
|
||||
size_t len = SkToSizeT(stop - start);
|
||||
SkASSERT(len >= 1 && (len & 1) == 1);
|
||||
SkASSERT(SkRegion::kRunTypeSentinel == (*fArray)[stop - 1]);
|
||||
SkASSERT(SkRegion_kRunTypeSentinel == (*fArray)[stop - 1]);
|
||||
|
||||
// Assert memcmp won't exceed fArray->count().
|
||||
SkASSERT(fArray->count() >= SkToInt(start + len - 1));
|
||||
if (fPrevLen == len &&
|
||||
(1 == len || !memcmp(&(*fArray)[fPrevDst],
|
||||
&(*fArray)[start],
|
||||
(len - 1) * sizeof(SkRegion::RunType)))) {
|
||||
(len - 1) * sizeof(SkRegionPriv::RunType)))) {
|
||||
// update Y value
|
||||
(*fArray)[fPrevDst - 2] = (SkRegion::RunType)bottom;
|
||||
(*fArray)[fPrevDst - 2] = (SkRegionPriv::RunType)bottom;
|
||||
} else { // accept the new span
|
||||
if (len == 1 && fPrevLen == 0) {
|
||||
fTop = (SkRegion::RunType)bottom; // just update our bottom
|
||||
fTop = (SkRegionPriv::RunType)bottom; // just update our bottom
|
||||
} else {
|
||||
(*fArray)[start - 2] = (SkRegion::RunType)bottom;
|
||||
(*fArray)[start - 2] = (SkRegionPriv::RunType)bottom;
|
||||
(*fArray)[start - 1] = SkToS32(len >> 1);
|
||||
fPrevDst = start;
|
||||
fPrevLen = len;
|
||||
@ -876,7 +880,7 @@ public:
|
||||
(*fArray)[fStartDst] = fTop;
|
||||
// Previously reserved enough for TWO sentinals.
|
||||
SkASSERT(fArray->count() > SkToInt(fPrevDst + fPrevLen));
|
||||
(*fArray)[fPrevDst + fPrevLen] = SkRegion::kRunTypeSentinel;
|
||||
(*fArray)[fPrevDst + fPrevLen] = SkRegion_kRunTypeSentinel;
|
||||
return (int)(fPrevDst - fStartDst + fPrevLen + 1);
|
||||
}
|
||||
|
||||
@ -889,21 +893,21 @@ private:
|
||||
int fStartDst = 0;
|
||||
int fPrevDst = 1;
|
||||
size_t fPrevLen = 0; // will never match a length from operate_on_span
|
||||
SkRegion::RunType fTop;
|
||||
SkRegionPriv::RunType fTop;
|
||||
};
|
||||
|
||||
// want a unique value to signal that we exited due to quickExit
|
||||
#define QUICK_EXIT_TRUE_COUNT (-1)
|
||||
|
||||
static int operate(const SkRegion::RunType a_runs[],
|
||||
const SkRegion::RunType b_runs[],
|
||||
static int operate(const SkRegionPriv::RunType a_runs[],
|
||||
const SkRegionPriv::RunType b_runs[],
|
||||
RunArray* dst,
|
||||
SkRegion::Op op,
|
||||
bool quickExit) {
|
||||
const SkRegion::RunType gEmptyScanline[] = {
|
||||
const SkRegionPriv::RunType gEmptyScanline[] = {
|
||||
0, // dummy bottom value
|
||||
0, // zero intervals
|
||||
SkRegion::kRunTypeSentinel,
|
||||
SkRegion_kRunTypeSentinel,
|
||||
// just need a 2nd value, since spanRec.init() reads 2 values, even
|
||||
// though if the first value is the sentinel, it ignores the 2nd value.
|
||||
// w/o the 2nd value here, we might read uninitialized memory.
|
||||
@ -911,7 +915,7 @@ static int operate(const SkRegion::RunType a_runs[],
|
||||
// our sentinel value.
|
||||
0
|
||||
};
|
||||
const SkRegion::RunType* const gSentinel = &gEmptyScanline[2];
|
||||
const SkRegionPriv::RunType* const gSentinel = &gEmptyScanline[2];
|
||||
|
||||
int a_top = *a_runs++;
|
||||
int a_bot = *a_runs++;
|
||||
@ -930,13 +934,13 @@ static int operate(const SkRegion::RunType a_runs[],
|
||||
|
||||
RgnOper oper(SkMin32(a_top, b_top), dst, op);
|
||||
|
||||
int prevBot = SkRegion::kRunTypeSentinel; // so we fail the first test
|
||||
int prevBot = SkRegion_kRunTypeSentinel; // so we fail the first test
|
||||
|
||||
while (a_bot < SkRegion::kRunTypeSentinel ||
|
||||
b_bot < SkRegion::kRunTypeSentinel) {
|
||||
while (a_bot < SkRegion_kRunTypeSentinel ||
|
||||
b_bot < SkRegion_kRunTypeSentinel) {
|
||||
int top, bot SK_INIT_TO_AVOID_WARNING;
|
||||
const SkRegion::RunType* run0 = gSentinel;
|
||||
const SkRegion::RunType* run1 = gSentinel;
|
||||
const SkRegionPriv::RunType* run0 = gSentinel;
|
||||
const SkRegionPriv::RunType* run1 = gSentinel;
|
||||
bool a_flush = false;
|
||||
bool b_flush = false;
|
||||
|
||||
@ -986,7 +990,7 @@ static int operate(const SkRegion::RunType a_runs[],
|
||||
a_top = a_bot;
|
||||
a_bot = *a_runs++;
|
||||
a_runs += 1; // skip uninitialized intervalCount
|
||||
if (a_bot == SkRegion::kRunTypeSentinel) {
|
||||
if (a_bot == SkRegion_kRunTypeSentinel) {
|
||||
a_top = a_bot;
|
||||
}
|
||||
}
|
||||
@ -995,7 +999,7 @@ static int operate(const SkRegion::RunType a_runs[],
|
||||
b_top = b_bot;
|
||||
b_bot = *b_runs++;
|
||||
b_runs += 1; // skip uninitialized intervalCount
|
||||
if (b_bot == SkRegion::kRunTypeSentinel) {
|
||||
if (b_bot == SkRegion_kRunTypeSentinel) {
|
||||
b_top = b_bot;
|
||||
}
|
||||
}
|
||||
@ -1138,7 +1142,7 @@ bool SkRegion::Oper(const SkRegion& rgnaOrig, const SkRegion& rgnbOrig, Op op,
|
||||
}
|
||||
|
||||
bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
return SkRegion::Oper(rgna, rgnb, op, this);
|
||||
}
|
||||
|
||||
@ -1209,16 +1213,16 @@ static bool validate_run(const int32_t* runs,
|
||||
}
|
||||
SkASSERT(runCount >= 7); // 7==SkRegion::kRectRegionRuns
|
||||
// quick sanity check:
|
||||
if (runs[runCount - 1] != SkRegion::kRunTypeSentinel ||
|
||||
runs[runCount - 2] != SkRegion::kRunTypeSentinel) {
|
||||
if (runs[runCount - 1] != SkRegion_kRunTypeSentinel ||
|
||||
runs[runCount - 2] != SkRegion_kRunTypeSentinel) {
|
||||
return false;
|
||||
}
|
||||
const int32_t* const end = runs + runCount;
|
||||
SkIRect bounds = {0, 0, 0 ,0}; // calulated bounds
|
||||
SkIRect rect = {0, 0, 0, 0}; // current rect
|
||||
rect.fTop = *runs++;
|
||||
if (rect.fTop == SkRegion::kRunTypeSentinel) {
|
||||
return false; // no rect can contain SkRegion::kRunTypeSentinel
|
||||
if (rect.fTop == SkRegion_kRunTypeSentinel) {
|
||||
return false; // no rect can contain SkRegion_kRunTypeSentinel
|
||||
}
|
||||
if (rect.fTop != givenBounds.fTop) {
|
||||
return false; // Must not begin with empty span that does not contribute to bounds.
|
||||
@ -1229,7 +1233,7 @@ static bool validate_run(const int32_t* runs,
|
||||
return false; // too many yspans
|
||||
}
|
||||
rect.fBottom = *runs++;
|
||||
if (rect.fBottom == SkRegion::kRunTypeSentinel) {
|
||||
if (rect.fBottom == SkRegion_kRunTypeSentinel) {
|
||||
return false;
|
||||
}
|
||||
if (rect.fBottom > givenBounds.fBottom) {
|
||||
@ -1250,8 +1254,8 @@ static bool validate_run(const int32_t* runs,
|
||||
while (xIntervals-- > 0) {
|
||||
rect.fLeft = *runs++;
|
||||
rect.fRight = *runs++;
|
||||
if (rect.fLeft == SkRegion::kRunTypeSentinel ||
|
||||
rect.fRight == SkRegion::kRunTypeSentinel ||
|
||||
if (rect.fLeft == SkRegion_kRunTypeSentinel ||
|
||||
rect.fRight == SkRegion_kRunTypeSentinel ||
|
||||
rect.fLeft >= rect.fRight || // check non-empty rect
|
||||
(!firstInterval && rect.fLeft <= lastRight)) {
|
||||
return false;
|
||||
@ -1260,12 +1264,12 @@ static bool validate_run(const int32_t* runs,
|
||||
firstInterval = false;
|
||||
bounds.join(rect);
|
||||
}
|
||||
if (*runs++ != SkRegion::kRunTypeSentinel) {
|
||||
if (*runs++ != SkRegion_kRunTypeSentinel) {
|
||||
return false; // required check sentinal.
|
||||
}
|
||||
rect.fTop = rect.fBottom;
|
||||
SkASSERT(runs < end);
|
||||
} while (*runs != SkRegion::kRunTypeSentinel);
|
||||
} while (*runs != SkRegion_kRunTypeSentinel);
|
||||
++runs;
|
||||
if (ySpanCount != 0 || intervalCount != 0 || givenBounds != bounds) {
|
||||
return false;
|
||||
@ -1318,13 +1322,6 @@ size_t SkRegion::readFromMemory(const void* storage, size_t length) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const SkRegion& SkRegion::GetEmptyRegion() {
|
||||
static SkRegion gEmpty;
|
||||
return gEmpty;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkRegion::isValid() const {
|
||||
if (this->isEmpty()) {
|
||||
return fBounds == SkIRect{0, 0, 0, 0};
|
||||
@ -1341,7 +1338,7 @@ bool SkRegion::isValid() const {
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void SkRegion::validate() const { SkASSERT(this->isValid()); }
|
||||
void SkRegionPriv::Validate(const SkRegion& rgn) { SkASSERT(rgn.isValid()); }
|
||||
|
||||
void SkRegion::dump() const {
|
||||
if (this->isEmpty()) {
|
||||
@ -1403,13 +1400,13 @@ void SkRegion::Iterator::next() {
|
||||
|
||||
const RunType* runs = fRuns;
|
||||
|
||||
if (runs[0] < kRunTypeSentinel) { // valid X value
|
||||
if (runs[0] < SkRegion_kRunTypeSentinel) { // valid X value
|
||||
fRect.fLeft = runs[0];
|
||||
fRect.fRight = runs[1];
|
||||
runs += 2;
|
||||
} else { // we're at the end of a line
|
||||
runs += 1;
|
||||
if (runs[0] < kRunTypeSentinel) { // valid Y value
|
||||
if (runs[0] < SkRegion_kRunTypeSentinel) { // valid Y value
|
||||
int intervals = runs[1];
|
||||
if (0 == intervals) { // empty line
|
||||
fRect.fTop = runs[0];
|
||||
@ -1472,7 +1469,7 @@ void SkRegion::Cliperator::next() {
|
||||
|
||||
SkRegion::Spanerator::Spanerator(const SkRegion& rgn, int y, int left,
|
||||
int right) {
|
||||
SkDEBUGCODE(rgn.validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(rgn));
|
||||
|
||||
const SkIRect& r = rgn.getBounds();
|
||||
|
||||
@ -1592,17 +1589,3 @@ void SkRegionPriv::VisitSpans(const SkRegion& rgn,
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
|
||||
bool SkRegion::debugSetRuns(const RunType runs[], int count) {
|
||||
// we need to make a copy, since the real method may modify the array, and
|
||||
// so it cannot be const.
|
||||
|
||||
SkAutoTArray<RunType> storage(count);
|
||||
memcpy(storage.get(), runs, count * sizeof(RunType));
|
||||
return this->setRuns(storage.get(), count);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -14,8 +14,29 @@
|
||||
#include "SkMalloc.h"
|
||||
#include "SkTo.h"
|
||||
|
||||
|
||||
#include <functional>
|
||||
|
||||
class SkRegionPriv {
|
||||
public:
|
||||
static constexpr int kRunTypeSentinel = 0x7FFFFFFF;
|
||||
typedef SkRegion::RunType RunType;
|
||||
typedef SkRegion::RunHead RunHead;
|
||||
|
||||
// Call the function with each span, in Y -> X ascending order.
|
||||
// We pass a rect, but we will still ensure the span Y->X ordering, so often the height
|
||||
// of the rect may be 1. It should never be empty.
|
||||
static void VisitSpans(const SkRegion& rgn, const std::function<void(const SkIRect&)>&);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
static void Validate(const SkRegion& rgn);
|
||||
#endif
|
||||
};
|
||||
|
||||
static constexpr int SkRegion_kRunTypeSentinel = 0x7FFFFFFF;
|
||||
|
||||
inline bool SkRegionValueIsSentinel(int32_t value) {
|
||||
return value == (int32_t)SkRegion::kRunTypeSentinel;
|
||||
return value == (int32_t)SkRegion_kRunTypeSentinel;
|
||||
}
|
||||
|
||||
#define assert_sentinel(value, isSentinel) \
|
||||
@ -27,11 +48,11 @@ inline bool SkRegionValueIsSentinel(int32_t value) {
|
||||
// Given the first interval (just past the interval-count), compute the
|
||||
// interval count, by search for the x-sentinel
|
||||
//
|
||||
static int compute_intervalcount(const SkRegion::RunType runs[]) {
|
||||
const SkRegion::RunType* curr = runs;
|
||||
while (*curr < SkRegion::kRunTypeSentinel) {
|
||||
static int compute_intervalcount(const SkRegionPriv::RunType runs[]) {
|
||||
const SkRegionPriv::RunType* curr = runs;
|
||||
while (*curr < SkRegion_kRunTypeSentinel) {
|
||||
SkASSERT(curr[0] < curr[1]);
|
||||
SkASSERT(curr[1] < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(curr[1] < SkRegion_kRunTypeSentinel);
|
||||
curr += 2;
|
||||
}
|
||||
return SkToInt((curr - runs) >> 1);
|
||||
@ -133,10 +154,10 @@ public:
|
||||
*/
|
||||
static SkRegion::RunType* SkipEntireScanline(const SkRegion::RunType runs[]) {
|
||||
// we are not the Y Sentinel
|
||||
SkASSERT(runs[0] < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(runs[0] < SkRegion_kRunTypeSentinel);
|
||||
|
||||
const int intervals = runs[1];
|
||||
SkASSERT(runs[2 + intervals * 2] == SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(runs[2 + intervals * 2] == SkRegion_kRunTypeSentinel);
|
||||
#ifdef SK_DEBUG
|
||||
{
|
||||
int n = compute_intervalcount(&runs[2]);
|
||||
@ -168,7 +189,7 @@ public:
|
||||
int bottom = runs[0];
|
||||
// If we hit this, we've walked off the region, and our bounds check
|
||||
// failed.
|
||||
SkASSERT(bottom < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(bottom < SkRegion_kRunTypeSentinel);
|
||||
if (y < bottom) {
|
||||
break;
|
||||
}
|
||||
@ -190,12 +211,12 @@ public:
|
||||
|
||||
do {
|
||||
bot = *runs++;
|
||||
SkASSERT(bot < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(bot < SkRegion_kRunTypeSentinel);
|
||||
ySpanCount += 1;
|
||||
|
||||
const int intervals = *runs++;
|
||||
SkASSERT(intervals >= 0);
|
||||
SkASSERT(intervals < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(intervals < SkRegion_kRunTypeSentinel);
|
||||
|
||||
if (intervals > 0) {
|
||||
#ifdef SK_DEBUG
|
||||
@ -205,25 +226,25 @@ public:
|
||||
}
|
||||
#endif
|
||||
RunType L = runs[0];
|
||||
SkASSERT(L < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(L < SkRegion_kRunTypeSentinel);
|
||||
if (left > L) {
|
||||
left = L;
|
||||
}
|
||||
|
||||
runs += intervals * 2;
|
||||
RunType R = runs[-1];
|
||||
SkASSERT(R < SkRegion::kRunTypeSentinel);
|
||||
SkASSERT(R < SkRegion_kRunTypeSentinel);
|
||||
if (rite < R) {
|
||||
rite = R;
|
||||
}
|
||||
|
||||
intervalCount += intervals;
|
||||
}
|
||||
SkASSERT(SkRegion::kRunTypeSentinel == *runs);
|
||||
SkASSERT(SkRegion_kRunTypeSentinel == *runs);
|
||||
runs += 1; // skip x-sentinel
|
||||
|
||||
// test Y-sentinel
|
||||
} while (SkRegion::kRunTypeSentinel > *runs);
|
||||
} while (SkRegion_kRunTypeSentinel > *runs);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
// +1 to skip the last Y-sentinel
|
||||
@ -244,14 +265,4 @@ private:
|
||||
int32_t fIntervalCount;
|
||||
};
|
||||
|
||||
#include <functional>
|
||||
|
||||
class SkRegionPriv {
|
||||
public:
|
||||
// Call the function with each span, in Y -> X ascending order.
|
||||
// We pass a rect, but we will still ensure the span Y->X ordering, so often the height
|
||||
// of the rect may be 1. It should never be empty.
|
||||
static void VisitSpans(const SkRegion& rgn, const std::function<void(const SkIRect&)>&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -236,11 +236,11 @@ void SkRgnBuilder::copyToRgn(SkRegion::RunType runs[]) const {
|
||||
memcpy(runs, line->firstX(), count * sizeof(SkRegion::RunType));
|
||||
runs += count;
|
||||
}
|
||||
*runs++ = SkRegion::kRunTypeSentinel;
|
||||
*runs++ = SkRegion_kRunTypeSentinel;
|
||||
line = line->nextScanline();
|
||||
} while (line < stop);
|
||||
SkASSERT(line == stop);
|
||||
*runs = SkRegion::kRunTypeSentinel;
|
||||
*runs = SkRegion_kRunTypeSentinel;
|
||||
}
|
||||
|
||||
static unsigned verb_to_initial_last_index(unsigned verb) {
|
||||
@ -320,7 +320,7 @@ static bool check_inverse_on_empty_return(SkRegion* dst, const SkPath& path, con
|
||||
}
|
||||
|
||||
bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
|
||||
if (clip.isEmpty() || !path.isFinite()) {
|
||||
return this->setEmpty();
|
||||
@ -382,7 +382,7 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
|
||||
tmp.fRunHead->computeRunBounds(&tmp.fBounds);
|
||||
this->swap(tmp);
|
||||
}
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkDEBUGCODE(SkRegionPriv::Validate(*this));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -397,17 +397,17 @@ struct Edge {
|
||||
kCompleteLink = (kY0Link | kY1Link)
|
||||
};
|
||||
|
||||
SkRegion::RunType fX;
|
||||
SkRegion::RunType fY0, fY1;
|
||||
SkRegionPriv::RunType fX;
|
||||
SkRegionPriv::RunType fY0, fY1;
|
||||
uint8_t fFlags;
|
||||
Edge* fNext;
|
||||
|
||||
void set(int x, int y0, int y1) {
|
||||
SkASSERT(y0 != y1);
|
||||
|
||||
fX = (SkRegion::RunType)(x);
|
||||
fY0 = (SkRegion::RunType)(y0);
|
||||
fY1 = (SkRegion::RunType)(y1);
|
||||
fX = (SkRegionPriv::RunType)(x);
|
||||
fY0 = (SkRegionPriv::RunType)(y0);
|
||||
fY1 = (SkRegionPriv::RunType)(y1);
|
||||
fFlags = 0;
|
||||
SkDEBUGCODE(fNext = nullptr;)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user