diff options
author | Kim Motoyoshi Kalland <kim.kalland@nokia.com> | 2009-08-21 15:44:57 (GMT) |
---|---|---|
committer | Kim Motoyoshi Kalland <kim.kalland@nokia.com> | 2009-08-24 12:16:23 (GMT) |
commit | 28ac217b04abaa4d226e43e402c14a88539fca3b (patch) | |
tree | a9eaaba34af3f1e929510972fdf5faacf31b0043 /src/svg/qsvghandler.cpp | |
parent | 7ee27ef732572e0eefe4d1c6dadec4a5ab077637 (diff) | |
download | Qt-28ac217b04abaa4d226e43e402c14a88539fca3b.zip Qt-28ac217b04abaa4d226e43e402c14a88539fca3b.tar.gz Qt-28ac217b04abaa4d226e43e402c14a88539fca3b.tar.bz2 |
Fixed SVG stroke attributes to work with 'use' tags.
In the process of rewriting the stroke handling code, I also fixed
gradients on strokes.
Task-number: 202426, 250618
Reviewed-by: Trond
Diffstat (limited to 'src/svg/qsvghandler.cpp')
-rw-r--r-- | src/svg/qsvghandler.cpp | 188 |
1 files changed, 70 insertions, 118 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index adfe468..5c0eda9 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -493,8 +493,7 @@ static bool resolveColor(const QString &colorStr, QColor &color, QSvgHandler *ha int(compo[1]), int(compo[2])); return true; - } else if (colorStr == QLatin1String("inherited") || - colorStr == QT_INHERIT) { + } else if (colorStr == QT_INHERIT) { return false; } else if (colorStr == QLatin1String("currentColor")) { color = handler->currentColor(); @@ -649,7 +648,7 @@ static void parseBrush(QSvgNode *node, QString myId = someId(attributes); if (!value.isEmpty() || !fillRule.isEmpty() || !opacity.isEmpty()) { - QSvgFillStyle *prop = new QSvgFillStyle(0); + QSvgFillStyle *prop = new QSvgFillStyle; //fill-rule attribute handling if (!fillRule.isEmpty() && fillRule != QT_INHERIT) { @@ -670,7 +669,8 @@ static void parseBrush(QSvgNode *node, value = value.remove(0, 3); QSvgStyleProperty *style = styleFromUrl(node, value); if (style) { - prop->setFillStyle(style); + if (style->type() == QSvgStyleProperty::SOLID_COLOR || style->type() == QSvgStyleProperty::GRADIENT) + prop->setFillStyle(reinterpret_cast<QSvgFillStyleProperty *>(style)); } else { QString id = idFromUrl(value); prop->setGradientId(id); @@ -834,154 +834,95 @@ static void parsePen(QSvgNode *node, //qDebug()<<"Node "<<node->type()<<", attrs are "<<value<<width; - if (!value.isEmpty() || !width.isEmpty() || !dashArray.isEmpty() || !linecap.isEmpty() || - !linejoin.isEmpty() || !miterlimit.isEmpty() || !opacity.isEmpty() || - !dashOffset.isEmpty() || !vectorEffect.isEmpty()) { + if (!value.isEmpty() || !dashArray.isEmpty() || !dashOffset.isEmpty() || !linecap.isEmpty() + || !linejoin.isEmpty() || !miterlimit.isEmpty() || !opacity.isEmpty() || !width.isEmpty() + || !vectorEffect.isEmpty()) { - QSvgStrokeStyle *inherited = - static_cast<QSvgStrokeStyle*>(node->parent()->styleProperty( - QSvgStyleProperty::STROKE)); - - QPen pen(handler->defaultPen()); - bool stroke = false; - if (inherited) { - pen = inherited->qpen(); - stroke = inherited->strokePresent(); - } - - // stroke-opacity attribute handling - qreal strokeAlpha; - if (!opacity.isEmpty() && opacity != QT_INHERIT) { - strokeAlpha = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); - } else { - strokeAlpha = pen.color().alphaF(); - } + QSvgStrokeStyle *prop = new QSvgStrokeStyle; //stroke attribute handling - if (!value.isEmpty() && value != QT_INHERIT) { + if ((!value.isEmpty()) && (value != QT_INHERIT) ) { if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); QSvgStyleProperty *style = styleFromUrl(node, value); if (style) { - 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()); - } - stroke = true; + if (style->type() == QSvgStyleProperty::SOLID_COLOR || style->type() == QSvgStyleProperty::GRADIENT) + prop->setStyle(reinterpret_cast<QSvgFillStyleProperty *>(style)); } else { - qWarning() << "QSvgHandler::parsePen could not resolve property" << idFromUrl(value); + QString id = idFromUrl(value); + prop->setGradientId(id); + prop->setGradientResolved(false); } - } else if (value == QLatin1String("none")) { - QColor color; //### fixme: dafalut value for color. - color.setAlphaF(strokeAlpha); - pen.setColor(color); - stroke = false; // This is required because, parent may have a valid stroke but the child may have stroke = "none" - } else { + } else if (value != QLatin1String("none")) { QColor color; - if (resolveColor(value, color, handler)) { - color.setAlphaF(strokeAlpha); - pen.setColor(color); - } - stroke = true; + if (resolveColor(value, color, handler)) + prop->setStroke(QBrush(color)); + } else { + prop->setStroke(QBrush(Qt::NoBrush)); } - } else { - QColor color = pen.color(); - color.setAlphaF(strokeAlpha); - pen.setColor(color); } //stroke-width handling + qreal w = 0; if (!width.isEmpty() && width != QT_INHERIT) { - qreal widthF; QSvgHandler::LengthType lt; - widthF = parseLength(width, lt, handler); - pen.setWidthF(widthF); + prop->setWidth(w = parseLength(width, lt, handler)); + } + + //stroke-dasharray + if (!dashArray.isEmpty() && dashArray != QT_INHERIT) { + if (dashArray == QLatin1String("none")) { + prop->setDashArrayNone(); + } else { + const QChar *s = dashArray.constData(); + QVector<qreal> dashes = parseNumbersList(s); + // if the dash count is odd the dashes should be duplicated + if ((dashes.size() & 1) != 0) + dashes << QVector<qreal>(dashes); + prop->setDashArray(dashes); + } } //stroke-linejoin attribute handling if (!linejoin.isEmpty()) { if (linejoin == QLatin1String("miter")) - pen.setJoinStyle(Qt::SvgMiterJoin); + prop->setLineJoin(Qt::SvgMiterJoin); else if (linejoin == QLatin1String("round")) - pen.setJoinStyle(Qt::RoundJoin); + prop->setLineJoin(Qt::RoundJoin); else if (linejoin == QLatin1String("bevel")) - pen.setJoinStyle(Qt::BevelJoin); + prop->setLineJoin(Qt::BevelJoin); } //stroke-linecap attribute handling if (!linecap.isEmpty()) { if (linecap == QLatin1String("butt")) - pen.setCapStyle(Qt::FlatCap); + prop->setLineCap(Qt::FlatCap); else if (linecap == QLatin1String("round")) - pen.setCapStyle(Qt::RoundCap); + prop->setLineCap(Qt::RoundCap); else if (linecap == QLatin1String("square")) - pen.setCapStyle(Qt::SquareCap); - } - - //strok-dasharray attribute handling - qreal penw = pen.widthF(); - if (!dashArray.isEmpty() && dashArray != QT_INHERIT) { - 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); - } else if (inherited) { - QVector<qreal> dashes(inherited->qpen().dashPattern()); - qreal *d = dashes.data(); - if (!penw) - penw = 1.0; - qreal inheritpenw = inherited->qpen().widthF(); - if (!inheritpenw) - inheritpenw = 1.0; - for ( int i = 0; i < dashes.size(); ++i) { - *d *= (inheritpenw/ penw); - ++d; - } - pen.setDashPattern(dashes); + prop->setLineCap(Qt::SquareCap); } - //stroke-dashoffset attribute handling - if (!dashOffset.isEmpty() && dashOffset != QT_INHERIT) { - qreal doffset = toDouble(dashOffset); - if (penw != 0) - doffset /= penw; - pen.setDashOffset(doffset); - } else if (inherited) { - qreal doffset = pen.dashOffset(); - if (!penw) - penw = 1.0; - qreal inheritpenw = inherited->qpen().widthF(); - if (!inheritpenw) - inheritpenw = 1.0; - doffset *= (inheritpenw/ penw); - pen.setDashOffset(doffset); - } + if (!dashOffset.isEmpty() && dashOffset != QT_INHERIT) + prop->setDashOffset(toDouble(dashOffset)); //vector-effect attribute handling if (!vectorEffect.isEmpty()) { if (vectorEffect == QLatin1String("non-scaling-stroke")) - pen.setCosmetic(true); + prop->setVectorEffect(true); else if (vectorEffect == QLatin1String("none")) - pen.setCosmetic(false); + prop->setVectorEffect(false); } + //stroke-miterlimit if (!miterlimit.isEmpty() && miterlimit != QT_INHERIT) - pen.setMiterLimit(toDouble(miterlimit)); + prop->setMiterLimit(toDouble(miterlimit)); + + //stroke-opacity atttribute handling + if (!opacity.isEmpty() && opacity != QT_INHERIT) + prop->setOpacity(qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)))); - QSvgStrokeStyle *prop = new QSvgStrokeStyle(pen); - prop->setStroke(stroke); node->appendStyleProperty(prop, myId); } } @@ -2770,7 +2711,7 @@ static bool parseStopNode(QSvgStyleProperty *parent, colorStr = QLatin1String("#000000"); } - bool colorOK = constructColor(colorStr, opacityStr, color, handler); + constructColor(colorStr, opacityStr, color, handler); QGradient *grad = style->qgradient(); @@ -2794,8 +2735,6 @@ static bool parseStopNode(QSvgStyleProperty *parent, grad->setColorAt(offset, color); style->setGradientStopsSet(true); - if (!colorOK) - style->addResolve(offset); return true; } @@ -3422,15 +3361,28 @@ bool QSvgHandler::endElement(const QStringRef &localName) QList<QSvgNode*>::iterator itr = ren.begin(); while (itr != ren.end()) { QSvgNode *eleNode = *itr++; - QSvgFillStyle *prop = static_cast<QSvgFillStyle*>(eleNode->styleProperty(QSvgStyleProperty::FILL)); - if (prop && !(prop->isGradientResolved())) { - QString id = prop->getGradientId(); + QSvgFillStyle *fill = static_cast<QSvgFillStyle*>(eleNode->styleProperty(QSvgStyleProperty::FILL)); + if (fill && !(fill->isGradientResolved())) { + QString id = fill->gradientId(); + QSvgStyleProperty *style = structureNode->scopeStyle(id); + if (style) { + if (style->type() == QSvgStyleProperty::SOLID_COLOR || style->type() == QSvgStyleProperty::GRADIENT) + fill->setFillStyle(reinterpret_cast<QSvgFillStyleProperty *>(style)); + } else { + qWarning("Couldn't resolve property : %s",qPrintable(id)); + fill->setBrush(QBrush(Qt::NoBrush)); + } + } + QSvgStrokeStyle *stroke = static_cast<QSvgStrokeStyle*>(eleNode->styleProperty(QSvgStyleProperty::STROKE)); + if (stroke && !(stroke->isGradientResolved())) { + QString id = stroke->gradientId(); QSvgStyleProperty *style = structureNode->scopeStyle(id); if (style) { - prop->setFillStyle(style); + if (style->type() == QSvgStyleProperty::SOLID_COLOR || style->type() == QSvgStyleProperty::GRADIENT) + stroke->setStyle(reinterpret_cast<QSvgFillStyleProperty *>(style)); } else { qWarning("Couldn't resolve property : %s",qPrintable(id)); - prop->setBrush(QBrush(Qt::NoBrush)); + stroke->setStroke(QBrush(Qt::NoBrush)); } } } |