📄 svgparserutilities.cpp
字号:
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) || !parseNumber(ptr, end, tox)) return false; largeArc = tox == 1; if (!parseNumber(ptr, end, tox)) return false; sweep = tox == 1; if (!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 >= '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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -