diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2017-02-13 12:38:10 +0100 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2017-02-14 13:56:52 +0000 |
commit | 914e25bf01e6264dd80b6f27e50b45a578a7fe89 (patch) | |
tree | 90b852d8ad4d9a36997c2a1e4e79ae0ff6de7596 /src/svg/qsvggenerator.cpp | |
parent | 8ea914c667e3d021d6618915e694a4d8bed5fe9f (diff) | |
download | qtsvg-914e25bf01e6264dd80b6f27e50b45a578a7fe89.tar.gz |
Add support for pattern brushes to svg generator
Pattern brushes was not implemented in the svg generator. Shapes
drawn with such brushes would not be included in the svg file.
[ChangeLog][][QSvgGenerator] Add support for pattern brushes
Task-number: QTBUG-58148
Change-Id: Ib275661c596631fea64cb250c9743a529cd7b834
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src/svg/qsvggenerator.cpp')
-rw-r--r-- | src/svg/qsvggenerator.cpp | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 6af4370..de6e8d4 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); @@ -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); |