diff options
author | Magdalena Stojek <[email protected]> | 2024-12-16 16:19:23 +0100 |
---|---|---|
committer | Magdalena Stojek <[email protected]> | 2025-02-21 08:33:57 +0100 |
commit | 727d2350391512cb8449f9db781b4e1041a8068c (patch) | |
tree | ac1b937e18d3bc4bcba40f6cb2db8542a98984a2 /src/quick/scenegraph/adaptations/software | |
parent | f024a3389e10118a9e9ae70f950b80d287cdd55b (diff) |
Refactor corner radius handling with explicit unset state
Replace the use of -1 to indicate unset corner radii with explicit
bitfield flags to track whether each corner radius is set.
The default value for unset radii remains 0.0.
Fixes: QTBUG-120188
Change-Id: If51a0165386a0c474ecd57ef23310d1c28f0f60b
Reviewed-by: Shawn Rutledge <[email protected]>
Diffstat (limited to 'src/quick/scenegraph/adaptations/software')
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp | 140 | ||||
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h | 9 |
2 files changed, 102 insertions, 47 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp index 411c189b3d..e651eadac2 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp @@ -11,13 +11,17 @@ QT_BEGIN_NAMESPACE QSGSoftwareInternalRectangleNode::QSGSoftwareInternalRectangleNode() : m_penWidth(0) , m_radius(0) - , m_topLeftRadius(-1) - , m_topRightRadius(-1) - , m_bottomLeftRadius(-1) - , m_bottomRightRadius(-1) + , m_topLeftRadius(0) + , m_topRightRadius(0) + , m_bottomLeftRadius(0) + , m_bottomRightRadius(0) , m_vertical(true) , m_cornerPixmapIsDirty(true) , m_devicePixelRatio(1) + , m_isTopLeftRadiusSet(false) + , m_isTopRightRadiusSet(false) + , m_isBottomLeftRadiusSet(false) + , m_isBottomRightRadiusSet(false) { m_pen.setJoinStyle(Qt::MiterJoin); m_pen.setMiterLimit(0); @@ -168,47 +172,87 @@ void QSGSoftwareInternalRectangleNode::setGradientVertical(bool vertical) void QSGSoftwareInternalRectangleNode::setRadius(qreal radius) { - if (m_radius != radius) { - m_radius = radius; - m_cornerPixmapIsDirty = true; - markDirty(DirtyMaterial); - } + if (m_radius == radius) + return; + m_radius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); } void QSGSoftwareInternalRectangleNode::setTopLeftRadius(qreal radius) { - if (m_topLeftRadius != radius) { - m_topLeftRadius = radius; - m_cornerPixmapIsDirty = true; - markDirty(DirtyMaterial); - } + if (m_isTopLeftRadiusSet && m_topLeftRadius == radius) + return; + m_isTopLeftRadiusSet = true; + m_topLeftRadius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); } void QSGSoftwareInternalRectangleNode::setTopRightRadius(qreal radius) { - if (m_topRightRadius != radius) { - m_topRightRadius = radius; - m_cornerPixmapIsDirty = true; - markDirty(DirtyMaterial); - } + if (m_isTopRightRadiusSet && m_topRightRadius == radius) + return; + m_isTopRightRadiusSet = true; + m_topRightRadius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); } void QSGSoftwareInternalRectangleNode::setBottomLeftRadius(qreal radius) { - if (m_bottomLeftRadius != radius) { - m_bottomLeftRadius = radius; - m_cornerPixmapIsDirty = true; - markDirty(DirtyMaterial); - } + if (m_isBottomLeftRadiusSet && m_bottomLeftRadius == radius) + return; + m_isBottomLeftRadiusSet = true; + m_bottomLeftRadius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); } void QSGSoftwareInternalRectangleNode::setBottomRightRadius(qreal radius) { - if (m_bottomRightRadius != radius) { - m_bottomRightRadius = radius; - m_cornerPixmapIsDirty = true; - markDirty(DirtyMaterial); - } + if (m_isBottomRightRadiusSet && m_bottomRightRadius == radius) + return; + m_isBottomRightRadiusSet = true; + m_bottomRightRadius = radius; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); +} + +void QSGSoftwareInternalRectangleNode::resetTopLeftRadius() +{ + if (!m_isTopLeftRadiusSet) + return; + m_isTopLeftRadiusSet = false; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); +} + +void QSGSoftwareInternalRectangleNode::resetTopRightRadius() +{ + if (!m_isTopRightRadiusSet) + return; + m_isTopRightRadiusSet = false; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); +} + +void QSGSoftwareInternalRectangleNode::resetBottomLeftRadius() +{ + if (!m_isBottomLeftRadiusSet) + return; + m_isBottomLeftRadiusSet = false; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); +} + +void QSGSoftwareInternalRectangleNode::resetBottomRightRadius() +{ + if (!m_isBottomRightRadiusSet) + return; + m_isBottomRightRadiusSet = false; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); } void QSGSoftwareInternalRectangleNode::setAligned(bool /*aligned*/) @@ -253,19 +297,19 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) if (m_radius == 0 && m_penWidth == 0 - && m_topLeftRadius <= 0 - && m_topRightRadius <= 0 - && m_bottomLeftRadius <= 0 - && m_bottomRightRadius <= 0) { + && !m_isTopLeftRadiusSet + && !m_isTopRightRadiusSet + && !m_isBottomLeftRadiusSet + && !m_isBottomRightRadiusSet) { //Non-Rounded Rects without borders (fall back to drawRect) //Most common case painter->setPen(Qt::NoPen); painter->setBrush(m_brush); painter->drawRect(m_rect); - } else if (m_topLeftRadius < 0 - && m_topRightRadius < 0 - && m_bottomLeftRadius < 0 - && m_bottomRightRadius < 0) { + } else if (!m_isTopLeftRadiusSet + && !m_isTopRightRadiusSet + && !m_isBottomLeftRadiusSet + && !m_isBottomRightRadiusSet) { //Rounded Rects and Rects with Borders //Avoids broken behaviors of QPainter::drawRect/roundedRect QPixmap pixmap = QPixmap(qRound(m_rect.width() * m_devicePixelRatio), qRound(m_rect.height() * m_devicePixelRatio)); @@ -298,16 +342,15 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) } else { //Paint directly - if (m_topLeftRadius < 0 - && m_topRightRadius < 0 - && m_bottomLeftRadius < 0 - && m_bottomRightRadius < 0) { + if (!m_isTopLeftRadiusSet + && !m_isTopRightRadiusSet + && !m_isBottomLeftRadiusSet + && !m_isBottomRightRadiusSet) { paintRectangle(painter, m_rect); } else { paintRectangleIndividualCorners(painter, m_rect); } } - } bool QSGSoftwareInternalRectangleNode::isOpaque() const @@ -338,7 +381,6 @@ void QSGSoftwareInternalRectangleNode::paintRectangle(QPainter *painter, const Q { //Radius should never exceeds half of the width or half of the height int radius = qFloor(qMin(qMin(rect.width(), rect.height()) * 0.5, m_radius)); - QPainter::RenderHints previousRenderHints = painter->renderHints(); painter->setRenderHint(QPainter::Antialiasing, false); @@ -463,10 +505,14 @@ void QSGSoftwareInternalRectangleNode::paintRectangleIndividualCorners(QPainter const float w = m_penWidth; // Radius should never exceeds half of the width or half of the height - const float radiusTL = qMin(qMin(rect.width(), rect.height()) * 0.5f, float(m_topLeftRadius < 0. ? m_radius : m_topLeftRadius)); - const float radiusTR = qMin(qMin(rect.width(), rect.height()) * 0.5f, float(m_topRightRadius < 0. ? m_radius : m_topRightRadius)); - const float radiusBL = qMin(qMin(rect.width(), rect.height()) * 0.5f, float(m_bottomLeftRadius < 0. ? m_radius : m_bottomLeftRadius)); - const float radiusBR = qMin(qMin(rect.width(), rect.height()) * 0.5f, float(m_bottomRightRadius < 0 ? m_radius : m_bottomRightRadius)); + const float radiusTL = qMin(qMin(rect.width(), rect.height()) * 0.5f, + m_isTopLeftRadiusSet ? m_topLeftRadius : m_radius); + const float radiusTR = qMin(qMin(rect.width(), rect.height()) * 0.5f, + m_isTopRightRadiusSet ? m_topRightRadius : m_radius); + const float radiusBL = qMin(qMin(rect.width(), rect.height()) * 0.5f, + m_isBottomLeftRadiusSet ? m_bottomLeftRadius : m_radius); + const float radiusBR = qMin(qMin(rect.width(), rect.height()) * 0.5f, + m_isBottomRightRadiusSet ? m_bottomRightRadius : m_radius); const float innerRadiusTL = qMin(qMin(rect.width(), rect.height()) * 0.5f, radiusTL - w); const float innerRadiusTR = qMin(qMin(rect.width(), rect.height()) * 0.5f, radiusTR - w); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h index ac58e7b254..2d02c9ad22 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h @@ -39,6 +39,10 @@ public: void setTopRightRadius(qreal radius) override; void setBottomLeftRadius(qreal radius) override; void setBottomRightRadius(qreal radius) override; + void resetTopLeftRadius() override; + void resetTopRightRadius() override; + void resetBottomLeftRadius() override; + void resetBottomRightRadius() override; void setAntialiasing(bool antialiasing) override { Q_UNUSED(antialiasing); } void setAligned(bool aligned) override; @@ -71,6 +75,11 @@ private: QPixmap m_cornerPixmap; qreal m_devicePixelRatio; + + uint m_isTopLeftRadiusSet : 1; + uint m_isTopRightRadiusSet : 1; + uint m_isBottomLeftRadiusSet : 1; + uint m_isBottomRightRadiusSet : 1; }; QT_END_NAMESPACE |