diff options
Diffstat (limited to 'src/gui/util/qgridlayoutengine.cpp')
-rw-r--r-- | src/gui/util/qgridlayoutengine.cpp | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp index 861b713efd..572dce9675 100644 --- a/src/gui/util/qgridlayoutengine.cpp +++ b/src/gui/util/qgridlayoutengine.cpp @@ -154,7 +154,7 @@ void QGridLayoutRowData::reset(int count) hasIgnoreFlag = false; } -void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) +void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo, bool snapToPixelGrid) { MultiCellMap::const_iterator i = multiCellMap.constBegin(); for (; i != multiCellMap.constEnd(); ++i) { @@ -173,7 +173,7 @@ void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) qreal extra = compare(box, totalBox, j); if (extra > 0.0) { calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(), - 0, totalBox, rowInfo); + 0, totalBox, rowInfo, snapToPixelGrid); for (int k = 0; k < span; ++k) extras[k].q_sizes(j) = newSizes[k]; @@ -188,11 +188,19 @@ void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo) } multiCellMap.clear(); } +namespace { +// does not return int +static inline qreal qround(qreal f) +{ + return floor(f + 0.5); +} + +} void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes, qreal *descents, const QGridLayoutBox &totalBox, - const QGridLayoutRowInfo &rowInfo) + const QGridLayoutRowInfo &rowInfo, bool snapToPixelGrid) { Q_ASSERT(end > start); @@ -335,17 +343,19 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz bool keepGoing = somethingHasAMaximumSize; while (keepGoing) { + //sumCurrentAvailable is so large that something *might* reach its maximum size keepGoing = false; for (int i = 0; i < n; ++i) { if (newSizes[i] >= 0.0) continue; - qreal maxBoxSize; - if (isLargerThanMaximum) - maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize; - else - maxBoxSize = boxes.at(start + i).q_maximumSize; + const QVector<QGridLayoutBox> &rBoxes = isLargerThanMaximum ? rowInfo.boxes : boxes; + const QGridLayoutBox &box = rBoxes.value(start + i); + qreal maxBoxSize = box.q_maximumSize; + + if (snapToPixelGrid) + maxBoxSize = qMax(box.q_minimumSize, floor(maxBoxSize)); qreal avail = sumCurrentAvailable * factors[i] / sumFactors; if (sizes[i] + avail >= maxBoxSize) { @@ -358,7 +368,6 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz } } } - for (int i = 0; i < n; ++i) { if (newSizes[i] < 0.0) { qreal delta = (sumFactors == 0.0) ? 0.0 @@ -402,6 +411,10 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz Q_ASSERT(surplus == 0); #endif } + if (snapToPixelGrid) { + for (int i = 0; i < n; ++i) + positions[i] = qround(positions[i]); + } if (descents) { for (int i = 0; i < n; ++i) { @@ -753,10 +766,11 @@ void QGridLayoutRowInfo::dump(int indent) const } #endif -QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment) +QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment, bool snapToPixelGrid) { m_visualDirection = Qt::LeftToRight; m_defaultAlignment = defaultAlignment; + m_snapToPixelGrid = snapToPixelGrid; invalidate(); } @@ -1007,8 +1021,17 @@ void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbs if (item->rowSpan() != 1) height += q_yy[item->lastRow()] - y; + const Qt::Alignment align = effectiveAlignment(item); QRectF geom = item->geometryWithin(contentsGeometry.x() + x, contentsGeometry.y() + y, - width, height, q_descents[item->lastRow()], effectiveAlignment(item)); + width, height, q_descents[item->lastRow()], align); + if (m_snapToPixelGrid) { + // x and y should already be rounded, but the call to geometryWithin() above might + // result in a geom with x,y at half-pixels (due to centering within the cell) + geom.setX(qround(geom.x())); + // Do not snap baseline aligned items, since that might cause the baselines to not be aligned. + if (align != Qt::AlignBaseline) + geom.setY(qround(geom.y())); + } visualRect(&geom, visualDirection(), contentsGeometry); item->setGeometry(geom); } @@ -1061,7 +1084,7 @@ QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint, //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as //constraints to find the row heights q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(), - 0, sizehint_totalBoxes[Hor], q_infos[Hor]); + 0, sizehint_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid); ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical, styleInfo); sizeHintCalculated = true; } @@ -1078,7 +1101,7 @@ QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint, //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as //constraints to find the column widths q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(), - 0, sizehint_totalBoxes[Ver], q_infos[Ver]); + 0, sizehint_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid); ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal, styleInfo); sizeHintCalculated = true; } @@ -1533,7 +1556,7 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri rowData->reset(rowCount(orientation)); fillRowData(rowData, colPositions, colSizes, orientation, styleInfo); const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical]; - rowData->distributeMultiCells(rowInfo); + rowData->distributeMultiCells(rowInfo, m_snapToPixelGrid); *totalBox = rowData->totalBox(0, rowCount(orientation)); if (totalBox != &q_totalBoxes[o]) @@ -1605,22 +1628,22 @@ void QGridLayoutEngine::ensureGeometries(const QSizeF &size, //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as //constraints to find the row heights q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor], q_infos[Hor] ); + 0, q_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid); ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], q_xx.data(), q_widths.data(), Qt::Vertical, styleInfo); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); + q_descents.data(), q_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid); } else { //We have items whose width depends on their height (WFH) ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as //constraints to find the column widths q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), - q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); + q_descents.data(), q_totalBoxes[Ver], q_infos[Ver], m_snapToPixelGrid); ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], q_yy.data(), q_heights.data(), Qt::Horizontal, styleInfo); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), - 0, q_totalBoxes[Hor], q_infos[Hor]); + 0, q_totalBoxes[Hor], q_infos[Hor], m_snapToPixelGrid); } } |