summaryrefslogtreecommitdiffstats
path: root/WebCore/svg/SVGParserUtilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/svg/SVGParserUtilities.cpp')
-rw-r--r--WebCore/svg/SVGParserUtilities.cpp658
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.