OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "SkPathOpsBounds.h" | 7 #include "SkPathOpsBounds.h" |
8 #include "SkPathOpsRect.h" | 8 #include "SkPathOpsRect.h" |
9 #include "SkPathOpsCurve.h" | 9 #include "SkPathOpsCurve.h" |
10 | 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, | 11 void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight, |
104 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 12 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
105 SkDConic dCurve; | 13 SkDConic dCurve; |
106 dCurve.set(curve, curveWeight); | 14 dCurve.set(curve, curveWeight); |
107 SkDRect dRect; | 15 SkDRect dRect; |
108 dRect.setBounds(dCurve, fConic, tStart, tEnd); | 16 dRect.setBounds(dCurve, fConic, tStart, tEnd); |
109 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 17 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
110 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 18 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
111 } | 19 } |
112 | 20 |
113 void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar , | 21 void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar , |
114 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 22 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
115 SkDCubic dCurve; | 23 SkDCubic dCurve; |
116 dCurve.set(curve); | 24 dCurve.set(curve); |
117 SkDRect dRect; | 25 SkDRect dRect; |
118 dRect.setBounds(dCurve, fCubic, tStart, tEnd); | 26 dRect.setBounds(dCurve, fCubic, tStart, tEnd); |
119 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 27 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
120 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 28 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
121 } | 29 } |
122 | 30 |
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 , | 31 void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar , |
130 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 32 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
131 SkDQuad dCurve; | 33 SkDQuad dCurve; |
132 dCurve.set(curve); | 34 dCurve.set(curve); |
133 SkDRect dRect; | 35 SkDRect dRect; |
134 dRect.setBounds(dCurve, fQuad, tStart, tEnd); | 36 dRect.setBounds(dCurve, fQuad, tStart, tEnd); |
135 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 37 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
136 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 38 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
137 } | 39 } |
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 |