void ShivaFilter::processImpl(KisPaintDeviceSP dev, const QRect& size, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { Q_UNUSED(progressUpdater); QPoint dstTopLeft = size.topLeft(); UpdaterProgressReport* report = 0; if (progressUpdater) { progressUpdater->setRange(0, size.height()); report = new UpdaterProgressReport(progressUpdater); } Q_ASSERT(!dev.isNull()); // Q_ASSERT(config); // TODO support for selection OpenShiva::Kernel kernel; kernel.setSource(*m_source); if (config) { QMap<QString, QVariant> map = config->getProperties(); for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it) { dbgPlugins << it.key() << " " << it.value(); const GTLCore::Metadata::Entry* entry = kernel.metadata()->parameter(it.key().toLatin1().constData()); if (entry && entry->asParameterEntry()) { GTLCore::Value val = qvariantToValue(it.value(), entry->asParameterEntry()->type()); if(val.isValid()) { kernel.setParameter(it.key().toLatin1().constData(), val); } } } } kernel.setParameter(OpenShiva::Kernel::IMAGE_WIDTH, float(dev->defaultBounds()->bounds().width())); kernel.setParameter(OpenShiva::Kernel::IMAGE_HEIGHT, float(dev->defaultBounds()->bounds().height())); KisGtlLocker gtlLocker; { dbgPlugins << "Compile: " << m_source->name().c_str(); QMutexLocker l(shivaMutex); kernel.compile(); } if (kernel.isCompiled()) { ConstPaintDeviceImage pdisrc(dev); PaintDeviceImage pdi(dev); std::list< const GTLCore::AbstractImage* > inputs; GTLCore::RegionI region(dstTopLeft.x(), dstTopLeft.y() , size.width(), size.height()); inputs.push_back(&pdisrc); dbgPlugins << "Run: " << m_source->name().c_str() << " " << dstTopLeft << " " << size; kernel.evaluatePixels(region, inputs, &pdi, report ); } }
void testWrappedLineIterator(QString testName, const QRect &rect) { testName = QString("%1_%2_%3_%4_%5") .arg(testName) .arg(rect.x()) .arg(rect.y()) .arg(rect.width()) .arg(rect.height()); const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = createWrapAroundPaintDevice(cs); // test rect fits the wrap rect in both dimensions IteratorSP it = createIterator<IteratorSP>(dev, rect); int y = 0; do { int x = 0; do { quint8 *data = it->rawData(); data[0] = 10 * x; data[1] = 10 * y; data[2] = 0; data[3] = 255; x++; } while (it->nextPixel()); } while (nextRowGeneral(it, ++y, rect)); QRect rc = dev->defaultBounds()->bounds() | dev->exactBounds(); QImage result = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height()); QVERIFY(TestUtil::checkQImage(result, "paint_device_test", "wrapped_iterators", testName)); }
QRect KisFilterMask::decorateRect(KisPaintDeviceSP &src, KisPaintDeviceSP &dst, const QRect & rc, PositionToFilthy maskPos) const { Q_UNUSED(maskPos); KisSafeFilterConfigurationSP filterConfig = filter(); Q_ASSERT(nodeProgressProxy()); Q_ASSERT_X(src != dst, "KisFilterMask::decorateRect", "src must be != dst, because we cant create transactions " "during merge, as it breaks reentrancy"); if (!filterConfig) { return QRect(); } KisFilterSP filter = KisFilterRegistry::instance()->value(filterConfig->name()); if (!filter) { warnKrita << "Could not retrieve filter \"" << filterConfig->name() << "\""; return QRect(); } KIS_ASSERT_RECOVER_NOOP(this->busyProgressIndicator()); this->busyProgressIndicator()->update(); filter->process(src, dst, 0, rc, filterConfig.data(), 0); QRect r = filter->changedRect(rc, filterConfig.data(), dst->defaultBounds()->currentLevelOfDetail()); return r; }
void KisMultipleProjection::syncLodCache() { QReadLocker readLocker(&m_d->lock); PlanesMap::const_iterator it = m_d->planes.constBegin(); PlanesMap::const_iterator end = m_d->planes.constEnd(); for (; it != end; ++it) { KisPaintDeviceSP device = it->device; QRegion dirtyRegion = device->syncLodCache(device->defaultBounds()->currentLevelOfDetail()); Q_UNUSED(dirtyRegion); } }
void testWrappedLineIteratorReadMoreThanBounds(QString testName) { const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8(); KisPaintDeviceSP dev = createWrapAroundPaintDevice(cs); KisPaintDeviceSP dst = new KisPaintDevice(cs); // fill device with a gradient QRect bounds = dev->defaultBounds()->bounds(); for (int y = bounds.y(); y < bounds.y() + bounds.height(); y++) { for (int x = bounds.x(); x < bounds.x() + bounds.width(); x++) { QColor c((10 * x) % 255, (10 * y) % 255, 0, 255); dev->setPixel(x, y, c); } } // test rect doesn't fit the wrap rect in both dimentions const QRect &rect(bounds.adjusted(-6,-6,8,8)); KisRandomAccessorSP dstIt = dst->createRandomAccessorNG(rect.x(), rect.y()); IteratorSP it = createIterator<IteratorSP>(dev, rect); for (int y = rect.y(); y < rect.y() + rect.height(); y++) { for (int x = rect.x(); x < rect.x() + rect.width(); x++) { quint8 *data = it->rawData(); QVERIFY(checkConseqPixels<IteratorSP>(it->nConseqPixels(), QPoint(x, y), KisWrappedRect(rect, bounds))); dstIt->moveTo(x, y); memcpy(dstIt->rawData(), data, cs->pixelSize()); QVERIFY(checkXY<IteratorSP>(QPoint(it->x(), it->y()), QPoint(x,y))); bool stepDone = it->nextPixel(); QCOMPARE(stepDone, x < rect.x() + rect.width() - 1); } if (!nextRowGeneral(it, y, rect)) break; } testName = QString("%1_%2_%3_%4_%5") .arg(testName) .arg(rect.x()) .arg(rect.y()) .arg(rect.width()) .arg(rect.height()); QRect rc = rect; QImage result = dst->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height()); QImage ref = dev->convertToQImage(0, rc.x(), rc.y(), rc.width(), rc.height()); QVERIFY(TestUtil::checkQImage(result, "paint_device_test", "wrapped_iterators_huge", testName)); }
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 FillProcessingVisitor::visitNodeWithPaintDevice(KisNode *node, KisUndoAdapter *undoAdapter) { KisPaintDeviceSP device = node->paintDevice(); Q_ASSERT(device); ProgressHelper helper(node); QRect fillRect = m_resources->image()->bounds(); if (!device->defaultBounds()->wrapAroundMode() && !fillRect.contains(m_startPoint)) { return; } if (m_selectionOnly) { KisPaintDeviceSP filledDevice = device->createCompositionSourceDevice(); KisFillPainter fillPainter(filledDevice); fillPainter.setProgress(helper.updater()); if (m_usePattern) { fillPainter.fillRect(fillRect, m_resources->currentPattern()); } else if (m_useBgColor) { fillPainter.fillRect(fillRect, m_resources->currentBgColor(), m_resources->opacity()); } else { fillPainter.fillRect(fillRect, m_resources->currentFgColor(), m_resources->opacity()); } QVector<QRect> dirtyRect = fillPainter.takeDirtyRegion(); KisPainter painter(device, m_selection); painter.beginTransaction(); m_resources->setupPainter(&painter); foreach(const QRect &rc, dirtyRect) { painter.bitBlt(rc.topLeft(), filledDevice, rc); } painter.endTransaction(undoAdapter); } else {
bool checkIfHasTransparency(KisPaintDeviceSP dev) { const QRect deviceBounds = dev->exactBounds(); const QRect imageBounds = dev->defaultBounds()->bounds(); if (deviceBounds.isEmpty() || (deviceBounds & imageBounds) != imageBounds) { return true; } const KoColorSpace *cs = dev->colorSpace(); KisSequentialConstIterator it(dev, deviceBounds); do { if (cs->opacityU8(it.rawDataConst()) != OPACITY_OPAQUE_U8) { return true; } } while(it.nextPixel()); return false; }
void KisRoundCornersFilter::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfiguration* config, KoUpdater* progressUpdater ) const { Q_UNUSED(config); Q_ASSERT(!device.isNull()); if (!device || !config) { warnKrita << "Invalid parameters for round corner filter"; dbgPlugins << device << " " << config; return; } //read the filter configuration values from the KisFilterConfiguration object qint32 radius = qMax(1, config->getInt("radius" , 30)); if (progressUpdater) { progressUpdater->setRange(0, applyRect.height()); } qint32 width = applyRect.width(); KisHLineIteratorSP dstIt = device->createHLineIteratorNG(applyRect.x(), applyRect.y(), width); const KoColorSpace* cs = device->colorSpace(); QRect bounds = device->defaultBounds()->bounds(); for (qint32 y = applyRect.y(); y < applyRect.y() + applyRect.height(); y++) { qint32 x = applyRect.x(); do { if (x <= radius && y <= radius) { double dx = radius - x; double dy = radius - y; double dradius = static_cast<double>(radius); if (dx >= sqrt(dradius*dradius - dy*dy)) { cs->setOpacity(dstIt->rawData(), OPACITY_TRANSPARENT_U8, 1); } } else if (x >= bounds.width() - radius && y <= radius) { double dx = x + radius - bounds.width(); double dy = radius - y; double dradius = static_cast<double>(radius); if (dx >= sqrt(dradius*dradius - dy*dy)) { cs->setOpacity(dstIt->rawData(), OPACITY_TRANSPARENT_U8, 1); } } else if (x <= radius && y >= bounds.height() - radius) { double dx = radius - x; double dy = y + radius - bounds.height(); double dradius = static_cast<double>(radius); if (dx >= sqrt(dradius*dradius - dy*dy)) { cs->setOpacity(dstIt->rawData(), OPACITY_TRANSPARENT_U8, 1); } } else if (x >= bounds.width() - radius && y >= bounds.height() - radius) { double dx = x + radius - bounds.width() ; double dy = y + radius - bounds.height(); double dradius = static_cast<double>(radius); if (dx >= sqrt(dradius*dradius - dy*dy)) { cs->setOpacity(dstIt->rawData(), OPACITY_TRANSPARENT_U8, 1); } } ++x; } while(dstIt->nextPixel()); dstIt->nextRow(); if (progressUpdater) progressUpdater->setValue(y); } }