chalk

kis_scale_visitor.h
1/*
2 * copyright (c) 2004, 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
3 *
4 * this program is free software; you can redistribute it and/or modify
5 * it under the terms of the gnu general public license as published by
6 * the free software foundation; either version 2 of the license, or
7 * (at your option) any later version.
8 *
9 * this program is distributed in the hope that it will be useful,
10 * but without any warranty; without even the implied warranty of
11 * merchantability or fitness for a particular purpose. see the
12 * gnu general public license for more details.
13 *
14 * you should have received a copy of the gnu general public license
15 * along with this program; if not, write to the free software
16 * foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
17 */
18
19#ifndef KIS_SCALE_VISITOR_H_
20#define KIS_SCALE_VISITOR_H_
21
22#include "tdelocale.h"
23
24#include "kis_progress_subject.h"
25#include "kis_progress_display_interface.h"
26#include "kis_thread.h"
27#include "kis_layer_visitor.h"
28#include "kis_types.h"
29#include "kis_layer.h"
30#include "kis_group_layer.h"
31#include "kis_paint_layer.h"
32#include "kis_adjustment_layer.h"
33#include "kis_transaction.h"
34#include "kis_undo_adapter.h"
35#include "kis_selection.h"
36
37class KisProgressDisplayInterface;
38class KisFilterStrategy;
39
40class KisScaleWorker : public KisThread {
41
42 /* Structs for the image rescaling routine */
43 class Contrib {
44 public:
45 TQ_INT32 m_pixel;
46 double m_weight;
47 };
48
49 class ContribList {
50 public:
51 TQ_INT32 n; //number of contributors
52 Contrib *p; //pointer to list of contributions
53 };
54
55public:
56
57 KisScaleWorker(KisPaintDevice * dev, double sx, double sy,
58 KisFilterStrategy *filterStrategy)
59 : KisThread()
60 , m_dev(dev)
61 , m_sx(sx)
62 , m_sy(sy)
63 , m_filterStrategy(filterStrategy) {};
64
65 virtual ~KisScaleWorker() {};
66
67 void run();
68
69private:
70 TQ_INT32 m_pixelSize;
71 KisPaintDevice * m_dev;
72 double m_sx, m_sy;
73 KisFilterStrategy * m_filterStrategy;
74
75
84 int calcContrib(ContribList *contribX, double cale, double fwidth, int srcwidth, KisFilterStrategy *filterStrategy, TQ_INT32 i);
85
86 ContribList * contrib; //array of contribution lists
87
88
89};
90
91
92class KisScaleVisitor : public KisLayerVisitor, KisProgressSubject {
93
94public:
95
96 KisScaleVisitor(KisImageSP img,
97 double sx,
98 double sy,
99 KisProgressDisplayInterface *progress,
100 KisFilterStrategy *filterStrategy)
101 : KisLayerVisitor()
102 , m_img(img)
103 , m_sx(sx)
104 , m_sy(sy)
105 , m_progress(progress)
106 , m_filterStrategy(filterStrategy)
107 {
108 if ( progress )
109 progress -> setSubject(this, true, true);
110 emit notifyProgressStage(i18n("Scaling..."),0);
111 }
112
113 virtual ~KisScaleVisitor()
114 {
115 // Wait for all threads to finish
116 KisThread * t;
117 int threadcount = m_scalethreads.count();
118 int i = 0;
119 for ( t = m_scalethreads.first(); t; t = m_scalethreads.next()) {
120 //progress info
121 if (t) t->wait();
122 emit notifyProgress((100 / threadcount) * i);
123 ++i;
124
125 }
126 emit notifyProgressDone();
127 // Delete all threads
128 m_scalethreads.setAutoDelete(true);
129 m_scalethreads.clear();
130 }
131
132 bool visit(KisPaintLayer *layer)
133 {
134 // XXX: If all is well, then the image's undoadapter will have started a macro for us
135 // This will break in a more multi-threaded environment
136 if (m_img->undoAdapter() && m_img->undoAdapter()->undo()) {
137 KisTransaction * cmd = new KisTransaction("", layer->paintDevice());
138 m_img->undoAdapter()->addCommand(cmd);
139 }
140
141 KisScaleWorker * scaleThread = new KisScaleWorker(layer->paintDevice(),
142 m_sx, m_sy, m_filterStrategy);
143 m_scalethreads.append(scaleThread);
144 scaleThread->start();
145 //scaleThread->run();
146 layer->setDirty();
147 return true;
148 }
149
150 bool visit(KisGroupLayer *layer)
151 {
152 //KisScaleVisitor visitor (m_img, m_sx, m_sy, m_progress, m_filterStrategy);
153
154 // XXX: Maybe faster to scale the projection and do something clever to avoid
155 // recompositing everything?
156 layer->resetProjection();
157
158
159 KisLayerSP child = layer->firstChild();
160 while (child) {
161 child->accept(*this);
162 child = child->nextSibling();
163 }
164
165 return true;
166 }
167
168 bool visit(KisPartLayer */*layer*/)
169 {
170 return true;
171 }
172
173 virtual bool visit(KisAdjustmentLayer* layer)
174 {
175 KisThread * scaleThread = new KisScaleWorker(layer->selection().data(), m_sx, m_sy, m_filterStrategy);
176 m_scalethreads.append(scaleThread);
177 scaleThread->start();
178 layer->resetCache();
179 layer->setDirty();
180 return true;
181 }
182
183
184 // Implement KisProgressSubject
185 virtual void cancel()
186 {
187 KisThread * t;
188 for ( t = m_scalethreads.first(); t; t = m_scalethreads.next()) {
189 t->cancel();
190 }
191 }
192
193
194private:
195
196 TQPtrList<KisThread> m_scalethreads;
197 KisImageSP m_img;
198 double m_sx;
199 double m_sy;
200 KisProgressDisplayInterface * m_progress;
201 KisFilterStrategy * m_filterStrategy;
202};
203
204#endif // KIS_SCALE_VISITOR_H_
Class that contains a KisFilter and optionally a KisSelection.
A KisLayer that bundles child layers into a single layer.
virtual KisLayerSP firstChild() const
Returns the first child layer of this layer (if it supports that).
virtual void resetProjection(KisPaintDevice *to=0)
virtual void setDirty(bool propagate=true)
Set the entire layer extent dirty; this percolates up to parent layers all the way to the root layer.
A paint device contains the actual pixel data and offers methods to read and write pixels.
This layer is of a type that can be painted on.
virtual void setDirty(bool propagate=true)
Overridden to call the private convertMaskToSelection.
An interface for the Part Layer so that we can use it in core/, but can implement it in ui/.
A KisThread is a TQThread that can be set in the canceled state.
Definition kis_thread.h:30
virtual void cancel()
Request the thread to cancel at the first opportunity.
Definition kis_thread.h:45