diff --git a/autotests/output_transform_test.cpp b/autotests/output_transform_test.cpp index f01e9d7e7b..baff029d4b 100644 --- a/autotests/output_transform_test.cpp +++ b/autotests/output_transform_test.cpp @@ -26,6 +26,10 @@ private Q_SLOTS: void mapRectF(); void mapRect_data(); void mapRect(); + void mapPointF_data(); + void mapPointF(); + void mapPoint_data(); + void mapPoint(); void inverted_data(); void inverted(); void combine_data(); @@ -138,6 +142,62 @@ void TestOutputTransform::mapRect() QCOMPARE(OutputTransform(kind).map(source, QSize(100, 200)), target); } +void TestOutputTransform::mapPointF_data() +{ + QTest::addColumn("kind"); + QTest::addColumn("source"); + QTest::addColumn("target"); + + QTest::addRow("rotate-0") << OutputTransform::Normal << QPointF(10, 20) << QPointF(10, 20); + QTest::addRow("rotate-90") << OutputTransform::Rotated90 << QPointF(10, 20) << QPointF(180, 10); + QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QPointF(10, 20) << QPointF(90, 180); + QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QPointF(10, 20) << QPointF(20, 90); + QTest::addRow("flip-0") << OutputTransform::Flipped << QPointF(10, 20) << QPointF(90, 20); + QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPointF(10, 20) << QPointF(20, 10); + QTest::addRow("flip-180") << OutputTransform::Flipped180 << QPointF(10, 20) << QPointF(10, 180); + QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPointF(10, 20) << QPointF(180, 90); +} + +void TestOutputTransform::mapPointF() +{ + QFETCH(OutputTransform::Kind, kind); + QFETCH(QPointF, source); + QFETCH(QPointF, target); + + const OutputTransform transform(kind); + + QCOMPARE(transform.map(source, QSizeF(100, 200)), target); + QCOMPARE(transform.map(QRectF(source, QSizeF(0, 0)), QSizeF(100, 200)), QRectF(target, QSizeF(0, 0))); +} + +void TestOutputTransform::mapPoint_data() +{ + QTest::addColumn("kind"); + QTest::addColumn("source"); + QTest::addColumn("target"); + + QTest::addRow("rotate-0") << OutputTransform::Normal << QPoint(10, 20) << QPoint(10, 20); + QTest::addRow("rotate-90") << OutputTransform::Rotated90 << QPoint(10, 20) << QPoint(180, 10); + QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QPoint(10, 20) << QPoint(90, 180); + QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QPoint(10, 20) << QPoint(20, 90); + QTest::addRow("flip-0") << OutputTransform::Flipped << QPoint(10, 20) << QPoint(90, 20); + QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPoint(10, 20) << QPoint(20, 10); + QTest::addRow("flip-180") << OutputTransform::Flipped180 << QPoint(10, 20) << QPoint(10, 180); + QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPoint(10, 20) << QPoint(180, 90); +} + +void TestOutputTransform::mapPoint() +{ + QFETCH(OutputTransform::Kind, kind); + QFETCH(QPoint, source); + QFETCH(QPoint, target); + + const OutputTransform transform(kind); + + QCOMPARE(transform.map(source, QSize(100, 200)), target); + QCOMPARE(transform.map(QRect(source, QSize(0, 0)), QSize(100, 200)), QRect(target, QSize(0, 0))); +} + void TestOutputTransform::inverted_data() { QTest::addColumn("kind"); diff --git a/src/core/output.cpp b/src/core/output.cpp index 11a7b0c9d4..7a1069596f 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -199,6 +199,68 @@ QRect OutputTransform::map(const QRect &rect, const QSize &bounds) const return dest; } +QPointF OutputTransform::map(const QPointF &point, const QSizeF &bounds) const +{ + switch (m_kind) { + case Kind::Normal: + return point; + case Kind::Rotated90: + return QPointF(bounds.height() - point.y(), + point.x()); + case Kind::Rotated180: + return QPointF(bounds.width() - point.x(), + bounds.height() - point.y()); + case Kind::Rotated270: + return QPointF(point.y(), + bounds.width() - point.x()); + case Kind::Flipped: + return QPointF(bounds.width() - point.x(), + point.y()); + case Kind::Flipped90: + return QPointF(point.y(), + point.x()); + case Kind::Flipped180: + return QPointF(point.x(), + bounds.height() - point.y()); + case Kind::Flipped270: + return QPointF(bounds.height() - point.y(), + bounds.width() - point.x()); + default: + Q_UNREACHABLE(); + } +} + +QPoint OutputTransform::map(const QPoint &point, const QSize &bounds) const +{ + switch (m_kind) { + case Kind::Normal: + return point; + case Kind::Rotated90: + return QPoint(bounds.height() - point.y(), + point.x()); + case Kind::Rotated180: + return QPoint(bounds.width() - point.x(), + bounds.height() - point.y()); + case Kind::Rotated270: + return QPoint(point.y(), + bounds.width() - point.x()); + case Kind::Flipped: + return QPoint(bounds.width() - point.x(), + point.y()); + case Kind::Flipped90: + return QPoint(point.y(), + point.x()); + case Kind::Flipped180: + return QPoint(point.x(), + bounds.height() - point.y()); + case Kind::Flipped270: + return QPoint(bounds.height() - point.y(), + bounds.width() - point.x()); + default: + Q_UNREACHABLE(); + } +} + QSizeF OutputTransform::map(const QSizeF &size) const { switch (m_kind) { diff --git a/src/core/output.h b/src/core/output.h index c1fc1744de..c6624a5b28 100644 --- a/src/core/output.h +++ b/src/core/output.h @@ -79,6 +79,12 @@ public: QRectF map(const QRectF &rect, const QSizeF &bounds) const; QRect map(const QRect &rect, const QSize &bounds) const; + /** + * Applies the output transform to the given @a point. + */ + QPointF map(const QPointF &point, const QSizeF &bounds) const; + QPoint map(const QPoint &point, const QSize &bounds) const; + /** * Returns an output transform that is equivalent to applying this transform and @a other * transform sequentially.