determine svg image size

workaround for qt5.9's poor handling of svgRenderer and viewBox
This commit is contained in:
konero 2023-07-09 13:34:08 +01:00
parent 73d9bdda64
commit c6ff89c397
2 changed files with 58 additions and 6 deletions

View file

@ -54,10 +54,6 @@ class TStroke;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QString DVAPI getIconThemePath(const QString &filePath);
//-----------------------------------------------------------------------------
QString DVAPI fileSizeString(qint64 size, int precision = 2); QString DVAPI fileSizeString(qint64 size, int precision = 2);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -106,6 +102,11 @@ SvgRenderParams calculateSvgRenderParams(const QSize &desiredSize,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Workaround issue with QT5.9's svgRenderer not handling viewBox very well
QSize determineSvgSize(const QString &svgFilePath);
//-----------------------------------------------------------------------------
QPixmap DVAPI QPixmap DVAPI
svgToPixmap(const QString &svgFilePath, QSize size = QSize(), svgToPixmap(const QString &svgFilePath, QSize size = QSize(),
Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio,

View file

@ -34,6 +34,7 @@
#include <QSvgRenderer> #include <QSvgRenderer>
#include <QScreen> #include <QScreen>
#include <QWindow> #include <QWindow>
#include <QXmlStreamReader>
#include <QDebug> #include <QDebug>
using namespace DVGui; using namespace DVGui;
@ -236,6 +237,48 @@ SvgRenderParams calculateSvgRenderParams(const QSize &desiredSize,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Workaround issue with QT5.9's svgRenderer not handling viewBox very well
QSize determineSvgSize(const QString &svgFilePath) {
QFile file(svgFilePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return QSize();
}
QXmlStreamReader xml(&file);
int width = 0;
int height = 0;
while (!xml.atEnd() && !xml.hasError()) {
QXmlStreamReader::TokenType token = xml.readNext();
if (token == QXmlStreamReader::StartDocument) {
continue;
}
if (token == QXmlStreamReader::StartElement) {
if (xml.name() == "svg") {
foreach (const QXmlStreamAttribute &attr, xml.attributes()) {
if (attr.name().toString() == "viewBox") {
QStringList parts = attr.value().toString().split(" ");
if (parts.size() == 4) {
width = parts[2].toInt();
height = parts[3].toInt();
}
}
}
}
}
}
if (xml.hasError()) {
qDebug() << "Error handling XML to determine SVG image size";
}
file.close();
return QSize(width, height);
}
//-----------------------------------------------------------------------------
QPixmap svgToPixmap(const QString &svgFilePath, QSize size, QPixmap svgToPixmap(const QString &svgFilePath, QSize size,
Qt::AspectRatioMode aspectRatioMode, QColor bgColor) { Qt::AspectRatioMode aspectRatioMode, QColor bgColor) {
if (svgFilePath.isEmpty()) return QPixmap(); if (svgFilePath.isEmpty()) return QPixmap();
@ -285,7 +328,13 @@ QImage svgToImage(const QString &svgFilePath, QSize size,
static int devPixRatio = getHighestDevicePixelRatio(); static int devPixRatio = getHighestDevicePixelRatio();
QSize imageSize = svgRenderer.defaultSize() * devPixRatio; // Determine SVG image size: there is a problem with QT5.9's svgRenderer
// not handling viewBox very well, so we'll calculate the image size a
// different way depending if the SVG uses width and height or viewBox.
QSize imageSize = determineSvgSize(svgFilePath) * devPixRatio;
if (imageSize.isNull())
imageSize = QSize(svgRenderer.defaultSize() * devPixRatio);
SvgRenderParams params = SvgRenderParams params =
calculateSvgRenderParams(size, imageSize, aspectRatioMode); calculateSvgRenderParams(size, imageSize, aspectRatioMode);
QImage image(params.size, QImage::Format_ARGB32_Premultiplied); QImage image(params.size, QImage::Format_ARGB32_Premultiplied);
@ -495,7 +544,9 @@ QIcon createQIcon(const QString &iconSVGName, bool useFullOpacity,
// Set an empty pixmap for menu icons when hiding icons from menus is true, // Set an empty pixmap for menu icons when hiding icons from menus is true,
// search bug ID for more info. // search bug ID for more info.
#ifdef _WIN32 #ifdef _WIN32
bool showIconInMenu = Preferences::instance()->getBoolValue(showIconsInMenu); bool showIconInMenu =
Preferences::instance()->isShowAdvancedOptionsEnabled() &&
Preferences::instance()->getBoolValue(showIconsInMenu);
if (isForMenuItem && baseImg.width() == (16 * devPixRatio) && if (isForMenuItem && baseImg.width() == (16 * devPixRatio) &&
baseImg.height() == (16 * devPixRatio) && !showIconInMenu) { baseImg.height() == (16 * devPixRatio) && !showIconInMenu) {
static QPixmap emptyPm(16 * devPixRatio, 16 * devPixRatio); static QPixmap emptyPm(16 * devPixRatio, 16 * devPixRatio);