summaryrefslogtreecommitdiff
path: root/core/SkPathRef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/SkPathRef.cpp')
-rw-r--r--core/SkPathRef.cpp55
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;
}