diff options
Diffstat (limited to 'WebCore/svg/SVGParserUtilities.cpp')
-rw-r--r-- | WebCore/svg/SVGParserUtilities.cpp | 658 |
1 files changed, 3 insertions, 655 deletions
diff --git a/WebCore/svg/SVGParserUtilities.cpp b/WebCore/svg/SVGParserUtilities.cpp index c722232..14e3d58 100644 --- a/WebCore/svg/SVGParserUtilities.cpp +++ b/WebCore/svg/SVGParserUtilities.cpp @@ -21,31 +21,16 @@ */ #include "config.h" + #if ENABLE(SVG) #include "SVGParserUtilities.h" +#include "Document.h" #include "ExceptionCode.h" -#include "FloatConversion.h" #include "FloatPoint.h" -#include "Path.h" #include "PlatformString.h" -#include "SVGPathSegList.h" -#include "SVGPathSegArc.h" -#include "SVGPathSegClosePath.h" -#include "SVGPathSegCurvetoCubic.h" -#include "SVGPathSegCurvetoCubicSmooth.h" -#include "SVGPathSegCurvetoQuadratic.h" -#include "SVGPathSegCurvetoQuadraticSmooth.h" -#include "SVGPathSegLineto.h" -#include "SVGPathSegLinetoHorizontal.h" -#include "SVGPathSegLinetoVertical.h" -#include "SVGPathSegList.h" -#include "SVGPathSegMoveto.h" #include "SVGPointList.h" -#include "SVGPathElement.h" -#include <math.h> #include <wtf/ASCIICType.h> -#include <wtf/MathExtras.h> namespace WebCore { @@ -135,15 +120,9 @@ bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip) return _parseNumber(ptr, end, number, skip); } -// Only used for parsing Paths -static bool parseNumber(const UChar*& ptr, const UChar* end, double& number, bool skip = true) -{ - return _parseNumber(ptr, end, number, skip); -} - // only used to parse largeArcFlag and sweepFlag which must be a "0" or "1" // and might not have any whitespace/comma after it -static bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag) +bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag) { const UChar flagChar = *ptr++; if (flagChar == '0') @@ -210,637 +189,6 @@ bool pointsListFromSVGData(SVGPointList* pointsList, const String& points) return cur == end && !delimParsed; } - /** - * Parser for svg path data, contained in the d attribute. - * - * The parser delivers encountered commands and parameters by calling - * methods that correspond to those commands. Clients have to derive - * from this class and implement the abstract command methods. - * - * There are two operating modes. By default the parser just delivers unaltered - * svg path data commands and parameters. In the second mode, it will convert all - * relative coordinates to absolute ones, and convert all curves to cubic beziers. - */ - class SVGPathParser { - public: - virtual ~SVGPathParser() { } - bool parseSVG(const String& d, bool process = false); - - protected: - virtual void svgMoveTo(double x1, double y1, bool closed, bool abs = true) = 0; - virtual void svgLineTo(double x1, double y1, bool abs = true) = 0; - virtual void svgLineToHorizontal(double, bool /*abs*/ = true) { } - virtual void svgLineToVertical(double /*y*/, bool /*abs*/ = true) { } - virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true) = 0; - virtual void svgCurveToCubicSmooth(double /*x*/, double /*y*/, double /*x2*/, double /*y2*/, bool /*abs*/ = true) { } - virtual void svgCurveToQuadratic(double /*x*/, double /*y*/, double /*x1*/, double /*y1*/, bool /*abs*/ = true) { } - virtual void svgCurveToQuadraticSmooth(double /*x*/, double /*y*/, bool /*abs*/ = true) { } - virtual void svgArcTo(double /*x*/, double /*y*/, double /*r1*/, double /*r2*/, double /*angle*/, bool /*largeArcFlag*/, bool /*sweepFlag*/, bool /*abs*/ = true) { } - virtual void svgClosePath() = 0; - - private: - void calculateArc(bool relative, double& curx, double& cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag); - }; - -bool SVGPathParser::parseSVG(const String& s, bool process) -{ - const UChar* ptr = s.characters(); - const UChar* end = ptr + s.length(); - - double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc; - double px1, py1, px2, py2, px3, py3; - bool closed = true; - - if (!skipOptionalSpaces(ptr, end)) // skip any leading spaces - return false; - - char command = *(ptr++), lastCommand = ' '; - if (command != 'm' && command != 'M') // path must start with moveto - return false; - - subpathx = subpathy = curx = cury = contrlx = contrly = 0.0; - while (1) { - skipOptionalSpaces(ptr, end); // skip spaces between command and first coord - - bool relative = false; - - switch (command) - { - case 'm': - relative = true; - case 'M': - { - if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - if (process) { - subpathx = curx = relative ? curx + tox : tox; - subpathy = cury = relative ? cury + toy : toy; - - svgMoveTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury), closed); - } else - svgMoveTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), closed, !relative); - closed = false; - break; - } - case 'l': - relative = true; - case 'L': - { - if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - if (process) { - curx = relative ? curx + tox : tox; - cury = relative ? cury + toy : toy; - - svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury)); - } - else - svgLineTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative); - break; - } - case 'h': - { - if (!parseNumber(ptr, end, tox)) - return false; - if (process) { - curx = curx + tox; - svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury)); - } - else - svgLineToHorizontal(narrowPrecisionToFloat(tox), false); - break; - } - case 'H': - { - if (!parseNumber(ptr, end, tox)) - return false; - if (process) { - curx = tox; - svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury)); - } - else - svgLineToHorizontal(narrowPrecisionToFloat(tox)); - break; - } - case 'v': - { - if (!parseNumber(ptr, end, toy)) - return false; - if (process) { - cury = cury + toy; - svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury)); - } - else - svgLineToVertical(narrowPrecisionToFloat(toy), false); - break; - } - case 'V': - { - if (!parseNumber(ptr, end, toy)) - return false; - if (process) { - cury = toy; - svgLineTo(narrowPrecisionToFloat(curx), narrowPrecisionToFloat(cury)); - } - else - svgLineToVertical(narrowPrecisionToFloat(toy)); - break; - } - case 'z': - case 'Z': - { - // reset curx, cury for next path - if (process) { - curx = subpathx; - cury = subpathy; - } - closed = true; - svgClosePath(); - break; - } - case 'c': - relative = true; - case 'C': - { - if (!parseNumber(ptr, end, x1) || !parseNumber(ptr, end, y1) || - !parseNumber(ptr, end, x2) || !parseNumber(ptr, end, y2) || - !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - if (process) { - px1 = relative ? curx + x1 : x1; - py1 = relative ? cury + y1 : y1; - px2 = relative ? curx + x2 : x2; - py2 = relative ? cury + y2 : y2; - px3 = relative ? curx + tox : tox; - py3 = relative ? cury + toy : toy; - - svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2), - narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3)); - - contrlx = relative ? curx + x2 : x2; - contrly = relative ? cury + y2 : y2; - curx = relative ? curx + tox : tox; - cury = relative ? cury + toy : toy; - } - else - svgCurveToCubic(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), narrowPrecisionToFloat(x2), - narrowPrecisionToFloat(y2), narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative); - - break; - } - case 's': - relative = true; - case 'S': - { - if (!parseNumber(ptr, end, x2) || !parseNumber(ptr, end, y2) || - !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - if (!(lastCommand == 'c' || lastCommand == 'C' || - lastCommand == 's' || lastCommand == 'S')) { - contrlx = curx; - contrly = cury; - } - - if (process) { - px1 = 2 * curx - contrlx; - py1 = 2 * cury - contrly; - px2 = relative ? curx + x2 : x2; - py2 = relative ? cury + y2 : y2; - px3 = relative ? curx + tox : tox; - py3 = relative ? cury + toy : toy; - - svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2), - narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3)); - - contrlx = relative ? curx + x2 : x2; - contrly = relative ? cury + y2 : y2; - curx = relative ? curx + tox : tox; - cury = relative ? cury + toy : toy; - } - else - svgCurveToCubicSmooth(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2), - narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative); - break; - } - case 'q': - relative = true; - case 'Q': - { - if (!parseNumber(ptr, end, x1) || !parseNumber(ptr, end, y1) || - !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - if (process) { - px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0); - py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0); - px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0); - py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0); - px3 = relative ? curx + tox : tox; - py3 = relative ? cury + toy : toy; - - svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2), - narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3)); - - contrlx = relative ? curx + x1 : x1; - contrly = relative ? cury + y1 : y1; - curx = relative ? curx + tox : tox; - cury = relative ? cury + toy : toy; - } - else - svgCurveToQuadratic(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), - narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative); - break; - } - case 't': - relative = true; - case 'T': - { - if (!parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - if (!(lastCommand == 'q' || lastCommand == 'Q' || - lastCommand == 't' || lastCommand == 'T')) { - contrlx = curx; - contrly = cury; - } - - if (process) { - xc = 2 * curx - contrlx; - yc = 2 * cury - contrly; - - px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0); - py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0); - px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0); - py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0); - px3 = relative ? curx + tox : tox; - py3 = relative ? cury + toy : toy; - - svgCurveToCubic(narrowPrecisionToFloat(px1), narrowPrecisionToFloat(py1), narrowPrecisionToFloat(px2), - narrowPrecisionToFloat(py2), narrowPrecisionToFloat(px3), narrowPrecisionToFloat(py3)); - - contrlx = xc; - contrly = yc; - curx = relative ? curx + tox : tox; - cury = relative ? cury + toy : toy; - } - else - svgCurveToQuadraticSmooth(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), !relative); - break; - } - case 'a': - relative = true; - case 'A': - { - bool largeArc, sweep; - double angle, rx, ry; - if (!parseNumber(ptr, end, rx) || !parseNumber(ptr, end, ry) - || !parseNumber(ptr, end, angle) - || !parseArcFlag(ptr, end, largeArc) || !parseArcFlag(ptr, end, sweep) - || !parseNumber(ptr, end, tox) || !parseNumber(ptr, end, toy)) - return false; - - // Spec: radii are nonnegative numbers - rx = fabs(rx); - ry = fabs(ry); - - if (process) - calculateArc(relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep); - else - svgArcTo(narrowPrecisionToFloat(tox), narrowPrecisionToFloat(toy), narrowPrecisionToFloat(rx), narrowPrecisionToFloat(ry), - narrowPrecisionToFloat(angle), largeArc, sweep, !relative); - break; - } - default: - // FIXME: An error should go to the JavaScript console, or the like. - return false; - } - lastCommand = command; - - if (ptr >= end) - return true; - - // Check for remaining coordinates in the current command. - if ((*ptr == '+' || *ptr == '-' || *ptr == '.' || (*ptr >= '0' && *ptr <= '9')) - && (command != 'z' && command != 'Z')) { - if (command == 'M') - command = 'L'; - else if (command == 'm') - command = 'l'; - } else - command = *(ptr++); - - if (lastCommand != 'C' && lastCommand != 'c' && - lastCommand != 'S' && lastCommand != 's' && - lastCommand != 'Q' && lastCommand != 'q' && - lastCommand != 'T' && lastCommand != 't') { - contrlx = curx; - contrly = cury; - } - } - - return false; -} - -// This works by converting the SVG arc to "simple" beziers. -// For each bezier found a svgToCurve call is done. -// Adapted from Niko's code in kdelibs/kdecore/svgicons. -// Maybe this can serve in some shared lib? (Rob) -void SVGPathParser::calculateArc(bool relative, double& curx, double& cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag) -{ - double sin_th, cos_th; - double a00, a01, a10, a11; - double x0, y0, x1, y1, xc, yc; - double d, sfactor, sfactor_sq; - double th0, th1, th_arc; - int i, n_segs; - - sin_th = sin(angle * (piDouble / 180.0)); - cos_th = cos(angle * (piDouble / 180.0)); - - double dx; - - if (!relative) - dx = (curx - x) / 2.0; - else - dx = -x / 2.0; - - double dy; - - if (!relative) - dy = (cury - y) / 2.0; - else - dy = -y / 2.0; - - double _x1 = cos_th * dx + sin_th * dy; - double _y1 = -sin_th * dx + cos_th * dy; - double Pr1 = r1 * r1; - double Pr2 = r2 * r2; - double Px = _x1 * _x1; - double Py = _y1 * _y1; - - // Spec : check if radii are large enough - double check = Px / Pr1 + Py / Pr2; - if (check > 1) { - r1 = r1 * sqrt(check); - r2 = r2 * sqrt(check); - } - - a00 = cos_th / r1; - a01 = sin_th / r1; - a10 = -sin_th / r2; - a11 = cos_th / r2; - - x0 = a00 * curx + a01 * cury; - y0 = a10 * curx + a11 * cury; - - if (!relative) - x1 = a00 * x + a01 * y; - else - x1 = a00 * (curx + x) + a01 * (cury + y); - - if (!relative) - y1 = a10 * x + a11 * y; - else - y1 = a10 * (curx + x) + a11 * (cury + y); - - /* (x0, y0) is current point in transformed coordinate space. - (x1, y1) is new point in transformed coordinate space. - - The arc fits a unit-radius circle in this space. - */ - - d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0); - - sfactor_sq = 1.0 / d - 0.25; - - if (sfactor_sq < 0) - sfactor_sq = 0; - - sfactor = sqrt(sfactor_sq); - - if (sweepFlag == largeArcFlag) - sfactor = -sfactor; - - xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0); - yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); - - /* (xc, yc) is center of the circle. */ - th0 = atan2(y0 - yc, x0 - xc); - th1 = atan2(y1 - yc, x1 - xc); - - th_arc = th1 - th0; - if (th_arc < 0 && sweepFlag) - th_arc += 2 * piDouble; - else if (th_arc > 0 && !sweepFlag) - th_arc -= 2 * piDouble; - - n_segs = (int) (int) ceil(fabs(th_arc / (piDouble * 0.5 + 0.001))); - - for (i = 0; i < n_segs; i++) { - double sin_th, cos_th; - double a00, a01, a10, a11; - double x1, y1, x2, y2, x3, y3; - double t; - double th_half; - - double _th0 = th0 + i * th_arc / n_segs; - double _th1 = th0 + (i + 1) * th_arc / n_segs; - - sin_th = sin(angle * (piDouble / 180.0)); - cos_th = cos(angle * (piDouble / 180.0)); - - /* inverse transform compared with rsvg_path_arc */ - a00 = cos_th * r1; - a01 = -sin_th * r2; - a10 = sin_th * r1; - a11 = cos_th * r2; - - th_half = 0.5 * (_th1 - _th0); - t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half); - x1 = xc + cos(_th0) - t * sin(_th0); - y1 = yc + sin(_th0) + t * cos(_th0); - x3 = xc + cos(_th1); - y3 = yc + sin(_th1); - x2 = x3 + t * sin(_th1); - y2 = y3 - t * cos(_th1); - - svgCurveToCubic(narrowPrecisionToFloat(a00 * x1 + a01 * y1), narrowPrecisionToFloat(a10 * x1 + a11 * y1), - narrowPrecisionToFloat(a00 * x2 + a01 * y2), narrowPrecisionToFloat(a10 * x2 + a11 * y2), - narrowPrecisionToFloat(a00 * x3 + a01 * y3), narrowPrecisionToFloat(a10 * x3 + a11 * y3)); - } - - if (!relative) - curx = x; - else - curx += x; - - if (!relative) - cury = y; - else - cury += y; -} - -class PathBuilder : private SVGPathParser { -public: - bool build(Path* path, const String& d) - { - Path temporaryPath; - m_path = &temporaryPath; - if (!parseSVG(d, true)) - return false; - temporaryPath.swap(*path); - return true; - } - -private: - virtual void svgMoveTo(double x1, double y1, bool closed, bool abs = true) - { - current.setX(narrowPrecisionToFloat(abs ? x1 : current.x() + x1)); - current.setY(narrowPrecisionToFloat(abs ? y1 : current.y() + y1)); - if (closed) - m_path->closeSubpath(); - m_path->moveTo(current); - } - virtual void svgLineTo(double x1, double y1, bool abs = true) - { - current.setX(narrowPrecisionToFloat(abs ? x1 : current.x() + x1)); - current.setY(narrowPrecisionToFloat(abs ? y1 : current.y() + y1)); - m_path->addLineTo(current); - } - virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true) - { - if (!abs) { - x1 += current.x(); - y1 += current.y(); - x2 += current.x(); - y2 += current.y(); - } - current.setX(narrowPrecisionToFloat(abs ? x : current.x() + x)); - current.setY(narrowPrecisionToFloat(abs ? y : current.y() + y)); - m_path->addBezierCurveTo(FloatPoint::narrowPrecision(x1, y1), FloatPoint::narrowPrecision(x2, y2), current); - } - virtual void svgClosePath() - { - m_path->closeSubpath(); - } - - Path* m_path; - FloatPoint current; -}; - -bool pathFromSVGData(Path& path, const String& d) -{ - PathBuilder builder; - return builder.build(&path, d); -} - -class SVGPathSegListBuilder : private SVGPathParser { -public: - bool build(SVGPathSegList* segList, const String& d, bool process) - { - bool result = parseSVG(d, process); - size_t size = m_vector.size(); - for (size_t i = 0; i < size; ++i) { - ExceptionCode ec; - segList->appendItem(m_vector[i].release(), ec); - } - m_vector.clear(); - return result; - } - -private: - virtual void svgMoveTo(double x1, double y1, bool, bool abs = true) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegMovetoAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1))); - else - m_vector.append(SVGPathElement::createSVGPathSegMovetoRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1))); - } - virtual void svgLineTo(double x1, double y1, bool abs = true) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegLinetoAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1))); - else - m_vector.append(SVGPathElement::createSVGPathSegLinetoRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1))); - } - virtual void svgLineToHorizontal(double x, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegLinetoHorizontalAbs(narrowPrecisionToFloat(x))); - else - m_vector.append(SVGPathElement::createSVGPathSegLinetoHorizontalRel(narrowPrecisionToFloat(x))); - } - virtual void svgLineToVertical(double y, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegLinetoVerticalAbs(narrowPrecisionToFloat(y))); - else - m_vector.append(SVGPathElement::createSVGPathSegLinetoVerticalRel(narrowPrecisionToFloat(y))); - } - virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), - narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), - narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2))); - else - m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), - narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), - narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2))); - } - virtual void svgCurveToCubicSmooth(double x, double y, double x2, double y2, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2), - narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - else - m_vector.append(SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(narrowPrecisionToFloat(x2), narrowPrecisionToFloat(y2), - narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - } - virtual void svgCurveToQuadratic(double x, double y, double x1, double y1, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), - narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - else - m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticRel(narrowPrecisionToFloat(x1), narrowPrecisionToFloat(y1), - narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - } - virtual void svgCurveToQuadraticSmooth(double x, double y, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - else - m_vector.append(SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y))); - } - virtual void svgArcTo(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, bool abs) - { - if (abs) - m_vector.append(SVGPathElement::createSVGPathSegArcAbs(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), - narrowPrecisionToFloat(r1), narrowPrecisionToFloat(r2), - narrowPrecisionToFloat(angle), largeArcFlag, sweepFlag)); - else - m_vector.append(SVGPathElement::createSVGPathSegArcRel(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), - narrowPrecisionToFloat(r1), narrowPrecisionToFloat(r2), - narrowPrecisionToFloat(angle), largeArcFlag, sweepFlag)); - } - virtual void svgClosePath() - { - m_vector.append(SVGPathElement::createSVGPathSegClosePath()); - } - - Vector<RefPtr<SVGPathSeg> > m_vector; -}; - -bool pathSegListFromSVGData(SVGPathSegList* path, const String& d, bool process) -{ - SVGPathSegListBuilder builder; - return builder.build(path, d, process); -} - bool parseGlyphName(const String& input, HashSet<String>& values) { // FIXME: Parsing error detection is missing. |