6#include "QskBoxMetrics.h"
7#include "QskBoxShapeMetrics.h"
8#include "QskBoxBorderMetrics.h"
9#include "QskVertexHelper.h"
10#include "QskFunctions.h"
12QskBoxMetrics::QskBoxMetrics(
const QRectF& rect,
16 isOutsideRounded = !shape.isRectangle();
18 if ( !isOutsideRounded )
20 isInsideRounded =
false;
21 isOutsideSymmetric =
true;
22 stepSymmetries = Qt::Vertical | Qt::Horizontal;
23 preferredOrientation = Qt::Vertical;
25 const auto bw = border.widths();
26 hasBorder = bw.width() > 0.0 || bw.height() > 0.0;
28 innerRect = qskValidOrEmptyInnerRect( rect, bw );
33 isOutsideSymmetric = shape.isRectellipse();
36 const auto tl = shape.topLeft();
37 const auto tr = shape.topRight();
38 const auto bl = shape.bottomLeft();
39 const auto br = shape.bottomRight();
41 if ( tl.isEmpty() || tr.isEmpty() || ( tl.height() == tr.height() ) )
43 if ( bl.isEmpty() || br.isEmpty() || ( bl.height() == br.height() ) )
44 stepSymmetries |= Qt::Vertical;
47 if ( tl.isEmpty() || bl.isEmpty() || ( tl.width() == bl.width() ) )
49 if ( tr.isEmpty() || br.isEmpty() || ( tr.width() == br.width() ) )
50 stepSymmetries |= Qt::Horizontal;
54 for (
int i = 0; i < 4; i++ )
56 auto& c = corners[ i ];
58 const auto radius = shape.radius(
static_cast< Qt::Corner
>( i ) );
60 c.radiusX = qBound( 0.0, radius.width(), 0.5 * outerRect.width() );
61 c.radiusY = qBound( 0.0, radius.height(), 0.5 * outerRect.height() );
62 c.stepCount = QskVertex::ArcIterator::segmentHint( qMax( c.radiusX, c.radiusY ) );
66 case Qt::TopLeftCorner:
67 c.centerX = outerRect.left() + c.radiusX;
68 c.centerY = outerRect.top() + c.radiusY;
73 case Qt::TopRightCorner:
74 c.centerX = outerRect.right() - c.radiusX;
75 c.centerY = outerRect.top() + c.radiusY;
80 case Qt::BottomLeftCorner:
81 c.centerX = outerRect.left() + c.radiusX;
82 c.centerY = outerRect.bottom() - c.radiusY;
87 case Qt::BottomRightCorner:
88 c.centerX = outerRect.right() - c.radiusX;
89 c.centerY = outerRect.bottom() - c.radiusY;
97 const auto cleft = qMax( corners[ Qt::TopLeftCorner ].centerX,
98 corners[ Qt::BottomLeftCorner ].centerX );
100 const auto cright = qMin( corners[ Qt::TopRightCorner ].centerX,
101 corners[ Qt::BottomRightCorner ].centerX );
103 const auto ctop = qMax( corners[ Qt::TopLeftCorner ].centerY,
104 corners[ Qt::TopRightCorner ].centerY );
106 const auto cbottom = qMin( corners[ Qt::BottomLeftCorner ].centerY,
107 corners[ Qt::BottomRightCorner ].centerY );
111 const auto bw = border.widths();
112 hasBorder = bw.width() > 0.0 || bw.height() > 0.0;
114 qreal l = outerRect.left() + bw.left();
115 qreal t = outerRect.top() + bw.top();
116 qreal r = outerRect.right() - bw.right();
117 qreal b = outerRect.bottom() - bw.bottom();
119 l = qMin( l, cright );
120 r = qMax( r, cleft );
121 t = qMin( t, cbottom );
125 l = r = r + 0.5 * ( l - r );
128 t = b = b + 0.5 * ( t - b );
130 innerRect.setCoords( l, t, r, b );
134 innerRect.left() - outerRect.left(),
135 innerRect.top() - outerRect.top(),
136 outerRect.right() - innerRect.right(),
137 outerRect.bottom() - innerRect.bottom() );
139 isBorderRegular = margins.isEquidistant();
141 isInsideRounded =
false;
143 for (
int i = 0; i < 4; i++ )
145 auto& c = corners[ i ];
148 c.radiusInnerX = c.radiusX - margins.left();
150 c.radiusInnerX = c.radiusX - margins.right();
153 c.radiusInnerY = c.radiusY - margins.top();
155 c.radiusInnerY = c.radiusY - margins.bottom();
157 if ( c.radiusInnerX > 0.0 && c.radiusInnerY > 0.0 )
159 c.centerInnerX = c.centerX;
160 c.centerInnerY = c.centerY;
162 isInsideRounded =
true;
170 c.radiusInnerX = c.radiusInnerY = 0.0;
171 c.centerInnerX = ( c.sx < 0.0 ) ? innerRect.left() : innerRect.right();
172 c.centerInnerY = ( c.sy < 0.0 ) ? innerRect.top() : innerRect.bottom();
177 const auto tl = corners[ Qt::TopLeftCorner ].innerStepCount();
178 const auto tr = corners[ Qt::TopRightCorner ].innerStepCount();
179 const auto bl = corners[ Qt::BottomLeftCorner ].innerStepCount();
180 const auto br = corners[ Qt::BottomRightCorner ].innerStepCount();
182 if ( qMax( tl, tr ) + qMax( bl, br ) >= qMax( tl, bl ) + qMax( tr, br ) )
183 preferredOrientation = Qt::Vertical;
185 preferredOrientation = Qt::Horizontal;
189int QskBoxMetrics::outerStepCount()
const
191 return corners[0].stepCount + corners[1].stepCount
192 + corners[2].stepCount + corners[3].stepCount;
195int QskBoxMetrics::innerStepCount()
const
197 return corners[0].innerStepCount() + corners[1].innerStepCount()
198 + corners[2].innerStepCount() + corners[3].innerStepCount();