⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pathtraversalstate.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * This file is part of the WebKit open source project. * * 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 "PathTraversalState.h"#include "Path.h"#include <math.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 distancetemplate<class CurveType>static float curveLength(PathTraversalState& traversalState, CurveType curve){    Vector<CurveType> curveStack;    curveStack.append(curve);    float totalLength = 0.0f;    do {        float length = curve.approximateDistance();        if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance) {            CurveType left, right;            curve.split(left, right);            curve = left;            curveStack.append(right);        } 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.0f)    , m_segmentIndex(0)    , m_desiredLength(0.0f)    , m_normalAngle(0.0f){}float PathTraversalState::closeSubpath(){    float distance = distanceLine(m_current, m_start);    m_start = m_control1 = m_control2 = m_current;    return distance;}float PathTraversalState::moveTo(const FloatPoint& point){    m_current = m_start = m_control1 = m_control2 = point;    return 0.0f;}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;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -