~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to krita/plugins/tools/tool_filter/kis_filterop.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2006-04-20 21:38:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060420213853-j5lxluqvymxt2zny
Tags: 1:1.5.0-0ubuntu2
UbuntuĀ uploadĀ 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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>
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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.
 
21
 */
 
22
 
 
23
#include <qrect.h>
 
24
 
 
25
#include <kdebug.h>
 
26
 
 
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"
 
37
 
 
38
 
 
39
KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
 
40
{
 
41
    KisPaintOp * op = new KisFilterOp(painter);
 
42
    return op;
 
43
}
 
44
 
 
45
 
 
46
KisFilterOp::KisFilterOp(KisPainter * painter)
 
47
    : super(painter)
 
48
{
 
49
    m_filterConfiguration = 0;
 
50
}
 
51
 
 
52
KisFilterOp::~KisFilterOp()
 
53
{
 
54
    delete m_filterConfiguration;
 
55
}
 
56
 
 
57
void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
 
58
{
 
59
    if (!m_painter) return;
 
60
 
 
61
    KisFilterSP filter = m_painter->filter();
 
62
    if (!filter) return;
 
63
 
 
64
    if ( ! m_source ) return;
 
65
 
 
66
    KisBrush * brush = m_painter->brush();
 
67
    if (!brush) return;
 
68
 
 
69
    KisColorSpace * colorSpace = m_source->colorSpace();
 
70
 
 
71
    KisPoint hotSpot = brush->hotSpot(info);
 
72
    KisPoint pt = pos - hotSpot;
 
73
 
 
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.
 
77
    Q_INT32 x;
 
78
    double xFraction;
 
79
    Q_INT32 y;
 
80
    double yFraction;
 
81
 
 
82
    splitCoordinate(pt.x(), &x, &xFraction);
 
83
    splitCoordinate(pt.y(), &y, &yFraction);
 
84
 
 
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);
 
88
 
 
89
    m_painter->setPressure(info.pressure);
 
90
 
 
91
    Q_INT32 maskWidth = mask->width();
 
92
    Q_INT32 maskHeight = mask->height();
 
93
 
 
94
    // Create a temporary paint device
 
95
    KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev");
 
96
    Q_CHECK_PTR(tmpDev);
 
97
 
 
98
    // Copy the layer data onto the new paint device
 
99
 
 
100
    KisPainter p( tmpDev );
 
101
    p.bitBlt( 0,  0,  COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, maskWidth, maskHeight );
 
102
 
 
103
    // Filter the paint device
 
104
    filter->disableProgress();
 
105
    filter->process( tmpDev,  tmpDev, m_filterConfiguration, QRect( 0, 0, maskWidth, maskHeight ));
 
106
    filter->enableProgress();
 
107
 
 
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++)
 
110
    {
 
111
        KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, maskWidth, false);
 
112
        int x=0;
 
113
        while(! hiter.isDone())
 
114
        {
 
115
            Q_UINT8 alpha = mask->alphaAt( x++, y );
 
116
            colorSpace->setAlpha(hiter.rawData(), alpha, 1);
 
117
 
 
118
            ++hiter;
 
119
        }
 
120
    }
 
121
 
 
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());
 
125
 
 
126
    KisImage * image = m_painter->device()->image();
 
127
 
 
128
    if (image != 0) {
 
129
        dstRect &= image->bounds();
 
130
    }
 
131
 
 
132
    if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
 
133
 
 
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();
 
138
 
 
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);
 
142
    }
 
143
    else {
 
144
        m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh);
 
145
    }
 
146
 
 
147
    m_painter->addDirtyRect(dstRect);
 
148
}
 
149
 
 
150
void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration)
 
151
{
 
152
    delete m_filterConfiguration;
 
153
    m_filterConfiguration = filterConfiguration;
 
154
}