📄 qsvghandler.cpp
字号:
y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 'C': { if (arg.count() < 6) { while (arg.count()) arg.pop_front(); break; } QPointF c1(arg[0], arg[1]); QPointF c2(arg[2], arg[3]); QPointF e(arg[4], arg[5]); path.cubicTo(c1, c2, e); ctrlPt = c2; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 's': { if (arg.count() < 4) { while (arg.count()) arg.pop_front(); break; } QPointF c1; if (lastMode == 'c' || lastMode == 'C' || lastMode == 's' || lastMode == 'S') c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); else c1 = QPointF(x, y); QPointF c2(arg[0]+offsetX, arg[1]+offsetY); QPointF e(arg[2]+offsetX, arg[3]+offsetY); path.cubicTo(c1, c2, e); ctrlPt = c2; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 'S': { if (arg.count() < 4) { while (arg.count()) arg.pop_front(); break; } QPointF c1; if (lastMode == 'c' || lastMode == 'C' || lastMode == 's' || lastMode == 'S') c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); else c1 = QPointF(x, y); QPointF c2(arg[0], arg[1]); QPointF e(arg[2], arg[3]); path.cubicTo(c1, c2, e); ctrlPt = c2; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 'q': { if (arg.count() < 4) { while (arg.count()) arg.pop_front(); break; } QPointF c(arg[0]+offsetX, arg[1]+offsetY); QPointF e(arg[2]+offsetX, arg[3]+offsetY); path.quadTo(c, e); ctrlPt = c; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 'Q': { if (arg.count() < 4) { while (arg.count()) arg.pop_front(); break; } QPointF c(arg[0], arg[1]); QPointF e(arg[2], arg[3]); path.quadTo(c, e); ctrlPt = c; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); break; } case 't': { if (arg.count() < 2) { while (arg.count()) arg.pop_front(); break; } QPointF e(arg[0]+offsetX, arg[1]+offsetY); QPointF c; if (lastMode == 'q' || lastMode == 'Q' || lastMode == 't' || lastMode == 'T') c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); else c = QPointF(x, y); path.quadTo(c, e); ctrlPt = c; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); break; } case 'T': { if (arg.count() < 2) { while (arg.count()) arg.pop_front(); break; } QPointF e(arg[0], arg[1]); QPointF c; if (lastMode == 'q' || lastMode == 'Q' || lastMode == 't' || lastMode == 'T') c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y()); else c = QPointF(x, y); path.quadTo(c, e); ctrlPt = c; x = e.x(); y = e.y(); arg.pop_front(); arg.pop_front(); break; } case 'a': { if (arg.count() < 7) { while (arg.count()) arg.pop_front(); break; } qreal rx = arg[0]; qreal ry = arg[1]; qreal xAxisRotation = arg[2]; qreal largeArcFlag = arg[3]; qreal sweepFlag = arg[4]; qreal ex = arg[5] + offsetX; qreal ey = arg[6] + offsetY; qreal curx = x; qreal cury = y; pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag), int(sweepFlag), ex, ey, curx, cury); x = ex; y = ey; arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); } break; case 'A': { if (arg.count() < 7) { while (arg.count()) arg.pop_front(); break; } qreal rx = arg[0]; qreal ry = arg[1]; qreal xAxisRotation = arg[2]; qreal largeArcFlag = arg[3]; qreal sweepFlag = arg[4]; qreal ex = arg[5]; qreal ey = arg[6]; qreal curx = x; qreal cury = y; pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag), int(sweepFlag), ex, ey, curx, cury); x = ex; y = ey; arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); arg.pop_front(); } break; default: return false; } lastMode = pathElem.toLatin1(); } } return true;}static bool parseStyle(QSvgNode *node, const QXmlStreamAttributes &attributes, QSvgHandler *);static bool parseStyle(QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *);static void parseCSStoXMLAttrs(const QVector<QCss::Declaration> &declarations, QXmlStreamAttributes &attributes){ for (int i = 0; i < declarations.count(); ++i) { const QCss::Declaration &decl = declarations.at(i); if (decl.property.isEmpty()) continue; if (decl.values.count() != 1) continue; QCss::Value val = decl.values.first(); QString valueStr = val.variant.toString(); if (val.type == QCss::Value::Uri) { valueStr.prepend(QLatin1String("url(")); valueStr.append(QLatin1Char(')')); } else if (val.type == QCss::Value::Function) { QStringList lst = val.variant.toStringList(); valueStr.append(lst.at(0)); valueStr.append(QLatin1Char('(')); for (int i = 1; i < lst.count(); ++i) { valueStr.append(lst.at(i)); if ((i +1) < lst.count()) valueStr.append(QLatin1Char(',')); } valueStr.append(QLatin1Char(')')); } else if (val.type == QCss::Value::KnownIdentifier) { switch (val.variant.toInt()) { case QCss::Value_None: valueStr = QLatin1String("none"); break; default: break; } } attributes.append(QString(), decl.property, valueStr); }}void QSvgHandler::parseCSStoXMLAttrs(QString css, QVector<QSvgCssAttribute> *attributes){ // preprocess (for unicode escapes), tokenize and remove comments m_cssParser.init(css); QString key; attributes->reserve(10); while (m_cssParser.hasNext()) { m_cssParser.skipSpace(); if (!m_cssParser.hasNext()) break; m_cssParser.next(); QStringRef name; if (m_cssParser.hasEscapeSequences) { key = m_cssParser.lexem(); name = QStringRef(&key, 0, key.length()); } else { const QCss::Symbol &sym = m_cssParser.symbol(); name = QStringRef(&sym.text, sym.start, sym.len); } m_cssParser.skipSpace(); if (!m_cssParser.test(QCss::COLON)) break; m_cssParser.skipSpace(); if (!m_cssParser.hasNext()) break; QSvgCssAttribute attribute; attribute.name = QXmlStreamStringRef(name); const int firstSymbol = m_cssParser.index; int symbolCount = 0; do { m_cssParser.next(); ++symbolCount; } while (m_cssParser.hasNext() && !m_cssParser.test(QCss::SEMICOLON)); bool canExtractValueByRef = !m_cssParser.hasEscapeSequences; if (canExtractValueByRef) { int len = m_cssParser.symbols.at(firstSymbol).len; for (int i = firstSymbol + 1; i < firstSymbol + symbolCount; ++i) { len += m_cssParser.symbols.at(i).len; if (m_cssParser.symbols.at(i - 1).start + m_cssParser.symbols.at(i - 1).len != m_cssParser.symbols.at(i).start) { canExtractValueByRef = false; break; } } if (canExtractValueByRef) { const QCss::Symbol &sym = m_cssParser.symbols.at(firstSymbol); attribute.value = QXmlStreamStringRef(QStringRef(&sym.text, sym.start, len)); } } if (!canExtractValueByRef) { QString value; for (int i = firstSymbol; i < m_cssParser.index - 1; ++i) value += m_cssParser.symbols.at(i).lexem(); attribute.value = QXmlStreamStringRef(QStringRef(&value, 0, value.length())); } attributes->append(attribute); m_cssParser.skipSpace(); }}static void cssStyleLookup(QSvgNode *node, QSvgHandler *handler, QSvgStyleSelector *selector){ QCss::StyleSelector::NodePtr cssNode; cssNode.ptr = node; QVector<QCss::Declaration> decls = selector->declarationsForNode(cssNode); QXmlStreamAttributes attributes; parseCSStoXMLAttrs(decls, attributes); parseStyle(node, attributes, handler);}static bool parseDefaultTextStyle(QSvgNode *node, const QXmlStreamAttributes &attributes, bool initial, QSvgHandler *handler){ Q_ASSERT(node->type() == QSvgText::TEXT); QSvgText *textNode = static_cast<QSvgText*>(node); QSvgAttributes attrs(attributes, handler); QString fontFamily = attrs.value(QString(), QLatin1String("font-family")).toString(); QString anchor = attrs.value(QString(), QLatin1String("text-anchor")).toString(); QSvgFontStyle *fontStyle = static_cast<QSvgFontStyle*>( node->styleProperty(QSvgStyleProperty::FONT)); if (fontStyle) { QSvgTinyDocument *doc = fontStyle->doc(); if (doc && fontStyle->svgFont()) { cssStyleLookup(node, handler, handler->selector()); parseStyle(node, attrs, handler); return true; } } else if (!fontFamily.isEmpty()) { QSvgTinyDocument *doc = node->document(); QSvgFont *svgFont = doc->svgFont(fontFamily); if (svgFont) { cssStyleLookup(node, handler, handler->selector()); parseStyle(node, attrs, handler); return true; } } QTextCharFormat format; QFont font; QBrush brush(QColor(0, 0, 0)); if (!initial) { font = textNode->topFormat().font(); brush = textNode->topFormat().foreground(); } if (initial) { QSvgFontStyle *fontStyle = static_cast<QSvgFontStyle*>( node->styleProperty(QSvgStyleProperty::FONT)); if (!fontStyle) fontStyle = static_cast<QSvgFontStyle*>( node->parent()->styleProperty(QSvgStyleProperty::FONT)); if (fontStyle) { font = fontStyle->qfont(); if (anchor.isEmpty(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -