aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkOpSegment.cpp
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2015-04-29 08:28:30 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-29 08:28:30 -0700
commitaec251012542e971100e218bf463adbfb5d21d20 (patch)
tree16c2e84c2d59d94b75d7d2bc50fec53c0e38a898 /src/pathops/SkOpSegment.cpp
parent97fdea6c4393cf0102d7eee5790782509fb4f57b (diff)
minor fixes to cubics code and overall alignment of how bounds and tops are computed for all curve types
All but 17 extended tests work. A helper function is privately added to SkPath.h to permit a test to modify a given point in a path. BUG=skia:3588 Review URL: https://codereview.chromium.org/1107353004
Diffstat (limited to 'src/pathops/SkOpSegment.cpp')
-rw-r--r--src/pathops/SkOpSegment.cpp33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index a571609f53..ce35f846b3 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -102,9 +102,9 @@ SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** sta
return other->activeAngleInner(oSpan, startPtr, endPtr, done, sortable);
}
-SkPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
+SkDPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
SkASSERT(!done());
- SkPoint topPt = {SK_ScalarMax, SK_ScalarMax};
+ SkDPoint topPt = {SK_ScalarMax, SK_ScalarMax};
// see if either end is not done since we want smaller Y of the pair
bool lastDone = true;
SkOpSpanBase* span = &fHead;
@@ -118,10 +118,11 @@ SkPoint SkOpSegment::activeLeftTop(SkOpSpanBase** firstSpan) {
*firstSpan = span;
}
}
- if (fVerb != SkPath::kLine_Verb && !lastDone
- && fCubicType != SkDCubic::kSplitAtMaxCurvature_SkDCubicType) {
+ if (fVerb != SkPath::kLine_Verb && !lastDone) {
double curveTopT;
- SkPoint curveTop = (*CurveTop[fVerb])(fPts, fWeight, lastSpan->t(), span->t(),
+ SkDCurve curve;
+ this->subDivide(lastSpan, span, &curve);
+ SkDPoint curveTop = (curve.*Top[fVerb])(fPts, fWeight, lastSpan->t(), span->t(),
&curveTopT);
if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY && topPt.fX > curveTop.fX)) {
topPt = curveTop;
@@ -1092,10 +1093,7 @@ SkOpSegment* SkOpSegment::findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpS
const SkOpSegment* next = angle->segment();
SkPathOpsBounds bounds;
next->subDivideBounds(angle->end(), angle->start(), &bounds);
- bool nearSame = AlmostEqualUlps(top, bounds.top());
- bool lowerSector = !firstAngle || angle->sectorEnd() < firstAngle->sectorStart();
- bool lesserSector = top > bounds.fTop;
- if (lesserSector && (!nearSame || lowerSector)) {
+ if (top > bounds.fTop) {
top = bounds.fTop;
firstAngle = angle;
}
@@ -1452,7 +1450,12 @@ bool SkOpSegment::monotonicInY(const SkOpSpanBase* start, const SkOpSpanBase* en
}
SkASSERT(fVerb == SkPath::kCubic_Verb);
SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
- return dst.monotonicInY();
+ if (dst.monotonicInY()) {
+ return true;
+ }
+ SkDCubic whole;
+ whole.set(fPts);
+ return whole.monotonicInY();
}
bool SkOpSegment::NextCandidate(SkOpSpanBase* span, SkOpSpanBase** start,
@@ -2023,9 +2026,15 @@ bool SkOpSegment::subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end,
void SkOpSegment::subDivideBounds(const SkOpSpanBase* start, const SkOpSpanBase* end,
SkPathOpsBounds* bounds) const {
- SkOpCurve edge;
+ SkDCurve edge;
+ subDivide(start, end, &edge);
+ (edge.*SetBounds[fVerb])(fPts, fWeight, start->t(), end->t(), bounds);
+}
+
+SkDPoint SkOpSegment::top(const SkOpSpanBase* start, const SkOpSpanBase* end, double* topT) const {
+ SkDCurve edge;
subDivide(start, end, &edge);
- (bounds->*SetCurveBounds[fVerb])(edge.fPts, edge.fWeight);
+ return (edge.*Top[fVerb])(fPts, fWeight, start->t(), end->t(), topT);
}
void SkOpSegment::undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end) {