diff --git a/autotests/output_transform_test.cpp b/autotests/output_transform_test.cpp index 16c99b896e..c9fa48e77b 100644 --- a/autotests/output_transform_test.cpp +++ b/autotests/output_transform_test.cpp @@ -22,6 +22,8 @@ private Q_SLOTS: void mapRectF(); void inverted_data(); void inverted(); + void combine_data(); + void combine(); }; TestOutputTransform::TestOutputTransform() @@ -101,6 +103,101 @@ void TestOutputTransform::inverted() QCOMPARE(KWin::OutputTransform(kind).inverted(), KWin::OutputTransform(inverted)); } +void TestOutputTransform::combine_data() +{ + QTest::addColumn("first"); + QTest::addColumn("second"); + QTest::addColumn("result"); + + QTest::addRow("rotate-0 | rotate-0") << KWin::OutputTransform::Normal << KWin::OutputTransform::Normal << KWin::OutputTransform::Normal; + QTest::addRow("rotate-90 | rotate-0") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated90; + QTest::addRow("rotate-180 | rotate-0") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated180; + QTest::addRow("rotate-270 | rotate-0") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated270; + QTest::addRow("flip-0 | rotate-0") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped; + QTest::addRow("flip-90 | rotate-0") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped90; + QTest::addRow("flip-180 | rotate-0") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped180; + QTest::addRow("flip-270 | rotate-0") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped270; + + QTest::addRow("rotate-0 | rotate-90") << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated90; + QTest::addRow("rotate-90 | rotate-90") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated180; + QTest::addRow("rotate-180 | rotate-90") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated270; + QTest::addRow("rotate-270 | rotate-90") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Normal; + QTest::addRow("flip-0 | rotate-90") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped270; + QTest::addRow("flip-90 | rotate-90") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped; + QTest::addRow("flip-180 | rotate-90") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped90; + QTest::addRow("flip-270 | rotate-90") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped180; + + QTest::addRow("rotate-0 | rotate-180") << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated180; + QTest::addRow("rotate-90 | rotate-180") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated270; + QTest::addRow("rotate-180 | rotate-180") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Normal; + QTest::addRow("rotate-270 | rotate-180") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated90; + QTest::addRow("flip-0 | rotate-180") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped180; + QTest::addRow("flip-90 | rotate-180") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped270; + QTest::addRow("flip-180 | rotate-180") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped; + QTest::addRow("flip-270 | rotate-180") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped90; + + QTest::addRow("rotate-0 | rotate-270") << KWin::OutputTransform::Normal << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated270; + QTest::addRow("rotate-90 | rotate-270") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Normal; + QTest::addRow("rotate-180 | rotate-270") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated90; + QTest::addRow("rotate-270 | rotate-270") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Rotated180; + QTest::addRow("flip-0 | rotate-270") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped90; + QTest::addRow("flip-90 | rotate-270") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped180; + QTest::addRow("flip-180 | rotate-270") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped270; + QTest::addRow("flip-270 | rotate-270") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped; + + QTest::addRow("rotate-0 | flip-0") << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped; + QTest::addRow("rotate-90 | flip-0") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped90; + QTest::addRow("rotate-180 | flip-0") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped180; + QTest::addRow("rotate-270 | flip-0") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped270; + QTest::addRow("flip-0 | flip-0") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped << KWin::OutputTransform::Normal; + QTest::addRow("flip-90 | flip-0") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated90; + QTest::addRow("flip-180 | flip-0") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated180; + QTest::addRow("flip-270 | flip-0") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped << KWin::OutputTransform::Rotated270; + + QTest::addRow("rotate-0 | flip-90") << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped90; + QTest::addRow("rotate-90 | flip-90") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped180; + QTest::addRow("rotate-180 | flip-90") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped270; + QTest::addRow("rotate-270 | flip-90") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped; + QTest::addRow("flip-0 | flip-90") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated270; + QTest::addRow("flip-90 | flip-90") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Normal; + QTest::addRow("flip-180 | flip-90") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated90; + QTest::addRow("flip-270 | flip-90") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Rotated180; + + QTest::addRow("rotate-0 | flip-180") << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped180; + QTest::addRow("rotate-90 | flip-180") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped270; + QTest::addRow("rotate-180 | flip-180") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped; + QTest::addRow("rotate-270 | flip-180") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped90; + QTest::addRow("flip-0 | flip-180") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated180; + QTest::addRow("flip-90 | flip-180") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated270; + QTest::addRow("flip-180 | flip-180") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Normal; + QTest::addRow("flip-270 | flip-180") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Rotated90; + + QTest::addRow("rotate-0 | flip-270") << KWin::OutputTransform::Normal << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped270; + QTest::addRow("rotate-90 | flip-270") << KWin::OutputTransform::Rotated90 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped; + QTest::addRow("rotate-180 | flip-270") << KWin::OutputTransform::Rotated180 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped90; + QTest::addRow("rotate-270 | flip-270") << KWin::OutputTransform::Rotated270 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped180; + QTest::addRow("flip-0 | flip-270") << KWin::OutputTransform::Flipped << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated90; + QTest::addRow("flip-90 | flip-270") << KWin::OutputTransform::Flipped90 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated180; + QTest::addRow("flip-180 | flip-270") << KWin::OutputTransform::Flipped180 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Rotated270; + QTest::addRow("flip-270 | flip-270") << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Flipped270 << KWin::OutputTransform::Normal; +} + +void TestOutputTransform::combine() +{ + QFETCH(KWin::OutputTransform::Kind, first); + QFETCH(KWin::OutputTransform::Kind, second); + QFETCH(KWin::OutputTransform::Kind, result); + + const KWin::OutputTransform firstTransform(first); + const KWin::OutputTransform secondTransform(second); + const KWin::OutputTransform combinedTransform = firstTransform.combine(secondTransform); + QCOMPARE(combinedTransform.kind(), result); + + const QRectF box(10, 20, 30, 40); + const QSizeF bounds(100, 200); + QCOMPARE(combinedTransform.map(box, bounds), secondTransform.map(firstTransform.map(box, bounds), firstTransform.map(bounds))); +} + QTEST_MAIN(TestOutputTransform) #include "output_transform_test.moc" diff --git a/src/core/output.cpp b/src/core/output.cpp index 833dcd685f..e2ec638aa3 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -156,6 +156,91 @@ QSizeF OutputTransform::map(const QSizeF &size) const } } +OutputTransform OutputTransform::combine(OutputTransform other) const +{ + int rotations = 0; + switch (other.kind()) { + case Kind::Normal: + case Kind::Flipped: + rotations = 0; + break; + case Kind::Rotated90: + case Kind::Flipped90: + rotations = 1; + break; + case Kind::Rotated180: + case Kind::Flipped180: + rotations = 2; + break; + case Kind::Rotated270: + case Kind::Flipped270: + rotations = 3; + break; + } + OutputTransform ret = m_kind; + for (int i = 0; i < rotations; i++) { + switch (ret.kind()) { + case Kind::Normal: + ret = Kind::Rotated90; + break; + case Kind::Rotated90: + ret = Kind::Rotated180; + break; + case Kind::Rotated180: + ret = Kind::Rotated270; + break; + case Kind::Rotated270: + ret = Kind::Normal; + break; + case Kind::Flipped: + ret = Kind::Flipped270; + break; + case Kind::Flipped90: + ret = Kind::Flipped; + break; + case Kind::Flipped180: + ret = Kind::Flipped90; + break; + case Kind::Flipped270: + ret = Kind::Flipped180; + break; + } + } + const bool otherFlipped = other.kind() == OutputTransform::Kind::Flipped + || other.kind() == OutputTransform::Kind::Flipped90 + || other.kind() == OutputTransform::Kind::Flipped180 + || other.kind() == OutputTransform::Kind::Flipped270; + if (otherFlipped) { + switch (ret.kind()) { + case Kind::Normal: + ret = Kind::Flipped; + break; + case Kind::Rotated90: + ret = Kind::Flipped90; + break; + case Kind::Rotated180: + ret = Kind::Flipped180; + break; + case Kind::Rotated270: + ret = Kind::Flipped270; + break; + case Kind::Flipped: + ret = Kind::Normal; + break; + case Kind::Flipped90: + ret = Kind::Rotated90; + break; + case Kind::Flipped180: + ret = Kind::Rotated180; + break; + case Kind::Flipped270: + ret = Kind::Rotated270; + break; + } + } + return ret; +} + Output::Output(QObject *parent) : QObject(parent) { diff --git a/src/core/output.h b/src/core/output.h index 8e0bb23fca..5e9690da68 100644 --- a/src/core/output.h +++ b/src/core/output.h @@ -84,6 +84,12 @@ public: */ QRectF map(const QRectF &rect, const QSizeF &bounds) const; + /** + * Returns an output transform that is equivalent to applying this transform and @a other + * transform sequentially. + */ + OutputTransform combine(OutputTransform other) const; + private: Kind m_kind = Kind::Normal; };