📄 svgparserutilities.cpp
字号:
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) { if (!parseSVG(d, process)) return false; 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 true; }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);}Vector<String> parseDelimitedString(const String& input, const char seperator){ Vector<String> values; const UChar* ptr = input.characters(); const UChar* end = ptr + input.length(); skipOptionalSpaces(ptr, end); while (ptr < end) { // Leading and trailing white space, and white space before and after semicolon separators, will be ignored. const UChar* inputStart = ptr; while (ptr < end && *ptr != seperator) // careful not to ignore whitespace inside inputs ptr++; if (ptr == inputStart) break; // walk backwards from the ; to ignore any whitespace const UChar* inputEnd = ptr - 1; while (inputStart < inputEnd && isWhitespace(*inputEnd)) inputEnd--; values.append(String(inputStart, inputEnd - inputStart + 1)); skipOptionalSpacesOrDelimiter(ptr, end, seperator); } return values;}}#endif // ENABLE(SVG)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -