OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 #include "SkPathOpsBounds.h" |
| 8 #include "SkPathOpsRect.h" |
| 9 #include "SkPathOpsCurve.h" |
| 10 |
| 11 SkDPoint SkDCurve::conicTop(const SkPoint curve[3], SkScalar curveWeight, |
| 12 double startT, double endT, double* topT) { |
| 13 SkDPoint topPt = fConic[0]; |
| 14 *topT = startT; |
| 15 if (topPt.fY > fConic[2].fY || (topPt.fY == fConic[2].fY && topPt.fX > fConi
c[2].fX)) { |
| 16 *topT = endT; |
| 17 topPt = fConic[2]; |
| 18 } |
| 19 if (!fConic.monotonicInY()) { |
| 20 double extremeT; |
| 21 if (SkDConic::FindExtrema(&fConic.fPts.fPts[0].fY, fConic.fWeight, &extr
emeT)) { |
| 22 SkDConic dCurve; |
| 23 dCurve.set(curve, curveWeight); |
| 24 extremeT = startT + (endT - startT) * extremeT; |
| 25 SkDPoint test = dCurve.ptAtT(extremeT); |
| 26 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { |
| 27 *topT = extremeT; |
| 28 topPt = test; |
| 29 } |
| 30 } |
| 31 } |
| 32 return topPt; |
| 33 } |
| 34 |
| 35 SkDPoint SkDCurve::cubicTop(const SkPoint curve[4], SkScalar , |
| 36 double startT, double endT, double* topT) { |
| 37 SkDPoint topPt = fCubic[0]; |
| 38 *topT = startT; |
| 39 if (topPt.fY > fCubic[3].fY || (topPt.fY == fCubic[3].fY && topPt.fX > fCubi
c[3].fX)) { |
| 40 *topT = endT; |
| 41 topPt = fCubic[3]; |
| 42 } |
| 43 double extremeTs[2]; |
| 44 if (!fCubic.monotonicInY()) { |
| 45 int roots = SkDCubic::FindExtrema(&fCubic.fPts[0].fY, extremeTs); |
| 46 SkDCubic dCurve; |
| 47 dCurve.set(curve); |
| 48 for (int index = 0; index < roots; ++index) { |
| 49 double t = startT + (endT - startT) * extremeTs[index]; |
| 50 SkDPoint mid = dCurve.ptAtT(t); |
| 51 if (topPt.fY > mid.fY || (topPt.fY == mid.fY && topPt.fX > mid.fX))
{ |
| 52 *topT = t; |
| 53 topPt = mid; |
| 54 } |
| 55 } |
| 56 } |
| 57 return topPt; |
| 58 } |
| 59 |
| 60 SkDPoint SkDCurve::lineTop(const SkPoint[2], SkScalar , double startT, double en
dT, double* topT) { |
| 61 SkDPoint topPt = fLine[0]; |
| 62 *topT = startT; |
| 63 if (topPt.fY > fLine[1].fY || (topPt.fY == fLine[1].fY && topPt.fX > fLine[1
].fX)) { |
| 64 *topT = endT; |
| 65 topPt = fLine[1]; |
| 66 } |
| 67 return topPt; |
| 68 } |
| 69 |
| 70 SkDPoint SkDCurve::quadTop(const SkPoint curve[3], SkScalar , |
| 71 double startT, double endT, double* topT) { |
| 72 SkDPoint topPt = fQuad[0]; |
| 73 *topT = startT; |
| 74 if (topPt.fY > fQuad[2].fY || (topPt.fY == fQuad[2].fY && topPt.fX > fQuad[2
].fX)) { |
| 75 *topT = endT; |
| 76 topPt = fQuad[2]; |
| 77 } |
| 78 if (!fQuad.monotonicInY()) { |
| 79 double extremeT; |
| 80 if (SkDQuad::FindExtrema(&fQuad.fPts[0].fY, &extremeT)) { |
| 81 SkDQuad dCurve; |
| 82 dCurve.set(curve); |
| 83 extremeT = startT + (endT - startT) * extremeT; |
| 84 SkDPoint test = dCurve.ptAtT(extremeT); |
| 85 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { |
| 86 *topT = extremeT; |
| 87 topPt = test; |
| 88 } |
| 89 } |
| 90 } |
| 91 return topPt; |
| 92 } |
| 93 |
| 94 SkDPoint (SkDCurve::* const Top[])(const SkPoint curve[], SkScalar curveWeight, |
| 95 double tStart, double tEnd, double* topT) = { |
| 96 NULL, |
| 97 &SkDCurve::lineTop, |
| 98 &SkDCurve::quadTop, |
| 99 &SkDCurve::conicTop, |
| 100 &SkDCurve::cubicTop |
| 101 }; |
| 102 |
| 103 void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight, |
| 104 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 105 SkDConic dCurve; |
| 106 dCurve.set(curve, curveWeight); |
| 107 SkDRect dRect; |
| 108 dRect.setBounds(dCurve, fConic, tStart, tEnd); |
| 109 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 110 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 111 } |
| 112 |
| 113 void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar , |
| 114 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 115 SkDCubic dCurve; |
| 116 dCurve.set(curve); |
| 117 SkDRect dRect; |
| 118 dRect.setBounds(dCurve, fCubic, tStart, tEnd); |
| 119 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 120 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 121 } |
| 122 |
| 123 void SkDCurve::setLineBounds(const SkPoint[2], SkScalar , |
| 124 double , double , SkPathOpsBounds* bounds) { |
| 125 bounds->setPointBounds(fLine[0]); |
| 126 bounds->add(fLine[1]); |
| 127 } |
| 128 |
| 129 void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar , |
| 130 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 131 SkDQuad dCurve; |
| 132 dCurve.set(curve); |
| 133 SkDRect dRect; |
| 134 dRect.setBounds(dCurve, fQuad, tStart, tEnd); |
| 135 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 136 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 137 } |
| 138 |
| 139 void (SkDCurve::* const SetBounds[])(const SkPoint curve[], SkScalar curveWeight
, |
| 140 double tStart, double tEnd, SkPathOpsBounds* bounds) = { |
| 141 NULL, |
| 142 &SkDCurve::setLineBounds, |
| 143 &SkDCurve::setQuadBounds, |
| 144 &SkDCurve::setConicBounds, |
| 145 &SkDCurve::setCubicBounds |
| 146 }; |
OLD | NEW |