2
* Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
3
* Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
4
* Copyright (c) 2004 Clarence Dang <dang@kde.org>
5
* Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
6
* Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
#include "kis_brush.h"
28
#include "kis_global.h"
29
#include "kis_paint_device.h"
30
#include "kis_painter.h"
31
#include "kis_types.h"
32
#include "kis_iterators_pixel.h"
33
#include "kis_paintop.h"
34
#include "kis_colorspace.h"
35
#include "kis_selection.h"
36
#include "kis_filterop.h"
39
KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
41
KisPaintOp * op = new KisFilterOp(painter);
46
KisFilterOp::KisFilterOp(KisPainter * painter)
49
m_filterConfiguration = 0;
52
KisFilterOp::~KisFilterOp()
54
delete m_filterConfiguration;
57
void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
59
if (!m_painter) return;
61
KisFilterSP filter = m_painter->filter();
64
if ( ! m_source ) return;
66
KisBrush * brush = m_painter->brush();
69
KisColorSpace * colorSpace = m_source->colorSpace();
71
KisPoint hotSpot = brush->hotSpot(info);
72
KisPoint pt = pos - hotSpot;
74
// Split the coordinates into integer plus fractional parts. The integer
75
// is where the dab will be positioned and the fractional part determines
76
// the sub-pixel positioning.
82
splitCoordinate(pt.x(), &x, &xFraction);
83
splitCoordinate(pt.y(), &y, &yFraction);
85
// Filters always work with a mask, never with an image; that
86
// wouldn't be useful at all.
87
KisAlphaMaskSP mask = brush->mask(info, xFraction, yFraction);
89
m_painter->setPressure(info.pressure);
91
Q_INT32 maskWidth = mask->width();
92
Q_INT32 maskHeight = mask->height();
94
// Create a temporary paint device
95
KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev");
98
// Copy the layer data onto the new paint device
100
KisPainter p( tmpDev );
101
p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight );
103
// Filter the paint device
104
filter->disableProgress();
105
filter->process( tmpDev, tmpDev, m_filterConfiguration, QRect( 0, 0, maskWidth, maskHeight ));
106
filter->enableProgress();
108
// Apply the mask on the paint device (filter before mask because edge pixels may be important)
109
for (int y = 0; y < maskHeight; y++)
111
KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false);
113
while(! hiter.isDone())
115
Q_UINT8 alpha = mask->alphaAt( x++, y );
116
colorSpace->setAlpha(hiter.rawData(), alpha, 1);
122
// Blit the paint device onto the layer
123
QRect dabRect = QRect(0, 0, maskWidth, maskHeight);
124
QRect dstRect = QRect(x, y, dabRect.width(), dabRect.height());
126
KisImage * image = m_painter->device()->image();
129
dstRect &= image->bounds();
132
if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
134
Q_INT32 sx = dstRect.x() - x;
135
Q_INT32 sy = dstRect.y() - y;
136
Q_INT32 sw = dstRect.width();
137
Q_INT32 sh = dstRect.height();
139
if (m_source->hasSelection()) {
140
m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(),
141
m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
144
m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh);
147
m_painter->addDirtyRect(dstRect);
150
void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration)
152
delete m_filterConfiguration;
153
m_filterConfiguration = filterConfiguration;