| Index: Source/core/platform/graphics/PathTraversalState.cpp
|
| diff --git a/Source/core/platform/graphics/PathTraversalState.cpp b/Source/core/platform/graphics/PathTraversalState.cpp
|
| deleted file mode 100644
|
| index 532fbae555e38f251796d7475b70085feef7d528..0000000000000000000000000000000000000000
|
| --- a/Source/core/platform/graphics/PathTraversalState.cpp
|
| +++ /dev/null
|
| @@ -1,224 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2006, 2007 Eric Seidel <eric@webkit.org>
|
| - *
|
| - * This library is free software; you can redistribute it and/or
|
| - * modify it under the terms of the GNU Library General Public
|
| - * License as published by the Free Software Foundation; either
|
| - * version 2 of the License, or (at your option) any later version.
|
| - *
|
| - * This library is distributed in the hope that it will be useful,
|
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| - * Library General Public License for more details.
|
| - *
|
| - * You should have received a copy of the GNU Library General Public License
|
| - * along with this library; see the file COPYING.LIB. If not, write to
|
| - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
| - * Boston, MA 02110-1301, USA.
|
| - */
|
| -
|
| -#include "config.h"
|
| -#include "core/platform/graphics/PathTraversalState.h"
|
| -
|
| -#include "wtf/MathExtras.h"
|
| -#include "wtf/Vector.h"
|
| -
|
| -namespace WebCore {
|
| -
|
| -static const float kPathSegmentLengthTolerance = 0.00001f;
|
| -
|
| -static inline FloatPoint midPoint(const FloatPoint& first, const FloatPoint& second)
|
| -{
|
| - return FloatPoint((first.x() + second.x()) / 2.0f, (first.y() + second.y()) / 2.0f);
|
| -}
|
| -
|
| -static inline float distanceLine(const FloatPoint& start, const FloatPoint& end)
|
| -{
|
| - return sqrtf((end.x() - start.x()) * (end.x() - start.x()) + (end.y() - start.y()) * (end.y() - start.y()));
|
| -}
|
| -
|
| -struct QuadraticBezier {
|
| - QuadraticBezier() { }
|
| - QuadraticBezier(const FloatPoint& s, const FloatPoint& c, const FloatPoint& e)
|
| - : start(s)
|
| - , control(c)
|
| - , end(e)
|
| - {
|
| - }
|
| -
|
| - float approximateDistance() const
|
| - {
|
| - return distanceLine(start, control) + distanceLine(control, end);
|
| - }
|
| -
|
| - void split(QuadraticBezier& left, QuadraticBezier& right) const
|
| - {
|
| - left.control = midPoint(start, control);
|
| - right.control = midPoint(control, end);
|
| -
|
| - FloatPoint leftControlToRightControl = midPoint(left.control, right.control);
|
| - left.end = leftControlToRightControl;
|
| - right.start = leftControlToRightControl;
|
| -
|
| - left.start = start;
|
| - right.end = end;
|
| - }
|
| -
|
| - FloatPoint start;
|
| - FloatPoint control;
|
| - FloatPoint end;
|
| -};
|
| -
|
| -struct CubicBezier {
|
| - CubicBezier() { }
|
| - CubicBezier(const FloatPoint& s, const FloatPoint& c1, const FloatPoint& c2, const FloatPoint& e)
|
| - : start(s)
|
| - , control1(c1)
|
| - , control2(c2)
|
| - , end(e)
|
| - {
|
| - }
|
| -
|
| - float approximateDistance() const
|
| - {
|
| - return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end);
|
| - }
|
| -
|
| - void split(CubicBezier& left, CubicBezier& right) const
|
| - {
|
| - FloatPoint startToControl1 = midPoint(control1, control2);
|
| -
|
| - left.start = start;
|
| - left.control1 = midPoint(start, control1);
|
| - left.control2 = midPoint(left.control1, startToControl1);
|
| -
|
| - right.control2 = midPoint(control2, end);
|
| - right.control1 = midPoint(right.control2, startToControl1);
|
| - right.end = end;
|
| -
|
| - FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.control1);
|
| - left.end = leftControl2ToRightControl1;
|
| - right.start = leftControl2ToRightControl1;
|
| - }
|
| -
|
| - FloatPoint start;
|
| - FloatPoint control1;
|
| - FloatPoint control2;
|
| - FloatPoint end;
|
| -};
|
| -
|
| -// FIXME: This function is possibly very slow due to the ifs required for proper path measuring
|
| -// A simple speed-up would be to use an additional boolean template parameter to control whether
|
| -// to use the "fast" version of this function with no PathTraversalState updating, vs. the slow
|
| -// version which does update the PathTraversalState. We'll have to shark it to see if that's necessary.
|
| -// Another check which is possible up-front (to send us down the fast path) would be to check if
|
| -// approximateDistance() + current total distance > desired distance
|
| -template<class CurveType>
|
| -static float curveLength(PathTraversalState& traversalState, CurveType curve)
|
| -{
|
| - static const unsigned curveStackDepthLimit = 20;
|
| -
|
| - Vector<CurveType> curveStack;
|
| - curveStack.append(curve);
|
| -
|
| - float totalLength = 0;
|
| - do {
|
| - float length = curve.approximateDistance();
|
| - if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance && curveStack.size() <= curveStackDepthLimit) {
|
| - CurveType leftCurve;
|
| - CurveType rightCurve;
|
| - curve.split(leftCurve, rightCurve);
|
| - curve = leftCurve;
|
| - curveStack.append(rightCurve);
|
| - } else {
|
| - totalLength += length;
|
| - if (traversalState.m_action == PathTraversalState::TraversalPointAtLength
|
| - || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLength) {
|
| - traversalState.m_previous = curve.start;
|
| - traversalState.m_current = curve.end;
|
| - if (traversalState.m_totalLength + totalLength > traversalState.m_desiredLength)
|
| - return totalLength;
|
| - }
|
| - curve = curveStack.last();
|
| - curveStack.removeLast();
|
| - }
|
| - } while (!curveStack.isEmpty());
|
| -
|
| - return totalLength;
|
| -}
|
| -
|
| -PathTraversalState::PathTraversalState(PathTraversalAction action)
|
| - : m_action(action)
|
| - , m_success(false)
|
| - , m_totalLength(0)
|
| - , m_segmentIndex(0)
|
| - , m_desiredLength(0)
|
| - , m_normalAngle(0)
|
| -{
|
| -}
|
| -
|
| -float PathTraversalState::closeSubpath()
|
| -{
|
| - float distance = distanceLine(m_current, m_start);
|
| - m_current = m_control1 = m_control2 = m_start;
|
| - return distance;
|
| -}
|
| -
|
| -float PathTraversalState::moveTo(const FloatPoint& point)
|
| -{
|
| - m_current = m_start = m_control1 = m_control2 = point;
|
| - return 0;
|
| -}
|
| -
|
| -float PathTraversalState::lineTo(const FloatPoint& point)
|
| -{
|
| - float distance = distanceLine(m_current, point);
|
| - m_current = m_control1 = m_control2 = point;
|
| - return distance;
|
| -}
|
| -
|
| -float PathTraversalState::quadraticBezierTo(const FloatPoint& newControl, const FloatPoint& newEnd)
|
| -{
|
| - float distance = curveLength<QuadraticBezier>(*this, QuadraticBezier(m_current, newControl, newEnd));
|
| -
|
| - m_control1 = newControl;
|
| - m_control2 = newEnd;
|
| -
|
| - if (m_action != TraversalPointAtLength && m_action != TraversalNormalAngleAtLength)
|
| - m_current = newEnd;
|
| -
|
| - return distance;
|
| -}
|
| -
|
| -float PathTraversalState::cubicBezierTo(const FloatPoint& newControl1, const FloatPoint& newControl2, const FloatPoint& newEnd)
|
| -{
|
| - float distance = curveLength<CubicBezier>(*this, CubicBezier(m_current, newControl1, newControl2, newEnd));
|
| -
|
| - m_control1 = newEnd;
|
| - m_control2 = newControl2;
|
| -
|
| - if (m_action != TraversalPointAtLength && m_action != TraversalNormalAngleAtLength)
|
| - m_current = newEnd;
|
| -
|
| - return distance;
|
| -}
|
| -
|
| -void PathTraversalState::processSegment()
|
| -{
|
| - if (m_action == TraversalSegmentAtLength && m_totalLength >= m_desiredLength)
|
| - m_success = true;
|
| -
|
| - if ((m_action == TraversalPointAtLength || m_action == TraversalNormalAngleAtLength) && m_totalLength >= m_desiredLength) {
|
| - float slope = FloatPoint(m_current - m_previous).slopeAngleRadians();
|
| - if (m_action == TraversalPointAtLength) {
|
| - float offset = m_desiredLength - m_totalLength;
|
| - m_current.move(offset * cosf(slope), offset * sinf(slope));
|
| - } else
|
| - m_normalAngle = rad2deg(slope);
|
| - m_success = true;
|
| - }
|
| - m_previous = m_current;
|
| -}
|
| -
|
| -}
|
| -
|
|
|