void KisPaintDeviceTest::testClear() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = new KisPaintDevice(cs); QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0)); QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0)); dev->clear(); QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0)); QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0)); dev->clear(QRect(100, 100, 100, 100)); // XXX: This is strange! QVERIFY(dev->extent() == QRect(64, 64, 192, 192)); QVERIFY(dev->exactBounds() == QRect(64, 64, 192, 192)); dev->clear(); QVERIFY(dev->extent() == QRect(2147483647, 2147483647, 0, 0)); QVERIFY(dev->exactBounds() == QRect(2147483647, 2147483647, 0, 0)); }
void KisSelectionBasedLayer::copyOriginalToProjection(const KisPaintDeviceSP original, KisPaintDeviceSP projection, const QRect& rect) const { lockTemporaryTarget(); m_d->selection->updateProjection(); KisSelectionSP tempSelection = m_d->selection; KisPainter gc(projection); if (m_d->selection) { if (hasTemporaryTarget()) { /** * Cloning a selection with COW * FIXME: check whether it's faster than usual bitBlt'ing */ tempSelection = new KisSelection(*tempSelection); KisPainter gc2(tempSelection->pixelSelection()); gc2.setOpacity(temporaryOpacity()); gc2.setCompositeOp(temporaryCompositeOp()); gc2.bitBlt(rect.topLeft(), temporaryTarget(), rect); } projection->clear(rect); gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_OVER)); gc.setSelection(tempSelection); } else gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY)); gc.bitBlt(rect.topLeft(), original, rect); unlockTemporaryTarget(); }
void KisShearVisitor::shear(KisPaintDeviceSP dev, qreal angleX, qreal angleY, KoUpdater *progress) { const qreal pi = 3.1415926535897932385; qreal thetaX = angleX * pi / 180; qreal shearX = tan(thetaX); qreal thetaY = angleY * pi / 180; qreal shearY = tan(thetaY); QRect r = dev->exactBounds(); progress->setRange(0, r.height() + r.width()); KisPaintDeviceSP sheared; sheared = xShear(dev, shearX, progress); sheared = yShear(sheared, shearY, progress); dev->clear(); KisPainter p2(dev); r = sheared->extent(); p2.bitBlt(r.x(), r.y(), sheared, r.x(), r.y(), r.width(), r.height()); p2.end(); progress->setProgress(progress->maximum()); }
void KisScratchPad::fillDefault() { if(!m_paintLayer) return; KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice(); paintDevice->setDefaultPixel(m_defaultColor.data()); paintDevice->clear(); update(); }
void KisScratchPad::fillBackground() { if(!m_paintLayer) return; KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice(); KoColor c(m_resourceProvider->bgColor(), paintDevice->colorSpace()); paintDevice->setDefaultPixel(c.data()); paintDevice->clear(); update(); }
void KisFilterTest::testOldDataApiAfterCopy() { QRect updateRect(0,0,63,63); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); quint8 *whitePixel = new quint8[cs->pixelSize()]; cs->fromQColor(Qt::white, whitePixel); cs->setOpacity(whitePixel, OPACITY_OPAQUE_U8, 1); KisPaintDeviceSP tmp = new KisPaintDevice(cs); KisPaintDeviceSP src = new KisPaintDevice(cs); src->fill(0, 0, 50, 50, whitePixel); /** * Make a full copy here to catch the bug. * Buggy memento manager would make a commit * that is not good. */ KisPaintDeviceSP dst = new KisPaintDevice(*src); /** * This would write go to a new revision in a buggy * memento manager */ dst->clear(updateRect); KisFilterSP f = KisFilterRegistry::instance()->value("invert"); Q_ASSERT(f); KisFilterConfiguration * kfc = f->defaultConfiguration(0); Q_ASSERT(kfc); /** * This filter reads from oldRawData, so if we have some * weirdness with transactions it will read from old and non-cleared * version of the device and we will see a black square instead * of empty device in tmp */ f->process(dst, tmp, 0, updateRect, kfc); /** * In theory, both devices: dst and tmp must be empty by now */ KisPaintDeviceSP reference = new KisPaintDevice(cs); QImage refImage = reference->convertToQImage(0,0,0,63,63); QImage dstImage = dst->convertToQImage(0,0,0,63,63); QImage tmpImage = tmp->convertToQImage(0,0,0,63,63); QPoint pt; QVERIFY(TestUtil::compareQImages(pt, refImage, dstImage)); QVERIFY(TestUtil::compareQImages(pt, refImage, tmpImage)); }
void KisUniformColorSource::colorize(KisPaintDeviceSP dev, const QRect& size) { Q_UNUSED(size); if (!m_cachedColor || !(*dev->colorSpace() == *m_cachedColor->colorSpace())) { if (m_cachedColor) delete m_cachedColor; m_cachedColor = new KoColor(dev->colorSpace()); m_cachedColor->fromKoColor(*m_color); } dev->dataManager()->setDefaultPixel(m_cachedColor->data()); dev->clear(); }
void KisPaintDeviceTest::testGeometry() { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = new KisPaintDevice(cs); quint8* pixel = new quint8[cs->pixelSize()]; cs->fromQColor(Qt::white, pixel); dev->fill(0, 0, 512, 512, pixel); QCOMPARE(dev->exactBounds(), QRect(0, 0, 512, 512)); QCOMPARE(dev->extent(), QRect(0, 0, 512, 512)); dev->move(10, 10); QCOMPARE(dev->exactBounds(), QRect(10, 10, 512, 512)); QCOMPARE(dev->extent(), QRect(10, 10, 512, 512)); dev->crop(50, 50, 50, 50); QCOMPARE(dev->exactBounds(), QRect(50, 50, 50, 50)); QCOMPARE(dev->extent(), QRect(10, 10, 128, 128)); QColor c; dev->clear(QRect(50, 50, 50, 50)); dev->pixel(80, 80, &c); QVERIFY(c.alpha() == OPACITY_TRANSPARENT_U8); dev->fill(0, 0, 512, 512, pixel); dev->pixel(80, 80, &c); QVERIFY(c == Qt::white); QVERIFY(c.alpha() == OPACITY_OPAQUE_U8); dev->clear(); dev->pixel(80, 80, &c); QVERIFY(c.alpha() == OPACITY_TRANSPARENT_U8); QVERIFY(dev->extent().isEmpty()); QVERIFY(dev->exactBounds().isEmpty()); }
void KisPaintDeviceTest::testDeviceDuplication() { QRect fillRect(0,0,64,64); quint8 fillPixel[4]={255,255,255,255}; QRect clearRect(10,10,20,20); QImage referenceImage; QImage resultImage; const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP device = new KisPaintDevice(cs); // qDebug()<<"FILLING"; device->fill(fillRect.left(), fillRect.top(), fillRect.width(), fillRect.height(),fillPixel); referenceImage = device->convertToQImage(0); KisTransaction transaction1(device); // qDebug()<<"CLEARING"; device->clear(clearRect); transaction1.revert(); resultImage = device->convertToQImage(0); QVERIFY(resultImage == referenceImage); KisPaintDeviceSP clone = new KisPaintDevice(*device); KisTransaction transaction(clone); // qDebug()<<"CLEARING"; clone->clear(clearRect); transaction.revert(); resultImage = clone->convertToQImage(0); QVERIFY(resultImage == referenceImage); }
void TransformStrokeStrategy::clearSelection(KisPaintDeviceSP device) { KisTransaction transaction(device); if (m_selection) { device->clearSelection(m_selection); } else { QRect oldExtent = device->extent(); device->clear(); device->setDirty(oldExtent); } runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()), KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::NORMAL); }
void KisPaintDeviceTest::testFastBitBlt() { QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "hakonepa.png"); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dstDev = new KisPaintDevice(cs); KisPaintDeviceSP srcDev = new KisPaintDevice(cs); srcDev->convertFromQImage(image, 0); QRect cloneRect(100,100,200,200); QPoint errpoint; QVERIFY(dstDev->fastBitBltPossible(srcDev)); dstDev->fastBitBlt(srcDev, cloneRect); QImage srcImage = srcDev->convertToQImage(0, cloneRect.x(), cloneRect.y(), cloneRect.width(), cloneRect.height()); QImage dstImage = dstDev->convertToQImage(0, cloneRect.x(), cloneRect.y(), cloneRect.width(), cloneRect.height()); if (!TestUtil::compareQImages(errpoint, srcImage, dstImage)) { QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); } // Test Rough version dstDev->clear(); dstDev->fastBitBltRough(srcDev, cloneRect); srcImage = srcDev->convertToQImage(0, cloneRect.x(), cloneRect.y(), cloneRect.width(), cloneRect.height()); dstImage = dstDev->convertToQImage(0, cloneRect.x(), cloneRect.y(), cloneRect.width(), cloneRect.height()); if (!TestUtil::compareQImages(errpoint, srcImage, dstImage)) { QFAIL(QString("Failed to create identical image, first different pixel: %1,%2 \n").arg(errpoint.x()).arg(errpoint.y()).toLatin1()); } srcDev->move(10,10); QVERIFY(!dstDev->fastBitBltPossible(srcDev)); }
void checkReadWriteRoundTrip(KisPaintDeviceSP dev, const QRect &rc) { KisPaintDeviceSP deviceCopy = new KisPaintDevice(*dev.data()); QRect readRect(10, 10, 20, 20); int bufSize = rc.width() * rc.height() * dev->pixelSize(); QScopedPointer<quint8> buf1(new quint8[bufSize]); deviceCopy->readBytes(buf1.data(), rc); deviceCopy->clear(); QVERIFY(deviceCopy->extent().isEmpty()); QScopedPointer<quint8> buf2(new quint8[bufSize]); deviceCopy->writeBytes(buf1.data(), rc); deviceCopy->readBytes(buf2.data(), rc); QVERIFY(!memcmp(buf1.data(), buf2.data(), bufSize)); }
void KisScratchPad::fillGradient() { if(!m_paintLayer) return; KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice(); KoAbstractGradient* gradient = m_resourceProvider->currentGradient(); QRect gradientRect = widgetToDocument().mapRect(rect()); paintDevice->clear(); KisGradientPainter painter(paintDevice); painter.setGradient(gradient); painter.paintGradient(gradientRect.topLeft(), gradientRect.bottomRight(), KisGradientPainter::GradientShapeLinear, KisGradientPainter::GradientRepeatNone, 0.2, false, gradientRect.left(), gradientRect.top(), gradientRect.width(), gradientRect.height()); update(); }
void KisPaintDeviceTest::testSharedDataManager() { QRect fillRect(0,0,100,100); quint8 fillPixel[4]={255,255,255,255}; QRect clearRect(10,10,20,20); QImage srcImage; QImage dstImage; const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP srcDevice = new KisPaintDevice(cs); srcDevice->setX(10); srcDevice->setY(20); srcDevice->fill(fillRect.left(), fillRect.top(), fillRect.width(), fillRect.height(),fillPixel); KisPaintDeviceSP dstDevice = new KisPaintDevice(srcDevice->dataManager(), srcDevice); QVERIFY(srcDevice->extent() == dstDevice->extent()); QVERIFY(srcDevice->exactBounds() == dstDevice->exactBounds()); QVERIFY(srcDevice->defaultBounds() == dstDevice->defaultBounds()); QVERIFY(srcDevice->x() == dstDevice->x()); QVERIFY(srcDevice->y() == dstDevice->y()); srcImage = srcDevice->convertToQImage(0); dstImage = dstDevice->convertToQImage(0); QVERIFY(srcImage == dstImage); srcDevice->clear(clearRect); srcImage = srcDevice->convertToQImage(0); dstImage = dstDevice->convertToQImage(0); QVERIFY(srcImage == dstImage); }
void KisTransactionTest::testUndoWithUnswitchedFrames() { KisSurrogateUndoAdapter undoAdapter; const QRect imageRect(0,0,100,100); const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = new KisPaintDevice(cs); TestUtil::TestingTimedDefaultBounds *bounds = new TestUtil::TestingTimedDefaultBounds(); dev->setDefaultBounds(bounds); KisRasterKeyframeChannel *channel = dev->createKeyframeChannel(KisKeyframeChannel::Content); QVERIFY(channel); KisPaintDeviceFramesInterface *i = dev->framesInterface(); QVERIFY(i); QCOMPARE(i->frames().size(), 1); dev->fill(QRect(10,10,20,20), KoColor(Qt::white, cs)); KIS_DUMP_DEVICE_2(dev, imageRect, "00_f0_w20", "dd"); QCOMPARE(dev->exactBounds(), QRect(10,10,20,20)); // add keyframe at position 10 channel->addKeyframe(10); // add keyframe at position 11 channel->addKeyframe(11); // add keyframe at position 12 channel->addKeyframe(12); KIS_DUMP_DEVICE_2(dev, imageRect, "01_f0_b20", "dd"); QCOMPARE(dev->exactBounds(), QRect(10,10,20,20)); { KisTransaction transaction(kundo2_noi18n("first_stroke"), dev, 0); dev->clear(); dev->fill(QRect(40,40,21,21), KoColor(Qt::red, cs)); transaction.commit(&undoAdapter); KIS_DUMP_DEVICE_2(dev, imageRect, "02_f0_b21_stroke", "dd"); QCOMPARE(dev->exactBounds(), QRect(40,40,21,21)); } // switch to frame 10 bounds->testingSetTime(10); KIS_DUMP_DEVICE_2(dev, imageRect, "03_f10_b0_switched", "dd"); QVERIFY(dev->exactBounds().isEmpty()); { KisTransaction transaction(kundo2_noi18n("second_stroke"), dev, 0); dev->fill(QRect(60,60,22,22), KoColor(Qt::green, cs)); transaction.commit(&undoAdapter); KIS_DUMP_DEVICE_2(dev, imageRect, "04_f10_b22_stroke", "dd"); QCOMPARE(dev->exactBounds(), QRect(60,60,22,22)); } undoAdapter.undo(); KIS_DUMP_DEVICE_2(dev, imageRect, "05_f10_b0_undone", "dd"); QVERIFY(dev->exactBounds().isEmpty()); bounds->testingSetTime(0); KIS_DUMP_DEVICE_2(dev, imageRect, "06_f0_b21_undone", "dd"); QCOMPARE(dev->exactBounds(), QRect(40,40,21,21)); bounds->testingSetTime(10); QVERIFY(dev->exactBounds().isEmpty()); undoAdapter.undo(); KIS_DUMP_DEVICE_2(dev, imageRect, "07_f10_b0_undone_x2", "dd"); QVERIFY(dev->exactBounds().isEmpty()); bounds->testingSetTime(0); KIS_DUMP_DEVICE_2(dev, imageRect, "08_f0_b20_undone_x2", "dd"); QCOMPARE(dev->exactBounds(), QRect(10,10,20,20)); { KisTransaction transaction(kundo2_noi18n("third_move"), dev, 0); dev->moveTo(17,17); transaction.commit(&undoAdapter); KIS_DUMP_DEVICE_2(dev, imageRect, "09_f0_o27_move", "dd"); QCOMPARE(dev->exactBounds(), QRect(27,27,20,20)); } bounds->testingSetTime(10); QVERIFY(dev->exactBounds().isEmpty()); undoAdapter.undo(); KIS_DUMP_DEVICE_2(dev, imageRect, "10_f10_b0_undone_x3", "dd"); QVERIFY(dev->exactBounds().isEmpty()); bounds->testingSetTime(0); KIS_DUMP_DEVICE_2(dev, imageRect, "11_f0_b20_undone_x3", "dd"); QCOMPARE(dev->exactBounds(), QRect(10,10,20,20)); }
bool PSDImageData::read(QIODevice *io, KisPaintDeviceSP dev ) { psdread(io, &m_compression); quint64 start = io->pos(); m_channelSize = m_header->channelDepth/8; m_channelDataLength = m_header->height * m_header->width * m_channelSize; dbgFile << "Reading Image Data Block: compression" << m_compression << "channelsize" << m_channelSize << "number of channels" << m_header->nChannels; switch (m_compression) { case 0: // Uncompressed for (int channel = 0; channel < m_header->nChannels; channel++) { m_channelOffsets << 0; ChannelInfo channelInfo; channelInfo.channelId = channel; channelInfo.compressionType = Compression::Uncompressed; channelInfo.channelDataStart = start; channelInfo.channelDataLength = m_header->width * m_header->height * m_channelSize; start += channelInfo.channelDataLength; m_channelInfoRecords.append(channelInfo); } break; case 1: // RLE { quint32 rlelength = 0; // The start of the actual channel data is _after_ the RLE rowlengths block if (m_header->version == 1) { start += m_header->nChannels * m_header->height * 2; } else if (m_header->version == 2) { start += m_header->nChannels * m_header->height * 4; } for (int channel = 0; channel < m_header->nChannels; channel++) { m_channelOffsets << 0; quint32 sumrlelength = 0; ChannelInfo channelInfo; channelInfo.channelId = channel; channelInfo.channelDataStart = start; channelInfo.compressionType = Compression::RLE; for (quint32 row = 0; row < m_header->height; row++ ) { if (m_header->version == 1) { psdread(io,(quint16*)&rlelength); } else if (m_header->version == 2) { psdread(io,&rlelength); } channelInfo.rleRowLengths.append(rlelength); sumrlelength += rlelength; } channelInfo.channelDataLength = sumrlelength; start += channelInfo.channelDataLength; m_channelInfoRecords.append(channelInfo); } break; } case 2: // ZIP without prediction case 3: // ZIP with prediction default: break; } if (!m_channelInfoRecords.isEmpty()) { QVector<ChannelInfo*> infoRecords; QVector<ChannelInfo>::iterator it = m_channelInfoRecords.begin(); QVector<ChannelInfo>::iterator end = m_channelInfoRecords.end(); for (; it != end; ++it) { infoRecords << &(*it); } const QRect imageRect(0, 0, m_header->width, m_header->height); try { PsdPixelUtils::readChannels(io, dev, m_header->colormode, m_channelSize, imageRect, infoRecords); } catch (KisAslReaderUtils::ASLParseException &e) { dev->clear(); return true; } } return true; }