File indexing completed on 2024-12-22 04:12:52
0001 /* 0002 * This file contains tests for: 0003 * 0004 * - KisPaintingAssistantsDecoration 0005 * - ParallelRulerAssistant 0006 * - PerspectiveAssistant 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 0011 #include <testutil.h> 0012 #include "qimage_based_test.h" 0013 0014 #include <KoCanvasResourceProvider.h> 0015 #include "kis_canvas_resource_provider.h" 0016 #include <util.h> 0017 #include <KisMainWindow.h> 0018 #include <KisDocument.h> 0019 #include <KisPart.h> 0020 #include <KisView.h> 0021 #include <KisViewManager.h> 0022 #include <KisDecorationsManager.h> 0023 0024 #include "kis_painting_assistants_decoration.h" 0025 #include "KisPart.h" 0026 #include "testui.h" 0027 #include <kis_config.h> 0028 #include <testutil.h> 0029 #include <KoResourcePaths.h> 0030 #include "opengl/kis_opengl.h" 0031 #include "kis_painting_assistants_decoration_test.h" 0032 0033 void KisPaintingAssistantsDecorationTest::initTestCase() 0034 { 0035 /* A bit of a heavy handed way to force the plugins to be loaded and get 0036 * access to the paintingAssistantsDecoration but can't find another way 0037 * at the moment 0038 */ 0039 m_document = createEmptyDocument(); 0040 m_mainWindow = KisPart::instance()->createMainWindow(); 0041 m_view = new KisView(m_document, m_mainWindow->viewManager(), m_mainWindow); 0042 m_viewManager = new KisViewManager(m_mainWindow, m_mainWindow->actionCollection()); 0043 QApplication::processEvents(); 0044 } 0045 0046 0047 void KisPaintingAssistantsDecorationTest::cleanupTestCase() 0048 { 0049 /* Clean-up properly otherwise there will be an 0050 * assert during application exit. 0051 */ 0052 m_mainWindow->hide(); 0053 QApplication::processEvents(); 0054 delete m_view; 0055 delete m_document; 0056 delete m_mainWindow; 0057 } 0058 0059 /* 0060 * Test Perspective Assistant construction and using it for brush position 0061 * Adjustment 0062 */ 0063 void KisPaintingAssistantsDecorationTest::testPerspectiveAssistant() 0064 { 0065 KisPaintingAssistantsDecorationSP paintingAssistantsDecoration = 0066 m_view->canvasBase()->paintingAssistantsDecoration(); 0067 0068 const KisPaintingAssistantFactoryRegistry* r = KisPaintingAssistantFactoryRegistry::instance(); 0069 QVERIFY(r); 0070 0071 KisPaintingAssistantFactory* factory = r->get("perspective"); 0072 QVERIFY(factory); 0073 0074 KisPaintingAssistantSP assistant = toQShared(factory->createPaintingAssistant()); 0075 0076 QVERIFY(assistant->isAssistantComplete() == false); 0077 0078 KisPaintingAssistantHandleSP h1 = new KisPaintingAssistantHandle(10.0, 10.0); 0079 KisPaintingAssistantHandleSP h2 = new KisPaintingAssistantHandle(20.0, 90.0); 0080 KisPaintingAssistantHandleSP h3 = new KisPaintingAssistantHandle(60.0, 90.0); 0081 KisPaintingAssistantHandleSP h4 = new KisPaintingAssistantHandle(70.0, 10.0); 0082 0083 assistant->addHandle(h1, NORMAL); 0084 assistant->addHandle(h2, NORMAL); 0085 assistant->addHandle(h3, NORMAL); 0086 assistant->addHandle(h4, NORMAL); 0087 0088 QVERIFY(assistant->isAssistantComplete() == true); 0089 0090 // Move straight up. 0091 QPointF startPosition(14.0, 14.0); 0092 QPointF p2(14.0, 90.0); 0093 QPointF adjustedPosition; 0094 // Compute twice to make sure state variables get taken into account 0095 adjustedPosition = assistant->adjustPosition(p2, startPosition, true, 4.0); 0096 adjustedPosition = assistant->adjustPosition(p2, startPosition, true, 4.0); 0097 // Should lead to a adjustment 0098 QVERIFY(adjustedPosition != p2); 0099 } 0100 0101 0102 /* 0103 * Test adjusting the brush position based on one or more Parallel rulers via 0104 * the PaintingAssistantDecoration. 0105 */ 0106 void KisPaintingAssistantsDecorationTest::testParallelRulerAdjustPosition() 0107 { 0108 KisPaintingAssistantsDecorationSP paintingAssistantsDecoration = 0109 m_view->canvasBase()->paintingAssistantsDecoration(); 0110 0111 QVERIFY(paintingAssistantsDecoration->isEditingAssistants() == false); 0112 0113 const KisPaintingAssistantFactoryRegistry* r = KisPaintingAssistantFactoryRegistry::instance(); 0114 QVERIFY(r); 0115 0116 KisPaintingAssistantFactory* factory = r->get("parallel ruler"); 0117 QVERIFY(factory); 0118 0119 KisPaintingAssistantSP assistant = toQShared(factory->createPaintingAssistant()); 0120 0121 QVERIFY(assistant->isAssistantComplete() == false); 0122 0123 // A horizontal parallel ruler 0124 KisPaintingAssistantHandleSP h1 = new KisPaintingAssistantHandle(10.0, 10.0); 0125 KisPaintingAssistantHandleSP h2 = new KisPaintingAssistantHandle(90.0, 10.0); 0126 assistant->addHandle(h1, NORMAL); 0127 assistant->addHandle(h2, NORMAL); 0128 // A parallel ruler assistant needs two handles so now it should be 0129 // complete 0130 QVERIFY(assistant->numHandles() == 2); 0131 QVERIFY(assistant->isAssistantComplete() == true); 0132 // The assistant is now complete and can be used for computing brush 0133 // position adjustments 0134 0135 0136 // Move in a slanted direction 0137 QPointF startPosition(10.0, 50.0); 0138 QPointF p2(90.0, 90.0); 0139 QPointF adjustedPosition; 0140 0141 // When the paintingAssistantsDecoration does not contain any assistants 0142 // there should be no position adjustments. 0143 // (Test twice to make sure state variables get taken into account). 0144 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p2, startPosition); 0145 QVERIFY(adjustedPosition == p2); 0146 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p2, startPosition); 0147 QVERIFY(adjustedPosition == p2); 0148 0149 // Add an assistant 0150 paintingAssistantsDecoration->addAssistant(assistant); 0151 0152 // First compute directly via the assistant 0153 adjustedPosition = assistant->adjustPosition(p2, startPosition, true, 4.0); 0154 // The position should be adjusted to the horizontal direction 0155 QVERIFY(adjustedPosition.x() == 90.0); 0156 QVERIFY(adjustedPosition.y() == 50.0); 0157 // Compute the same adjustment via the PaintingAssistantDecoration 0158 QPointF adjustedPosition2 = paintingAssistantsDecoration->adjustPosition(p2, startPosition); 0159 // Resulting positions should match 0160 QVERIFY(adjustedPosition == adjustedPosition2); 0161 0162 // Add two more assistants 0163 0164 // (1) A vertical parallel ruler 0165 KisPaintingAssistantSP assistant_2 = toQShared(factory->createPaintingAssistant()); 0166 KisPaintingAssistantHandleSP h3 = new KisPaintingAssistantHandle(10.0, 10.0); 0167 KisPaintingAssistantHandleSP h4 = new KisPaintingAssistantHandle(10.0, 90.0); 0168 assistant_2->addHandle(h3, NORMAL); 0169 assistant_2->addHandle(h4, NORMAL); 0170 0171 // (2) A 45 degree parallel ruler 0172 KisPaintingAssistantSP assistant_3 = toQShared(factory->createPaintingAssistant()); 0173 KisPaintingAssistantHandleSP h5 = new KisPaintingAssistantHandle(10.0, 10.0); 0174 KisPaintingAssistantHandleSP h6 = new KisPaintingAssistantHandle(90.0, 90.0); 0175 assistant_3->addHandle(h5, NORMAL); 0176 assistant_3->addHandle(h6, NORMAL); 0177 0178 paintingAssistantsDecoration->addAssistant(assistant_2); 0179 paintingAssistantsDecoration->addAssistant(assistant_3); 0180 0181 // startPosition == 10.0, 50.0 0182 QPointF p3(11.0, 50.1); // Less than |4| from the start position 0183 QPointF p4(15.0, 50.1); // More than |4| from the start position 0184 QPointF p5(18.0, 51.1); // Almost horizontal line 0185 QPointF p6(11.0, 65.1); // Almost vertical line 0186 0187 // Switch to the more were we continuously snap to the best matching 0188 // assistant 0189 paintingAssistantsDecoration->setOnlyOneAssistantSnap(false); 0190 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p3, startPosition); 0191 0192 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p4, startPosition); 0193 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p5, startPosition); 0194 // Horizontal ruler should be the best match 0195 QVERIFY(adjustedPosition.y() == 50.0); 0196 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p6, startPosition); 0197 // Vertical ruler should be the best match 0198 QVERIFY(adjustedPosition.x() == 10.0); 0199 paintingAssistantsDecoration->endStroke(); 0200 0201 // Switch to the more were first find the best matching 0202 // assistant and then keep using it 0203 paintingAssistantsDecoration->setOnlyOneAssistantSnap(true); 0204 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p3, startPosition); 0205 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p4, startPosition); 0206 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p5, startPosition); 0207 // Horizontal ruler should be the best match 0208 QVERIFY(adjustedPosition.y() == 50.0); 0209 adjustedPosition = paintingAssistantsDecoration->adjustPosition(p6, startPosition); 0210 // Horizontal ruler should still be the best match, even though we moved 0211 // vertically 0212 QVERIFY(adjustedPosition.y() == 50.0); 0213 paintingAssistantsDecoration->endStroke(); 0214 0215 } 0216 0217 0218 KISTEST_MAIN(KisPaintingAssistantsDecorationTest) 0219