зеркало из https://github.com/mozilla/moz-skia.git
Move fIsOval from SkPath to SkPathRef
https://codereview.chromium.org/89123002/ git-svn-id: http://skia.googlecode.com/svn/trunk@12463 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
8272d87d30
Коммит
466310dbd3
|
@ -151,7 +151,7 @@ public:
|
|||
* optimization for performance and so some paths that are in
|
||||
* fact ovals can report false.
|
||||
*/
|
||||
bool isOval(SkRect* rect) const;
|
||||
bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); }
|
||||
|
||||
/** Clear any lines and curves from the path, making it empty. This frees up
|
||||
internal storage associated with those segments.
|
||||
|
@ -931,6 +931,9 @@ public:
|
|||
|
||||
private:
|
||||
enum SerializationOffsets {
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
kNewFormat2_SerializationShift = 29, // requires 1 bit
|
||||
#endif
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
kNewFormat_SerializationShift = 28, // requires 1 bit
|
||||
#endif
|
||||
|
@ -939,7 +942,9 @@ private:
|
|||
// rename to kUnused_SerializationShift
|
||||
kOldIsFinite_SerializationShift = 25, // 1 bit
|
||||
#endif
|
||||
kIsOval_SerializationShift = 24, // requires 1 bit
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
kOldIsOval_SerializationShift = 24, // requires 1 bit
|
||||
#endif
|
||||
kConvexity_SerializationShift = 16, // requires 8 bits
|
||||
kFillType_SerializationShift = 8, // requires 8 bits
|
||||
kSegmentMask_SerializationShift = 0 // requires 4 bits
|
||||
|
@ -952,7 +957,6 @@ private:
|
|||
uint8_t fSegmentMask;
|
||||
mutable uint8_t fConvexity;
|
||||
mutable uint8_t fDirection;
|
||||
mutable SkBool8 fIsOval;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
const SkPath* fSourcePath;
|
||||
#endif
|
||||
|
@ -1008,7 +1012,7 @@ private:
|
|||
fPathRef->setBounds(rect);
|
||||
}
|
||||
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
friend class SkPathRef; // just for SerializationOffsets
|
||||
#endif
|
||||
friend class SkAutoPathBoundsUpdate;
|
||||
|
|
|
@ -23,7 +23,7 @@ class SkWBuffer;
|
|||
* Holds the path verbs and points. It is versioned by a generation ID. None of its public methods
|
||||
* modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an
|
||||
* SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs
|
||||
* copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller passes the Editor's
|
||||
* copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's
|
||||
* constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's
|
||||
* constructor returns.
|
||||
*
|
||||
|
@ -100,6 +100,8 @@ public:
|
|||
*/
|
||||
SkPathRef* pathRef() { return fPathRef; }
|
||||
|
||||
void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
|
||||
|
||||
private:
|
||||
SkPathRef* fPathRef;
|
||||
};
|
||||
|
@ -121,6 +123,24 @@ public:
|
|||
return SkToBool(fIsFinite);
|
||||
}
|
||||
|
||||
/** Returns true if the path is an oval.
|
||||
*
|
||||
* @param rect returns the bounding rect of this oval. It's a circle
|
||||
* if the height and width are the same.
|
||||
*
|
||||
* @return true if this path is an oval.
|
||||
* Tracking whether a path is an oval is considered an
|
||||
* optimization for performance and so some paths that are in
|
||||
* fact ovals can report false.
|
||||
*/
|
||||
bool isOval(SkRect* rect) const {
|
||||
if (fIsOval && NULL != rect) {
|
||||
*rect = getBounds();
|
||||
}
|
||||
|
||||
return SkToBool(fIsOval);
|
||||
}
|
||||
|
||||
bool hasComputedBounds() const {
|
||||
return !fBoundsIsDirty;
|
||||
}
|
||||
|
@ -152,7 +172,7 @@ public:
|
|||
const SkMatrix& matrix);
|
||||
|
||||
static SkPathRef* CreateFromBuffer(SkRBuffer* buffer
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
, bool newFormat, int32_t oldPacked
|
||||
#endif
|
||||
);
|
||||
|
@ -237,6 +257,7 @@ public:
|
|||
private:
|
||||
enum SerializationOffsets {
|
||||
kIsFinite_SerializationShift = 25, // requires 1 bit
|
||||
kIsOval_SerializationShift = 24, // requires 1 bit
|
||||
};
|
||||
|
||||
SkPathRef() {
|
||||
|
@ -247,6 +268,7 @@ private:
|
|||
fPoints = NULL;
|
||||
fFreeSpace = 0;
|
||||
fGenerationID = kEmptyGenID;
|
||||
fIsOval = false;
|
||||
SkDEBUGCODE(fEditorsAttached = 0;)
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
@ -289,6 +311,8 @@ private:
|
|||
fBoundsIsDirty = true; // this also invalidates fIsFinite
|
||||
fGenerationID = 0;
|
||||
|
||||
fIsOval = false;
|
||||
|
||||
size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount;
|
||||
size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints;
|
||||
size_t minSize = newSize + newReserve;
|
||||
|
@ -394,6 +418,8 @@ private:
|
|||
*/
|
||||
static void CreateEmptyImpl(SkPathRef** empty);
|
||||
|
||||
void setIsOval(bool isOval) { fIsOval = isOval; }
|
||||
|
||||
enum {
|
||||
kMinSize = 256,
|
||||
};
|
||||
|
@ -401,6 +427,7 @@ private:
|
|||
mutable SkRect fBounds;
|
||||
mutable uint8_t fBoundsIsDirty;
|
||||
mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
|
||||
mutable SkBool8 fIsOval;
|
||||
|
||||
SkPoint* fPoints; // points to begining of the allocation
|
||||
uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards)
|
||||
|
|
|
@ -219,13 +219,17 @@ protected:
|
|||
// parameterize blurs by sigma rather than radius
|
||||
// V14: Add flags word to PathRef serialization
|
||||
// V15: Remove A1 bitmpa config (and renumber remaining configs)
|
||||
// V16: Move SkPath's isOval flag to SkPathRef
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V13_AND_ALL_OTHER_INSTANCES_TOO
|
||||
static const uint32_t PRIOR_PRIOR_PICTURE_VERSION = 12; // TODO: remove when .skps regenerated
|
||||
#endif
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
static const uint32_t PRIOR_PICTURE_VERSION2 = 13; // TODO: remove when .skps regenerated
|
||||
#endif
|
||||
static const uint32_t PICTURE_VERSION = 15;
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
static const uint32_t PRIOR_PICTURE_VERSION3 = 15; // TODO: remove when .skps regenerated
|
||||
#endif
|
||||
static const uint32_t PICTURE_VERSION = 16;
|
||||
|
||||
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
|
||||
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
|
||||
|
|
|
@ -42,22 +42,6 @@ static bool is_degenerate(const SkPath& path) {
|
|||
return SkPath::kDone_Verb == iter.next(pts);
|
||||
}
|
||||
|
||||
class SkAutoDisableOvalCheck {
|
||||
public:
|
||||
SkAutoDisableOvalCheck(SkPath* path) : fPath(path) {
|
||||
fSaved = fPath->fIsOval;
|
||||
}
|
||||
|
||||
~SkAutoDisableOvalCheck() {
|
||||
fPath->fIsOval = fSaved;
|
||||
}
|
||||
|
||||
private:
|
||||
SkPath* fPath;
|
||||
bool fSaved;
|
||||
};
|
||||
#define SkAutoDisableOvalCheck(...) SK_REQUIRE_LOCAL_VAR(SkAutoDisableOvalCheck)
|
||||
|
||||
class SkAutoDisableDirectionCheck {
|
||||
public:
|
||||
SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) {
|
||||
|
@ -84,7 +68,7 @@ private:
|
|||
|
||||
It also notes if the path was originally degenerate, and if so, sets
|
||||
isConvex to true. Thus it can only be used if the contour being added is
|
||||
convex (which is always true since we only allow the addition of rects).
|
||||
convex.
|
||||
*/
|
||||
class SkAutoPathBoundsUpdate {
|
||||
public:
|
||||
|
@ -164,7 +148,6 @@ void SkPath::resetFields() {
|
|||
fSegmentMask = 0;
|
||||
fConvexity = kUnknown_Convexity;
|
||||
fDirection = kUnknown_Direction;
|
||||
fIsOval = false;
|
||||
|
||||
// We don't touch Android's fSourcePath. It's used to track texture garbage collection, so we
|
||||
// don't want to muck with it if it's been set to something non-NULL.
|
||||
|
@ -204,7 +187,6 @@ void SkPath::copyFields(const SkPath& that) {
|
|||
fSegmentMask = that.fSegmentMask;
|
||||
fConvexity = that.fConvexity;
|
||||
fDirection = that.fDirection;
|
||||
fIsOval = that.fIsOval;
|
||||
}
|
||||
|
||||
bool operator==(const SkPath& a, const SkPath& b) {
|
||||
|
@ -230,7 +212,6 @@ void SkPath::swap(SkPath& that) {
|
|||
SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask);
|
||||
SkTSwap<uint8_t>(fConvexity, that.fConvexity);
|
||||
SkTSwap<uint8_t>(fDirection, that.fDirection);
|
||||
SkTSwap<SkBool8>(fIsOval, that.fIsOval);
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath);
|
||||
#endif
|
||||
|
@ -631,7 +612,6 @@ void SkPath::setLastPt(SkScalar x, SkScalar y) {
|
|||
if (count == 0) {
|
||||
this->moveTo(x, y);
|
||||
} else {
|
||||
fIsOval = false;
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
ed.atPoint(count-1)->set(x, y);
|
||||
}
|
||||
|
@ -650,7 +630,6 @@ void SkPath::setConvexity(Convexity c) {
|
|||
do { \
|
||||
fConvexity = kUnknown_Convexity; \
|
||||
fDirection = kUnknown_Direction; \
|
||||
fIsOval = false; \
|
||||
} while (0)
|
||||
|
||||
void SkPath::incReserve(U16CPU inc) {
|
||||
|
@ -1263,14 +1242,13 @@ void SkPath::addOval(const SkRect& oval, Direction dir) {
|
|||
We can't simply check isEmpty() in this case, as additional
|
||||
moveTo() would mark the path non empty.
|
||||
*/
|
||||
fIsOval = hasOnlyMoveTos();
|
||||
if (fIsOval) {
|
||||
bool isOval = hasOnlyMoveTos();
|
||||
if (isOval) {
|
||||
fDirection = dir;
|
||||
} else {
|
||||
fDirection = kUnknown_Direction;
|
||||
}
|
||||
|
||||
SkAutoDisableOvalCheck adoc(this);
|
||||
SkAutoDisableDirectionCheck addc(this);
|
||||
|
||||
SkAutoPathBoundsUpdate apbu(this, oval);
|
||||
|
@ -1318,14 +1296,10 @@ void SkPath::addOval(const SkRect& oval, Direction dir) {
|
|||
this->quadTo( R, cy - sy, R, cy );
|
||||
}
|
||||
this->close();
|
||||
}
|
||||
|
||||
bool SkPath::isOval(SkRect* rect) const {
|
||||
if (fIsOval && rect) {
|
||||
*rect = getBounds();
|
||||
}
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
|
||||
return fIsOval;
|
||||
ed.setIsOval(isOval);
|
||||
}
|
||||
|
||||
void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) {
|
||||
|
@ -1459,8 +1433,6 @@ void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy) {
|
|||
void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
|
||||
SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints());
|
||||
|
||||
fIsOval = false;
|
||||
|
||||
RawIter iter(path);
|
||||
SkPoint pts[4];
|
||||
Verb verb;
|
||||
|
@ -1525,8 +1497,6 @@ void SkPath::reversePathTo(const SkPath& path) {
|
|||
|
||||
SkPathRef::Editor(&fPathRef, vcount, path.countPoints());
|
||||
|
||||
fIsOval = false;
|
||||
|
||||
const uint8_t* verbs = path.fPathRef->verbs();
|
||||
const SkPoint* pts = path.fPathRef->points();
|
||||
const SkScalar* conicWeights = path.fPathRef->conicWeights();
|
||||
|
@ -1574,8 +1544,6 @@ void SkPath::reverseAddPath(const SkPath& src) {
|
|||
const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the first verb
|
||||
const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd();
|
||||
|
||||
fIsOval = false;
|
||||
|
||||
bool needMove = true;
|
||||
bool needClose = false;
|
||||
while (verbs < verbsEnd) {
|
||||
|
@ -1725,9 +1693,6 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
|
|||
}
|
||||
}
|
||||
|
||||
// It's an oval only if it stays a rect.
|
||||
dst->fIsOval = fIsOval && matrix.rectStaysRect();
|
||||
|
||||
SkDEBUGCODE(dst->validate();)
|
||||
}
|
||||
}
|
||||
|
@ -2080,13 +2045,15 @@ size_t SkPath::writeToMemory(void* storage) const {
|
|||
|
||||
SkWBuffer buffer(storage);
|
||||
|
||||
int32_t packed = ((fIsOval & 1) << kIsOval_SerializationShift) |
|
||||
(fConvexity << kConvexity_SerializationShift) |
|
||||
int32_t packed = (fConvexity << kConvexity_SerializationShift) |
|
||||
(fFillType << kFillType_SerializationShift) |
|
||||
(fSegmentMask << kSegmentMask_SerializationShift) |
|
||||
(fDirection << kDirection_SerializationShift)
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
| (0x1 << kNewFormat_SerializationShift)
|
||||
#endif
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
| (0x1 << kNewFormat2_SerializationShift)
|
||||
#endif
|
||||
;
|
||||
|
||||
|
@ -2106,17 +2073,16 @@ size_t SkPath::readFromMemory(const void* storage, size_t length) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
fIsOval = (packed >> kIsOval_SerializationShift) & 1;
|
||||
fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF;
|
||||
fFillType = (packed >> kFillType_SerializationShift) & 0xFF;
|
||||
fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF;
|
||||
fDirection = (packed >> kDirection_SerializationShift) & 0x3;
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
bool newFormat = (packed >> kNewFormat_SerializationShift) & 1;
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
bool newFormat = (packed >> kNewFormat2_SerializationShift) & 1;
|
||||
#endif
|
||||
|
||||
SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
, newFormat, packed
|
||||
#endif
|
||||
);
|
||||
|
|
|
@ -26,6 +26,7 @@ SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef,
|
|||
}
|
||||
fPathRef = *pathRef;
|
||||
fPathRef->fGenerationID = 0;
|
||||
fPathRef->fIsOval = false;
|
||||
SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);)
|
||||
}
|
||||
|
||||
|
@ -100,28 +101,35 @@ void SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst,
|
|||
(*dst)->fBoundsIsDirty = true;
|
||||
}
|
||||
|
||||
// It's an oval only if it stays a rect.
|
||||
(*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect();
|
||||
|
||||
SkDEBUGCODE((*dst)->validate();)
|
||||
}
|
||||
|
||||
SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
, bool newFormat, int32_t oldPacked
|
||||
#endif
|
||||
) {
|
||||
SkPathRef* ref = SkNEW(SkPathRef);
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
bool isOval;
|
||||
|
||||
int32_t packed;
|
||||
if (!buffer->readS32(&packed)) {
|
||||
SkDELETE(ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
|
||||
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
if (newFormat) {
|
||||
#endif
|
||||
int32_t packed;
|
||||
if (!buffer->readS32(&packed)) {
|
||||
SkDELETE(ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
isOval = (packed >> kIsOval_SerializationShift) & 1;
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
} else {
|
||||
ref->fIsFinite = (oldPacked >> SkPath::kOldIsFinite_SerializationShift) & 1;
|
||||
isOval = (oldPacked >> SkPath::kOldIsOval_SerializationShift) & 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -147,6 +155,7 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer
|
|||
return NULL;
|
||||
}
|
||||
ref->fBoundsIsDirty = false;
|
||||
ref->fIsOval = isOval;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
@ -159,6 +168,7 @@ void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) {
|
|||
(*pathRef)->fFreeSpace = (*pathRef)->currSize();
|
||||
(*pathRef)->fGenerationID = 0;
|
||||
(*pathRef)->fConicWeights.rewind();
|
||||
(*pathRef)->fIsOval = false;
|
||||
SkDEBUGCODE((*pathRef)->validate();)
|
||||
} else {
|
||||
int oldVCnt = (*pathRef)->countVerbs();
|
||||
|
@ -216,7 +226,8 @@ void SkPathRef::writeToBuffer(SkWBuffer* buffer) {
|
|||
// and fIsFinite are computed.
|
||||
const SkRect& bounds = this->getBounds();
|
||||
|
||||
int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift);
|
||||
int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) |
|
||||
((fIsOval & 1) << kIsOval_SerializationShift);
|
||||
buffer->write32(packed);
|
||||
|
||||
// TODO: write gen ID here. Problem: We don't know if we're cross process or not from
|
||||
|
@ -258,15 +269,18 @@ void SkPathRef::copy(const SkPathRef& ref,
|
|||
fBounds = ref.fBounds;
|
||||
fIsFinite = ref.fIsFinite;
|
||||
}
|
||||
fIsOval = ref.fIsOval;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
||||
SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
int pCnt;
|
||||
bool dirtyAfterEdit = true;
|
||||
switch (verb) {
|
||||
case SkPath::kMove_Verb:
|
||||
pCnt = 1;
|
||||
dirtyAfterEdit = false;
|
||||
break;
|
||||
case SkPath::kLine_Verb:
|
||||
pCnt = 1;
|
||||
|
@ -281,12 +295,14 @@ SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb) {
|
|||
break;
|
||||
case SkPath::kClose_Verb:
|
||||
pCnt = 0;
|
||||
dirtyAfterEdit = false;
|
||||
break;
|
||||
case SkPath::kDone_Verb:
|
||||
SkDEBUGFAIL("growForVerb called for kDone");
|
||||
// fall through
|
||||
default:
|
||||
SkDEBUGFAIL("default is not reached");
|
||||
dirtyAfterEdit = false;
|
||||
pCnt = 0;
|
||||
}
|
||||
size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint);
|
||||
|
@ -297,6 +313,9 @@ SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb) {
|
|||
fPointCnt += pCnt;
|
||||
fFreeSpace -= space;
|
||||
fBoundsIsDirty = true; // this also invalidates fIsFinite
|
||||
if (dirtyAfterEdit) {
|
||||
fIsOval = false;
|
||||
}
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -292,6 +292,10 @@ bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
|
|||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TOO
|
||||
// V14 is backwards compatible with V13
|
||||
&& PRIOR_PICTURE_VERSION2 != info.fVersion // TODO: remove when .skps regenerated
|
||||
#endif
|
||||
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
|
||||
// V16 is backwards compatible with V15
|
||||
&& PRIOR_PICTURE_VERSION3 != info.fVersion // TODO: remove when .skps regenerated
|
||||
#endif
|
||||
) {
|
||||
return false;
|
||||
|
|
|
@ -2477,7 +2477,7 @@ static void check_for_circle(skiatest::Reporter* reporter,
|
|||
const SkPath& path,
|
||||
bool expectedCircle,
|
||||
SkPath::Direction expectedDir) {
|
||||
SkRect rect;
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
REPORTER_ASSERT(reporter, path.isOval(&rect) == expectedCircle);
|
||||
REPORTER_ASSERT(reporter, path.cheapIsDirection(expectedDir));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче