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

Unified Diff: src/pathops/SkPathOpsCurve.cpp

Issue 1107353004: align top and bounds computations (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up code 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/SkPathOpsCurve.h ('k') | src/pathops/SkPathOpsDebug.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkPathOpsCurve.cpp
diff --git a/src/pathops/SkPathOpsCurve.cpp b/src/pathops/SkPathOpsCurve.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..651e64a908e66c260e31df7338bddbe3602792f2
--- /dev/null
+++ b/src/pathops/SkPathOpsCurve.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsBounds.h"
+#include "SkPathOpsRect.h"
+#include "SkPathOpsCurve.h"
+
+SkDPoint SkDCurve::conicTop(const SkPoint curve[3], SkScalar curveWeight,
+ double startT, double endT, double* topT) {
+ SkDPoint topPt = fConic[0];
+ *topT = startT;
+ if (topPt.fY > fConic[2].fY || (topPt.fY == fConic[2].fY && topPt.fX > fConic[2].fX)) {
+ *topT = endT;
+ topPt = fConic[2];
+ }
+ if (!fConic.monotonicInY()) {
+ double extremeT;
+ if (SkDConic::FindExtrema(&fConic.fPts.fPts[0].fY, fConic.fWeight, &extremeT)) {
+ SkDConic dCurve;
+ dCurve.set(curve, curveWeight);
+ extremeT = startT + (endT - startT) * extremeT;
+ SkDPoint test = dCurve.ptAtT(extremeT);
+ if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX)) {
+ *topT = extremeT;
+ topPt = test;
+ }
+ }
+ }
+ return topPt;
+}
+
+SkDPoint SkDCurve::cubicTop(const SkPoint curve[4], SkScalar ,
+ double startT, double endT, double* topT) {
+ SkDPoint topPt = fCubic[0];
+ *topT = startT;
+ if (topPt.fY > fCubic[3].fY || (topPt.fY == fCubic[3].fY && topPt.fX > fCubic[3].fX)) {
+ *topT = endT;
+ topPt = fCubic[3];
+ }
+ double extremeTs[2];
+ if (!fCubic.monotonicInY()) {
+ int roots = SkDCubic::FindExtrema(&fCubic.fPts[0].fY, extremeTs);
+ SkDCubic dCurve;
+ dCurve.set(curve);
+ for (int index = 0; index < roots; ++index) {
+ double t = startT + (endT - startT) * extremeTs[index];
+ SkDPoint mid = dCurve.ptAtT(t);
+ if (topPt.fY > mid.fY || (topPt.fY == mid.fY && topPt.fX > mid.fX)) {
+ *topT = t;
+ topPt = mid;
+ }
+ }
+ }
+ return topPt;
+}
+
+SkDPoint SkDCurve::lineTop(const SkPoint[2], SkScalar , double startT, double endT, double* topT) {
+ SkDPoint topPt = fLine[0];
+ *topT = startT;
+ if (topPt.fY > fLine[1].fY || (topPt.fY == fLine[1].fY && topPt.fX > fLine[1].fX)) {
+ *topT = endT;
+ topPt = fLine[1];
+ }
+ return topPt;
+}
+
+SkDPoint SkDCurve::quadTop(const SkPoint curve[3], SkScalar ,
+ double startT, double endT, double* topT) {
+ SkDPoint topPt = fQuad[0];
+ *topT = startT;
+ if (topPt.fY > fQuad[2].fY || (topPt.fY == fQuad[2].fY && topPt.fX > fQuad[2].fX)) {
+ *topT = endT;
+ topPt = fQuad[2];
+ }
+ if (!fQuad.monotonicInY()) {
+ double extremeT;
+ if (SkDQuad::FindExtrema(&fQuad.fPts[0].fY, &extremeT)) {
+ SkDQuad dCurve;
+ dCurve.set(curve);
+ extremeT = startT + (endT - startT) * extremeT;
+ SkDPoint test = dCurve.ptAtT(extremeT);
+ if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX)) {
+ *topT = extremeT;
+ topPt = test;
+ }
+ }
+ }
+ return topPt;
+}
+
+SkDPoint (SkDCurve::* const Top[])(const SkPoint curve[], SkScalar curveWeight,
+ double tStart, double tEnd, double* topT) = {
+ NULL,
+ &SkDCurve::lineTop,
+ &SkDCurve::quadTop,
+ &SkDCurve::conicTop,
+ &SkDCurve::cubicTop
+};
+
+void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight,
+ double tStart, double tEnd, SkPathOpsBounds* bounds) {
+ SkDConic dCurve;
+ dCurve.set(curve, curveWeight);
+ SkDRect dRect;
+ dRect.setBounds(dCurve, fConic, tStart, tEnd);
+ bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
+ SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
+}
+
+void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar ,
+ double tStart, double tEnd, SkPathOpsBounds* bounds) {
+ SkDCubic dCurve;
+ dCurve.set(curve);
+ SkDRect dRect;
+ dRect.setBounds(dCurve, fCubic, tStart, tEnd);
+ bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
+ SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
+}
+
+void SkDCurve::setLineBounds(const SkPoint[2], SkScalar ,
+ double , double , SkPathOpsBounds* bounds) {
+ bounds->setPointBounds(fLine[0]);
+ bounds->add(fLine[1]);
+}
+
+void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar ,
+ double tStart, double tEnd, SkPathOpsBounds* bounds) {
+ SkDQuad dCurve;
+ dCurve.set(curve);
+ SkDRect dRect;
+ dRect.setBounds(dCurve, fQuad, tStart, tEnd);
+ bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
+ SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
+}
+
+void (SkDCurve::* const SetBounds[])(const SkPoint curve[], SkScalar curveWeight,
+ double tStart, double tEnd, SkPathOpsBounds* bounds) = {
+ NULL,
+ &SkDCurve::setLineBounds,
+ &SkDCurve::setQuadBounds,
+ &SkDCurve::setConicBounds,
+ &SkDCurve::setCubicBounds
+};
« no previous file with comments | « src/pathops/SkPathOpsCurve.h ('k') | src/pathops/SkPathOpsDebug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698