1 /*
2 * Copyright (c) 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "kis_colorize_mask_test.h"
20
21 #include <QTest>
22
23 #include "testutil.h"
24 #include "lazybrush/kis_colorize_mask.h"
25 #include "kis_paint_device_debug_utils.h"
26 #include "kis_global.h"
27 #include "lazybrush/kis_lazy_fill_tools.h"
28 #include "kundo2command.h"
29 #include "kistest.h"
30
31 #include <KoColor.h>
32
33 struct ColorizeMaskTester
34 {
ColorizeMaskTesterColorizeMaskTester35 ColorizeMaskTester()
36 : refRect(0,0,200,200),
37 p(refRect)
38 {
39 KisPaintDeviceSP src = p.layer->paintDevice();
40
41 fillRect = kisGrowRect(refRect, -20);
42 internalFillRect = kisGrowRect(fillRect, -10);
43 src->fill(fillRect, KoColor(Qt::black, src->colorSpace()));
44 src->fill(internalFillRect, KoColor(Qt::transparent, src->colorSpace()));
45 src->fill(QRect(100, 10, 10, 130), KoColor(Qt::black, src->colorSpace()));
46
47 // KIS_DUMP_DEVICE_2(src, refRect, "src", "dd");
48
49 mask = new KisColorizeMask(p.image, "mask1");
50 p.image->addNode(mask, p.layer);
51
52 mask->initializeCompositeOp();
53
54 {
55 KisPaintDeviceSP key1 = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8());
56 key1->fill(QRect(50,50,10,20), KoColor(Qt::black, key1->colorSpace()));
57 mask->testingAddKeyStroke(key1, KoColor(Qt::green, src->colorSpace()));
58 // KIS_DUMP_DEVICE_2(key1, refRect, "key1", "dd");
59 }
60
61 {
62 KisPaintDeviceSP key2 = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8());
63 key2->fill(QRect(150,50,10,20), KoColor(Qt::black, key2->colorSpace()));
64 mask->testingAddKeyStroke(key2, KoColor(Qt::red, src->colorSpace()));
65 // KIS_DUMP_DEVICE_2(key2, refRect, "key2", "dd");
66 }
67
68 {
69 KisPaintDeviceSP key3 = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8());
70 key3->fill(QRect(0,0,10,10), KoColor(Qt::black, key3->colorSpace()));
71 mask->testingAddKeyStroke(key3, KoColor(Qt::blue, src->colorSpace()), true);
72 // KIS_DUMP_DEVICE_2(key3, refRect, "key3", "dd");
73 }
74
75 mask->resetCache();
76
77 mask->testingRegenerateMask();
78 p.image->waitForDone();
79
80 // KIS_DUMP_DEVICE_2(mask->coloringProjection(), refRect, "coloring", "dd");
81 // KIS_DUMP_DEVICE_2(mask->paintDevice(), refRect, "paintDevice", "dd");
82 // KIS_DUMP_DEVICE_2(mask->testingFilteredSource(), refRect, "filteredSource", "dd");
83 }
84
85 QRect refRect;
86 TestUtil::MaskParent p;
87 KisColorizeMaskSP mask;
88
89 QRect fillRect;
90 QRect internalFillRect;
91 };
92
93
test()94 void KisColorizeMaskTest::test()
95 {
96 ColorizeMaskTester t;
97
98 QList<KisLazyFillTools::KeyStroke> strokes;
99
100 strokes = t.mask->fetchKeyStrokesDirect();
101
102 const QRect expectedFillRect(25,25,145,150);
103
104 // Check initial bounding rects
105
106 QCOMPARE(t.mask->paintDevice()->exactBounds(), QRect(0,0,160,70));
107 QCOMPARE(t.mask->coloringProjection()->exactBounds(), expectedFillRect);
108 QCOMPARE(t.mask->testingFilteredSource()->exactBounds(), t.refRect);
109
110 QCOMPARE(strokes[0].dev->exactBounds(), QRect(50,50,10,20));
111 QCOMPARE(strokes[1].dev->exactBounds(), QRect(150,50,10,20));
112 QCOMPARE(strokes[2].dev->exactBounds(), QRect(0,0,10,10));
113
114 // Move the t.mask: the filled area is also expected to be moved!
115 t.mask->setX(5);
116 t.mask->setY(7);
117
118 // KIS_DUMP_DEVICE_2(t.mask->coloringProjection(), t.refRect, "coloring2", "dd");
119 // KIS_DUMP_DEVICE_2(t.mask->paintDevice(), t.refRect, "paintDevice2", "dd");
120 // KIS_DUMP_DEVICE_2(t.mask->testingFilteredSource(), t.refRect, "filteredSource2", "dd");
121
122 QCOMPARE(t.mask->paintDevice()->exactBounds(), QRect(5,7,160,70));
123 QCOMPARE(t.mask->coloringProjection()->exactBounds(), expectedFillRect.translated(5, 7));
124 QCOMPARE(t.mask->testingFilteredSource()->exactBounds(), t.refRect);
125
126 QCOMPARE(strokes[0].dev->exactBounds(), QRect(55,57,10,20));
127 QCOMPARE(strokes[1].dev->exactBounds(), QRect(155,57,10,20));
128 QCOMPARE(strokes[2].dev->exactBounds(), QRect(5,7,10,10));
129
130 // Test changing t.mask color space
131
132 const KoColorSpace *oldCS = KoColorSpaceRegistry::instance()->rgb8();
133 const KoColorSpace *newCS = KoColorSpaceRegistry::instance()->lab16();
134
135 QCOMPARE(t.mask->colorSpace(), oldCS);
136 QCOMPARE(t.mask->paintDevice()->colorSpace(), oldCS);
137 QCOMPARE(t.mask->coloringProjection()->colorSpace(), oldCS);
138
139 QCOMPARE(strokes[0].color.colorSpace(), oldCS);
140 QCOMPARE(strokes[1].color.colorSpace(), oldCS);
141 QCOMPARE(strokes[2].color.colorSpace(), oldCS);
142
143 QScopedPointer<KUndo2Command> cmd(t.mask->setColorSpace(newCS));
144 cmd->redo();
145 strokes = t.mask->fetchKeyStrokesDirect();
146
147 QCOMPARE(t.mask->colorSpace(), newCS);
148 QCOMPARE(t.mask->paintDevice()->colorSpace(), newCS);
149 QCOMPARE(t.mask->coloringProjection()->colorSpace(), newCS);
150
151 QCOMPARE(strokes[0].color.colorSpace(), newCS);
152 QCOMPARE(strokes[1].color.colorSpace(), newCS);
153 QCOMPARE(strokes[2].color.colorSpace(), newCS);
154
155 cmd->undo();
156 strokes = t.mask->fetchKeyStrokesDirect();
157
158 QCOMPARE(t.mask->colorSpace(), oldCS);
159 QCOMPARE(t.mask->paintDevice()->colorSpace(), oldCS);
160 QCOMPARE(t.mask->coloringProjection()->colorSpace(), oldCS);
161
162 QCOMPARE(strokes[0].color.colorSpace(), oldCS);
163 QCOMPARE(strokes[1].color.colorSpace(), oldCS);
164 QCOMPARE(strokes[2].color.colorSpace(), oldCS);
165
166 cmd->redo();
167 strokes = t.mask->fetchKeyStrokesDirect();
168
169 QCOMPARE(t.mask->colorSpace(), newCS);
170 QCOMPARE(t.mask->paintDevice()->colorSpace(), newCS);
171 QCOMPARE(t.mask->coloringProjection()->colorSpace(), newCS);
172
173 QCOMPARE(strokes[0].color.colorSpace(), newCS);
174 QCOMPARE(strokes[1].color.colorSpace(), newCS);
175 QCOMPARE(strokes[2].color.colorSpace(), newCS);
176 }
177
178 #include "processing/kis_crop_processing_visitor.h"
179
testCrop()180 void KisColorizeMaskTest::testCrop()
181 {
182 ColorizeMaskTester t;
183 QList<KisLazyFillTools::KeyStroke> strokes;
184 strokes = t.mask->fetchKeyStrokesDirect();
185
186 const QRect expectedFillRect(25,25,145,150);
187
188 // Check initial bounding rects
189
190 QCOMPARE(t.mask->paintDevice()->exactBounds(), QRect(0,0,160,70));
191 QCOMPARE(t.mask->coloringProjection()->exactBounds(), expectedFillRect);
192 QCOMPARE(t.mask->testingFilteredSource()->exactBounds(), t.refRect);
193
194 // KIS_DUMP_DEVICE_2(t.mask->coloringProjection(), t.refRect, "coloring3", "dd");
195 // KIS_DUMP_DEVICE_2(t.mask->paintDevice(), t.refRect, "paintDevice3", "dd");
196 // KIS_DUMP_DEVICE_2(t.mask->testingFilteredSource(), t.refRect, "filteredSource3", "dd");
197
198 QCOMPARE(strokes[0].dev->exactBounds(), QRect(50,50,10,20));
199 QCOMPARE(strokes[1].dev->exactBounds(), QRect(150,50,10,20));
200 QCOMPARE(strokes[2].dev->exactBounds(), QRect(0,0,10,10));
201
202 QRect cropRect(5,5,150,55);
203 KisCropProcessingVisitor visitor(cropRect, true, true);
204 t.mask->accept(visitor, t.p.image->undoAdapter());
205
206 // KIS_DUMP_DEVICE_2(t.mask->coloringProjection(), t.refRect, "coloring4", "dd");
207 // KIS_DUMP_DEVICE_2(t.mask->paintDevice(), t.refRect, "paintDevice4", "dd");
208 // KIS_DUMP_DEVICE_2(t.mask->testingFilteredSource(), t.refRect, "filteredSource4", "dd");
209
210 QCOMPARE(t.mask->paintDevice()->exactBounds(), QRect(0,0,150,55));
211 QCOMPARE(t.mask->coloringProjection()->exactBounds(), (expectedFillRect & cropRect).translated(-cropRect.topLeft()));
212 QCOMPARE(t.mask->testingFilteredSource()->exactBounds(), t.refRect);
213
214 QCOMPARE(strokes[0].dev->exactBounds(), QRect(45,45,10,10));
215 QCOMPARE(strokes[1].dev->exactBounds(), QRect(145,45,5,10));
216 QCOMPARE(strokes[2].dev->exactBounds(), QRect(0,0,5,5));
217 }
218
219 KISTEST_MAIN(KisColorizeMaskTest)
220