File indexing completed on 2024-12-22 04:08:46

0001 /*
0002  *  SPDX-FileCopyrightText: 2007 Boudewijn Rempt boud @valdyas.org
0003  *  SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "kis_auto_brush_test.h"
0009 
0010 #include <simpletest.h>
0011 #include <testutil.h>
0012 #include "../kis_auto_brush.h"
0013 #include "kis_mask_generator.h"
0014 #include "kis_paint_device.h"
0015 #include "kis_fill_painter.h"
0016 #include <KoColor.h>
0017 #include <KoColorSpace.h>
0018 #include <KoColorSpaceRegistry.h>
0019 #include <KoCompositeOpRegistry.h>
0020 #include <kis_fixed_paint_device.h>
0021 #include <brushengine/kis_paint_information.h>
0022 
0023 void KisAutoBrushTest::testCreation()
0024 {
0025     KisCircleMaskGenerator circle(10, 1.0, 1.0, 1.0, 2, true);
0026     KisRectangleMaskGenerator rect(10, 1.0, 1.0, 1.0, 2, true);
0027 }
0028 
0029 void KisAutoBrushTest::testMaskGeneration()
0030 {
0031     KisCircleMaskGenerator* circle = new KisCircleMaskGenerator(10, 1.0, 1.0, 1.0, 2, false);
0032     KisBrushSP a(new KisAutoBrush(circle, 0.0, 0.0));
0033     const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
0034 
0035     KisPaintInformation info(QPointF(100.0, 100.0), 0.5);
0036 
0037     // check masking an existing paint device
0038     KisFixedPaintDeviceSP fdev = new KisFixedPaintDevice(cs);
0039     fdev->setRect(QRect(0, 0, 100, 100));
0040     fdev->initialize();
0041     cs->setOpacity(fdev->data(), OPACITY_OPAQUE_U8, 100 * 100);
0042 
0043     QPoint errpoint;
0044     QImage result(QString(FILES_DATA_DIR) + '/' + "result_autobrush_1.png");
0045     QImage image = fdev->convertToQImage(0);
0046 
0047     if (!TestUtil::compareQImages(errpoint, image, result)) {
0048         image.save("kis_autobrush_test_1.png");
0049         QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
0050     }
0051 
0052     // Check creating a mask dab with a single color
0053     fdev = new KisFixedPaintDevice(cs);
0054     a->mask(fdev, KoColor(Qt::black, cs), KisDabShape(), info);
0055 
0056     result = QImage(QString(FILES_DATA_DIR) + '/' + "result_autobrush_3.png");
0057     image = fdev->convertToQImage(0);
0058     if (!TestUtil::compareQImages(errpoint, image, result)) {
0059         image.save("kis_autobrush_test_3.png");
0060         QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
0061     }
0062 
0063     // Check creating a mask dab with a color taken from a paint device
0064     KoColor red(Qt::red, cs);
0065     cs->setOpacity(red.data(), quint8(128), 1);
0066     KisPaintDeviceSP dev = new KisPaintDevice(cs);
0067     dev->fill(0, 0, 100, 100, red.data());
0068 
0069     fdev = new KisFixedPaintDevice(cs);
0070     a->mask(fdev, dev, KisDabShape(), info);
0071 
0072     result = QImage(QString(FILES_DATA_DIR) + '/' + "result_autobrush_4.png");
0073     image = fdev->convertToQImage(0);
0074     if (!TestUtil::compareQImages(errpoint, image, result)) {
0075         image.save("kis_autobrush_test_4.png");
0076         QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1());
0077     }
0078 
0079 }
0080 
0081 static void dabSizeHelper(KisBrushSP const& brush,
0082     QString const& name, KisDabShape const& shape, int expectedWidth, int expectedHeight)
0083 {
0084     qDebug() << name;
0085     QCOMPARE(brush->maskWidth(shape, 0.0, 0.0, KisPaintInformation()), expectedWidth);
0086     QCOMPARE(brush->maskHeight(shape, 0.0, 0.0, KisPaintInformation()), expectedHeight);
0087 }
0088 
0089 void KisAutoBrushTest::testDabSize()
0090 {
0091     KisCircleMaskGenerator* circle = new KisCircleMaskGenerator(10, 0.5, 1.0, 1.0, 2, false);
0092     KisBrushSP a(new KisAutoBrush(circle, 0.0, 0.0));
0093     QCOMPARE(a->width(), 10);
0094     QCOMPARE(a->height(), 5);
0095 
0096     dabSizeHelper(a, "Identity",  KisDabShape(),                        10,  5);
0097     dabSizeHelper(a, "Double",    KisDabShape(2.0, 1.0, 0.0),           20, 10);
0098     dabSizeHelper(a, "Halve",     KisDabShape(0.5, 1.0, 0.0),            5,  3);
0099     dabSizeHelper(a, "180 deg",   KisDabShape(1.0, 1.0, M_PI),          10,  5);
0100     dabSizeHelper(a, "90 deg",    KisDabShape(1.0, 1.0, M_PI_2),         6, 10); // ceil rule
0101     dabSizeHelper(a, "-90 deg",   KisDabShape(1.0, 1.0, -M_PI_2),        6, 11); // ceil rule
0102     dabSizeHelper(a, "45 deg",    KisDabShape(1.0, 1.0, 0.25 * M_PI),   11, 11);
0103     dabSizeHelper(a, "2x, 45d",   KisDabShape(2.0, 1.0, 0.25 * M_PI),   22, 22);
0104     dabSizeHelper(a, "0.5x, 45d", KisDabShape(0.5, 1.0, 0.25 * M_PI),    6, 6);
0105     dabSizeHelper(a, "0.5x, 45d", KisDabShape(0.5, 1.0, 0.25 * M_PI),    6, 6);
0106     dabSizeHelper(a, "0.5y",      KisDabShape(1.0, 0.5, 0.0),           10, 3);
0107 }
0108 
0109 //#define SAVE_OUTPUT_IMAGES
0110 void KisAutoBrushTest::testCopyMasking()
0111 {
0112     int w = 64;
0113     int h = 64;
0114     int x = 0;
0115     int y = 0;
0116     QRect rc(x, y, w, h);
0117 
0118     const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
0119 
0120     KoColor black(Qt::black, cs);
0121     KoColor red(Qt::red, cs);
0122 
0123 
0124     KisPaintDeviceSP tempDev = new KisPaintDevice(cs);
0125     tempDev->fill(0, 0, w, h, red.data());
0126 #ifdef SAVE_OUTPUT_IMAGES
0127     tempDev->convertToQImage(0).save("tempDev.png");
0128 #endif
0129 
0130     KisCircleMaskGenerator * mask = new KisCircleMaskGenerator(w, 1.0, 0.5, 0.5, 2, true);
0131     KisAutoBrush brush(mask, 0, 0);
0132 
0133     KisFixedPaintDeviceSP maskDab = new KisFixedPaintDevice(cs);
0134     brush.mask(maskDab, black, KisDabShape(), KisPaintInformation());
0135     maskDab->convertTo(KoColorSpaceRegistry::instance()->alpha8());
0136 
0137 #ifdef SAVE_OUTPUT_IMAGES
0138     maskDab->convertToQImage(0, 0, 0, 64, 64).save("maskDab.png");
0139 #endif
0140 
0141     QCOMPARE(tempDev->exactBounds(), rc);
0142     QCOMPARE(maskDab->bounds(), rc);
0143 
0144     KisFixedPaintDeviceSP dev2fixed = new KisFixedPaintDevice(cs);
0145     dev2fixed->setRect(rc);
0146     dev2fixed->initialize();
0147     tempDev->readBytes(dev2fixed->data(), rc);
0148     dev2fixed->convertToQImage(0).save("converted-tempDev-to-fixed.png");
0149 
0150     KisPaintDeviceSP dev = new KisPaintDevice(cs);
0151     KisPainter painter(dev);
0152     painter.setCompositeOpId(COMPOSITE_COPY);
0153     painter.bltFixedWithFixedSelection(x, y, dev2fixed, maskDab, 0, 0, 0, 0, rc.width(), rc.height());
0154     //painter.bitBltWithFixedSelection(x, y, tempDev, maskDab, 0, 0, 0, 0, rc.width(), rc.height());
0155 
0156 #ifdef SAVE_OUTPUT_IMAGES
0157     dev->convertToQImage(0).save("final.png");
0158 #endif
0159 }
0160 
0161 void KisAutoBrushTest::testClone()
0162 {
0163     const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
0164 
0165     KisCircleMaskGenerator* circle = new KisCircleMaskGenerator(10, 0.7, 0.85, 0.5, 2, true);
0166     KisBrushSP brush(new KisAutoBrush(circle, 0.5, 0.0));
0167 
0168     KisPaintInformation info(QPointF(100.0, 100.0), 0.5);
0169 
0170     KisFixedPaintDeviceSP fdev1 = new KisFixedPaintDevice(cs);
0171     brush->mask(fdev1, KoColor(Qt::black, cs), KisDabShape(0.8, 1.0, 8.0), info);
0172     QImage res1 = fdev1->convertToQImage(0);
0173 
0174     KisBrushSP clone = brush->clone().dynamicCast<KisBrush>();
0175 
0176     KisFixedPaintDeviceSP fdev2 = new KisFixedPaintDevice(cs);
0177     clone->mask(fdev2, KoColor(Qt::black, cs), KisDabShape(0.8, 1.0, 8.0), info);
0178     QImage res2 = fdev2->convertToQImage(0);
0179 
0180     QCOMPARE(res1, res2);
0181 }
0182 
0183 SIMPLE_TEST_MAIN(KisAutoBrushTest)