Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Eric Seidel <eric@webkit.org> | 2 * Copyright (C) 2006, 2007 Eric Seidel <eric@webkit.org> |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 , control(c) | 44 , control(c) |
| 45 , end(e) | 45 , end(e) |
| 46 { | 46 { |
| 47 } | 47 } |
| 48 | 48 |
| 49 float approximateDistance() const | 49 float approximateDistance() const |
| 50 { | 50 { |
| 51 return distanceLine(start, control) + distanceLine(control, end); | 51 return distanceLine(start, control) + distanceLine(control, end); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void split(QuadraticBezier& left, QuadraticBezier& right) const | 54 bool equals(const QuadraticBezier& other) const |
| 55 { | |
| 56 return start == other.start | |
| 57 && end == other.end | |
| 58 && control == other.control; | |
| 59 } | |
| 60 | |
| 61 bool split(QuadraticBezier& left, QuadraticBezier& right) const | |
| 55 { | 62 { |
| 56 left.control = midPoint(start, control); | 63 left.control = midPoint(start, control); |
| 57 right.control = midPoint(control, end); | 64 right.control = midPoint(control, end); |
| 58 | 65 |
| 59 FloatPoint leftControlToRightControl = midPoint(left.control, right.cont rol); | 66 FloatPoint leftControlToRightControl = midPoint(left.control, right.cont rol); |
| 60 left.end = leftControlToRightControl; | 67 left.end = leftControlToRightControl; |
| 61 right.start = leftControlToRightControl; | 68 right.start = leftControlToRightControl; |
| 62 | 69 |
| 63 left.start = start; | 70 left.start = start; |
| 64 right.end = end; | 71 right.end = end; |
| 72 | |
| 73 return !equals(left) && !equals(right); | |
| 65 } | 74 } |
| 66 | 75 |
| 67 FloatPoint start; | 76 FloatPoint start; |
| 68 FloatPoint control; | 77 FloatPoint control; |
| 69 FloatPoint end; | 78 FloatPoint end; |
| 70 }; | 79 }; |
| 71 | 80 |
| 72 struct CubicBezier { | 81 struct CubicBezier { |
| 73 CubicBezier() { } | 82 CubicBezier() { } |
| 74 CubicBezier(const FloatPoint& s, const FloatPoint& c1, const FloatPoint& c2, const FloatPoint& e) | 83 CubicBezier(const FloatPoint& s, const FloatPoint& c1, const FloatPoint& c2, const FloatPoint& e) |
| 75 : start(s) | 84 : start(s) |
| 76 , control1(c1) | 85 , control1(c1) |
| 77 , control2(c2) | 86 , control2(c2) |
| 78 , end(e) | 87 , end(e) |
| 79 { | 88 { |
| 80 } | 89 } |
| 81 | 90 |
| 82 float approximateDistance() const | 91 float approximateDistance() const |
| 83 { | 92 { |
| 84 return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end); | 93 return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end); |
| 85 } | 94 } |
| 86 | 95 |
| 87 void split(CubicBezier& left, CubicBezier& right) const | 96 bool equals(const CubicBezier& other) const |
| 97 { | |
| 98 return start == other.start | |
| 99 && end == other.end | |
| 100 && control1 == other.control1 | |
| 101 && control2 == other.control2; | |
| 102 } | |
| 103 | |
| 104 bool split(CubicBezier& left, CubicBezier& right) const | |
| 88 { | 105 { |
| 89 FloatPoint startToControl1 = midPoint(control1, control2); | 106 FloatPoint startToControl1 = midPoint(control1, control2); |
| 90 | 107 |
| 91 left.start = start; | 108 left.start = start; |
| 92 left.control1 = midPoint(start, control1); | 109 left.control1 = midPoint(start, control1); |
| 93 left.control2 = midPoint(left.control1, startToControl1); | 110 left.control2 = midPoint(left.control1, startToControl1); |
| 94 | 111 |
| 95 right.control2 = midPoint(control2, end); | 112 right.control2 = midPoint(control2, end); |
| 96 right.control1 = midPoint(right.control2, startToControl1); | 113 right.control1 = midPoint(right.control2, startToControl1); |
| 97 right.end = end; | 114 right.end = end; |
| 98 | 115 |
| 99 FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.c ontrol1); | 116 FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.c ontrol1); |
| 100 left.end = leftControl2ToRightControl1; | 117 left.end = leftControl2ToRightControl1; |
| 101 right.start = leftControl2ToRightControl1; | 118 right.start = leftControl2ToRightControl1; |
| 119 | |
| 120 return !equals(left) && !equals(right); | |
| 102 } | 121 } |
| 103 | 122 |
| 104 FloatPoint start; | 123 FloatPoint start; |
| 105 FloatPoint control1; | 124 FloatPoint control1; |
| 106 FloatPoint control2; | 125 FloatPoint control2; |
| 107 FloatPoint end; | 126 FloatPoint end; |
| 108 }; | 127 }; |
| 109 | 128 |
| 110 // FIXME: This function is possibly very slow due to the ifs required for proper path measuring | 129 // FIXME: This function is possibly very slow due to the ifs required for proper path measuring |
| 111 // A simple speed-up would be to use an additional boolean template parameter to control whether | 130 // A simple speed-up would be to use an additional boolean template parameter to control whether |
| 112 // to use the "fast" version of this function with no PathTraversalState updatin g, vs. the slow | 131 // to use the "fast" version of this function with no PathTraversalState updatin g, vs. the slow |
| 113 // version which does update the PathTraversalState. We'll have to shark it to s ee if that's necessary. | 132 // version which does update the PathTraversalState. We'll have to shark it to s ee if that's necessary. |
| 114 // Another check which is possible up-front (to send us down the fast path) woul d be to check if | 133 // Another check which is possible up-front (to send us down the fast path) woul d be to check if |
| 115 // approximateDistance() + current total distance > desired distance | 134 // approximateDistance() + current total distance > desired distance |
| 116 template<class CurveType> | 135 template<class CurveType> |
| 117 static float curveLength(PathTraversalState& traversalState, CurveType curve) | 136 static float curveLength(PathTraversalState& traversalState, CurveType curve) |
| 118 { | 137 { |
| 119 static const unsigned curveStackDepthLimit = 20; | 138 static const unsigned curveStackDepthLimit = 20; |
| 120 | 139 |
| 121 Vector<CurveType> curveStack; | 140 Vector<CurveType> curveStack; |
| 122 curveStack.append(curve); | 141 curveStack.append(curve); |
| 123 | 142 |
| 124 float totalLength = 0; | 143 float totalLength = 0; |
| 144 CurveType leftCurve, rightCurve; | |
| 125 do { | 145 do { |
| 126 float length = curve.approximateDistance(); | 146 float length = curve.approximateDistance(); |
| 127 if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLength Tolerance && curveStack.size() <= curveStackDepthLimit) { | 147 if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLength Tolerance |
|
Stephen Chennney
2014/03/07 16:25:31
The real problem is that tolerance is a fixed valu
f(malita)
2014/03/07 18:02:26
I disagree: the immediate problem is that the algo
f(malita)
2014/03/07 19:14:08
Come to think of it, it's obvious this would not w
| |
| 128 CurveType leftCurve; | 148 && curveStack.size() <= curveStackDepthLimit |
| 129 CurveType rightCurve; | 149 && curve.split(leftCurve, rightCurve)) { |
| 130 curve.split(leftCurve, rightCurve); | |
| 131 curve = leftCurve; | 150 curve = leftCurve; |
| 132 curveStack.append(rightCurve); | 151 curveStack.append(rightCurve); |
| 133 } else { | 152 } else { |
| 134 totalLength += length; | 153 totalLength += length; |
| 135 if (traversalState.m_action == PathTraversalState::TraversalPointAtL ength || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLe ngth) { | 154 if (traversalState.m_action == PathTraversalState::TraversalPointAtL ength || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLe ngth) { |
| 136 traversalState.m_previous = curve.start; | 155 traversalState.m_previous = curve.start; |
| 137 traversalState.m_current = curve.end; | 156 traversalState.m_current = curve.end; |
| 138 if (traversalState.m_totalLength + totalLength > traversalState. m_desiredLength) | 157 if (traversalState.m_totalLength + totalLength > traversalState. m_desiredLength) |
| 139 return totalLength; | 158 return totalLength; |
| 140 } | 159 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 } else { | 234 } else { |
| 216 m_normalAngle = rad2deg(slope); | 235 m_normalAngle = rad2deg(slope); |
| 217 } | 236 } |
| 218 m_success = true; | 237 m_success = true; |
| 219 } | 238 } |
| 220 m_previous = m_current; | 239 m_previous = m_current; |
| 221 } | 240 } |
| 222 | 241 |
| 223 } | 242 } |
| 224 | 243 |
| OLD | NEW |