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

📄 svgpathseglist.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/*    Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>                  2004, 2005 Rob Buis <buis@kde.org>    Copyright (C) 2007 Eric Seidel <eric@webkit.org>     This file is part of the WebKit project     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"#if ENABLE(SVG)#include "SVGPathSegList.h"#include "FloatPoint.h"#include "Path.h"#include "PathTraversalState.h"#include "SVGPathSegArc.h"#include "SVGPathSegClosePath.h"#include "SVGPathSegMoveto.h"#include "SVGPathSegLineto.h"#include "SVGPathSegLinetoHorizontal.h"#include "SVGPathSegLinetoVertical.h"#include "SVGPathSegCurvetoCubic.h"#include "SVGPathSegCurvetoCubicSmooth.h"#include "SVGPathSegCurvetoQuadratic.h"#include "SVGPathSegCurvetoQuadraticSmooth.h"namespace WebCore {SVGPathSegList::SVGPathSegList(const QualifiedName& attributeName)    : SVGList<RefPtr<SVGPathSeg> >(attributeName){}SVGPathSegList::~SVGPathSegList(){}unsigned SVGPathSegList::getPathSegAtLength(double){    // FIXME : to be useful this will need to support non-normalized SVGPathSegLists    ExceptionCode ec = 0;    int len = numberOfItems();    // FIXME: Eventually this will likely move to a "path applier"-like model, until then PathTraversalState is less useful as we could just use locals    PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);    for (int i = 0; i < len; ++i) {        SVGPathSeg* segment = getItem(i, ec).get();        float segmentLength = 0;        switch (segment->pathSegType()) {        case SVGPathSeg::PATHSEG_MOVETO_ABS:        {            SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment);            segmentLength = traversalState.moveTo(FloatPoint(moveTo->x(), moveTo->y()));            break;        }        case SVGPathSeg::PATHSEG_LINETO_ABS:        {            SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment);            segmentLength = traversalState.lineTo(FloatPoint(lineTo->x(), lineTo->y()));            break;        }        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:        {            SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment);            segmentLength = traversalState.cubicBezierTo(FloatPoint(curveTo->x1(), curveTo->y1()),                                      FloatPoint(curveTo->x2(), curveTo->y2()),                                      FloatPoint(curveTo->x(), curveTo->y()));            break;        }        case SVGPathSeg::PATHSEG_CLOSEPATH:            segmentLength = traversalState.closeSubpath();            break;        default:            ASSERT(false); // FIXME: This only works with normalized/processed path data.            break;        }        traversalState.m_totalLength += segmentLength;        if ((traversalState.m_action == PathTraversalState::TraversalSegmentAtLength)            && (traversalState.m_totalLength > traversalState.m_desiredLength)) {            return traversalState.m_segmentIndex;        }        traversalState.m_segmentIndex++;    }        return 0; // The SVG spec is unclear as to what to return when the distance is not on the path    }Path SVGPathSegList::toPathData(){    // FIXME : This should also support non-normalized PathSegLists    Path pathData;    ExceptionCode ec = 0;    int len = numberOfItems();    for (int i = 0; i < len; ++i) {        SVGPathSeg* segment = getItem(i, ec).get();        switch (segment->pathSegType()) {            case SVGPathSeg::PATHSEG_MOVETO_ABS:            {                SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment);                pathData.moveTo(FloatPoint(moveTo->x(), moveTo->y()));                break;            }            case SVGPathSeg::PATHSEG_LINETO_ABS:            {                SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment);                pathData.addLineTo(FloatPoint(lineTo->x(), lineTo->y()));                break;            }            case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:            {                SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment);                pathData.addBezierCurveTo(FloatPoint(curveTo->x1(), curveTo->y1()),                                          FloatPoint(curveTo->x2(), curveTo->y2()),                                          FloatPoint(curveTo->x(), curveTo->y()));                break;            }            case SVGPathSeg::PATHSEG_CLOSEPATH:                pathData.closeSubpath();                break;            default:                ASSERT(false); // FIXME: This only works with normalized/processed path data.                break;        }    }        return pathData;}    static inline float blendFunc(float from, float to, float progress){    return (to - from) * progress + from;}    #define BLENDPATHSEG1(class, attr1) \    class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress))    #define BLENDPATHSEG2(class, attr1, attr2) \    class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \                    blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress))    #define BLENDPATHSEG4(class, attr1, attr2, attr3, attr4) \    class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \                blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \                blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \                blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress))    #define BLENDPATHSEG6(class, attr1, attr2, attr3, attr4, attr5, attr6) \    class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \                blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \                blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \                blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress), \                blendFunc(static_cast<class*>(from)->attr5(), static_cast<class*>(to)->attr5(), progress), \                blendFunc(static_cast<class*>(from)->attr6(), static_cast<class*>(to)->attr6(), progress))#define BLENDPATHSEG7(class, attr1, attr2, attr3, attr4, attr5, bool1, bool2) \    class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \                blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \                blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \                blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress), \                blendFunc(static_cast<class*>(from)->attr5(), static_cast<class*>(to)->attr5(), progress), \                static_cast<bool>(blendFunc(static_cast<class*>(from)->bool1(), static_cast<class*>(to)->bool1(), progress)), \                static_cast<bool>(blendFunc(static_cast<class*>(from)->bool2(), static_cast<class*>(to)->bool2(), progress)))PassRefPtr<SVGPathSegList> SVGPathSegList::createAnimated(const SVGPathSegList* fromList, const SVGPathSegList* toList, float progress){    unsigned itemCount = fromList->numberOfItems();    if (!itemCount || itemCount != toList->numberOfItems())        return 0;    RefPtr<SVGPathSegList> result = create(fromList->associatedAttributeName());    ExceptionCode ec;    for (unsigned n = 0; n < itemCount; ++n) {        SVGPathSeg* from = fromList->getItem(n, ec).get();        SVGPathSeg* to = toList->getItem(n, ec).get();        if (from->pathSegType() == SVGPathSeg::PATHSEG_UNKNOWN || from->pathSegType() != to->pathSegType())            return 0;        RefPtr<SVGPathSeg> segment = 0;        switch (static_cast<SVGPathSeg::SVGPathSegType>(from->pathSegType())) {        case SVGPathSeg::PATHSEG_CLOSEPATH:            segment = SVGPathSegClosePath::create();            break;        case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS:            segment = BLENDPATHSEG1(SVGPathSegLinetoHorizontalAbs, x);            break;        case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL:            segment = BLENDPATHSEG1(SVGPathSegLinetoHorizontalRel, x);            break;           case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:            segment = BLENDPATHSEG1(SVGPathSegLinetoVerticalAbs, y);            break;        case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL:            segment = BLENDPATHSEG1(SVGPathSegLinetoVerticalRel, y);            break;                case SVGPathSeg::PATHSEG_MOVETO_ABS:            segment = BLENDPATHSEG2(SVGPathSegMovetoAbs, x, y);            break;        case SVGPathSeg::PATHSEG_MOVETO_REL:            segment = BLENDPATHSEG2(SVGPathSegMovetoRel, x, y);            break;        case SVGPathSeg::PATHSEG_LINETO_ABS:            segment = BLENDPATHSEG2(SVGPathSegLinetoAbs, x, y);            break;        case SVGPathSeg::PATHSEG_LINETO_REL:            segment = BLENDPATHSEG2(SVGPathSegLinetoRel, x, y);            break;        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:            segment = BLENDPATHSEG6(SVGPathSegCurvetoCubicAbs, x, y, x1, y1, x2, y2);            break;        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL:            segment = BLENDPATHSEG6(SVGPathSegCurvetoCubicRel, x, y, x1, y1, x2, y2);            break;        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:            segment = BLENDPATHSEG4(SVGPathSegCurvetoCubicSmoothAbs, x, y, x2, y2);            break;        case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL:            segment = BLENDPATHSEG4(SVGPathSegCurvetoCubicSmoothRel, x, y, x2, y2);            break;        case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS:            segment = BLENDPATHSEG4(SVGPathSegCurvetoQuadraticAbs, x, y, x1, y1);            break;        case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL:            segment = BLENDPATHSEG4(SVGPathSegCurvetoQuadraticRel, x, y, x1, y1);            break;        case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:            segment = BLENDPATHSEG2(SVGPathSegCurvetoQuadraticSmoothAbs, x, y);            break;        case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:            segment = BLENDPATHSEG2(SVGPathSegCurvetoQuadraticSmoothRel, x, y);            break;        case SVGPathSeg::PATHSEG_ARC_ABS:            segment = BLENDPATHSEG7(SVGPathSegArcAbs, x, y, r1, r2, angle, largeArcFlag, sweepFlag);            break;        case SVGPathSeg::PATHSEG_ARC_REL:            segment = BLENDPATHSEG7(SVGPathSegArcRel, x, y, r1, r2, angle, largeArcFlag, sweepFlag);            break;        case SVGPathSeg::PATHSEG_UNKNOWN:            ASSERT_NOT_REACHED();        }        result->appendItem(segment, ec);    }    return result.release();}}#endif // ENABLE(SVG)

⌨️ 快捷键说明

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