📄 qsvghandler.cpp
字号:
font.setPointSizeF(len); } if (!style.isEmpty()) { if (style == QLatin1String("normal")) { font.setStyle(QFont::StyleNormal); } else if (style == QLatin1String("italic")) { font.setStyle(QFont::StyleItalic); } else if (style == QLatin1String("oblique")) { font.setStyle(QFont::StyleOblique); } else if (style == QLatin1String("inherit")) { //inherited already } } if (!weight.isEmpty()) { bool ok = false; int weightNum = weight.toInt(&ok); if (ok) { switch (weightNum) { case 100: case 200: font.setWeight(QFont::Light); break; case 300: case 400: font.setWeight(QFont::Normal); break; case 500: case 600: font.setWeight(QFont::DemiBold); break; case 700: case 800: font.setWeight(QFont::Bold); break; case 900: font.setWeight(QFont::Black); break; default: break; } } else { if (weight == QLatin1String("normal")) { font.setWeight(QFont::Normal); } else if (weight == QLatin1String("bold")) { font.setWeight(QFont::Bold); } else if (weight == QLatin1String("bolder")) { font.setWeight(QFont::DemiBold); } else if (weight == QLatin1String("lighter")) { font.setWeight(QFont::Light); } } } // QFontInfo fi(font); // font.setPointSize(fi.pointSize()); return true; } return false;}static void parseFont(QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *handler){ QFont font; QSvgFontStyle *inherited = static_cast<QSvgFontStyle*>(node->styleProperty( QSvgStyleProperty::FONT)); if (!inherited) inherited = static_cast<QSvgFontStyle*>(node->parent()->styleProperty( QSvgStyleProperty::FONT)); if (inherited) font = inherited->qfont(); if (parseQFont(attributes, font, handler)) { QString myId = someId(attributes); QString anchor = attributes.value(QLatin1String("text-anchor")).toString(); QSvgTinyDocument *doc = node->document(); QSvgFontStyle *fontStyle = 0; QString family = (font.family().isEmpty())?myId:font.family(); if (!family.isEmpty()) { QSvgFont *svgFont = doc->svgFont(family); if (svgFont) { fontStyle = new QSvgFontStyle(svgFont, doc); if (font.pixelSize() < 0) fontStyle->setPointSize(font.pointSizeF()); else fontStyle->setPointSize(font.pixelSize()); } } if (!fontStyle) fontStyle = new QSvgFontStyle(font, node->document()); if (!anchor.isEmpty()) fontStyle->setTextAnchor(anchor); node->appendStyleProperty(fontStyle, myId); }}static void parseTransform(QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *){ QString value = attributes.value(QLatin1String("transform")).toString(); QString myId = someId(attributes); value = value.trimmed(); if (value.isEmpty()) return; QMatrix matrix = parseTransformationMatrix(value); if (!matrix.isIdentity()) { node->appendStyleProperty(new QSvgTransformStyle(matrix), myId); }}static void parseVisibility(QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *){ QString value = attributes.value(QLatin1String("visibility")).toString(); QSvgNode *parent = node->parent(); if (parent && (value.isEmpty() || value == QLatin1String("inherit"))) node->setVisible(parent->isVisible()); else if (value == QLatin1String("hidden") || value == QLatin1String("collapse")) { node->setVisible(false); } else node->setVisible(true);}static void pathArcSegment(QPainterPath &path, qreal xc, qreal yc, qreal th0, qreal th1, qreal rx, qreal ry, qreal xAxisRotation){ qreal sinTh, cosTh; qreal a00, a01, a10, a11; qreal x1, y1, x2, y2, x3, y3; qreal t; qreal thHalf; sinTh = sin(xAxisRotation * (Q_PI / 180.0)); cosTh = cos(xAxisRotation * (Q_PI / 180.0)); a00 = cosTh * rx; a01 = -sinTh * ry; a10 = sinTh * rx; a11 = cosTh * ry; thHalf = 0.5 * (th1 - th0); t = (8.0 / 3.0) * sin(thHalf * 0.5) * sin(thHalf * 0.5) / sin(thHalf); 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); path.cubicTo(a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3);}// the arc handling code underneath is from XSVG (BSD license)/* * Copyright 2002 USC/Information Sciences Institute * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the name of * Information Sciences Institute not be used in advertising or * publicity pertaining to distribution of the software without * specific, written prior permission. Information Sciences Institute * makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied * warranty. * * INFORMATION SCIENCES INSTITUTE DISCLAIMS ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INFORMATION SCIENCES * INSTITUTE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * */static void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation, int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx, qreal cury){ qreal sin_th, cos_th; qreal a00, a01, a10, a11; qreal x0, y0, x1, y1, xc, yc; qreal d, sfactor, sfactor_sq; qreal th0, th1, th_arc; int i, n_segs; qreal dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check; rx = qAbs(rx); ry = qAbs(ry); sin_th = sin(x_axis_rotation * (Q_PI / 180.0)); cos_th = cos(x_axis_rotation * (Q_PI / 180.0)); dx = (curx - x) / 2.0; dy = (cury - y) / 2.0; dx1 = cos_th * dx + sin_th * dy; dy1 = -sin_th * dx + cos_th * dy; Pr1 = rx * rx; Pr2 = ry * ry; Px = dx1 * dx1; Py = dy1 * dy1; /* Spec : check if radii are large enough */ check = Px / Pr1 + Py / Pr2; if (check > 1) { rx = rx * sqrt(check); ry = ry * sqrt(check); } a00 = cos_th / rx; a01 = sin_th / rx; a10 = -sin_th / ry; a11 = cos_th / ry; x0 = a00 * curx + a01 * cury; y0 = a10 * curx + a11 * cury; x1 = a00 * x + a01 * y; y1 = a10 * x + a11 * 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 (sweep_flag == large_arc_flag) 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 && sweep_flag) th_arc += 2 * Q_PI; else if (th_arc > 0 && !sweep_flag) th_arc -= 2 * Q_PI; n_segs = int(ceil(qAbs(th_arc / (Q_PI * 0.5 + 0.001)))); for (i = 0; i < n_segs; i++) { pathArcSegment(path, xc, yc, th0 + i * th_arc / n_segs, th0 + (i + 1) * th_arc / n_segs, rx, ry, x_axis_rotation); }}static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path){ qreal x0 = 0, y0 = 0; // starting point qreal x = 0, y = 0; // current point char lastMode = 0; QPointF ctrlPt; const QChar *str = dataStr.constData(); const QChar *end = str + dataStr.size(); while (str != end) { while (*str == QLatin1Char(' ')) ++str; QChar pathElem = *str; ++str; QChar endc = *end; *const_cast<QChar *>(end) = 0; // parseNumbersList requires 0-termination that QStringRef cannot guarantee QVector<qreal> arg = parseNumbersList(str); *const_cast<QChar *>(end) = endc; if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z')) arg.append(0);//dummy while (!arg.isEmpty()) { qreal offsetX = x; // correction offsets qreal offsetY = y; // for relative commands switch (pathElem.unicode()) { case 'm': { if (arg.count() < 2) { arg.pop_front(); break; } x = x0 = arg[0] + offsetX; y = y0 = arg[1] + offsetY; path.moveTo(x0, y0); arg.pop_front(); arg.pop_front(); } break; case 'M': { if (arg.count() < 2) { arg.pop_front(); break; } x = x0 = arg[0]; y = y0 = arg[1]; path.moveTo(x0, y0); arg.pop_front(); arg.pop_front(); } break; case 'z': case 'Z': { x = x0; y = y0; path.closeSubpath(); arg.pop_front();//pop dummy } break; case 'l': { if (arg.count() < 2) { arg.pop_front(); break; } x = arg.front() + offsetX; arg.pop_front(); y = arg.front() + offsetY; arg.pop_front(); path.lineTo(x, y); } break; case 'L': { if (arg.count() < 2) { arg.pop_front(); break; } x = arg.front(); arg.pop_front(); y = arg.front(); arg.pop_front(); path.lineTo(x, y); } break; case 'h': { x = arg.front() + offsetX; arg.pop_front(); path.lineTo(x, y); } break; case 'H': { x = arg[0]; path.lineTo(x, y); arg.pop_front(); } break; case 'v': { y = arg[0] + offsetY; path.lineTo(x, y); arg.pop_front(); } break; case 'V': { y = arg[0]; path.lineTo(x, y); arg.pop_front(); } break; case 'c': { if (arg.count() < 6) { while (arg.count()) arg.pop_front(); break; } QPointF c1(arg[0]+offsetX, arg[1]+offsetY); QPointF c2(arg[2]+offsetX, arg[3]+offsetY); QPointF e(arg[4]+offsetX, arg[5]+offsetY); path.cubicTo(c1, c2, e); ctrlPt = c2; x = e.x();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -