From 8fd6910ca490dcdaa3b5109f5522aad23ed44632 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 10 Apr 2019 19:39:06 +0200 Subject: [PATCH] manually scaling textures according to window coordinates --- src/controls/QskSkinlet.cpp | 51 +++++++++++++++++++----------------- src/nodes/QskGraphicNode.cpp | 4 +-- src/nodes/QskGraphicNode.h | 2 +- src/nodes/QskTextureNode.cpp | 4 +-- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/controls/QskSkinlet.cpp b/src/controls/QskSkinlet.cpp index b3a9451e..4d559ee6 100644 --- a/src/controls/QskSkinlet.cpp +++ b/src/controls/QskSkinlet.cpp @@ -57,37 +57,43 @@ static inline QSGNode* qskFindNodeByFlag( QSGNode* parent, int nodeRole ) return nullptr; } -static qreal qskDevicePixelRatio( const QskSkinnable* skinnable ) -{ - if ( auto control = skinnable->owningControl() ) - { - if ( auto window = control->window() ) - return window->effectiveDevicePixelRatio(); - } - - return qGuiApp->devicePixelRatio(); -} - static inline QSGNode* qskUpdateGraphicNode( const QskSkinnable* skinnable, QSGNode* node, const QskGraphic& graphic, const QskColorFilter& colorFilter, - const QRect& rect ) + const QRectF& rect ) { if ( rect.isEmpty() ) return nullptr; auto mode = QskTextureRenderer::OpenGL; - const auto control = skinnable->owningControl(); - if ( control && control->testControlFlag( QskControl::PreferRasterForTextures ) ) - mode = QskTextureRenderer::Raster; - auto graphicNode = static_cast< QskGraphicNode* >( node ); if ( graphicNode == nullptr ) graphicNode = new QskGraphicNode(); - const qreal ratio = qskDevicePixelRatio( skinnable ); - const QRect r( rect.x(), rect.y(), ratio * rect.width(), ratio * rect.height() ); + QRectF r = rect; + + if ( const auto control = skinnable->owningControl() ) + { + if ( control->testControlFlag( QskControl::PreferRasterForTextures ) ) + mode = QskTextureRenderer::Raster; + + if ( auto window = control->window() ) + { + /* + Aligning the rect according to scene coordinates, so that + we don't run into rounding issues downstream, where values + will be floored/ceiled ending up with a slightly different + aspect ratio. + */ + const QRectF sceneRect( + control->mapToScene( r.topLeft() ), + r.size() * window->effectiveDevicePixelRatio() ); + + r = qskInnerRect( sceneRect ); + r.moveTopLeft( control->mapFromScene( r.topLeft() ) ); + } + } graphicNode->setGraphic( graphic, colorFilter, mode, r ); @@ -538,12 +544,10 @@ QSGNode* QskSkinlet::updateGraphicNode( if ( graphic.isNull() ) return nullptr; - const QSizeF scaledSize = graphic.defaultSize().scaled( + const QSizeF size = graphic.defaultSize().scaled( rect.size(), Qt::KeepAspectRatio ); - const QRect r = qskAlignedRect( qskInnerRect( rect ), - int( scaledSize.width() ), int( scaledSize.height() ), alignment ); - + const QRectF r = qskAlignedRectF( rect, size.width(), size.height(), alignment ); return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, r ); } @@ -555,8 +559,7 @@ QSGNode* QskSkinlet::updateGraphicNode( if ( graphic.isNull() ) return nullptr; - return qskUpdateGraphicNode( skinnable, node, - graphic, colorFilter, rect.toAlignedRect() ); + return qskUpdateGraphicNode( skinnable, node, graphic, colorFilter, rect ); } #include "moc_QskSkinlet.cpp" diff --git a/src/nodes/QskGraphicNode.cpp b/src/nodes/QskGraphicNode.cpp index 56419623..e4ff34b1 100644 --- a/src/nodes/QskGraphicNode.cpp +++ b/src/nodes/QskGraphicNode.cpp @@ -47,7 +47,7 @@ QskGraphicNode::~QskGraphicNode() void QskGraphicNode::setGraphic( const QskGraphic& graphic, const QskColorFilter& colorFilter, - QskTextureRenderer::RenderMode renderMode, const QRect& rect ) + QskTextureRenderer::RenderMode renderMode, const QRectF& rect ) { bool isTextureDirty = ( QskTextureNode::textureId() == 0 ); @@ -70,7 +70,7 @@ void QskGraphicNode::setGraphic( if ( isTextureDirty ) { const uint textureId = QskTextureRenderer::createTextureFromGraphic( - renderMode, rect.size(), graphic, colorFilter, Qt::IgnoreAspectRatio ); + renderMode, rect.size().toSize(), graphic, colorFilter, Qt::IgnoreAspectRatio ); QskTextureNode::setTextureId( textureId ); } diff --git a/src/nodes/QskGraphicNode.h b/src/nodes/QskGraphicNode.h index e039d5be..3c139adf 100644 --- a/src/nodes/QskGraphicNode.h +++ b/src/nodes/QskGraphicNode.h @@ -19,7 +19,7 @@ class QSK_EXPORT QskGraphicNode : public QskTextureNode ~QskGraphicNode() override; void setGraphic( const QskGraphic&, const QskColorFilter&, - QskTextureRenderer::RenderMode, const QRect& ); + QskTextureRenderer::RenderMode, const QRectF& ); private: void setTextureId( int ) = delete; diff --git a/src/nodes/QskTextureNode.cpp b/src/nodes/QskTextureNode.cpp index 53dfe5d0..5051ad0d 100644 --- a/src/nodes/QskTextureNode.cpp +++ b/src/nodes/QskTextureNode.cpp @@ -316,11 +316,9 @@ void QskTextureNode::updateTexture() r.setBottom( 0 ); } -#if 1 const qreal ratio = qskDevicePixelRatio(); - const QRect rect( d->rect.x(), d->rect.y(), + const QRectF rect( d->rect.x(), d->rect.y(), d->rect.width() / ratio, d->rect.height() / ratio ); -#endif QSGGeometry::updateTexturedRectGeometry( &d->geometry, rect, r ); }