Chromium Code Reviews| 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 // this cheats and assumes that the perpendicular to the point is the closest r ay to the curve | |
| 12 // this case (where the line and the curve are nearly coincident) may be the on ly case that counts | |
| 13 double SkDCurve::nearPoint(SkPath::Verb verb, const SkDPoint& xy, const SkDPoint & opp) const { | |
| 14 int count = SkPathOpsVerbToPoints(verb); | |
| 15 double minX = fCubic.fPts[0].fX; | |
| 16 double maxX = minX; | |
| 17 for (int index = 0; index < count; ++index) { | |
| 18 minX = SkTMin(minX, fCubic.fPts[index].fX); | |
| 19 maxX = SkTMax(maxX, fCubic.fPts[index].fX); | |
| 20 } | |
| 21 if (!AlmostBetweenUlps(minX, xy.fX, maxX)) { | |
| 22 return -1; | |
| 23 } | |
| 24 double minY = fCubic.fPts[0].fY; | |
| 25 double maxY = minY; | |
| 26 for (int index = 0; index < count; ++index) { | |
| 27 minY = SkTMin(minY, fCubic.fPts[index].fY); | |
| 28 maxY = SkTMax(maxY, fCubic.fPts[index].fY); | |
| 29 } | |
| 30 if (!AlmostBetweenUlps(minY, xy.fY, maxY)) { | |
| 31 return -1; | |
| 32 } | |
| 33 SkIntersections i; | |
| 34 SkDLine perp = {{ xy, { xy.fX + opp.fY - xy.fY, xy.fY + xy.fX - opp.fX }}}; | |
| 35 (*CurveDIntersectRay[verb])(*this, perp, &i); | |
| 36 int minIndex = -1; | |
| 37 double minDist = FLT_MAX; | |
| 38 for (int index = 0; index < i.used(); ++index) { | |
| 39 double dist = xy.distance(i.pt(index)); | |
| 40 if (minDist > dist) { | |
| 41 minDist = dist; | |
| 42 minIndex = index; | |
| 43 } | |
| 44 } | |
| 45 if (minIndex < 0) { | |
| 46 return -1; | |
| 47 } | |
| 48 double largest = SkTMax(SkTMax(maxX, maxY), -SkTMin(minX, minY)); | |
| 49 if (!AlmostEqualUlps_Pin(largest, largest + minDist)) { // is distance withi n ULPS tolerance? | |
| 50 return -1; | |
| 51 } | |
| 52 return SkPinT(i[0][minIndex]); | |
| 53 } | |
| 54 | |
| 55 void SkDCurve::offset(SkPath::Verb verb, const SkDVector& off) { | |
| 56 int count = SkPathOpsVerbToPoints(verb); | |
| 57 for (int index = 0; index < count; ++index) { | |
| 58 fCubic.fPts[index] += off; | |
| 59 } | |
| 60 } | |
| 61 | |
| 11 void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight, | 62 void SkDCurve::setConicBounds(const SkPoint curve[3], SkScalar curveWeight, |
| 12 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 63 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 13 SkDConic dCurve; | 64 SkDConic dCurve; |
| 14 dCurve.set(curve, curveWeight); | 65 dCurve.set(curve, curveWeight); |
| 15 SkDRect dRect; | 66 SkDRect dRect; |
| 16 dRect.setBounds(dCurve, fConic, tStart, tEnd); | 67 dRect.setBounds(dCurve, fConic, tStart, tEnd); |
| 17 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 68 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 18 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 69 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 19 } | 70 } |
| 20 | 71 |
| 21 void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar , | 72 void SkDCurve::setCubicBounds(const SkPoint curve[4], SkScalar , |
|
herb_g
2016/07/18 15:13:39
Space before ","
caryclark
2016/07/18 15:55:49
See earlier reply.
| |
| 22 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 73 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 23 SkDCubic dCurve; | 74 SkDCubic dCurve; |
| 24 dCurve.set(curve); | 75 dCurve.set(curve); |
| 25 SkDRect dRect; | 76 SkDRect dRect; |
| 26 dRect.setBounds(dCurve, fCubic, tStart, tEnd); | 77 dRect.setBounds(dCurve, fCubic, tStart, tEnd); |
| 27 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 78 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 28 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 79 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 29 } | 80 } |
| 30 | 81 |
| 31 void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar , | 82 void SkDCurve::setQuadBounds(const SkPoint curve[3], SkScalar , |
| 32 double tStart, double tEnd, SkPathOpsBounds* bounds) { | 83 double tStart, double tEnd, SkPathOpsBounds* bounds) { |
| 33 SkDQuad dCurve; | 84 SkDQuad dCurve; |
| 34 dCurve.set(curve); | 85 dCurve.set(curve); |
| 35 SkDRect dRect; | 86 SkDRect dRect; |
| 36 dRect.setBounds(dCurve, fQuad, tStart, tEnd); | 87 dRect.setBounds(dCurve, fQuad, tStart, tEnd); |
| 37 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), | 88 bounds->set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop), |
| 38 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); | 89 SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom)); |
| 39 } | 90 } |
| OLD | NEW |