diff options
Diffstat (limited to 'core/SkPathRef.cpp')
-rw-r--r-- | core/SkPathRef.cpp | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/core/SkPathRef.cpp b/core/SkPathRef.cpp index c66d75b3..a02df302 100644 --- a/core/SkPathRef.cpp +++ b/core/SkPathRef.cpp @@ -10,8 +10,6 @@ #include "SkPath.h" #include "SkPathRef.h" -SK_DEFINE_INST_COUNT(SkPathRef); - ////////////////////////////////////////////////////////////////////////////// SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, int incReserveVerbs, @@ -26,6 +24,7 @@ SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, } fPathRef = *pathRef; fPathRef->fGenerationID = 0; + fPathRef->fIsOval = false; SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);) } @@ -62,14 +61,20 @@ void SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, return; } - bool dstUnique = (*dst)->unique(); - if (!dstUnique) { + if (!(*dst)->unique()) { dst->reset(SkNEW(SkPathRef)); + } + + if (*dst != &src) { (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count()); memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * sizeof(uint8_t)); (*dst)->fConicWeights = src.fConicWeights; } + SkASSERT((*dst)->countPoints() == src.countPoints()); + SkASSERT((*dst)->countVerbs() == src.countVerbs()); + SkASSERT((*dst)->fConicWeights.count() == src.fConicWeights.count()); + // Need to check this here in case (&src == dst) bool canXformBounds = !src.fBoundsIsDirty && matrix.rectStaysRect() && src.countPoints() > 1; @@ -100,28 +105,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 +159,7 @@ SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer return NULL; } ref->fBoundsIsDirty = false; + ref->fIsOval = isOval; return ref; } @@ -159,6 +172,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 +230,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 +273,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 +299,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 +317,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; } |