| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkGeometry.h" | 7 #include "SkGeometry.h" |
| 8 #include "SkOpEdgeBuilder.h" | 8 #include "SkOpEdgeBuilder.h" |
| 9 #include "SkReduceOrder.h" | 9 #include "SkReduceOrder.h" |
| 10 | 10 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 void SkOpEdgeBuilder::closeContour(const SkPoint& curveEnd, const SkPoint& curve
Start) { | 40 void SkOpEdgeBuilder::closeContour(const SkPoint& curveEnd, const SkPoint& curve
Start) { |
| 41 if (!SkDPoint::ApproximatelyEqual(curveEnd, curveStart)) { | 41 if (!SkDPoint::ApproximatelyEqual(curveEnd, curveStart)) { |
| 42 fPathVerbs.push_back(SkPath::kLine_Verb); | 42 fPathVerbs.push_back(SkPath::kLine_Verb); |
| 43 fPathPts.push_back_n(1, &curveStart); | 43 fPathPts.push_back_n(1, &curveStart); |
| 44 } else { | 44 } else { |
| 45 fPathPts[fPathPts.count() - 1] = curveStart; | 45 fPathPts[fPathPts.count() - 1] = curveStart; |
| 46 } | 46 } |
| 47 fPathVerbs.push_back(SkPath::kClose_Verb); | 47 fPathVerbs.push_back(SkPath::kClose_Verb); |
| 48 } | 48 } |
| 49 | 49 |
| 50 // very tiny points cause numerical instability : don't allow them |
| 51 static void force_small_to_zero(SkPoint* pt) { |
| 52 if (SkScalarAbs(pt->fX) < FLT_EPSILON_ORDERABLE_ERR) { |
| 53 pt->fX = 0; |
| 54 } |
| 55 if (SkScalarAbs(pt->fY) < FLT_EPSILON_ORDERABLE_ERR) { |
| 56 pt->fY = 0; |
| 57 } |
| 58 } |
| 59 |
| 60 |
| 50 int SkOpEdgeBuilder::preFetch() { | 61 int SkOpEdgeBuilder::preFetch() { |
| 51 if (!fPath->isFinite()) { | 62 if (!fPath->isFinite()) { |
| 52 fUnparseable = true; | 63 fUnparseable = true; |
| 53 return 0; | 64 return 0; |
| 54 } | 65 } |
| 55 SkAutoConicToQuads quadder; | 66 SkAutoConicToQuads quadder; |
| 56 const SkScalar quadderTol = SK_Scalar1 / 16; | 67 const SkScalar quadderTol = SK_Scalar1 / 16; |
| 57 SkPath::RawIter iter(*fPath); | 68 SkPath::RawIter iter(*fPath); |
| 58 SkPoint curveStart; | 69 SkPoint curveStart; |
| 59 SkPoint curve[4]; | 70 SkPoint curve[4]; |
| 60 SkPoint pts[4]; | 71 SkPoint pts[4]; |
| 61 SkPath::Verb verb; | 72 SkPath::Verb verb; |
| 62 bool lastCurve = false; | 73 bool lastCurve = false; |
| 63 do { | 74 do { |
| 64 verb = iter.next(pts); | 75 verb = iter.next(pts); |
| 65 switch (verb) { | 76 switch (verb) { |
| 66 case SkPath::kMove_Verb: | 77 case SkPath::kMove_Verb: |
| 67 if (!fAllowOpenContours && lastCurve) { | 78 if (!fAllowOpenContours && lastCurve) { |
| 68 closeContour(curve[0], curveStart); | 79 closeContour(curve[0], curveStart); |
| 69 } | 80 } |
| 70 fPathVerbs.push_back(verb); | 81 fPathVerbs.push_back(verb); |
| 82 force_small_to_zero(&pts[0]); |
| 71 fPathPts.push_back(pts[0]); | 83 fPathPts.push_back(pts[0]); |
| 72 curveStart = curve[0] = pts[0]; | 84 curveStart = curve[0] = pts[0]; |
| 73 lastCurve = false; | 85 lastCurve = false; |
| 74 continue; | 86 continue; |
| 75 case SkPath::kLine_Verb: | 87 case SkPath::kLine_Verb: |
| 88 force_small_to_zero(&pts[1]); |
| 76 if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) { | 89 if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) { |
| 77 uint8_t lastVerb = fPathVerbs.back(); | 90 uint8_t lastVerb = fPathVerbs.back(); |
| 78 if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kM
ove_Verb) { | 91 if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kM
ove_Verb) { |
| 79 fPathPts.back() = pts[1]; | 92 fPathPts.back() = pts[1]; |
| 80 } | 93 } |
| 81 continue; // skip degenerate points | 94 continue; // skip degenerate points |
| 82 } | 95 } |
| 83 break; | 96 break; |
| 84 case SkPath::kQuad_Verb: | 97 case SkPath::kQuad_Verb: |
| 98 force_small_to_zero(&pts[1]); |
| 99 force_small_to_zero(&pts[2]); |
| 85 curve[1] = pts[1]; | 100 curve[1] = pts[1]; |
| 86 curve[2] = pts[2]; | 101 curve[2] = pts[2]; |
| 87 verb = SkReduceOrder::Quad(curve, pts); | 102 verb = SkReduceOrder::Quad(curve, pts); |
| 88 if (verb == SkPath::kMove_Verb) { | 103 if (verb == SkPath::kMove_Verb) { |
| 89 continue; // skip degenerate points | 104 continue; // skip degenerate points |
| 90 } | 105 } |
| 91 break; | 106 break; |
| 92 case SkPath::kConic_Verb: { | 107 case SkPath::kConic_Verb: { |
| 93 const SkPoint* quadPts = quadder.computeQuads(pts, iter.coni
cWeight(), | 108 const SkPoint* quadPts = quadder.computeQuads(pts, iter.coni
cWeight(), |
| 94 quadderTol); | 109 quadderTol); |
| 95 const int nQuads = quadder.countQuads(); | 110 const int nQuads = quadder.countQuads(); |
| 96 for (int i = 0; i < nQuads; ++i) { | 111 for (int i = 0; i < nQuads; ++i) { |
| 97 fPathVerbs.push_back(SkPath::kQuad_Verb); | 112 fPathVerbs.push_back(SkPath::kQuad_Verb); |
| 98 } | 113 } |
| 99 fPathPts.push_back_n(nQuads * 2, quadPts); | 114 fPathPts.push_back_n(nQuads * 2, quadPts); |
| 100 curve[0] = quadPts[nQuads * 2 - 1]; | 115 curve[0] = quadPts[nQuads * 2 - 1]; |
| 101 lastCurve = true; | 116 lastCurve = true; |
| 102 } | 117 } |
| 103 continue; | 118 continue; |
| 104 case SkPath::kCubic_Verb: | 119 case SkPath::kCubic_Verb: |
| 120 force_small_to_zero(&pts[1]); |
| 121 force_small_to_zero(&pts[2]); |
| 122 force_small_to_zero(&pts[3]); |
| 105 curve[1] = pts[1]; | 123 curve[1] = pts[1]; |
| 106 curve[2] = pts[2]; | 124 curve[2] = pts[2]; |
| 107 curve[3] = pts[3]; | 125 curve[3] = pts[3]; |
| 108 verb = SkReduceOrder::Cubic(curve, pts); | 126 verb = SkReduceOrder::Cubic(curve, pts); |
| 109 if (verb == SkPath::kMove_Verb) { | 127 if (verb == SkPath::kMove_Verb) { |
| 110 continue; // skip degenerate points | 128 continue; // skip degenerate points |
| 111 } | 129 } |
| 112 break; | 130 break; |
| 113 case SkPath::kClose_Verb: | 131 case SkPath::kClose_Verb: |
| 114 closeContour(curve[0], curveStart); | 132 closeContour(curve[0], curveStart); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 return false; | 199 return false; |
| 182 } | 200 } |
| 183 pointsPtr += SkPathOpsVerbToPoints(verb); | 201 pointsPtr += SkPathOpsVerbToPoints(verb); |
| 184 SkASSERT(fCurrentContour); | 202 SkASSERT(fCurrentContour); |
| 185 } | 203 } |
| 186 if (fCurrentContour && !fAllowOpenContours && !close()) { | 204 if (fCurrentContour && !fAllowOpenContours && !close()) { |
| 187 return false; | 205 return false; |
| 188 } | 206 } |
| 189 return true; | 207 return true; |
| 190 } | 208 } |
| OLD | NEW |