print: QPageLayout: Fix pt unit conversion
This patch corrects the miscalculation in point unit conversion, ensuring correct margin updates. Previously, non-pt units were rounded to two decimal places. When converting back to pt, rounding was to zero decimals, making the result always less than the original. This could result in margins falling below the minimum allowed. Example: original_points = 8.4 multiplier = 2.83464566929 mm: qRound(8.4 / multiplier * 100) / 100 = 2.96 new_points: qRound(2.96 * multiplier) = 8 // wrong! The fix rounds back-converted values up to two decimals, ensuring they are never less than the original and thus stay above minimum margins. new_points: qCeil(2.96 * multiplier * 100) / 100 = 8.4 Also, remove unused function qt_convertPoint. Change-Id: I6109f8d381aec96db1ce04cc167f7b73c1c0b9a8 Reviewed-by: David Faure <david.faure@kdab.com> (cherry picked from commit d420c1e25a0fb3b25ba4c572f2938701ce8494ec) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
85e7b700d9
commit
b3fdb93ba9
@ -39,41 +39,19 @@ Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit)
|
||||
// Multiplier for converting pixels to points.
|
||||
extern qreal qt_pixelMultiplier(int resolution);
|
||||
|
||||
QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
|
||||
{
|
||||
// If the size have the same units, or are all 0, then don't need to convert
|
||||
if (fromUnits == toUnits || xy.isNull())
|
||||
return xy;
|
||||
|
||||
// If converting to points then convert and round to 0 decimal places
|
||||
if (toUnits == QPageLayout::Point) {
|
||||
const qreal multiplier = qt_pointMultiplier(fromUnits);
|
||||
return QPointF(qRound(xy.x() * multiplier),
|
||||
qRound(xy.y() * multiplier));
|
||||
}
|
||||
|
||||
// If converting to other units, need to convert to unrounded points first
|
||||
QPointF pointXy = (fromUnits == QPageLayout::Point) ? xy : xy * qt_pointMultiplier(fromUnits);
|
||||
|
||||
// Then convert from points to required units rounded to 2 decimal places
|
||||
const qreal multiplier = qt_pointMultiplier(toUnits);
|
||||
return QPointF(qRound(pointXy.x() * 100 / multiplier) / 100.0,
|
||||
qRound(pointXy.y() * 100 / multiplier) / 100.0);
|
||||
}
|
||||
|
||||
Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
|
||||
{
|
||||
// If the margins have the same units, or are all 0, then don't need to convert
|
||||
if (fromUnits == toUnits || margins.isNull())
|
||||
return margins;
|
||||
|
||||
// If converting to points then convert and round to 0 decimal places
|
||||
// If converting to points then convert and round up to 2 decimal places
|
||||
if (toUnits == QPageLayout::Point) {
|
||||
const qreal multiplier = qt_pointMultiplier(fromUnits);
|
||||
return QMarginsF(qRound(margins.left() * multiplier),
|
||||
qRound(margins.top() * multiplier),
|
||||
qRound(margins.right() * multiplier),
|
||||
qRound(margins.bottom() * multiplier));
|
||||
const qreal multiplierX100 = qt_pointMultiplier(fromUnits) * 100;
|
||||
return QMarginsF(qCeil(margins.left() * multiplierX100) / 100.0,
|
||||
qCeil(margins.top() * multiplierX100) / 100.0,
|
||||
qCeil(margins.right() * multiplierX100) / 100.0,
|
||||
qCeil(margins.bottom() * multiplierX100) / 100.0);
|
||||
}
|
||||
|
||||
// If converting to other units, need to convert to unrounded points first
|
||||
|
@ -12,6 +12,8 @@ private slots:
|
||||
void invalid();
|
||||
void basics();
|
||||
void setGetMargins();
|
||||
void setUnits_data();
|
||||
void setUnits();
|
||||
};
|
||||
|
||||
void tst_QPageLayout::invalid()
|
||||
@ -238,6 +240,54 @@ void tst_QPageLayout::setGetMargins()
|
||||
QCOMPARE(fullPage.maximumMargins(), max);
|
||||
}
|
||||
|
||||
void tst_QPageLayout::setUnits_data()
|
||||
{
|
||||
QTest::addColumn<QPageLayout::Unit>("units");
|
||||
QTest::newRow("Millimeter") << QPageLayout::Millimeter;
|
||||
QTest::newRow("Point") << QPageLayout::Point;
|
||||
QTest::newRow("Inch") << QPageLayout::Inch;
|
||||
QTest::newRow("Pica") << QPageLayout::Pica;
|
||||
QTest::newRow("Didot") << QPageLayout::Didot;
|
||||
QTest::newRow("Cicero") << QPageLayout::Cicero;
|
||||
}
|
||||
|
||||
void tst_QPageLayout::setUnits()
|
||||
{
|
||||
QFETCH(QPageLayout::Unit, units);
|
||||
QPageLayout pageLayout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(), units);
|
||||
int maxLeftX100 = qFloor(pageLayout.maximumMargins().left() * 100);
|
||||
QVERIFY(maxLeftX100 > 0);
|
||||
for (int i = 1; i <= maxLeftX100; ++i) {
|
||||
const qreal margin = i / 100.;
|
||||
const QMarginsF unitsMargins = QMarginsF(margin, margin, margin, margin);
|
||||
pageLayout.setMargins(unitsMargins);
|
||||
pageLayout.setUnits(QPageLayout::Point);
|
||||
const QMarginsF pointsMargins = pageLayout.margins();
|
||||
if (units == QPageLayout::Point) {
|
||||
QCOMPARE(pointsMargins, unitsMargins);
|
||||
} else {
|
||||
QCOMPARE_GT(pointsMargins.left(), unitsMargins.left());
|
||||
QCOMPARE_GT(pointsMargins.top(), unitsMargins.top());
|
||||
QCOMPARE_GT(pointsMargins.right(), unitsMargins.right());
|
||||
QCOMPARE_GT(pointsMargins.bottom(), unitsMargins.bottom());
|
||||
}
|
||||
pageLayout.setUnits(units);
|
||||
const QMarginsF convertedUnitsMargins = pageLayout.margins();
|
||||
if (units == QPageLayout::Didot) {
|
||||
// When using Didot units, the small multiplier and ceiling function in conversion
|
||||
// may cause the converted units to not match the original exactly. However, we
|
||||
// can verify that the converted margins are always greater than or equal to the
|
||||
// original.
|
||||
QCOMPARE_GE(convertedUnitsMargins.left(), unitsMargins.left());
|
||||
QCOMPARE_GE(convertedUnitsMargins.top(), unitsMargins.top());
|
||||
QCOMPARE_GE(convertedUnitsMargins.right(), unitsMargins.right());
|
||||
QCOMPARE_GE(convertedUnitsMargins.bottom(), unitsMargins.bottom());
|
||||
} else {
|
||||
QCOMPARE(convertedUnitsMargins, unitsMargins);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QPageLayout)
|
||||
|
||||
#include "tst_qpagelayout.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user