Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: src/core/SkPath.cpp

Issue 16195004: add asserts to point<-->verb helpers (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkEdgeBuilder.cpp ('k') | src/core/SkPathMeasure.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPath.cpp
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 95cd9fe93895e1cfc84505025a73b20a0792a98f..7485c0b4ff06b3e2d05c2dc568c119f582b30cce 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -369,6 +369,7 @@ bool SkPath::conservativelyContainsRect(const SkRect& rect) const {
SkASSERT(moveCnt);
break;
case kQuad_Verb:
+ case kConic_Verb:
SkASSERT(moveCnt);
nextPt = 2;
break;
@@ -558,12 +559,16 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts
break;
}
case kQuad_Verb:
+ case kConic_Verb:
case kCubic_Verb:
return false; // quadratic, cubic not allowed
case kMove_Verb:
last = *pts++;
closedOrMoved = true;
break;
+ default:
+ SkASSERT(!"unexpected verb");
+ break;
}
*currVerb += 1;
lastDirection = nextDirection;
@@ -805,15 +810,15 @@ void SkPath::rLineTo(SkScalar x, SkScalar y) {
void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
SkDEBUGCODE(this->validate();)
-
+
this->injectMoveToIfNeeded();
-
+
SkPathRef::Editor ed(&fPathRef);
SkPoint* pts = ed.growForVerb(kQuad_Verb);
pts[0].set(x1, y1);
pts[1].set(x2, y2);
fSegmentMask |= kQuad_SegmentMask;
-
+
GEN_ID_INC;
DIRTY_AFTER_EDIT;
}
@@ -824,6 +829,39 @@ void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2);
}
+void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
+ SkScalar w) {
+ // check for <= 0 or NaN with this test
+ if (!(w > 0)) {
+ this->lineTo(x2, y2);
+ } else if (!SkScalarIsFinite(w)) {
+ this->lineTo(x1, y1);
+ this->lineTo(x2, y2);
+ } else if (SK_Scalar1 == w) {
+ this->quadTo(x1, y1, x2, y2);
+ } else {
+ SkDEBUGCODE(this->validate();)
+
+ this->injectMoveToIfNeeded();
+
+ SkPathRef::Editor ed(&fPathRef);
+ SkPoint* pts = ed.growForConic(w);
+ pts[0].set(x1, y1);
+ pts[1].set(x2, y2);
+ fSegmentMask |= kConic_SegmentMask;
+
+ GEN_ID_INC;
+ DIRTY_AFTER_EDIT;
+ }
+}
+
+void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
+ SkScalar w) {
+ SkPoint pt;
+ this->getLastPt(&pt);
+ this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w);
+}
+
void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
SkScalar x3, SkScalar y3) {
SkDEBUGCODE(this->validate();)
@@ -857,6 +895,7 @@ void SkPath::close() {
switch (fPathRef->atVerb(count - 1)) {
case kLine_Verb:
case kQuad_Verb:
+ case kConic_Verb:
case kCubic_Verb:
case kMove_Verb: {
SkPathRef::Editor ed(&fPathRef);
@@ -864,9 +903,12 @@ void SkPath::close() {
GEN_ID_INC;
break;
}
- default:
+ case kClose_Verb:
// don't add a close if it's the first verb or a repeat
break;
+ default:
+ SkASSERT(!"unexpected verb");
+ break;
}
}
@@ -1430,6 +1472,10 @@ void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
proc(matrix, &pts[1], &pts[1], 2);
this->quadTo(pts[1], pts[2]);
break;
+ case kConic_Verb:
+ proc(matrix, &pts[1], &pts[1], 2);
+ this->conicTo(pts[1], pts[2], iter.conicWeight());
+ break;
case kCubic_Verb:
proc(matrix, &pts[1], &pts[1], 3);
this->cubicTo(pts[1], pts[2], pts[3]);
@@ -1445,14 +1491,20 @@ void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
///////////////////////////////////////////////////////////////////////////////
-static const uint8_t gPtsInVerb[] = {
- 1, // kMove
- 1, // kLine
- 2, // kQuad
- 3, // kCubic
- 0, // kClose
- 0 // kDone
-};
+static int pts_in_verb(unsigned verb) {
+ static const uint8_t gPtsInVerb[] = {
+ 1, // kMove
+ 1, // kLine
+ 2, // kQuad
+ 2, // kConic
+ 3, // kCubic
+ 0, // kClose
+ 0 // kDone
+ };
+
+ SkASSERT(verb < SK_ARRAY_COUNT(gPtsInVerb));
+ return gPtsInVerb[verb];
+}
// ignore the initial moveto, and stop when the 1st contour ends
void SkPath::pathTo(const SkPath& path) {
@@ -1469,6 +1521,7 @@ void SkPath::pathTo(const SkPath& path) {
const uint8_t* verbs = path.fPathRef->verbs();
// skip the initial moveTo
const SkPoint* pts = path.fPathRef->points() + 1;
+ const SkScalar* conicWeight = path.fPathRef->conicWeights();
SkASSERT(verbs[~0] == kMove_Verb);
for (i = 1; i < vcount; i++) {
@@ -1479,13 +1532,16 @@ void SkPath::pathTo(const SkPath& path) {
case kQuad_Verb:
this->quadTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
break;
+ case kConic_Verb:
+ this->conicTo(pts[0], pts[1], *conicWeight++);
+ break;
case kCubic_Verb:
this->cubicTo(pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
break;
case kClose_Verb:
return;
}
- pts += gPtsInVerb[verbs[~i]];
+ pts += pts_in_verb(verbs[~i]);
}
}
@@ -1503,14 +1559,17 @@ void SkPath::reversePathTo(const SkPath& path) {
const uint8_t* verbs = path.fPathRef->verbs();
const SkPoint* pts = path.fPathRef->points();
+ const SkScalar* conicWeights = path.fPathRef->conicWeights();
SkASSERT(verbs[~0] == kMove_Verb);
for (i = 1; i < vcount; ++i) {
- int n = gPtsInVerb[verbs[~i]];
+ unsigned v = verbs[~i];
+ int n = pts_in_verb(v);
if (n == 0) {
break;
}
pts += n;
+ conicWeights += (SkPath::kConic_Verb == v);
}
while (--i > 0) {
@@ -1521,6 +1580,9 @@ void SkPath::reversePathTo(const SkPath& path) {
case kQuad_Verb:
this->quadTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY);
break;
+ case kConic_Verb:
+ this->conicTo(pts[-1], pts[-2], *--conicWeights);
+ break;
case kCubic_Verb:
this->cubicTo(pts[-1].fX, pts[-1].fY, pts[-2].fX, pts[-2].fY,
pts[-3].fX, pts[-3].fY);
@@ -1529,7 +1591,7 @@ void SkPath::reversePathTo(const SkPath& path) {
SkDEBUGFAIL("bad verb");
break;
}
- pts -= gPtsInVerb[verbs[~i]];
+ pts -= pts_in_verb(verbs[~i]);
}
}
@@ -1540,6 +1602,7 @@ void SkPath::reverseAddPath(const SkPath& src) {
// we will iterator through src's verbs backwards
const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last verb
const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the first verb
+ const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd();
fIsOval = false;
@@ -1547,7 +1610,7 @@ void SkPath::reverseAddPath(const SkPath& src) {
bool needClose = false;
while (verbs < verbsEnd) {
uint8_t v = *(verbs++);
- int n = gPtsInVerb[v];
+ int n = pts_in_verb(v);
if (needMove) {
--pts;
@@ -1570,6 +1633,9 @@ void SkPath::reverseAddPath(const SkPath& src) {
case kQuad_Verb:
this->quadTo(pts[1], pts[0]);
break;
+ case kConic_Verb:
+ this->conicTo(pts[1], pts[0], *--conicWeights);
+ break;
case kCubic_Verb:
this->cubicTo(pts[2], pts[1], pts[0]);
break;
@@ -1644,6 +1710,10 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
case kQuad_Verb:
subdivide_quad_to(&tmp, pts);
break;
+ case kConic_Verb:
+ SkASSERT(!"TODO: compute new weight");
+ tmp.conicTo(pts[1], pts[2], iter.conicWeight());
+ break;
case kCubic_Verb:
subdivide_cubic_to(&tmp, pts);
break;
@@ -1741,6 +1811,7 @@ enum SegmentState {
SkPath::Iter::Iter() {
#ifdef SK_DEBUG
fPts = NULL;
+ fConicWeights = NULL;
fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0;
fForceClose = fCloseLine = false;
fSegmentState = kEmptyContour_SegmentState;
@@ -1759,6 +1830,7 @@ void SkPath::Iter::setPath(const SkPath& path, bool forceClose) {
fPts = path.fPathRef->points();
fVerbs = path.fPathRef->verbs();
fVerbStop = path.fPathRef->verbsMemBegin();
+ fConicWeights = path.fPathRef->conicWeights() - 1; // begin one behind
fLastPt.fX = fLastPt.fY = 0;
fMoveTo.fX = fMoveTo.fY = 0;
fForceClose = SkToU8(forceClose);
@@ -1870,6 +1942,7 @@ void SkPath::Iter::consumeDegenerateSegments() {
fPts++;
break;
+ case kConic_Verb:
case kQuad_Verb:
if (!IsQuadDegenerate(lastPt, fPts[0], fPts[1])) {
if (lastMoveVerb) {
@@ -1882,6 +1955,7 @@ void SkPath::Iter::consumeDegenerateSegments() {
// Ignore this line and continue
fVerbs--;
fPts += 2;
+ fConicWeights += (kConic_Verb == verb);
break;
case kCubic_Verb:
@@ -1951,6 +2025,9 @@ SkPath::Verb SkPath::Iter::doNext(SkPoint ptsParam[4]) {
fCloseLine = false;
srcPts += 1;
break;
+ case kConic_Verb:
+ fConicWeights += 1;
+ // fall-through
case kQuad_Verb:
pts[0] = this->cons_moveTo();
memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint));
@@ -1983,6 +2060,7 @@ SkPath::Verb SkPath::Iter::doNext(SkPoint ptsParam[4]) {
SkPath::RawIter::RawIter() {
#ifdef SK_DEBUG
fPts = NULL;
+ fConicWeights = NULL;
fMoveTo.fX = fMoveTo.fY = fLastPt.fX = fLastPt.fY = 0;
#endif
// need to init enough to make next() harmlessly return kDone_Verb
@@ -1998,6 +2076,7 @@ void SkPath::RawIter::setPath(const SkPath& path) {
fPts = path.fPathRef->points();
fVerbs = path.fPathRef->verbs();
fVerbStop = path.fPathRef->verbsMemBegin();
+ fConicWeights = path.fPathRef->conicWeights() - 1; // begin one behind
fMoveTo.fX = fMoveTo.fY = 0;
fLastPt.fX = fLastPt.fY = 0;
}
@@ -2025,6 +2104,9 @@ SkPath::Verb SkPath::RawIter::next(SkPoint pts[4]) {
fLastPt = srcPts[0];
srcPts += 1;
break;
+ case kConic_Verb:
+ fConicWeights += 1;
+ // fall-through
case kQuad_Verb:
pts[0] = fLastPt;
memcpy(&pts[1], srcPts, 2 * sizeof(SkPoint));
@@ -2057,22 +2139,12 @@ uint32_t SkPath::writeToMemory(void* storage) const {
if (NULL == storage) {
const int byteCount = sizeof(int32_t)
-#if NEW_PICTURE_FORMAT
+ fPathRef->writeSize()
-#else
- + 2 * sizeof(int32_t)
- + sizeof(SkPoint) * fPathRef->countPoints()
- + sizeof(uint8_t) * fPathRef->countVerbs()
-#endif
+ sizeof(SkRect);
return SkAlign4(byteCount);
}
SkWBuffer buffer(storage);
-#if !NEW_PICTURE_FORMAT
- buffer.write32(fPathRef->countPoints());
- buffer.write32(fPathRef->countVerbs());
-#endif
// Call getBounds() to ensure (as a side-effect) that fBounds
// and fIsFinite are computed.
@@ -2098,24 +2170,16 @@ uint32_t SkPath::writeToMemory(void* storage) const {
uint32_t SkPath::readFromMemory(const void* storage) {
SkRBuffer buffer(storage);
-#if !NEW_PICTURE_FORMAT
- int32_t pcount = buffer.readS32();
- int32_t vcount = buffer.readS32();
-#endif
uint32_t packed = buffer.readS32();
fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
fIsOval = (packed >> kIsOval_SerializationShift) & 1;
fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF;
fFillType = (packed >> kFillType_SerializationShift) & 0xFF;
- fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0x7;
+ fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF;
fDirection = (packed >> kDirection_SerializationShift) & 0x3;
-#if NEW_PICTURE_FORMAT
fPathRef.reset(SkPathRef::CreateFromBuffer(&buffer));
-#else
- fPathRef.reset(SkPathRef::CreateFromBuffer(vcount, pcount, &buffer));
-#endif
buffer.read(&fBounds, sizeof(fBounds));
fBoundsIsDirty = false;
@@ -2142,7 +2206,7 @@ static void append_scalar(SkString* str, SkScalar value) {
}
static void append_params(SkString* str, const char label[], const SkPoint pts[],
- int count) {
+ int count, SkScalar conicWeight = -1) {
str->append(label);
str->append("(");
@@ -2155,6 +2219,10 @@ static void append_params(SkString* str, const char label[], const SkPoint pts[]
str->append(", ");
}
}
+ if (conicWeight >= 0) {
+ str->append(", ");
+ append_scalar(str, conicWeight);
+ }
str->append(");\n");
}
@@ -2180,6 +2248,9 @@ void SkPath::dump(bool forceClose, const char title[]) const {
case kQuad_Verb:
append_params(&builder, "path.quadTo", &pts[1], 2);
break;
+ case kConic_Verb:
+ append_params(&builder, "path.conicTo", &pts[1], 2, iter.conicWeight());
+ break;
case kCubic_Verb:
append_params(&builder, "path.cubicTo", &pts[1], 3);
break;
@@ -2239,6 +2310,9 @@ void SkPath::validate() const {
case kQuad_Verb:
mask |= kQuad_SegmentMask;
break;
+ case kConic_Verb:
+ mask |= kConic_SegmentMask;
+ break;
case kCubic_Verb:
mask |= kCubic_SegmentMask;
case kMove_Verb: // these verbs aren't included in the segment mask.
@@ -2379,6 +2453,7 @@ SkPath::Convexity SkPath::internalGetConvexity() const {
break;
case kLine_Verb: count = 1; break;
case kQuad_Verb: count = 2; break;
+ case kConic_Verb: count = 2; break;
case kCubic_Verb: count = 3; break;
case kClose_Verb:
state.close();
@@ -2423,6 +2498,7 @@ private:
const SkPoint* fCurrPt;
const uint8_t* fCurrVerb;
const uint8_t* fStopVerbs;
+ const SkScalar* fCurrConicWeight;
bool fDone;
SkDEBUGCODE(int fContourCounter;)
};
@@ -2432,6 +2508,7 @@ ContourIter::ContourIter(const SkPathRef& pathRef) {
fDone = false;
fCurrPt = pathRef.points();
fCurrVerb = pathRef.verbs();
+ fCurrConicWeight = pathRef.conicWeights();
fCurrPtCount = 0;
SkDEBUGCODE(fContourCounter = 0;)
this->next();
@@ -2459,13 +2536,19 @@ void ContourIter::next() {
case SkPath::kLine_Verb:
ptCount += 1;
break;
+ case SkPath::kConic_Verb:
+ fCurrConicWeight += 1;
+ // fall-through
case SkPath::kQuad_Verb:
ptCount += 2;
break;
case SkPath::kCubic_Verb:
ptCount += 3;
break;
- default: // kClose_Verb, just keep going
+ case SkPath::kClose_Verb:
+ break;
+ default:
+ SkASSERT(!"unexpected verb");
break;
}
}
@@ -2957,13 +3040,16 @@ bool SkPath::contains(SkScalar x, SkScalar y) const {
case SkPath::kQuad_Verb:
w += winding_quad(pts, x, y);
break;
+ case SkPath::kConic_Verb:
+ SkASSERT(0);
+ break;
case SkPath::kCubic_Verb:
w += winding_cubic(pts, x, y);
break;
case SkPath::kDone_Verb:
done = true;
break;
- }
+ }
} while (!done);
switch (this->getFillType()) {
« no previous file with comments | « src/core/SkEdgeBuilder.cpp ('k') | src/core/SkPathMeasure.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698