📄 qsvghandler.cpp
字号:
} qreal penw = pen.widthF(); if (!linejoin.isEmpty()) { if (linejoin == QLatin1String("miter")) pen.setJoinStyle(Qt::SvgMiterJoin); else if (linejoin == QLatin1String("round")) pen.setJoinStyle(Qt::RoundJoin); else if (linejoin == QLatin1String("bevel")) pen.setJoinStyle(Qt::BevelJoin); } if (!miterlimit.isEmpty()) pen.setMiterLimit(::toDouble(miterlimit)); if (!linecap.isEmpty()) { if (linecap == QLatin1String("butt")) pen.setCapStyle(Qt::FlatCap); else if (linecap == QLatin1String("round")) pen.setCapStyle(Qt::RoundCap); else if (linecap == QLatin1String("square")) pen.setCapStyle(Qt::SquareCap); } if (!dashArray.isEmpty()) { const QChar *s = dashArray.constData(); QVector<qreal> dashes = parseNumbersList(s); qreal *d = dashes.data(); if (penw != 0) for (int i = 0; i < dashes.size(); ++i) { *d /= penw; ++d; } pen.setDashPattern(dashes); } if (!dashOffset.isEmpty()) { pen.setDashOffset(::toDouble(dashOffset)); } } else { pen.setStyle(Qt::NoPen); } }}static QMatrix parseTransformationMatrix(const QString &value){ QMatrix matrix; const QChar *str = value.constData(); while (*str != QLatin1Char(0)) { if (str->isSpace() || *str == QLatin1Char(',')) { ++str; continue; } enum State { Matrix, Translate, Rotate, Scale, SkewX, SkewY }; State state = Matrix; if (*str == QLatin1Char('m')) { //matrix const char *ident = "atrix"; for (int i = 0; i < 5; ++i) if (*(++str) != QLatin1Char(ident[i])) goto error; ++str; state = Matrix; } else if (*str == QLatin1Char('t')) { //translate const char *ident = "ranslate"; for (int i = 0; i < 8; ++i) if (*(++str) != QLatin1Char(ident[i])) goto error; ++str; state = Translate; } else if (*str == QLatin1Char('r')) { //rotate const char *ident = "otate"; for (int i = 0; i < 5; ++i) if (*(++str) != QLatin1Char(ident[i])) goto error; ++str; state = Rotate; } else if (*str == QLatin1Char('s')) { //scale, skewX, skewY ++str; if (*str == QLatin1Char('c')) { const char *ident = "ale"; for (int i = 0; i < 3; ++i) if (*(++str) != QLatin1Char(ident[i])) goto error; ++str; state = Scale; } else if (*str == QLatin1Char('k')) { if (*(++str) != QLatin1Char('e')) goto error; if (*(++str) != QLatin1Char('w')) goto error; ++str; if (*str == QLatin1Char('X')) state = SkewX; else if (*str == QLatin1Char('Y')) state = SkewY; else goto error; ++str; } else { goto error; } } else { goto error; } while (str->isSpace()) ++str; if (*str != QLatin1Char('(')) goto error; ++str; QVector<qreal> points = parseNumbersList(str); if (*str != QLatin1Char(')')) goto error; ++str; if(state == Matrix) { if(points.count() != 6) goto error; matrix = matrix * QMatrix(points[0], points[1], points[2], points[3], points[4], points[5]); } else if (state == Translate) { if (points.count() == 1) matrix.translate(points[0], 0); else if (points.count() == 2) matrix.translate(points[0], points[1]); else goto error; } else if (state == Rotate) { if(points.count() == 1) { matrix.rotate(points[0]); } else if (points.count() == 3) { matrix.translate(points[1], points[2]); matrix.rotate(points[0]); matrix.translate(-points[1], -points[2]); } else { goto error; } } else if (state == Scale) { if (points.count() < 1 || points.count() > 2) goto error; qreal sx = points[0]; qreal sy = sx; if(points.count() == 2) sy = points[1]; matrix.scale(sx, sy); } else if (state == SkewX) { if (points.count() != 1) goto error; const qreal deg2rad = qreal(0.017453292519943295769); matrix.shear(tan(points[0]*deg2rad), 0); } else if (state == SkewY) { if (points.count() != 1) goto error; const qreal deg2rad = qreal(0.017453292519943295769); matrix.shear(0, tan(points[0]*deg2rad)); } } error: return matrix;}static void parsePen(QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *handler){ QString value = attributes.value(QLatin1String("stroke")).toString(); QString dashArray = attributes.value(QLatin1String("stroke-dasharray")).toString(); QString dashOffset = attributes.value(QLatin1String("stroke-dashoffset")).toString(); QString linecap = attributes.value(QLatin1String("stroke-linecap")).toString(); QString linejoin = attributes.value(QLatin1String("stroke-linejoin")).toString(); QString miterlimit = attributes.value(QLatin1String("stroke-miterlimit")).toString(); QString opacity = attributes.value(QLatin1String("stroke-opacity")).toString(); QString width = attributes.value(QLatin1String("stroke-width")).toString(); QString myId = someId(attributes); //qDebug()<<"Node "<<node->type()<<", attrs are "<<value<<width; if (!value.isEmpty() || !width.isEmpty() || !linecap.isEmpty() || linejoin.isEmpty()) { if (value != QLatin1String("none")) { QSvgStrokeStyle *inherited = static_cast<QSvgStrokeStyle*>(node->styleProperty( QSvgStyleProperty::STROKE)); if (!inherited) inherited = static_cast<QSvgStrokeStyle*>(node->parent()->styleProperty( QSvgStyleProperty::STROKE)); QPen pen(defaultPen); if (inherited) pen = inherited->qpen(); if (!value.isEmpty()) { if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); QString id = idFromUrl(value); QSvgStructureNode *group = 0; QSvgNode *dummy = node; while (dummy && (dummy->type() != QSvgNode::DOC && dummy->type() != QSvgNode::G && dummy->type() != QSvgNode::DEFS && dummy->type() != QSvgNode::SWITCH)) { dummy = dummy->parent(); } if (dummy) group = static_cast<QSvgStructureNode*>(dummy); if (group) { if (QSvgStyleProperty *style = group->scopeStyle(id)) { if (style->type() == QSvgStyleProperty::GRADIENT) { QBrush b(*((QSvgGradientStyle*)style)->qgradient()); pen.setBrush(b); } else if (style->type() == QSvgStyleProperty::SOLID_COLOR) { pen.setColor( ((QSvgSolidColorStyle*)style)->qcolor()); } } } else { qDebug()<<"QSvgHandler::parsePen no parent group?"; } } else { QColor color; if (constructColor(value, opacity, color, handler)) pen.setColor(color); } //since we could inherit stroke="none" //we need to reset the style of our stroke to something pen.setStyle(Qt::SolidLine); } if (!width.isEmpty()) { QSvgHandler::LengthType lt; qreal widthF = parseLength(width, lt, handler); //### fixme if (!widthF) { pen.setStyle(Qt::NoPen); return; } pen.setWidthF(widthF); } if (!linejoin.isEmpty()) { if (linejoin == QLatin1String("miter")) pen.setJoinStyle(Qt::SvgMiterJoin); else if (linejoin == QLatin1String("round")) pen.setJoinStyle(Qt::RoundJoin); else if (linejoin == QLatin1String("bevel")) pen.setJoinStyle(Qt::BevelJoin); } if (!linecap.isEmpty()) { if (linecap == QLatin1String("butt")) pen.setCapStyle(Qt::FlatCap); else if (linecap == QLatin1String("round")) pen.setCapStyle(Qt::RoundCap); else if (linecap == QLatin1String("square")) pen.setCapStyle(Qt::SquareCap); } qreal penw = pen.widthF(); if (!dashArray.isEmpty()) { const QChar *s = dashArray.constData(); QVector<qreal> dashes = parseNumbersList(s); qreal *d = dashes.data(); if(penw != 0) for (int i = 0; i < dashes.size(); ++i) { *d /= penw; ++d; } // if the dash count is odd the dashes should be duplicated if (dashes.size() % 2 != 0) dashes << QVector<qreal>(dashes); pen.setDashPattern(dashes); } if (!dashOffset.isEmpty()) { qreal doffset = ::toDouble(dashOffset); if (penw != 0) doffset /= penw; pen.setDashOffset(doffset); } if (!miterlimit.isEmpty()) pen.setMiterLimit(::toDouble(miterlimit)); node->appendStyleProperty(new QSvgStrokeStyle(pen), myId); } else { QPen pen(defaultPen); pen.setStyle(Qt::NoPen); node->appendStyleProperty(new QSvgStrokeStyle(pen), myId); } }}static bool parseQBrush(const QSvgAttributes &attributes, QSvgNode *node, QBrush &brush, QSvgHandler *handler){ QString value = attributes.value(QLatin1String("fill")).toString(); QString opacity = attributes.value(QLatin1String("fill-opacity")).toString(); QColor color; if (!value.isEmpty() || !opacity.isEmpty()) { if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); QString id = idFromUrl(value); QSvgStructureNode *group = 0; QSvgNode *dummy = node; while (dummy && (dummy->type() != QSvgNode::DOC && dummy->type() != QSvgNode::G && dummy->type() != QSvgNode::DEFS && dummy->type() != QSvgNode::SWITCH)) { dummy = dummy->parent(); } if (dummy) group = static_cast<QSvgStructureNode*>(dummy); if (group) { QSvgStyleProperty *style = group->scopeStyle(id); switch (style->type()) { case QSvgStyleProperty::FILL: { brush = static_cast<QSvgFillStyle*>(style)->qbrush(); break; } case QSvgStyleProperty::SOLID_COLOR: { brush = QBrush(static_cast<QSvgSolidColorStyle*>(style)->qcolor()); break; } case QSvgStyleProperty::GRADIENT: { brush = QBrush(*static_cast<QSvgGradientStyle*>(style)->qgradient()); break; } default: qWarning("Couldn't resolve property: %s", qPrintable(id)); } } } else if (value != QLatin1String("none")) { if (constructColor(value, opacity, color, handler)) { brush.setStyle(Qt::SolidPattern); brush.setColor(color); } } else { brush = QBrush(Qt::NoBrush); } return true; } return false;}static bool parseQFont(const QSvgAttributes &attributes, QFont &font, QSvgHandler *handler){ QString family = attributes.value(QLatin1String("font-family")).toString(); QString size = attributes.value(QLatin1String("font-size")).toString(); QString style = attributes.value(QLatin1String("font-style")).toString(); QString weight = attributes.value(QLatin1String("font-weight")).toString(); if (!family.isEmpty() || !size.isEmpty() || !style.isEmpty() || !weight.isEmpty()) { if (!family.isEmpty()) { font.setFamily(family.trimmed()); } if (!size.isEmpty()) { QSvgHandler::LengthType type; qreal len = parseLength(size, type, handler); //len = convertToPixels(len, false, type); // ### org_module.svg shows that font size // seems to be always in px... type = QSvgHandler::PX; if (type == QSvgHandler::PX || type == QSvgHandler::OTHER) font.setPixelSize(int(len)); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -