diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-02-12 09:54:18 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-02-12 09:54:18 +0100 |
commit | 41aa1dc3afa11c52d12cb5c2b7c69d0c8d36763e (patch) | |
tree | 92cd4c1a3d8532fe3e17ef6c5f85bdc595fc8b81 /src/svg | |
parent | cf932594dcc9fa3e701e6cd8f564aa9fc3277563 (diff) | |
parent | 0ecf1ff936e43f1d6978bdd2001acfabf3c7aaee (diff) | |
download | qtsvg-41aa1dc3afa11c52d12cb5c2b7c69d0c8d36763e.tar.gz |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Change-Id: I35cfe1a52ec4a02dccc0895e3b4a40bd2ffe7295
Diffstat (limited to 'src/svg')
-rw-r--r-- | src/svg/qsvggenerator.cpp | 5 | ||||
-rw-r--r-- | src/svg/qsvghandler.cpp | 23 | ||||
-rw-r--r-- | src/svg/qsvgrenderer.cpp | 56 | ||||
-rw-r--r-- | src/svg/qsvgrenderer.h | 9 | ||||
-rw-r--r-- | src/svg/qsvgstyle.cpp | 8 | ||||
-rw-r--r-- | src/svg/qsvgstyle_p.h | 10 | ||||
-rw-r--r-- | src/svg/qsvgtinydocument.cpp | 37 | ||||
-rw-r--r-- | src/svg/qsvgtinydocument_p.h | 7 | ||||
-rw-r--r-- | src/svg/qsvgwidget.cpp | 4 |
9 files changed, 106 insertions, 53 deletions
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 360b02b..59dd7fc 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -53,6 +53,7 @@ #include "qbuffer.h" #include "qmath.h" #include "qbitmap.h" +#include "qtransform.h" #include "qdebug.h" @@ -117,7 +118,7 @@ public: QBrush brush; QPen pen; - QMatrix matrix; + QTransform matrix; QFont font; QString generateGradientName() { @@ -1009,7 +1010,7 @@ void QSvgPaintEngine::updateState(const QPaintEngineState &state) } if (flags & QPaintEngine::DirtyTransform) { - d->matrix = state.transform().toAffine(); + d->matrix = state.transform(); *d->stream << "transform=\"matrix(" << d->matrix.m11() << ',' << d->matrix.m12() << ',' << d->matrix.m21() << ',' << d->matrix.m22() << ',' diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 86ca77e..64a2bdc 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -60,6 +60,7 @@ #include "qmath.h" #include "qnumeric.h" #include <qregularexpression.h> +#include "qtransform.h" #include "qvarlengtharray.h" #include "private/qmath_p.h" @@ -1068,12 +1069,12 @@ static void parseBrush(QSvgNode *node, -static QMatrix parseTransformationMatrix(const QStringRef &value) +static QTransform parseTransformationMatrix(const QStringRef &value) { if (value.isEmpty()) - return QMatrix(); + return QTransform(); - QMatrix matrix; + QTransform matrix; const QChar *str = value.constData(); const QChar *end = str + value.length(); @@ -1156,9 +1157,9 @@ static QMatrix parseTransformationMatrix(const QStringRef &value) if(state == Matrix) { if(points.count() != 6) goto error; - matrix = QMatrix(points[0], points[1], - points[2], points[3], - points[4], points[5]) * matrix; + matrix = QTransform(points[0], points[1], + points[2], points[3], + points[4], points[5]) * matrix; } else if (state == Translate) { if (points.count() == 1) matrix.translate(points[0], 0); @@ -1435,7 +1436,7 @@ static void parseTransform(QSvgNode *node, { if (attributes.transform.isEmpty()) return; - QMatrix matrix = parseTransformationMatrix(trimRef(attributes.transform)); + QTransform matrix = parseTransformationMatrix(trimRef(attributes.transform)); if (!matrix.isIdentity()) { node->appendStyleProperty(new QSvgTransformStyle(QTransform(matrix)), attributes.id); @@ -2846,7 +2847,7 @@ static void parseBaseGradient(QSvgNode *node, handler->pushColor(color); } - QMatrix matrix; + QTransform matrix; QGradient *grad = gradProp->qgradient(); if (!link.isEmpty()) { QSvgStyleProperty *prop = node->styleProperty(link); @@ -2861,7 +2862,7 @@ static void parseBaseGradient(QSvgNode *node, gradProp->setGradientStopsSet(inherited->gradientStopsSet()); } - matrix = inherited->qmatrix(); + matrix = inherited->qtransform(); } else { gradProp->setStopLink(link, handler->document()); } @@ -2869,9 +2870,9 @@ static void parseBaseGradient(QSvgNode *node, if (!trans.isEmpty()) { matrix = parseTransformationMatrix(trans); - gradProp->setMatrix(matrix); + gradProp->setTransform(matrix); } else if (!matrix.isIdentity()) { - gradProp->setMatrix(matrix); + gradProp->setTransform(matrix); } if (!spread.isEmpty()) { diff --git a/src/svg/qsvgrenderer.cpp b/src/svg/qsvgrenderer.cpp index d4ad373..7cc7968 100644 --- a/src/svg/qsvgrenderer.cpp +++ b/src/svg/qsvgrenderer.cpp @@ -45,6 +45,7 @@ #include "qbytearray.h" #include "qtimer.h" +#include "qtransform.h" #include "qdebug.h" #include "private/qobject_p.h" @@ -256,6 +257,41 @@ void QSvgRenderer::setFramesPerSecond(int num) } /*! + \property QSvgRenderer::aspectRatioMode + + \brief how rendering adheres to the SVG view box aspect ratio + + The accepted modes are: + \list + \li Qt::IgnoreAspectRatio (the default): the aspect ratio is ignored and the + rendering is stretched to the target bounds. + \li Qt::KeepAspectRatio: rendering is centered and scaled as large as possible + within the target bounds while preserving aspect ratio. + \endlist + + \since 5.15 +*/ + +Qt::AspectRatioMode QSvgRenderer::aspectRatioMode() const +{ + Q_D(const QSvgRenderer); + if (d->render && d->render->preserveAspectRatio()) + return Qt::KeepAspectRatio; + return Qt::IgnoreAspectRatio; +} + +void QSvgRenderer::setAspectRatioMode(Qt::AspectRatioMode mode) +{ + Q_D(QSvgRenderer); + if (d->render) { + if (mode == Qt::KeepAspectRatio) + d->render->setPreserveAspectRatio(true); + else if (mode == Qt::IgnoreAspectRatio) + d->render->setPreserveAspectRatio(false); + } +} + +/*! \property QSvgRenderer::currentFrame \brief the current frame of the document's animation, or 0 if the document is not animated \internal @@ -401,10 +437,10 @@ void QSvgRenderer::render(QPainter *painter, const QString &elementId, } /*! - Renders the current document, or the current frame of an animated - document, using the given \a painter on the specified \a bounds within - the painter. If the bounding rectangle is not specified - the SVG file is mapped to the whole paint device. + Renders the current document, or the current frame of an animated document, + using the given \a painter on the specified \a bounds within the painter. + If \a bounds is not empty, the output will be scaled to fill it, ignoring + any aspect ratio implied by the SVG. */ void QSvgRenderer::render(QPainter *painter, const QRectF &bounds) { @@ -437,7 +473,7 @@ void QSvgRenderer::setViewBox(const QRectF &viewbox) The transformation matrix of parent elements is not affecting the bounds of the element. - \sa matrixForElement() + \sa transformForElement() */ QRectF QSvgRenderer::boundsOnElement(const QString &id) const { @@ -472,7 +508,7 @@ bool QSvgRenderer::elementExists(const QString &id) const } /*! - \since 4.2 + \since 5.15 Returns the transformation matrix for the element with the given \a id. The matrix is a product of @@ -484,13 +520,13 @@ bool QSvgRenderer::elementExists(const QString &id) const \sa boundsOnElement() */ -QMatrix QSvgRenderer::matrixForElement(const QString &id) const +QTransform QSvgRenderer::transformForElement(const QString &id) const { Q_D(const QSvgRenderer); - QMatrix mat; + QTransform trans; if (d->render) - mat = d->render->matrixForElement(id); - return mat; + trans = d->render->transformForElement(id); + return trans; } QT_END_NAMESPACE diff --git a/src/svg/qsvgrenderer.h b/src/svg/qsvgrenderer.h index 4413509..418da85 100644 --- a/src/svg/qsvgrenderer.h +++ b/src/svg/qsvgrenderer.h @@ -40,8 +40,6 @@ #ifndef QSVGRENDERER_H #define QSVGRENDERER_H -#include <QtGui/qmatrix.h> - #ifndef QT_NO_SVGRENDERER #include <QtCore/qobject.h> @@ -56,6 +54,7 @@ QT_BEGIN_NAMESPACE class QSvgRendererPrivate; class QPainter; class QByteArray; +class QTransform; class Q_SVG_EXPORT QSvgRenderer : public QObject { @@ -64,6 +63,7 @@ class Q_SVG_EXPORT QSvgRenderer : public QObject Q_PROPERTY(QRectF viewBox READ viewBoxF WRITE setViewBox) Q_PROPERTY(int framesPerSecond READ framesPerSecond WRITE setFramesPerSecond) Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode) public: QSvgRenderer(QObject *parent = nullptr); QSvgRenderer(const QString &filename, QObject *parent = nullptr); @@ -80,6 +80,9 @@ public: void setViewBox(const QRect &viewbox); void setViewBox(const QRectF &viewbox); + Qt::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(Qt::AspectRatioMode mode); + bool animated() const; int framesPerSecond() const; void setFramesPerSecond(int num); @@ -89,7 +92,7 @@ public: QRectF boundsOnElement(const QString &id) const; bool elementExists(const QString &id) const; - QMatrix matrixForElement(const QString &id) const; + QTransform transformForElement(const QString &id) const; public Q_SLOTS: bool load(const QString &filename); diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index c4edd25..f981931 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -421,16 +421,16 @@ QBrush QSvgGradientStyle::brush(QPainter *, QSvgExtraStates &) QBrush b(*m_gradient); - if (!m_matrix.isIdentity()) - b.setMatrix(m_matrix); + if (!m_transform.isIdentity()) + b.setTransform(m_transform); return b; } -void QSvgGradientStyle::setMatrix(const QMatrix &mat) +void QSvgGradientStyle::setTransform(const QTransform &transform) { - m_matrix = mat; + m_transform = transform; } QSvgTransformStyle::QSvgTransformStyle(const QTransform &trans) diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index 39aa690..9dd4f53 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -54,7 +54,7 @@ #include "QtGui/qpainter.h" #include "QtGui/qpen.h" #include "QtGui/qbrush.h" -#include "QtGui/qmatrix.h" +#include "QtGui/qtransform.h" #include "QtGui/qcolor.h" #include "QtGui/qfont.h" #include <qdebug.h> @@ -579,10 +579,10 @@ public: void resolveStops(); void resolveStops_helper(QStringList *visited); - void setMatrix(const QMatrix &matrix); - QMatrix qmatrix() const + void setTransform(const QTransform &transform); + QTransform qtransform() const { - return m_matrix; + return m_transform; } QGradient *qgradient() const @@ -603,7 +603,7 @@ public: QBrush brush(QPainter *, QSvgExtraStates &) override; private: QGradient *m_gradient; - QMatrix m_matrix; + QTransform m_transform; QSvgTinyDocument *m_doc; QString m_link; diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp index 3143ad2..b4b9526 100644 --- a/src/svg/qsvgtinydocument.cpp +++ b/src/svg/qsvgtinydocument.cpp @@ -48,6 +48,7 @@ #include "qbytearray.h" #include "qqueue.h" #include "qstack.h" +#include "qtransform.h" #include "qdebug.h" #ifndef QT_NO_COMPRESS @@ -335,10 +336,15 @@ void QSvgTinyDocument::setHeight(int len, bool percent) m_heightPercent = percent; } +void QSvgTinyDocument::setPreserveAspectRatio(bool on) +{ + m_preserveAspectRatio = on; +} + void QSvgTinyDocument::setViewBox(const QRectF &rect) { m_viewBox = rect; - m_implicitViewBox = false; + m_implicitViewBox = rect.isNull(); } void QSvgTinyDocument::addSvgFont(QSvgFont *font) @@ -420,7 +426,10 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, source = viewBox(); if (source != target && !source.isNull()) { - if (m_implicitViewBox) { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + if (m_implicitViewBox || !preserveAspectRatio()) { + // Code path used when no view box is set, or IgnoreAspectRatio requested +#endif QTransform transform; transform.scale(target.width() / source.width(), target.height() / source.height()); @@ -429,26 +438,26 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, target.y() - c2.y()); p->scale(target.width() / source.width(), target.height() / source.height()); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) } else { - // Code path used when a view box is specified and we're not rendering a specific element by id - // but the entire document. This attempts to emulate the default values of the <preserveAspectRatio> - // tag that's implicitly defined when <viewbox> is used. - - // Apply the view box translation if specified. - p->translate(target.x() - source.x(), - target.y() - source.y()); + // Code path used when KeepAspectRatio is requested. This attempts to emulate the default values + // of the <preserveAspectRatio tag that's implicitly defined when <viewbox> is used. // Scale the view box into the view port (target) by preserve the aspect ratio. QSizeF viewBoxSize = source.size(); viewBoxSize.scale(target.width(), target.height(), Qt::KeepAspectRatio); // Center the view box in the view port - p->translate((target.width() - viewBoxSize.width()) / 2, - (target.height() - viewBoxSize.height()) / 2); + p->translate(target.x() + (target.width() - viewBoxSize.width()) / 2, + target.y() + (target.height() - viewBoxSize.height()) / 2); p->scale(viewBoxSize.width() / source.width(), viewBoxSize.height() / source.height()); + + // Apply the view box translation if specified. + p->translate(-source.x(), -source.y()); } +#endif } } @@ -467,13 +476,13 @@ bool QSvgTinyDocument::elementExists(const QString &id) const return (node!=0); } -QMatrix QSvgTinyDocument::matrixForElement(const QString &id) const +QTransform QSvgTinyDocument::transformForElement(const QString &id) const { QSvgNode *node = scopeNode(id); if (!node) { qCDebug(lcSvgHandler, "Couldn't find node %s. Skipping rendering.", qPrintable(id)); - return QMatrix(); + return QTransform(); } QTransform t; @@ -485,7 +494,7 @@ QMatrix QSvgTinyDocument::matrixForElement(const QString &id) const node = node->parent(); } - return t.toAffine(); + return t; } int QSvgTinyDocument::currentFrame() const diff --git a/src/svg/qsvgtinydocument_p.h b/src/svg/qsvgtinydocument_p.h index 404587d..d4b92e8 100644 --- a/src/svg/qsvgtinydocument_p.h +++ b/src/svg/qsvgtinydocument_p.h @@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE class QPainter; class QByteArray; class QSvgFont; +class QTransform; class Q_SVG_PRIVATE_EXPORT QSvgTinyDocument : public QSvgStructureNode { @@ -88,6 +89,7 @@ public: bool heightPercent() const; bool preserveAspectRatio() const; + void setPreserveAspectRatio(bool on); QRectF viewBox() const; void setViewBox(const QRectF &rect); @@ -99,7 +101,7 @@ public: void draw(QPainter *p, const QString &id, const QRectF &bounds=QRectF()); - QMatrix matrixForElement(const QString &id) const; + QTransform transformForElement(const QString &id) const; QRectF boundsOnElement(const QString &id) const; bool elementExists(const QString &id) const; @@ -127,6 +129,7 @@ private: mutable bool m_implicitViewBox = true; mutable QRectF m_viewBox; + bool m_preserveAspectRatio = false; QHash<QString, QSvgRefCounter<QSvgFont> > m_fonts; QHash<QString, QSvgNode *> m_namedNodes; @@ -184,7 +187,7 @@ inline QRectF QSvgTinyDocument::viewBox() const inline bool QSvgTinyDocument::preserveAspectRatio() const { - return false; + return m_preserveAspectRatio; } inline int QSvgTinyDocument::currentElapsed() const diff --git a/src/svg/qsvgwidget.cpp b/src/svg/qsvgwidget.cpp index 4b86306..acc8cca 100644 --- a/src/svg/qsvgwidget.cpp +++ b/src/svg/qsvgwidget.cpp @@ -90,7 +90,7 @@ public: Constructs a new SVG display widget with the given \a parent. */ QSvgWidget::QSvgWidget(QWidget *parent) - : QWidget(*new QSvgWidgetPrivate, parent, 0) + : QWidget(*new QSvgWidgetPrivate, parent, {}) { d_func()->renderer = new QSvgRenderer(this); QObject::connect(d_func()->renderer, SIGNAL(repaintNeeded()), @@ -102,7 +102,7 @@ QSvgWidget::QSvgWidget(QWidget *parent) of the specified \a file. */ QSvgWidget::QSvgWidget(const QString &file, QWidget *parent) - : QWidget(*new QSvgWidgetPrivate, parent, 0) + : QWidget(*new QSvgWidgetPrivate, parent, {}) { d_func()->renderer = new QSvgRenderer(file, this); QObject::connect(d_func()->renderer, SIGNAL(repaintNeeded()), |