Commit e65d7065 authored by Cyrille Berger's avatar Cyrille Berger

go in the direction of actually fixing the issue of painting on a layer with a...

go in the direction of actually fixing the issue of painting on a layer with a convolution filter mask: use KisFilter::neededRect to increase the area of data made available to filters

svn path=/trunk/koffice/; revision=898311
parent cacb3725
......@@ -107,11 +107,11 @@ void KisGeneratorLayer::updateProjection(const QRect& rc)
m_d->projection = new KisPaintDevice(*m_d->paintDevice);
} else {
KisPainter gc(m_d->projection);
gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY));
gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY)); // TODO don't copy
gc.bitBlt(rc.topLeft(), m_d->paintDevice, rc);
}
applyEffectMasks(m_d->projection, rc);
applyEffectMasks( m_d->paintDevice, m_d->projection, rc);
}
......
......@@ -108,15 +108,19 @@ void KisCloneLayer::updateProjection(const QRect& r)
KisPainter gc(m_d->projection);
gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY));
// TODO don't copy
KisPaintDeviceSP src = 0;
switch (m_d->type) {
case COPY_PROJECTION:
gc.bitBlt(rc.topLeft(), m_d->copyFrom->projection(), rc);
src = m_d->copyFrom->projection();
break;
case COPY_ORIGINAL:
default:
gc.bitBlt(rc.topLeft(), m_d->copyFrom->original(), rc);
src = m_d->copyFrom->original();
}
applyEffectMasks(m_d->projection, r);
applyEffectMasks(m_d->copyFrom->original(), m_d->projection, r);
}
}
......
......@@ -123,4 +123,10 @@ QRect KisFilterMask::adjustedDirtyRect( const QRect& _rect ) const
return filter->changedRect( _rect, m_d->filterConfig );
}
QRect KisFilterMask::neededRect( const QRect& _rect ) const
{
KisFilterSP filter = KisFilterRegistry::instance()->value(m_d->filterConfig->name());
return filter->neededRect( _rect, m_d->filterConfig );
}
#include "kis_filter_mask.moc"
......@@ -64,6 +64,7 @@ public:
virtual void setDirty();
virtual QRect adjustedDirtyRect( const QRect& _rect ) const;
virtual QRect neededRect( const QRect& _rect ) const;
private:
......
......@@ -196,7 +196,7 @@ void KisLayer::setDirty(const QRect & rect)
QList<KisMaskSP> masks = effectMasks();
foreach( KisMaskSP mask, masks)
{
dr |= mask->adjustedDirtyRect( rect );
dr |= mask->adjustedDirtyRect( dr );
}
KisNode::setDirty( dr );
}
......@@ -242,7 +242,7 @@ bool KisLayer::hasEffectMasks() const
return false;
}
void KisLayer::applyEffectMasks(const KisPaintDeviceSP projection, const QRect & rc)
void KisLayer::applyEffectMasks(const KisPaintDeviceSP original, const KisPaintDeviceSP projection, const QRect & rc)
{
if (m_d->previewMask) {
m_d->previewMask->apply(projection, rc);
......@@ -253,17 +253,47 @@ void KisLayer::applyEffectMasks(const KisPaintDeviceSP projection, const QRect &
QList<KisNodeSP> masks = childNodes(QStringList("KisEffectMask"), props);
// Compute the needed area
QRect currentNeededRc = rc;
QList< QRect > neededRects;
neededRects.push_front( rc );
for( int i = masks.size() - 1; i >= 0 ; --i )
{
const KisEffectMask * effectMask = dynamic_cast<const KisEffectMask*>(masks.at(i).data());
if (effectMask) {
dbgImage << i << " " << effectMask->neededRect( currentNeededRc );
currentNeededRc |= effectMask->neededRect( currentNeededRc );
dbgImage << i << currentNeededRc;
if( i > 0 )
{
neededRects.push_front( currentNeededRc );
}
}
}
dbgImage << "Apply effects on " << rc << " with a total needed rect of " << currentNeededRc;
KisPaintDeviceSP tmp = new KisPaintDevice( projection->colorSpace());
KisPainter gc(tmp);
gc.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY));
gc.bitBlt(currentNeededRc.topLeft(), original, currentNeededRc);
// Then loop through the effect masks and apply them
for (int i = 0; i < masks.size(); ++i) {
const KisEffectMask * effectMask = dynamic_cast<const KisEffectMask*>(masks.at(i).data());
if (effectMask) {
dbgImage << " layer " << name() << " has effect mask " << effectMask->name();
effectMask->apply(projection, rc);
dbgImage << " layer " << name() << " has effect mask " << effectMask->name() << " on " << neededRects[i];
effectMask->apply(tmp, neededRects[i]);
}
}
KisPainter gc2(projection);
gc2.setCompositeOp(colorSpace()->compositeOp(COMPOSITE_COPY));
gc2.bitBlt(rc.topLeft(), tmp, rc);
}
......
......@@ -224,7 +224,7 @@ protected:
* Apply the effect masks to the given projection, producing
* finally the dst paint device.
*/
void applyEffectMasks(KisPaintDeviceSP projection, const QRect & rc);
void applyEffectMasks(const KisPaintDeviceSP original, KisPaintDeviceSP projection, const QRect & rc);
private:
class Private;
......
......@@ -117,7 +117,12 @@ void KisMask::setY(qint32 y)
QRect KisMask::adjustedDirtyRect( const QRect& _rect ) const
{
return _rect;
return _rect;
}
QRect KisMask::neededRect( const QRect& _rect ) const
{
return _rect;
}
#include "kis_mask.moc"
......@@ -129,7 +129,14 @@ public:
*/
void setY(qint32 y);
/**
* Adjust the dirty to rect to check which values need to be recomputed
*/
virtual QRect adjustedDirtyRect( const QRect& _rect ) const;
/**
* @return the rect that is needed to compute the corresponding values
*/
virtual QRect neededRect( const QRect& _rect ) const;
private:
struct Private;
......
......@@ -32,6 +32,7 @@
#include <KoColorSpace.h>
#include <KoColorProfile.h>
#include <KoCompositeOp.h>
#include <KoProperties.h>
#include "kis_image.h"
#include "kis_selection.h"
......@@ -140,16 +141,36 @@ void KisPaintLayer::updateProjection(const QRect & rc)
gc.bitBlt(rc.topLeft(), m_d->paintDevice, rc);
}
// TODO copy less
KisPaintDeviceSP source = m_d->paintDevice;
if( temporaryTarget() )
{
KisPainter gc(m_d->projection);
gc.bitBlt( rc.left(), rc.top(), temporaryCompositeOp(), temporaryTarget(),
temporaryOpacity(), rc.left(), rc.top(), rc.width(), rc.height());
source = new KisPaintDevice( m_d->paintDevice->colorSpace() );
QRect currentNeededRc = rc;
KoProperties props;
props.setProperty("visible", true);
QList<KisNodeSP> masks = childNodes(QStringList("KisEffectMask"), props);
for( int i = masks.size() - 1; i >= 0 ; --i )
{
const KisEffectMask * effectMask = dynamic_cast<const KisEffectMask*>(masks.at(i).data());
if (effectMask) {
currentNeededRc |= effectMask->neededRect( currentNeededRc );
}
}
KisPainter gc(source);
gc.bitBlt( currentNeededRc.left(), currentNeededRc.top(), COMPOSITE_COPY,
m_d->paintDevice, temporaryOpacity(), currentNeededRc.left(),
currentNeededRc.top(), currentNeededRc.width(), currentNeededRc.height());
gc.bitBlt( currentNeededRc.left(), currentNeededRc.top(), temporaryCompositeOp(),
temporaryTarget(), temporaryOpacity(), currentNeededRc.left(),
currentNeededRc.top(), currentNeededRc.width(), currentNeededRc.height());
}
if( visible() )
{
applyEffectMasks(m_d->projection, rc);
applyEffectMasks(source, m_d->projection, rc);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment