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

Unified Diff: src/pathops/SkOpSegment.cpp

Issue 1096923003: working on initial winding for cubics (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 8 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/pathops/SkOpSegment.h ('k') | src/pathops/SkPathOpsCommon.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkOpSegment.cpp
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index 161eb33765de35bec78cc85ba9dbb736ced84480..b14be78d06fed2d17cbc9bacf26090314f6972f8 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -107,13 +107,10 @@ SkPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
SkPoint topPt = {SK_ScalarMax, SK_ScalarMax};
// see if either end is not done since we want smaller Y of the pair
bool lastDone = true;
- double lastT = -1;
SkOpSpanBase* span = &fHead;
+ SkOpSpanBase* lastSpan = NULL;
do {
- if (lastDone && (span->final() || span->upCast()->done())) {
- goto next;
- }
- {
+ if (!lastDone || (!span->final() && !span->upCast()->done())) {
const SkPoint& xy = span->pt();
if (topPt.fY > xy.fY || (topPt.fY == xy.fY && topPt.fX > xy.fX)) {
topPt = xy;
@@ -121,19 +118,22 @@ SkPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
*firstSpan = span;
}
}
- if (fVerb != SkPath::kLine_Verb && !lastDone) {
- SkPoint curveTop = (*CurveTop[fVerb])(fPts, fWeight, lastT, span->t());
- if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY
- && topPt.fX > curveTop.fX)) {
+ if (fVerb != SkPath::kLine_Verb && !lastDone
+ && fCubicType != SkDCubic::kSplitAtMaxCurvature_SkDCubicType) {
+ double curveTopT;
+ SkPoint curveTop = (*CurveTop[fVerb])(fPts, fWeight, lastSpan->t(), span->t(),
+ &curveTopT);
+ if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY && topPt.fX > curveTop.fX)) {
topPt = curveTop;
if (firstSpan) {
- *firstSpan = span;
+ const SkPoint& lastXY = lastSpan->pt();
+ *firstSpan = lastXY.fY > xy.fY || (lastXY.fY == xy.fY && lastXY.fX > xy.fX)
+ ? span : lastSpan;
}
}
}
- lastT = span->t();
+ lastSpan = span;
}
-next:
if (span->final()) {
break;
}
@@ -490,52 +490,12 @@ void SkOpSegment::checkAngleCoin(SkOpCoincidence* coincidences, SkChunkAlloc* al
// from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
bool SkOpSegment::clockwise(const SkOpSpanBase* start, const SkOpSpanBase* end, bool* swap) const {
SkASSERT(fVerb != SkPath::kLine_Verb);
- SkOpCurve edge;
- if (fVerb == SkPath::kCubic_Verb) {
- double startT = start->t();
- double endT = end->t();
- bool flip = startT > endT;
- SkDCubic cubic;
- cubic.set(fPts);
- double inflectionTs[2];
- int inflections = cubic.findInflections(inflectionTs);
- for (int index = 0; index < inflections; ++index) {
- double inflectionT = inflectionTs[index];
- if (between(startT, inflectionT, endT)) {
- if (flip) {
- if (!roughly_equal(inflectionT, endT)) {
- startT = inflectionT;
- }
- } else {
- if (!roughly_equal(inflectionT, startT)) {
- endT = inflectionT;
- }
- }
- }
- }
- SkDCubic part = cubic.subDivide(startT, endT);
- edge.set(part);
- } else {
- subDivide(start, end, &edge);
+ if (fVerb != SkPath::kCubic_Verb) {
+ SkOpCurve edge;
+ this->subDivide(start, end, &edge);
+ return SkDQuad::Clockwise(edge, swap);
}
- bool sumSet = false;
- int points = SkPathOpsVerbToPoints(fVerb);
- double sum = (edge[0].fX - edge[points].fX) * (edge[0].fY + edge[points].fY);
- if (!sumSet) {
- for (int idx = 0; idx < points; ++idx){
- sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx].fY);
- }
- }
- if (fVerb == SkPath::kCubic_Verb) {
- SkDCubic cubic;
- cubic.set(edge.fPts);
- *swap = sum > 0 && !cubic.monotonicInY();
- } else {
- SkDQuad quad;
- quad.set(edge.fPts);
- *swap = sum > 0 && !quad.monotonicInY();
- }
- return sum <= 0;
+ return SkDCubic::Clockwise(fPts, start->t(), end->t(), swap);
}
void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
@@ -1116,6 +1076,10 @@ SkOpSegment* SkOpSegment::findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpS
SkScalar top = SK_ScalarMax;
const SkOpAngle* firstAngle = NULL;
const SkOpAngle* angle = baseAngle;
+#if DEBUG_SWAP_TOP
+ SkDebugf("-%s- baseAngle\n", __FUNCTION__);
+ baseAngle->debugLoop();
+#endif
do {
if (!angle->unorderable()) {
const SkOpSegment* next = angle->segment();
@@ -1134,8 +1098,8 @@ SkOpSegment* SkOpSegment::findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpS
if (!firstAngle) {
return NULL; // if all are unorderable, give up
}
-#if DEBUG_SORT
- SkDebugf("%s\n", __FUNCTION__);
+#if DEBUG_SWAP_TOP
+ SkDebugf("-%s- firstAngle\n", __FUNCTION__);
firstAngle->debugLoop();
#endif
// skip edges that have already been processed
@@ -1163,20 +1127,26 @@ SkOpSegment* SkOpSegment::findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpS
SkOpSpanBase* start = *startPtr;
SkOpSpanBase* end = *endPtr;
bool swap;
- if (!leftSegment->clockwise(start, end, &swap)) {
- #if DEBUG_SWAP_TOP
- SkDebugf("%s swap=%d inflections=%d monotonic=%d\n",
- __FUNCTION__,
- swap, leftSegment->debugInflections(start, end),
- leftSegment->monotonicInY(start, end));
- #endif
- if (swap) {
+ bool cw = leftSegment->clockwise(start, end, &swap);
+#if DEBUG_SWAP_TOP
+ SkDebugf("%s id=%d s=%1.9g e=%1.9g (%c) cw=%d swap=%d inflections=%d monotonic=%d\n",
+ __FUNCTION__, leftSegment->debugID(), start->t(), end->t(),
+ start->t() < end->t() ? '-' : '+', cw,
+ swap, leftSegment->debugInflections(start, end),
+ leftSegment->monotonicInY(start, end));
+#endif
+ if (!cw && swap) {
// FIXME: I doubt it makes sense to (necessarily) swap if the edge was not the first
// sorted but merely the first not already processed (i.e., not done)
- SkTSwap(*startPtr, *endPtr);
- }
+ SkTSwap(*startPtr, *endPtr);
}
// FIXME: clockwise isn't reliable -- try computing swap from tangent ?
+ } else {
+#if DEBUG_SWAP_TOP
+ SkDebugf("%s id=%d s=%1.9g e=%1.9g (%c) cw=%d swap=%d inflections=%d monotonic=%d\n",
+ __FUNCTION__, leftSegment->debugID(), (*startPtr)->t(), (*endPtr)->t(),
+ (*startPtr)->t() < (*endPtr)->t() ? '-' : '+', -1, -1, -1, 1);
+#endif
}
return leftSegment;
}
@@ -1191,6 +1161,7 @@ void SkOpSegment::init(SkPoint pts[], SkScalar weight, SkOpContour* contour, SkP
fPts = pts;
fWeight = weight;
fVerb = verb;
+ fCubicType = SkDCubic::kUnsplit_SkDCubicType;
fCount = 0;
fDoneCount = 0;
fVisited = false;
« no previous file with comments | « src/pathops/SkOpSegment.h ('k') | src/pathops/SkPathOpsCommon.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698