diff options
author | Liang Qi <liang.qi@qt.io> | 2017-04-21 11:10:10 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-04-21 11:10:10 +0200 |
commit | 1ef3d38562f686cf06b7a62be13cf9d3a23d0e41 (patch) | |
tree | 886e5c76aeabbb9b229bd64b9cb090e2a6bb395f /src/svg/qsvggenerator.cpp | |
parent | 4a9470e55ce08752501868c60762268fdf2c44af (diff) | |
parent | 0b48e0821b9691ff369ad7b401cbf1f63c6397a9 (diff) | |
download | qtsvg-1ef3d38562f686cf06b7a62be13cf9d3a23d0e41.tar.gz |
Merge remote-tracking branch 'origin/5.9' into dev
Change-Id: I855627bf0387be820d97bbc0226fed07fd1db64a
Diffstat (limited to 'src/svg/qsvggenerator.cpp')
-rw-r--r-- | src/svg/qsvggenerator.cpp | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 5829a1a..3f4e545 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -52,6 +52,7 @@ #include "qtextstream.h" #include "qbuffer.h" #include "qmath.h" +#include "qbitmap.h" #include "qdebug.h" @@ -128,6 +129,9 @@ public: QString currentGradientName; int numGradients; + QStringList savedPatternBrushes; + QStringList savedPatternMasks; + struct _attributes { QString document_title; QString document_description; @@ -145,12 +149,13 @@ static inline QPaintEngine::PaintEngineFeatures svgEngineFeatures() { return QPaintEngine::PaintEngineFeatures( QPaintEngine::AllFeatures - & ~QPaintEngine::PatternBrush & ~QPaintEngine::PerspectiveTransform & ~QPaintEngine::ConicalGradientFill & ~QPaintEngine::PorterDuff); } +Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); + class QSvgPaintEngine : public QPaintEngine { Q_DECLARE_PRIVATE(QSvgPaintEngine) @@ -212,6 +217,41 @@ public: Q_ASSERT(!isActive()); d_func()->resolution = resolution; } + + QString savePatternMask(Qt::BrushStyle style) + { + QString maskId = QString(QStringLiteral("patternmask%1")).arg(style); + if (!d_func()->savedPatternMasks.contains(maskId)) { + QImage img = qt_imageForBrush(style, true); + QRegion reg(QBitmap::fromData(img.size(), img.constBits())); + QString rct(QStringLiteral("<rect x=\"%1\" y=\"%2\" width=\"%3\" height=\"%4\" />")); + QTextStream str(&d_func()->defs, QIODevice::Append); + str << "<mask id=\"" << maskId << "\" x=\"0\" y=\"0\" width=\"8\" height=\"8\" " + << "stroke=\"none\" fill=\"#ffffff\" patternUnits=\"userSpaceOnUse\" >" << endl; + for (QRect r : reg.rects()) { + str << rct.arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height()) << endl; + } + str << QStringLiteral("</mask>") << endl << endl; + d_func()->savedPatternMasks.append(maskId); + } + return maskId; + } + + QString savePatternBrush(const QString &color, const QBrush &brush) + { + QString patternId = QString(QStringLiteral("fillpattern%1_")).arg(brush.style()) + color.midRef(1); + if (!d_func()->savedPatternBrushes.contains(patternId)) { + QString maskId = savePatternMask(brush.style()); + QString geo(QStringLiteral("x=\"0\" y=\"0\" width=\"8\" height=\"8\"")); + QTextStream str(&d_func()->defs, QIODevice::Append); + str << QString(QStringLiteral("<pattern id=\"%1\" %2 patternUnits=\"userSpaceOnUse\" >")).arg(patternId, geo) << endl; + str << QString(QStringLiteral("<rect %1 stroke=\"none\" fill=\"%2\" mask=\"url(#%3);\" />")).arg(geo, color, maskId) << endl; + str << QStringLiteral("</pattern>") << endl << endl; + d_func()->savedPatternBrushes.append(patternId); + } + return patternId; + } + void saveLinearGradientBrush(const QGradient *g) { QTextStream str(&d_func()->defs, QIODevice::Append); @@ -242,7 +282,7 @@ public: << QLatin1String("fx=\"") <<grad->focalPoint().x() << QLatin1String("\" ") << QLatin1String("fy=\"") <<grad->focalPoint().y() << QLatin1String("\" "); } - str << QLatin1String("xml:id=\"") <<d_func()->generateGradientName()<< QLatin1String("\">\n"); + str << QLatin1String("id=\"") <<d_func()->generateGradientName()<< QLatin1String("\">\n"); saveGradientStops(str, g); str << QLatin1String("</radialGradient>") << endl; } @@ -421,6 +461,28 @@ public: d_func()->attributes.fillOpacity = colorOpacity; } break; + case Qt::Dense1Pattern: + case Qt::Dense2Pattern: + case Qt::Dense3Pattern: + case Qt::Dense4Pattern: + case Qt::Dense5Pattern: + case Qt::Dense6Pattern: + case Qt::Dense7Pattern: + case Qt::HorPattern: + case Qt::VerPattern: + case Qt::CrossPattern: + case Qt::BDiagPattern: + case Qt::FDiagPattern: + case Qt::DiagCrossPattern: { + QString color, colorOpacity; + translate_color(sbrush.color(), &color, &colorOpacity); + QString patternId = savePatternBrush(color, sbrush); + QString patternRef = QString(QStringLiteral("url(#%1)")).arg(patternId); + stream() << "fill=\"" << patternRef << "\" fill-opacity=\"" << colorOpacity << "\" "; + d_func()->attributes.fill = patternRef; + d_func()->attributes.fillOpacity = colorOpacity; + break; + } case Qt::LinearGradientPattern: saveLinearGradientBrush(sbrush.gradient()); d_func()->attributes.fill = QString::fromLatin1("url(#%1)").arg(d_func()->currentGradientName); @@ -1062,7 +1124,7 @@ void QSvgPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QSvgPaintEngine); for (int i=0; i < rectCount; ++i) { - const QRectF &rect = rects[i]; + const QRectF &rect = rects[i].normalized(); *d->stream << "<rect"; if (state->pen().isCosmetic()) *d->stream << " vector-effect=\"non-scaling-stroke\""; |