File indexing completed on 2024-05-26 04:26:29
0001 /* 0002 * SPDX-FileCopyrightText: 2006-2010 Thomas Zander <zander@kde.org> 0003 * SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "TestShapePainting.h" 0007 0008 #include <QtGui> 0009 #include "KoShapeContainer.h" 0010 #include "KoShapeManager.h" 0011 0012 #include <MockShapes.h> 0013 #include <testflake.h> 0014 0015 0016 #include <simpletest.h> 0017 0018 void TestShapePainting::testPaintShape() 0019 { 0020 MockShape *shape1 = new MockShape(); 0021 MockShape *shape2 = new MockShape(); 0022 QScopedPointer<MockContainer> container(new MockContainer()); 0023 0024 container->addShape(shape1); 0025 container->addShape(shape2); 0026 QCOMPARE(shape1->parent(), container.data()); 0027 QCOMPARE(shape2->parent(), container.data()); 0028 container->setClipped(shape1, false); 0029 container->setClipped(shape2, false); 0030 QCOMPARE(container->isClipped(shape1), false); 0031 QCOMPARE(container->isClipped(shape2), false); 0032 0033 MockCanvas canvas; 0034 KoShapeManager manager(&canvas); 0035 manager.addShape(container.data()); 0036 QCOMPARE(manager.shapes().count(), 3); 0037 0038 QImage image(100, 100, QImage::Format_Mono); 0039 QPainter painter(&image); 0040 manager.paint(painter); 0041 0042 // with the shape not being clipped, the shapeManager will paint it for us. 0043 QCOMPARE(shape1->paintedCount, 1); 0044 QCOMPARE(shape2->paintedCount, 1); 0045 QCOMPARE(container->paintedCount, 1); 0046 0047 // the container should thus not paint the shape 0048 shape1->paintedCount = 0; 0049 shape2->paintedCount = 0; 0050 container->paintedCount = 0; 0051 0052 container->paint(painter); 0053 QCOMPARE(shape1->paintedCount, 0); 0054 QCOMPARE(shape2->paintedCount, 0); 0055 QCOMPARE(container->paintedCount, 1); 0056 0057 0058 container->setClipped(shape1, false); 0059 container->setClipped(shape2, true); 0060 QCOMPARE(container->isClipped(shape1), false); 0061 QCOMPARE(container->isClipped(shape2), true); 0062 0063 shape1->paintedCount = 0; 0064 shape2->paintedCount = 0; 0065 container->paintedCount = 0; 0066 manager.paint(painter); 0067 0068 0069 // with this shape not being clipped, the shapeManager will paint the container and this shape 0070 QCOMPARE(shape1->paintedCount, 1); 0071 // with this shape being clipped, the container will paint it for us. 0072 QCOMPARE(shape2->paintedCount, 1); 0073 QCOMPARE(container->paintedCount, 1); 0074 } 0075 0076 void TestShapePainting::testPaintHiddenShape() 0077 { 0078 QScopedPointer<MockContainer> top(new MockContainer()); 0079 0080 MockShape *shape = new MockShape(); 0081 MockContainer *fourth = new MockContainer(); 0082 MockContainer *third = new MockContainer(); 0083 MockContainer *second = new MockContainer(); 0084 0085 0086 top->addShape(second); 0087 second->addShape(third); 0088 third->addShape(fourth); 0089 fourth->addShape(shape); 0090 0091 second->setVisible(false); 0092 0093 MockCanvas canvas; 0094 KoShapeManager manager(&canvas); 0095 manager.addShape(top.data()); 0096 QCOMPARE(manager.shapes().count(), 5); 0097 0098 QImage image(100, 100, QImage::Format_Mono); 0099 QPainter painter(&image); 0100 manager.paint(painter); 0101 0102 QCOMPARE(top->paintedCount, 1); 0103 QCOMPARE(second->paintedCount, 0); 0104 QCOMPARE(third->paintedCount, 0); 0105 QCOMPARE(fourth->paintedCount, 0); 0106 QCOMPARE(shape->paintedCount, 0); 0107 } 0108 0109 void TestShapePainting::testPaintOrder() 0110 { 0111 // the stacking order determines the painting order so things on top 0112 // get their paint called last. 0113 // Each shape has a zIndex and within the children a container has 0114 // it determines the stacking order. Its important to realize that 0115 // the zIndex is thus local to a container, if you have layer1 and layer2 0116 // with both various child shapes the stacking order of the layer shapes 0117 // is most important, then within this the child shape index is used. 0118 0119 class OrderedMockShape : public MockShape { 0120 public: 0121 OrderedMockShape(QList<const MockShape*> *list) : order(list) {} 0122 void paint(QPainter &painter) const override { 0123 order->append(this); 0124 MockShape::paint(painter); 0125 } 0126 mutable QList<const MockShape*> *order; 0127 }; 0128 0129 QList<const MockShape*> order; 0130 0131 { 0132 QScopedPointer<MockContainer> top(new MockContainer()); 0133 top->setZIndex(2); 0134 OrderedMockShape *shape1 = new OrderedMockShape(&order); 0135 shape1->setZIndex(5); 0136 OrderedMockShape *shape2 = new OrderedMockShape(&order); 0137 shape2->setZIndex(0); 0138 top->addShape(shape1); 0139 top->addShape(shape2); 0140 0141 QScopedPointer<MockContainer> bottom(new MockContainer()); 0142 bottom->setZIndex(1); 0143 OrderedMockShape *shape3 = new OrderedMockShape(&order); 0144 shape3->setZIndex(-1); 0145 OrderedMockShape *shape4 = new OrderedMockShape(&order); 0146 shape4->setZIndex(9); 0147 bottom->addShape(shape3); 0148 bottom->addShape(shape4); 0149 0150 MockCanvas canvas; 0151 KoShapeManager manager(&canvas); 0152 manager.addShape(top.data()); 0153 manager.addShape(bottom.data()); 0154 QCOMPARE(manager.shapes().count(), 6); 0155 0156 QImage image(100, 100, QImage::Format_Mono); 0157 QPainter painter(&image); 0158 manager.paint(painter); 0159 QCOMPARE(top->paintedCount, 1); 0160 QCOMPARE(bottom->paintedCount, 1); 0161 QCOMPARE(shape1->paintedCount, 1); 0162 QCOMPARE(shape2->paintedCount, 1); 0163 QCOMPARE(shape3->paintedCount, 1); 0164 QCOMPARE(shape4->paintedCount, 1); 0165 0166 QCOMPARE(order.count(), 4); 0167 QVERIFY(order[0] == shape3); // lowest first 0168 QVERIFY(order[1] == shape4); 0169 QVERIFY(order[2] == shape2); 0170 QVERIFY(order[3] == shape1); 0171 0172 // again, with clipping. 0173 order.clear(); 0174 painter.setClipRect(0, 0, 100, 100); 0175 manager.paint(painter); 0176 QCOMPARE(top->paintedCount, 2); 0177 QCOMPARE(bottom->paintedCount, 2); 0178 QCOMPARE(shape1->paintedCount, 2); 0179 QCOMPARE(shape2->paintedCount, 2); 0180 QCOMPARE(shape3->paintedCount, 2); 0181 QCOMPARE(shape4->paintedCount, 2); 0182 0183 QCOMPARE(order.count(), 4); 0184 QVERIFY(order[0] == shape3); // lowest first 0185 QVERIFY(order[1] == shape4); 0186 QVERIFY(order[2] == shape2); 0187 QVERIFY(order[3] == shape1); 0188 0189 } 0190 0191 order.clear(); 0192 0193 { 0194 QScopedPointer<MockContainer> root(new MockContainer()); 0195 root->setZIndex(0); 0196 0197 MockContainer *branch1 = new MockContainer(); 0198 branch1->setZIndex(1); 0199 OrderedMockShape *child1_1 = new OrderedMockShape(&order); 0200 child1_1->setZIndex(1); 0201 OrderedMockShape *child1_2 = new OrderedMockShape(&order); 0202 child1_2->setZIndex(2); 0203 branch1->addShape(child1_1); 0204 branch1->addShape(child1_2); 0205 0206 MockContainer *branch2 = new MockContainer(); 0207 branch2->setZIndex(2); 0208 OrderedMockShape *child2_1 = new OrderedMockShape(&order); 0209 child2_1->setZIndex(1); 0210 OrderedMockShape *child2_2 = new OrderedMockShape(&order); 0211 child2_2->setZIndex(2); 0212 branch2->addShape(child2_1); 0213 branch2->addShape(child2_2); 0214 0215 root->addShape(branch1); 0216 root->addShape(branch2); 0217 0218 QList<KoShape*> sortedShapes; 0219 sortedShapes.append(root.data()); 0220 sortedShapes.append(branch1); 0221 sortedShapes.append(branch2); 0222 sortedShapes.append(branch1->shapes()); 0223 sortedShapes.append(branch2->shapes()); 0224 0225 std::sort(sortedShapes.begin(), sortedShapes.end(), KoShape::compareShapeZIndex); 0226 QCOMPARE(sortedShapes.count(), 7); 0227 QVERIFY(sortedShapes[0] == root.data()); 0228 QVERIFY(sortedShapes[1] == branch1); 0229 QVERIFY(sortedShapes[2] == child1_1); 0230 QVERIFY(sortedShapes[3] == child1_2); 0231 QVERIFY(sortedShapes[4] == branch2); 0232 QVERIFY(sortedShapes[5] == child2_1); 0233 QVERIFY(sortedShapes[6] == child2_2); 0234 } 0235 } 0236 #include <kundo2command.h> 0237 #include <KoShapeController.h> 0238 #include <KoShapeGroupCommand.h> 0239 #include <KoShapeUngroupCommand.h> 0240 #include "kis_debug.h" 0241 void TestShapePainting::testGroupUngroup() 0242 { 0243 MockShapeController controller; 0244 MockCanvas canvas(&controller); 0245 0246 KoShapeManager *manager = canvas.shapeManager(); 0247 0248 QScopedPointer<MockContainer> shapesFakeLayer(new MockContainer()); 0249 shapesFakeLayer->setAssociatedRootShapeManager(manager); 0250 0251 MockShape *shape1(new MockShape()); 0252 MockShape *shape2(new MockShape()); 0253 shape1->setName("shape1"); 0254 shape2->setName("shape2"); 0255 shape1->setParent(shapesFakeLayer.data()); 0256 shape2->setParent(shapesFakeLayer.data()); 0257 0258 QList<KoShape*> groupedShapes = {shape1, shape2}; 0259 0260 QImage image(100, 100, QImage::Format_Mono); 0261 QPainter painter(&image); 0262 painter.setClipRect(image.rect()); 0263 0264 for (int i = 0; i < 3; i++) { 0265 KoShapeGroup *group = new KoShapeGroup(); 0266 0267 { 0268 group->setName("group"); 0269 0270 KUndo2Command groupingCommand; 0271 canvas.shapeController()->addShapeDirect(group, shapesFakeLayer.data(), &groupingCommand); 0272 new KoShapeGroupCommand(group, groupedShapes, true, &groupingCommand); 0273 0274 groupingCommand.redo(); 0275 0276 manager->paint(painter); 0277 0278 QCOMPARE(shape1->paintedCount, 2 * i + 1); 0279 QCOMPARE(shape2->paintedCount, 2 * i + 1); 0280 QCOMPARE(manager->shapes().size(), 3); 0281 } 0282 0283 { 0284 KUndo2Command ungroupingCommand; 0285 0286 new KoShapeUngroupCommand(group, group->shapes(), QList<KoShape*>(), &ungroupingCommand); 0287 canvas.shapeController()->removeShape(group, &ungroupingCommand); 0288 // NOTE: group will be deleted in ungroupingCommand's d-tor 0289 0290 ungroupingCommand.redo(); 0291 0292 manager->paint(painter); 0293 0294 QCOMPARE(shape1->paintedCount, 2 * i + 2); 0295 QCOMPARE(shape2->paintedCount, 2 * i + 2); 0296 QCOMPARE(manager->shapes().size(), 2); 0297 } 0298 } 0299 } 0300 0301 KISTEST_MAIN(TestShapePainting)