From ca06055c3eaeb716109f8126cd3e3e1976ed3e1c Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Sun, 9 Jun 2024 21:42:10 +0200 Subject: [PATCH] Revert "Support for fractional scaling" This reverts commit 3dd28b0640d2c613654f992ad3453a0b92beebe1. --- src/declarativeimports/framesvgitem.cpp | 9 ++- src/declarativeimports/svgitem.cpp | 7 +- src/ksvg/framesvg.cpp | 102 ++++++++++-------------- src/ksvg/private/framesvg_helpers.h | 22 ++--- src/ksvg/private/framesvg_p.h | 62 +++++++------- src/ksvg/private/svg_p.h | 6 +- src/ksvg/svg.cpp | 27 ++++--- 7 files changed, 115 insertions(+), 120 deletions(-) diff --git a/src/declarativeimports/framesvgitem.cpp b/src/declarativeimports/framesvgitem.cpp index 56c2b3a..678bdcb 100644 --- a/src/declarativeimports/framesvgitem.cpp +++ b/src/declarativeimports/framesvgitem.cpp @@ -122,7 +122,7 @@ public: void reposition(const QRect &frameGeometry, QSize &fullSize) { - QRectF nodeRect = FrameSvgHelpers::sectionRect(m_border, frameGeometry, fullSize); + QRect nodeRect = FrameSvgHelpers::sectionRect(m_border, frameGeometry, fullSize); // ensure we're not passing a weird rectangle to updateTexturedRectGeometry if (!nodeRect.isValid() || nodeRect.isEmpty()) { @@ -152,7 +152,7 @@ public: QString elementId = prefix + FrameSvgHelpers::borderToElementId(m_border); // re-render the SVG at new size - updateTexture(nodeRect.size().toSize(), elementId); + updateTexture(nodeRect.size(), elementId); textureRect = texture()->normalizedTextureSubRect(); } else if (texture()) { // for fast stretch. textureRect = texture()->normalizedTextureSubRect(); @@ -726,7 +726,10 @@ void FrameSvgItem::componentComplete() void FrameSvgItem::updateDevicePixelRatio() { - const auto newDevicePixelRatio = std::max(1.0, (window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + // devicepixelratio is always set integer in the svg, so needs at least 192dpi to double up. + //(it needs to be integer to have lines contained inside a svg piece to keep being pixel aligned) + const auto newDevicePixelRatio = std::max(1.0, floor(window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + if (newDevicePixelRatio != m_frameSvg->devicePixelRatio()) { m_frameSvg->setDevicePixelRatio(newDevicePixelRatio); m_textureChanged = true; diff --git a/src/declarativeimports/svgitem.cpp b/src/declarativeimports/svgitem.cpp index bec4533..aa1f2a2 100644 --- a/src/declarativeimports/svgitem.cpp +++ b/src/declarativeimports/svgitem.cpp @@ -16,6 +16,8 @@ #include "managedtexturenode.h" +#include //floor() + #include #include @@ -265,7 +267,10 @@ void SvgItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometr void SvgItem::updateDevicePixelRatio() { - const auto newDevicePixelRatio = std::max(1.0, (window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + // devicepixelratio is always set integer in the svg, so needs at least 192dpi to double up. + //(it needs to be integer to have lines contained inside a svg piece to keep being pixel aligned) + const auto newDevicePixelRatio = std::max(1.0, floor(window() ? window()->devicePixelRatio() : qApp->devicePixelRatio())); + if (newDevicePixelRatio != m_svg->devicePixelRatio()) { m_svg->setDevicePixelRatio(newDevicePixelRatio); m_textureChanged = true; diff --git a/src/ksvg/framesvg.cpp b/src/ksvg/framesvg.cpp index 3b094ab..f2c8663 100644 --- a/src/ksvg/framesvg.cpp +++ b/src/ksvg/framesvg.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -188,7 +188,7 @@ void FrameSvg::resizeFrame(const QSizeF &size) QSizeF FrameSvg::frameSize() const { if (!d->frame) { - return QSizeF(-1, -1); + return QSize(-1, -1); } else { return d->frameSize(d->frame.data()); } @@ -478,6 +478,9 @@ QPixmap FrameSvgPrivate::alphaMask() if (maskFrame->cachedBackground.isNull()) { generateBackground(maskFrame); + // When we take the maskFrame from cache, the pixel ratio gets + // reset to 1 + maskFrame->cachedBackground.setDevicePixelRatio(q->devicePixelRatio()); } return maskFrame->cachedBackground; @@ -542,8 +545,8 @@ void FrameSvgPrivate::generateBackground(const QSharedPointer &frame) } // Overlays - QSizeF overlaySize; - QPointF actualOverlayPos = QPointF(0, 0); + QSize overlaySize; + QPoint actualOverlayPos = QPoint(0, 0); if (overlayAvailable && !overlayCached) { overlaySize = q->elementSize(frame->prefix % QLatin1String("overlay")).toSize(); @@ -569,13 +572,13 @@ void FrameSvgPrivate::generateBackground(const QSharedPointer &frame) // Tiling? if (q->hasElement(frame->prefix % QLatin1String("hint-overlay-tile-horizontal")) || q->hasElement(frame->prefix % QLatin1String("hint-overlay-tile-vertical"))) { - QSizeF s = q->size().toSize(); + QSize s = q->size().toSize(); q->resize(q->elementSize(frame->prefix % QLatin1String("overlay"))); - overlayPainter.drawTiledPixmap(QRectF(QPointF(0, 0), overlaySize), q->pixmap(frame->prefix % QLatin1String("overlay"))); + overlayPainter.drawTiledPixmap(QRect(QPoint(0, 0), overlaySize), q->pixmap(frame->prefix % QLatin1String("overlay"))); q->resize(s); } else { - q->paint(&overlayPainter, QRectF(actualOverlayPos, overlaySize), frame->prefix % QLatin1String("overlay")); + q->paint(&overlayPainter, QRect(actualOverlayPos, overlaySize), frame->prefix % QLatin1String("overlay")); } overlayPainter.end(); @@ -588,14 +591,14 @@ void FrameSvgPrivate::generateBackground(const QSharedPointer &frame) if (!overlay.isNull()) { QPainter p(&frame->cachedBackground); p.setCompositionMode(QPainter::CompositionMode_SourceOver); - p.drawPixmap(actualOverlayPos, overlay, QRectF(actualOverlayPos, overlaySize)); + p.drawPixmap(actualOverlayPos, overlay, QRect(actualOverlayPos, overlaySize)); } } void FrameSvgPrivate::generateFrameBackground(const QSharedPointer &frame) { // qCDebug(LOG_KSVG) << "generating background"; - const QSizeF size = frameSize(frame) * q->devicePixelRatio(); + const QSize size = frameSize(frame).toSize() * q->devicePixelRatio(); if (!size.isValid()) { #ifndef NDEBUG @@ -608,14 +611,13 @@ void FrameSvgPrivate::generateFrameBackground(const QSharedPointer &f return; } - // Don't cut away pieces of the frame - frame->cachedBackground = QPixmap(QSize(std::ceil(size.width()), std::ceil(size.height()))); + frame->cachedBackground = QPixmap(size); frame->cachedBackground.fill(Qt::transparent); QPainter p(&frame->cachedBackground); p.setCompositionMode(QPainter::CompositionMode_Source); p.setRenderHint(QPainter::SmoothPixmapTransform); - QRectF contentRect = contentGeometry(frame, size); + QRect contentRect = contentGeometry(frame, size); paintCenter(p, frame, contentRect, size); paintCorner(p, frame, FrameSvg::LeftBorder | FrameSvg::TopBorder, contentRect); @@ -624,26 +626,25 @@ void FrameSvgPrivate::generateFrameBackground(const QSharedPointer &f paintCorner(p, frame, FrameSvg::RightBorder | FrameSvg::BottomBorder, contentRect); // Sides - const qreal leftHeight = q->elementSize(frame->prefix % QLatin1String("left")).height(); - paintBorder(p, frame, FrameSvg::LeftBorder, QSizeF(frame->leftWidth, leftHeight) * q->devicePixelRatio(), contentRect); - const qreal rightHeight = q->elementSize(frame->prefix % QLatin1String("right")).height(); - paintBorder(p, frame, FrameSvg::RightBorder, QSizeF(frame->rightWidth, rightHeight) * q->devicePixelRatio(), contentRect); - - const qreal topWidth = q->elementSize(frame->prefix % QLatin1String("top")).width(); - paintBorder(p, frame, FrameSvg::TopBorder, QSizeF(topWidth, frame->topHeight) * q->devicePixelRatio(), contentRect); - const qreal bottomWidth = q->elementSize(frame->prefix % QLatin1String("bottom")).width(); - paintBorder(p, frame, FrameSvg::BottomBorder, QSizeF(bottomWidth, frame->bottomHeight) * q->devicePixelRatio(), contentRect); + const int leftHeight = q->elementSize(frame->prefix % QLatin1String("left")).height(); + paintBorder(p, frame, FrameSvg::LeftBorder, QSize(frame->leftWidth, leftHeight) * q->devicePixelRatio(), contentRect); + const int rightHeight = q->elementSize(frame->prefix % QLatin1String("right")).height(); + paintBorder(p, frame, FrameSvg::RightBorder, QSize(frame->rightWidth, rightHeight) * q->devicePixelRatio(), contentRect); + + const int topWidth = q->elementSize(frame->prefix % QLatin1String("top")).width(); + paintBorder(p, frame, FrameSvg::TopBorder, QSize(topWidth, frame->topHeight) * q->devicePixelRatio(), contentRect); + const int bottomWidth = q->elementSize(frame->prefix % QLatin1String("bottom")).width(); + paintBorder(p, frame, FrameSvg::BottomBorder, QSize(bottomWidth, frame->bottomHeight) * q->devicePixelRatio(), contentRect); p.end(); - // Set the devicePixelRatio only at the end, drawing all happened in device pixels frame->cachedBackground.setDevicePixelRatio(q->devicePixelRatio()); } -QRectF FrameSvgPrivate::contentGeometry(const QSharedPointer &frame, const QSizeF &size) const +QRect FrameSvgPrivate::contentGeometry(const QSharedPointer &frame, const QSize &size) const { - const QSizeF contentSize(size.width() - frame->leftWidth * q->devicePixelRatio() - frame->rightWidth * q->devicePixelRatio(), - size.height() - frame->topHeight * q->devicePixelRatio() - frame->bottomHeight * q->devicePixelRatio()); - QRectF contentRect(QPointF(0, 0), contentSize); + const QSize contentSize(size.width() - frame->leftWidth * q->devicePixelRatio() - frame->rightWidth * q->devicePixelRatio(), + size.height() - frame->topHeight * q->devicePixelRatio() - frame->bottomHeight * q->devicePixelRatio()); + QRect contentRect(QPoint(0, 0), contentSize); if (frame->enabledBorders & FrameSvg::LeftBorder && q->hasElement(frame->prefix % QLatin1String("left"))) { contentRect.translate(frame->leftWidth * q->devicePixelRatio(), 0); } @@ -665,7 +666,7 @@ void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType) const QString oldPath = fd->imagePath; const FrameSvg::EnabledBorders oldBorders = fd->enabledBorders; - const QSizeF currentSize = fd->frameSize; + const QSize currentSize = fd->frameSize; fd->enabledBorders = enabledBorders; fd->frameSize = pendingFrameSize; @@ -722,28 +723,27 @@ void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType) } } -void FrameSvgPrivate::paintCenter(QPainter &p, const QSharedPointer &frame, const QRectF &contentRect, const QSizeF &fullSize) +void FrameSvgPrivate::paintCenter(QPainter &p, const QSharedPointer &frame, const QRect &contentRect, const QSize &fullSize) { - // fullSize and contentRect are in device pixels if (!contentRect.isEmpty()) { const QString centerElementId = frame->prefix % QLatin1String("center"); if (frame->tileCenter) { - QSizeF centerTileSize = q->elementSize(centerElementId); - QPixmap center(centerTileSize.toSize()); + QSize centerTileSize = q->elementSize(centerElementId).toSize(); + QPixmap center(centerTileSize); center.fill(Qt::transparent); QPainter centerPainter(¢er); centerPainter.setCompositionMode(QPainter::CompositionMode_Source); - q->paint(¢erPainter, QRectF(QPointF(0, 0), centerTileSize), centerElementId); + q->paint(¢erPainter, QRect(QPoint(0, 0), centerTileSize), centerElementId); if (frame->composeOverBorder) { - p.drawTiledPixmap(QRectF(QPointF(0, 0), fullSize), center); + p.drawTiledPixmap(QRect(QPoint(0, 0), fullSize), center); } else { p.drawTiledPixmap(FrameSvgHelpers::sectionRect(FrameSvg::NoBorder, contentRect, fullSize * q->devicePixelRatio()), center); } } else { if (frame->composeOverBorder) { - q->paint(&p, QRectF(QPointF(0, 0), fullSize), centerElementId); + q->paint(&p, QRect(QPoint(0, 0), fullSize), centerElementId); } else { q->paint(&p, FrameSvgHelpers::sectionRect(FrameSvg::NoBorder, contentRect, fullSize * q->devicePixelRatio()), centerElementId); } @@ -752,7 +752,7 @@ void FrameSvgPrivate::paintCenter(QPainter &p, const QSharedPointer & if (frame->composeOverBorder) { p.setCompositionMode(QPainter::CompositionMode_DestinationIn); - p.drawPixmap(QRectF(QPointF(0, 0), fullSize), alphaMask(), QRectF(QPointF(0, 0), alphaMask().size())); + p.drawPixmap(QRect(QPoint(0, 0), fullSize), alphaMask()); p.setCompositionMode(QPainter::CompositionMode_SourceOver); } } @@ -760,51 +760,35 @@ void FrameSvgPrivate::paintCenter(QPainter &p, const QSharedPointer & void FrameSvgPrivate::paintBorder(QPainter &p, const QSharedPointer &frame, const FrameSvg::EnabledBorders borders, - const QSizeF &size, - const QRectF &contentRect) const + const QSize &size, + const QRect &contentRect) const { - // size and contentRect are in device pixels QString side = frame->prefix % FrameSvgHelpers::borderToElementId(borders); if (frame->enabledBorders & borders && q->hasElement(side) && !size.isEmpty()) { if (frame->stretchBorders) { q->paint(&p, FrameSvgHelpers::sectionRect(borders, contentRect, frame->frameSize * q->devicePixelRatio()), side); } else { - QSize grownSize(std::ceil(size.width()), std::ceil(size.height())); - QPixmap px(grownSize); - // QPixmap px(QSize(std::ceil(size.width()), std::ceil(size.height()))); + QPixmap px(size); px.fill(Qt::transparent); QPainter sidePainter(&px); sidePainter.setCompositionMode(QPainter::CompositionMode_Source); - // A QRect as we have to exactly fill a QPixmap of integer size, prefer going slightly outside it to not have empty edges in the pixmap to tile - q->paint(&sidePainter, QRect(QPoint(0, 0), grownSize), side); + q->paint(&sidePainter, QRect(QPoint(0, 0), size), side); - // We are composing QPixmaps here, so all objects with integer size - // Rounding the position and ceiling the size is the way that gives better tiled results - auto r = FrameSvgHelpers::sectionRect(borders, contentRect, frame->frameSize * q->devicePixelRatio()); - r.setTopLeft(r.topLeft().toPoint()); - r.setSize(QSizeF(std::ceil(r.size().width()), std::ceil(r.size().height()))); - - p.drawTiledPixmap(r, px); + p.drawTiledPixmap(FrameSvgHelpers::sectionRect(borders, contentRect, frame->frameSize * q->devicePixelRatio()), px); } } } -void FrameSvgPrivate::paintCorner(QPainter &p, const QSharedPointer &frame, KSvg::FrameSvg::EnabledBorders border, const QRectF &contentRect) const +void FrameSvgPrivate::paintCorner(QPainter &p, const QSharedPointer &frame, KSvg::FrameSvg::EnabledBorders border, const QRect &contentRect) const { - // contentRect is in device pixels // Draw the corner only if both borders in both directions are enabled. if ((frame->enabledBorders & border) != border) { return; } const QString corner = frame->prefix % FrameSvgHelpers::borderToElementId(border); if (q->hasElement(corner)) { - auto r = FrameSvgHelpers::sectionRect(border, contentRect, frame->frameSize * q->devicePixelRatio()); - // We are composing QPixmaps here, so all objects with integer size - // Rounding the position and ceiling the size is the way that gives better tiled results - r.setTopLeft(r.topLeft().toPoint()); - r.setSize(QSizeF(std::ceil(r.size().width()), std::ceil(r.size().height()))); - q->paint(&p, r.toRect(), corner); + q->paint(&p, FrameSvgHelpers::sectionRect(border, contentRect, frame->frameSize * q->devicePixelRatio()), corner); } } @@ -852,7 +836,7 @@ void FrameSvgPrivate::updateSizes(FrameData *frame) const // qCDebug(LOG_KSVG) << "!!!!!!!!!!!!!!!!!!!!!! updating sizes" << prefix; Q_ASSERT(frame); - QSizeF s = q->size(); + QSize s = q->size().toSize(); q->resize(); if (!frame->cachedBackground.isNull()) { frame->cachedBackground = QPixmap(); diff --git a/src/ksvg/private/framesvg_helpers.h b/src/ksvg/private/framesvg_helpers.h index 95cd6ba..691aa3c 100644 --- a/src/ksvg/private/framesvg_helpers.h +++ b/src/ksvg/private/framesvg_helpers.h @@ -45,7 +45,7 @@ QString borderToElementId(FrameSvg::EnabledBorders borders) /** * @returns the suggested geometry for the @p borders given a @p fullSize frame size and a @p contentRect */ -QRectF sectionRect(KSvg::FrameSvg::EnabledBorders borders, const QRectF &contentRect, const QSizeF &fullSize) +QRect sectionRect(KSvg::FrameSvg::EnabledBorders borders, const QRect &contentRect, const QSize &fullSize) { // don't use QRect corner methods here, they have semantics that might come as unexpected. // prefer constructing the points explicitly. e.g. from QRect::topRight docs: @@ -54,26 +54,26 @@ QRectF sectionRect(KSvg::FrameSvg::EnabledBorders borders, const QRectF &content if (borders == FrameSvg::NoBorder) { return contentRect; } else if (borders == FrameSvg::TopBorder) { - return QRectF(QPointF(contentRect.left(), 0), QSizeF(contentRect.width(), contentRect.top())); + return QRect(QPoint(contentRect.left(), 0), QSize(contentRect.width(), contentRect.top())); } else if (borders == FrameSvg::BottomBorder) { - return QRectF(QPointF(contentRect.left(), contentRect.bottom()), QSizeF(contentRect.width(), fullSize.height() - contentRect.bottom())); + return QRect(QPoint(contentRect.left(), contentRect.bottom() + 1), QSize(contentRect.width(), fullSize.height() - contentRect.bottom() - 1)); } else if (borders == FrameSvg::LeftBorder) { - return QRectF(QPointF(0, contentRect.top()), QSizeF(contentRect.left(), contentRect.height())); + return QRect(QPoint(0, contentRect.top()), QSize(contentRect.left(), contentRect.height())); } else if (borders == FrameSvg::RightBorder) { - return QRectF(QPointF(contentRect.right(), contentRect.top()), QSizeF(fullSize.width() - contentRect.right(), contentRect.height())); + return QRect(QPoint(contentRect.right() + 1, contentRect.top()), QSize(fullSize.width() - contentRect.right() - 1, contentRect.height())); } else if (borders == (FrameSvg::TopBorder | FrameSvg::LeftBorder)) { - return QRectF(QPointF(0, 0), QSizeF(contentRect.left(), contentRect.top())); + return QRect(QPoint(0, 0), QSize(contentRect.left(), contentRect.top())); } else if (borders == (FrameSvg::TopBorder | FrameSvg::RightBorder)) { - return QRectF(QPointF(contentRect.right(), 0), QSizeF(fullSize.width() - contentRect.right(), contentRect.top())); + return QRect(QPoint(contentRect.right() + 1, 0), QSize(fullSize.width() - contentRect.right() - 1, contentRect.top())); } else if (borders == (FrameSvg::BottomBorder | FrameSvg::LeftBorder)) { - return QRectF(QPointF(0, contentRect.bottom()), QSizeF(contentRect.left(), fullSize.height() - contentRect.bottom())); + return QRect(QPoint(0, contentRect.bottom() + 1), QSize(contentRect.left(), fullSize.height() - contentRect.bottom() - 1)); } else if (borders == (FrameSvg::BottomBorder | FrameSvg::RightBorder)) { - return QRectF(QPointF(contentRect.right(), contentRect.bottom()), - QSizeF(fullSize.width() - contentRect.right(), fullSize.height() - contentRect.bottom())); + return QRect(QPoint(contentRect.right() + 1, contentRect.bottom() + 1), + QSize(fullSize.width() - contentRect.right() - 1, fullSize.height() - contentRect.bottom() - 1)); } else { qWarning() << "unrecognized border" << borders; } - return QRectF(); + return QRect(); } } diff --git a/src/ksvg/private/framesvg_p.h b/src/ksvg/private/framesvg_p.h index 463b2ee..2b9e881 100644 --- a/src/ksvg/private/framesvg_p.h +++ b/src/ksvg/private/framesvg_p.h @@ -78,39 +78,38 @@ public: static const int MAX_CACHED_MASKS = 10; uint lastModified = 0; - // Those sizes are in logical pixels - QSizeF frameSize; + QSize frameSize; uint cacheId; // measures - qreal topHeight; - qreal leftWidth; - qreal rightWidth; - qreal bottomHeight; + int topHeight; + int leftWidth; + int rightWidth; + int bottomHeight; // margins, are equal to the measures by default - qreal topMargin; - qreal leftMargin; - qreal rightMargin; - qreal bottomMargin; + int topMargin; + int leftMargin; + int rightMargin; + int bottomMargin; // measures - qreal fixedTopHeight; - qreal fixedLeftWidth; - qreal fixedRightWidth; - qreal fixedBottomHeight; + int fixedTopHeight; + int fixedLeftWidth; + int fixedRightWidth; + int fixedBottomHeight; // margins, are equal to the measures by default - qreal fixedTopMargin; - qreal fixedLeftMargin; - qreal fixedRightMargin; - qreal fixedBottomMargin; + int fixedTopMargin; + int fixedLeftMargin; + int fixedRightMargin; + int fixedBottomMargin; - // margins, we only have the hqreal for insets - qreal insetTopMargin; - qreal insetLeftMargin; - qreal insetRightMargin; - qreal insetBottomMargin; + // margins, we only have the hint for insets + int insetTopMargin; + int insetLeftMargin; + int insetRightMargin; + int insetBottomMargin; // size of the svg where the size of the "center" // element is contentWidth x contentHeight @@ -159,17 +158,14 @@ public: return frameSize(frame.data()); } QSizeF frameSize(FrameData *frame) const; - - // paintBorder, paintCorder and paintCenter sizes are in device pixels void paintBorder(QPainter &p, const QSharedPointer &frame, KSvg::FrameSvg::EnabledBorders border, - const QSizeF &originalSize, - const QRectF &output) const; - void paintCorner(QPainter &p, const QSharedPointer &frame, KSvg::FrameSvg::EnabledBorders border, const QRectF &output) const; - void paintCenter(QPainter &p, const QSharedPointer &frame, const QRectF &contentRect, const QSizeF &fullSize); - - QRectF contentGeometry(const QSharedPointer &frame, const QSizeF &size) const; + const QSize &originalSize, + const QRect &output) const; + void paintCorner(QPainter &p, const QSharedPointer &frame, KSvg::FrameSvg::EnabledBorders border, const QRect &output) const; + void paintCenter(QPainter &p, const QSharedPointer &frame, const QRect &contentRect, const QSize &fullSize); + QRect contentGeometry(const QSharedPointer &frame, const QSize &size) const; void updateFrameData(uint lastModified, UpdateType updateType = UpdateFrameAndMargins); QSharedPointer lookupOrCreateMaskFrame(const QSharedPointer &frame, const QString &maskPrefix, const QString &maskRequestedPrefix); @@ -181,7 +177,7 @@ public: FrameSvg *const q; - QPointF overlayPos; + QPoint overlayPos; QSharedPointer frame; QSharedPointer maskFrame; @@ -189,7 +185,7 @@ public: // those can differ from frame->enabledBorders if we are in a transition FrameSvg::EnabledBorders enabledBorders; // this can differ from frame->frameSize if we are in a transition - QSizeF pendingFrameSize; + QSize pendingFrameSize; static QHash>> s_sharedFrames; diff --git a/src/ksvg/private/svg_p.h b/src/ksvg/private/svg_p.h index 818a477..bb80c75 100644 --- a/src/ksvg/private/svg_p.h +++ b/src/ksvg/private/svg_p.h @@ -138,8 +138,8 @@ public: void setNaturalSize(const QString &path, const QSizeF &size); QSizeF naturalSize(const QString &path); - QList sizeHintsForId(const QString &path, const QString &id); - void insertSizeHintForId(const QString &path, const QString &id, const QSizeF &size); + QList sizeHintsForId(const QString &path, const QString &id); + void insertSizeHintForId(const QString &path, const QString &id, const QSize &size); QString iconThemePath(); void setIconThemePath(const QString &path); @@ -166,7 +166,7 @@ private: */ QHash m_localRectCache; QHash> m_invalidElements; - QHash> m_sizeHintsForId; + QHash> m_sizeHintsForId; QHash m_lastModifiedTimes; }; } diff --git a/src/ksvg/svg.cpp b/src/ksvg/svg.cpp index 1bdafd6..01ce058 100644 --- a/src/ksvg/svg.cpp +++ b/src/ksvg/svg.cpp @@ -272,7 +272,7 @@ void SvgRectsCache::dropImageFromCache(const QString &path) QMetaObject::invokeMethod(m_configSyncTimer, qOverload<>(&QTimer::start)); } -QList SvgRectsCache::sizeHintsForId(const QString &path, const QString &id) +QList SvgRectsCache::sizeHintsForId(const QString &path, const QString &id) { const QString pathId = path % id; @@ -280,7 +280,7 @@ QList SvgRectsCache::sizeHintsForId(const QString &path, const QString & if (it == m_sizeHintsForId.constEnd()) { KConfigGroup imageGroup(m_svgElementsCache, path); const QStringList &encoded = imageGroup.readEntry(id, QStringList()); - QList sizes; + QList sizes; for (const auto &token : encoded) { const auto &parts = token.split(QLatin1Char('x')); if (parts.size() != 2) { @@ -298,10 +298,10 @@ QList SvgRectsCache::sizeHintsForId(const QString &path, const QString & return *it; } -void SvgRectsCache::insertSizeHintForId(const QString &path, const QString &id, const QSizeF &size) +void SvgRectsCache::insertSizeHintForId(const QString &path, const QString &id, const QSize &size) { // TODO: need to make this more efficient - auto sizeListToString = [](const QList &list) { + auto sizeListToString = [](const QList &list) { QString ret; for (const auto &s : list) { ret += QString::number(s.width()) % QLatin1Char('x') % QString::number(s.height()) % QLatin1Char(','); @@ -561,7 +561,7 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, qreal ratio, const QSi // Look at the size hinted elements and try to find the smallest one with an // identical aspect ratio. if (s.isValid() && !elementId.isEmpty()) { - const QList elementSizeHints = SvgRectsCache::instance()->sizeHintsForId(path, elementId); + const QList elementSizeHints = SvgRectsCache::instance()->sizeHintsForId(path, elementId); if (!elementSizeHints.isEmpty()) { QSizeF bestFit(-1, -1); @@ -873,11 +873,18 @@ Svg::~Svg() void Svg::setDevicePixelRatio(qreal ratio) { + // be completely integer for now + // devicepixelratio is always set integer in the svg, so needs at least 192dpi to double up. + //(it needs to be integer to have lines contained inside a svg piece to keep being pixel aligned) + if (floor(d->devicePixelRatio) == floor(ratio)) { + return; + } + if (FrameSvg *f = qobject_cast(this)) { f->clearCache(); } - d->devicePixelRatio = ratio; + d->devicePixelRatio = floor(ratio); Q_EMIT repaintNeeded(); } @@ -905,7 +912,7 @@ QImage Svg::image(const QSize &size, const QString &elementID) void Svg::paint(QPainter *painter, const QPointF &point, const QString &elementID) { Q_ASSERT(painter->device()); - const qreal ratio = painter->device()->devicePixelRatio(); + const int ratio = painter->device()->devicePixelRatio(); QPixmap pix((elementID.isNull() || d->multipleImages) ? d->findInCache(elementID, ratio, size()) : d->findInCache(elementID, ratio)); if (pix.isNull()) { @@ -923,16 +930,16 @@ void Svg::paint(QPainter *painter, int x, int y, const QString &elementID) void Svg::paint(QPainter *painter, const QRectF &rect, const QString &elementID) { Q_ASSERT(painter->device()); - const qreal ratio = painter->device()->devicePixelRatio(); + const int ratio = painter->device()->devicePixelRatio(); QPixmap pix(d->findInCache(elementID, ratio, rect.size())); - painter->drawPixmap(rect, pix, QRect(QPoint(0, 0), pix.size())); + painter->drawPixmap(QRectF(rect.topLeft(), rect.size()), pix, QRectF(QPointF(0, 0), pix.size())); } void Svg::paint(QPainter *painter, int x, int y, int width, int height, const QString &elementID) { Q_ASSERT(painter->device()); - const qreal ratio = painter->device()->devicePixelRatio(); + const int ratio = painter->device()->devicePixelRatio(); QPixmap pix(d->findInCache(elementID, ratio, QSizeF(width, height))); painter->drawPixmap(x, y, pix, 0, 0, pix.size().width(), pix.size().height()); } -- 2.45.2