summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-05-24 13:40:31 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2019-05-24 15:21:05 +0200
commit14fa4591eb34a35cf3d485fd901e3f1e2caa7770 (patch)
tree892b767206e6d44513c1a01390fe504c66098e68 /src
parent357a5bd4d6682a50d85c88ba485ed34c745fae85 (diff)
downloadqtsvg-14fa4591eb34a35cf3d485fd901e3f1e2caa7770.tar.gz
Fix rendering of SVGs with viewBoxes
The presence of the viewBox attribute in the svg tag implies the presence of the preserveAspectRatio attribute as well. It defaults to scaling the view box to the view port while preserving the aspect ratio and the box is also centered. This patch does not implement the full preserveAspectRatio attribute, but it does implement the default of aspect ratio preservation and centering, as that is what caused the rendering error in the linked task. This causes some tests in the SVG Tiny 1.2 test suite to differ. This is visible using the rendertestsuite helper program (see other change). In particular it corrects the rendering of struct-svg-203-t.svg to correctly center the text and avoid scaling it. For animate-elem-38-t.svg the rendering improved by making the entire text visible, as in the reference. The same applies to media-video-216-t.svg. In both rendering the scaling changes slightly. Done-With: Rainer Keller <rainer.keller@qt.io> Fixes: QTBUG-70256 Change-Id: I9142c511890765993ee3e316f0383550919fdcd4 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/svg/qsvgtinydocument.cpp38
-rw-r--r--src/svg/qsvgtinydocument_p.h5
2 files changed, 34 insertions, 9 deletions
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index da464cc..77aafb4 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -339,6 +339,7 @@ void QSvgTinyDocument::setHeight(int len, bool percent)
void QSvgTinyDocument::setViewBox(const QRectF &rect)
{
m_viewBox = rect;
+ m_implicitViewBox = false;
}
void QSvgTinyDocument::addSvgFont(QSvgFont *font)
@@ -420,14 +421,35 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
source = viewBox();
if (source != target && !source.isNull()) {
- QTransform transform;
- transform.scale(target.width() / source.width(),
- target.height() / source.height());
- QRectF c2 = transform.mapRect(source);
- p->translate(target.x() - c2.x(),
- target.y() - c2.y());
- p->scale(target.width() / source.width(),
- target.height() / source.height());
+ if (m_implicitViewBox) {
+ QTransform transform;
+ transform.scale(target.width() / source.width(),
+ target.height() / source.height());
+ QRectF c2 = transform.mapRect(source);
+ p->translate(target.x() - c2.x(),
+ target.y() - c2.y());
+ p->scale(target.width() / source.width(),
+ target.height() / source.height());
+ } 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());
+
+ // 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->scale(viewBoxSize.width() / source.width(),
+ viewBoxSize.height() / source.height());
+ }
}
}
diff --git a/src/svg/qsvgtinydocument_p.h b/src/svg/qsvgtinydocument_p.h
index aa51751..5f5d06b 100644
--- a/src/svg/qsvgtinydocument_p.h
+++ b/src/svg/qsvgtinydocument_p.h
@@ -125,6 +125,7 @@ private:
bool m_widthPercent;
bool m_heightPercent;
+ mutable bool m_implicitViewBox = true;
mutable QRectF m_viewBox;
QHash<QString, QSvgRefCounter<QSvgFont> > m_fonts;
@@ -173,8 +174,10 @@ inline bool QSvgTinyDocument::heightPercent() const
inline QRectF QSvgTinyDocument::viewBox() const
{
- if (m_viewBox.isNull())
+ if (m_viewBox.isNull()) {
m_viewBox = transformedBounds();
+ m_implicitViewBox = true;
+ }
return m_viewBox;
}