Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: Source/core/platform/graphics/PathTraversalState.cpp

Issue 27123003: Move PathTraversalState.cpp/.h to platform/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006, 2007 Eric Seidel <eric@webkit.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "core/platform/graphics/PathTraversalState.h"
22
23 #include "wtf/MathExtras.h"
24 #include "wtf/Vector.h"
25
26 namespace WebCore {
27
28 static const float kPathSegmentLengthTolerance = 0.00001f;
29
30 static inline FloatPoint midPoint(const FloatPoint& first, const FloatPoint& sec ond)
31 {
32 return FloatPoint((first.x() + second.x()) / 2.0f, (first.y() + second.y()) / 2.0f);
33 }
34
35 static inline float distanceLine(const FloatPoint& start, const FloatPoint& end)
36 {
37 return sqrtf((end.x() - start.x()) * (end.x() - start.x()) + (end.y() - star t.y()) * (end.y() - start.y()));
38 }
39
40 struct QuadraticBezier {
41 QuadraticBezier() { }
42 QuadraticBezier(const FloatPoint& s, const FloatPoint& c, const FloatPoint& e)
43 : start(s)
44 , control(c)
45 , end(e)
46 {
47 }
48
49 float approximateDistance() const
50 {
51 return distanceLine(start, control) + distanceLine(control, end);
52 }
53
54 void split(QuadraticBezier& left, QuadraticBezier& right) const
55 {
56 left.control = midPoint(start, control);
57 right.control = midPoint(control, end);
58
59 FloatPoint leftControlToRightControl = midPoint(left.control, right.cont rol);
60 left.end = leftControlToRightControl;
61 right.start = leftControlToRightControl;
62
63 left.start = start;
64 right.end = end;
65 }
66
67 FloatPoint start;
68 FloatPoint control;
69 FloatPoint end;
70 };
71
72 struct CubicBezier {
73 CubicBezier() { }
74 CubicBezier(const FloatPoint& s, const FloatPoint& c1, const FloatPoint& c2, const FloatPoint& e)
75 : start(s)
76 , control1(c1)
77 , control2(c2)
78 , end(e)
79 {
80 }
81
82 float approximateDistance() const
83 {
84 return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end);
85 }
86
87 void split(CubicBezier& left, CubicBezier& right) const
88 {
89 FloatPoint startToControl1 = midPoint(control1, control2);
90
91 left.start = start;
92 left.control1 = midPoint(start, control1);
93 left.control2 = midPoint(left.control1, startToControl1);
94
95 right.control2 = midPoint(control2, end);
96 right.control1 = midPoint(right.control2, startToControl1);
97 right.end = end;
98
99 FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.c ontrol1);
100 left.end = leftControl2ToRightControl1;
101 right.start = leftControl2ToRightControl1;
102 }
103
104 FloatPoint start;
105 FloatPoint control1;
106 FloatPoint control2;
107 FloatPoint end;
108 };
109
110 // 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
112 // 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 see 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
115 // approximateDistance() + current total distance > desired distance
116 template<class CurveType>
117 static float curveLength(PathTraversalState& traversalState, CurveType curve)
118 {
119 static const unsigned curveStackDepthLimit = 20;
120
121 Vector<CurveType> curveStack;
122 curveStack.append(curve);
123
124 float totalLength = 0;
125 do {
126 float length = curve.approximateDistance();
127 if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLength Tolerance && curveStack.size() <= curveStackDepthLimit) {
128 CurveType leftCurve;
129 CurveType rightCurve;
130 curve.split(leftCurve, rightCurve);
131 curve = leftCurve;
132 curveStack.append(rightCurve);
133 } else {
134 totalLength += length;
135 if (traversalState.m_action == PathTraversalState::TraversalPointAtL ength
136 || traversalState.m_action == PathTraversalState::TraversalNormalAn gleAtLength) {
137 traversalState.m_previous = curve.start;
138 traversalState.m_current = curve.end;
139 if (traversalState.m_totalLength + totalLength > traversalState. m_desiredLength)
140 return totalLength;
141 }
142 curve = curveStack.last();
143 curveStack.removeLast();
144 }
145 } while (!curveStack.isEmpty());
146
147 return totalLength;
148 }
149
150 PathTraversalState::PathTraversalState(PathTraversalAction action)
151 : m_action(action)
152 , m_success(false)
153 , m_totalLength(0)
154 , m_segmentIndex(0)
155 , m_desiredLength(0)
156 , m_normalAngle(0)
157 {
158 }
159
160 float PathTraversalState::closeSubpath()
161 {
162 float distance = distanceLine(m_current, m_start);
163 m_current = m_control1 = m_control2 = m_start;
164 return distance;
165 }
166
167 float PathTraversalState::moveTo(const FloatPoint& point)
168 {
169 m_current = m_start = m_control1 = m_control2 = point;
170 return 0;
171 }
172
173 float PathTraversalState::lineTo(const FloatPoint& point)
174 {
175 float distance = distanceLine(m_current, point);
176 m_current = m_control1 = m_control2 = point;
177 return distance;
178 }
179
180 float PathTraversalState::quadraticBezierTo(const FloatPoint& newControl, const FloatPoint& newEnd)
181 {
182 float distance = curveLength<QuadraticBezier>(*this, QuadraticBezier(m_curre nt, newControl, newEnd));
183
184 m_control1 = newControl;
185 m_control2 = newEnd;
186
187 if (m_action != TraversalPointAtLength && m_action != TraversalNormalAngleAt Length)
188 m_current = newEnd;
189
190 return distance;
191 }
192
193 float PathTraversalState::cubicBezierTo(const FloatPoint& newControl1, const Flo atPoint& newControl2, const FloatPoint& newEnd)
194 {
195 float distance = curveLength<CubicBezier>(*this, CubicBezier(m_current, newC ontrol1, newControl2, newEnd));
196
197 m_control1 = newEnd;
198 m_control2 = newControl2;
199
200 if (m_action != TraversalPointAtLength && m_action != TraversalNormalAngleAt Length)
201 m_current = newEnd;
202
203 return distance;
204 }
205
206 void PathTraversalState::processSegment()
207 {
208 if (m_action == TraversalSegmentAtLength && m_totalLength >= m_desiredLength )
209 m_success = true;
210
211 if ((m_action == TraversalPointAtLength || m_action == TraversalNormalAngleA tLength) && m_totalLength >= m_desiredLength) {
212 float slope = FloatPoint(m_current - m_previous).slopeAngleRadians();
213 if (m_action == TraversalPointAtLength) {
214 float offset = m_desiredLength - m_totalLength;
215 m_current.move(offset * cosf(slope), offset * sinf(slope));
216 } else
217 m_normalAngle = rad2deg(slope);
218 m_success = true;
219 }
220 m_previous = m_current;
221 }
222
223 }
224
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/PathTraversalState.h ('k') | Source/core/svg/SVGPathTraversalStateBuilder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698