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

« back to all changes in this revision

Viewing changes to krita/core/kis_image.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:
13
13
 *
14
14
 *  You should have received a copy of the GNU General Public License
15
15
 *  along with this program; if not, write to the Free Software
16
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
 */
18
18
#include <stdlib.h>
19
19
#include <math.h>
23
23
 
24
24
#include <qimage.h>
25
25
#include <qpainter.h>
26
 
#include <qpixmap.h>
27
26
#include <qsize.h>
28
27
#include <qtl.h>
 
28
#include <qapplication.h>
 
29
#include <qthread.h>
 
30
#include <qdatetime.h>
29
31
 
30
32
#include <kcommand.h>
31
 
#include <kocommandhistory.h>
32
33
#include <kdebug.h>
33
34
#include <klocale.h>
34
35
 
35
 
#include "KIsImageIface.h"
 
36
#include "kis_image_iface.h"
36
37
 
 
38
#include "kis_annotation.h"
 
39
#include "kis_colorspace_factory_registry.h"
 
40
#include "kis_color.h"
 
41
#include "kis_command.h"
 
42
#include "kis_types.h"
 
43
//#include "kis_guide.h"
37
44
#include "kis_image.h"
38
45
#include "kis_paint_device.h"
39
 
#include "kis_paint_device_visitor.h"
 
46
#include "kis_paint_device_action.h"
 
47
#include "kis_selection.h"
40
48
#include "kis_painter.h"
41
49
#include "kis_fill_painter.h"
42
50
#include "kis_layer.h"
 
51
#include "kis_group_layer.h"
 
52
#include "kis_adjustment_layer.h"
 
53
#include "kis_paint_layer.h"
 
54
#include "kis_colorspace_convert_visitor.h"
43
55
#include "kis_background.h"
44
 
#include "kis_doc.h"
45
56
#include "kis_nameserver.h"
46
 
#include "visitors/kis_flatten.h"
47
 
#include "visitors/kis_merge.h"
 
57
#include "kis_undo_adapter.h"
 
58
#include "kis_merge_visitor.h"
48
59
#include "kis_transaction.h"
49
 
#include "kis_scale_visitor.h"
 
60
#include "kis_crop_visitor.h"
 
61
#include "kis_transform_visitor.h"
 
62
#include "kis_filter_strategy.h"
50
63
#include "kis_profile.h"
51
 
#include "kis_config.h"
52
 
#include "kis_colorspace_registry.h"
53
 
 
54
 
#define DEBUG_IMAGES 0
55
 
 
56
 
#if DEBUG_IMAGES
57
 
static int numImages = 0;
58
 
#endif
 
64
#include "kis_paint_layer.h"
 
65
#include "kis_change_profile_visitor.h"
 
66
#include "kis_group_layer.h"
 
67
#include "kis_iterators_pixel.h"
 
68
#include "kis_shear_visitor.h"
 
69
 
 
70
class KisImage::KisImagePrivate {
 
71
public:
 
72
    KisColor backgroundColor;
 
73
    Q_UINT32     lockCount;
 
74
    bool sizeChangedWhileLocked;
 
75
    bool selectionChangedWhileLocked;
 
76
};
 
77
 
59
78
 
60
79
namespace {
61
80
 
62
 
        class KisResizeImageCmd : public KNamedCommand {
63
 
                typedef KNamedCommand super;
64
 
 
65
 
        public:
66
 
                KisResizeImageCmd(KisUndoAdapter *adapter,
67
 
                                  KisImageSP img,
68
 
                                  Q_INT32 width,
69
 
                                  Q_INT32 height,
70
 
                                  Q_INT32 oldWidth,
71
 
                                  Q_INT32 oldHeight) : super(i18n("Resize Image"))
72
 
                        {
73
 
                                m_adapter = adapter;
74
 
                                m_img = img;
75
 
                                m_before = QSize(oldWidth, oldHeight);
76
 
                                m_after = QSize(width, height);
77
 
                        }
78
 
 
79
 
                virtual ~KisResizeImageCmd()
80
 
                        {
81
 
                        }
82
 
 
83
 
        public:
84
 
                virtual void execute()
85
 
                        {
86
 
                                m_adapter -> setUndo(false);
87
 
                                m_img -> resize(m_after.width(), m_after.height());
88
 
                                m_adapter -> setUndo(true);
89
 
                                m_img -> notify(0, 0, QMAX(m_before.width(), m_after.width()), QMAX(m_before.height(), m_after.height()));
90
 
                        }
91
 
 
92
 
                virtual void unexecute()
93
 
                        {
94
 
                                m_adapter -> setUndo(false);
95
 
                                m_img -> resize(m_before.width(), m_before.height());
96
 
                                m_adapter -> setUndo(true);
97
 
                                m_img -> notify(0, 0, QMAX(m_before.width(), m_after.width()), QMAX(m_before.height(), m_after.height()));
98
 
                        }
99
 
 
100
 
        private:
101
 
                KisUndoAdapter *m_adapter;
102
 
                KisImageSP m_img;
103
 
                QSize m_before;
104
 
                QSize m_after;
105
 
        };
106
 
 
107
 
 
108
 
        class KisChangeLayersCmd : public KNamedCommand {
109
 
                typedef KNamedCommand super;
110
 
 
111
 
        public:
112
 
                KisChangeLayersCmd(KisUndoAdapter *adapter, KisImageSP img, vKisLayerSP& beforeLayers, vKisLayerSP& afterLayers, const QString& name) : super(name)
113
 
                        {
114
 
                                m_adapter = adapter;
115
 
                                m_img = img;
116
 
                                m_beforeLayers = beforeLayers;
117
 
                                m_afterLayers = afterLayers;
118
 
                        }
119
 
 
120
 
                virtual ~KisChangeLayersCmd()
121
 
                        {
122
 
                        }
123
 
 
124
 
        public:
125
 
                virtual void execute()
126
 
                        {
127
 
                                m_adapter -> setUndo(false);
128
 
 
129
 
                                for (vKisLayerSP::const_iterator it = m_beforeLayers.begin(); it != m_beforeLayers.end(); it++) {
130
 
                                        m_img -> rm(*it);
131
 
                                }
132
 
 
133
 
                                for (vKisLayerSP::const_iterator it = m_afterLayers.begin(); it != m_afterLayers.end(); it++) {
134
 
                                        m_img -> add(*it, -1);
135
 
                                }
136
 
 
137
 
                                m_adapter -> setUndo(true);
138
 
                                m_img -> notify();
139
 
                                m_img -> notifyLayersChanged();
140
 
                        }
141
 
 
142
 
                virtual void unexecute()
143
 
                        {
144
 
                                m_adapter -> setUndo(false);
145
 
 
146
 
                                for (vKisLayerSP::const_iterator it = m_afterLayers.begin(); it != m_afterLayers.end(); it++) {
147
 
                                        m_img -> rm(*it);
148
 
                                }
149
 
 
150
 
                                for (vKisLayerSP::const_iterator it = m_beforeLayers.begin(); it != m_beforeLayers.end(); it++) {
151
 
                                        m_img -> add(*it, -1);
152
 
                                }
153
 
 
154
 
                                m_adapter -> setUndo(true);
155
 
                                m_img -> notify();
156
 
                                m_img -> notifyLayersChanged();
157
 
                        }
158
 
 
159
 
        private:
160
 
                KisUndoAdapter *m_adapter;
161
 
                KisImageSP m_img;
162
 
                vKisLayerSP m_beforeLayers;
163
 
                vKisLayerSP m_afterLayers;
164
 
        };
165
 
 
166
 
        class KisConvertImageTypeCmd : public KNamedCommand {
167
 
                typedef KNamedCommand super;
168
 
 
169
 
        public:
170
 
                KisConvertImageTypeCmd(KisUndoAdapter *adapter, KisImageSP img, 
171
 
                                       KisStrategyColorSpaceSP beforeColorSpace, KisProfileSP beforeProfile, 
172
 
                                       KisStrategyColorSpaceSP afterColorSpace, KisProfileSP afterProfile
173
 
                                       ) : super(i18n("&Convert Image Type...")) //XXX: fix when string freeze over
174
 
                        {
175
 
                                m_adapter = adapter;
176
 
                                m_img = img;
177
 
                                m_beforeColorSpace = beforeColorSpace;
178
 
                                m_beforeProfile = beforeProfile;
179
 
                                m_afterColorSpace = afterColorSpace;
180
 
                                m_afterProfile = afterProfile;
181
 
                        }
182
 
 
183
 
                virtual ~KisConvertImageTypeCmd()
184
 
                        {
185
 
                        }
186
 
 
187
 
        public:
188
 
                virtual void execute()
189
 
                        {
190
 
                                m_adapter -> setUndo(false);
191
 
 
192
 
                                m_img -> setColorStrategy(m_afterColorSpace);
193
 
                                m_img -> setProfile(m_afterProfile);
194
 
 
195
 
                                m_adapter -> setUndo(true);
196
 
                                m_img -> notify();
197
 
                                m_img -> notifyLayersChanged();
198
 
                        }
199
 
 
200
 
                virtual void unexecute()
201
 
                        {
202
 
                                m_adapter -> setUndo(false);
203
 
 
204
 
                                m_img -> setColorStrategy(m_beforeColorSpace);
205
 
                                m_img -> setProfile(m_beforeProfile);
206
 
 
207
 
                                m_adapter -> setUndo(true);
208
 
                                m_img -> notify();
209
 
                                m_img -> notifyLayersChanged();
210
 
                        }
211
 
 
212
 
        private:
213
 
                KisUndoAdapter *m_adapter;
214
 
                KisImageSP m_img;
215
 
                KisStrategyColorSpaceSP m_beforeColorSpace;
216
 
                KisStrategyColorSpaceSP m_afterColorSpace;
217
 
                KisProfileSP m_beforeProfile;
218
 
                KisProfileSP m_afterProfile;
219
 
        };
220
 
 
 
81
    class KisResizeImageCmd : public KNamedCommand {
 
82
        typedef KNamedCommand super;
 
83
 
 
84
    public:
 
85
        KisResizeImageCmd(KisUndoAdapter *adapter,
 
86
                          KisImageSP img,
 
87
                          Q_INT32 width,
 
88
                          Q_INT32 height,
 
89
                          Q_INT32 oldWidth,
 
90
                          Q_INT32 oldHeight) : super(i18n("Resize Image"))
 
91
            {
 
92
                m_adapter = adapter;
 
93
                m_img = img;
 
94
                m_before = QSize(oldWidth, oldHeight);
 
95
                m_after = QSize(width, height);
 
96
            }
 
97
 
 
98
        virtual ~KisResizeImageCmd()
 
99
            {
 
100
            }
 
101
 
 
102
    public:
 
103
        virtual void execute()
 
104
            {
 
105
                m_adapter->setUndo(false);
 
106
                m_img->resize(m_after.width(), m_after.height());
 
107
                m_adapter->setUndo(true);
 
108
            }
 
109
 
 
110
        virtual void unexecute()
 
111
            {
 
112
                m_adapter->setUndo(false);
 
113
                m_img->resize(m_before.width(), m_before.height());
 
114
                m_adapter->setUndo(true);
 
115
            }
 
116
 
 
117
    private:
 
118
        KisUndoAdapter *m_adapter;
 
119
        KisImageSP m_img;
 
120
        QSize m_before;
 
121
        QSize m_after;
 
122
    };
 
123
 
 
124
    // -------------------------------------------------------
 
125
 
 
126
    class KisChangeLayersCmd : public KNamedCommand {
 
127
        typedef KNamedCommand super;
 
128
 
 
129
    public:
 
130
        KisChangeLayersCmd(KisUndoAdapter *adapter, KisImageSP img,
 
131
                           KisGroupLayerSP oldRootLayer, KisGroupLayerSP newRootLayer, const QString& name)
 
132
            : super(name)
 
133
            {
 
134
                m_adapter = adapter;
 
135
                m_img = img;
 
136
                m_oldRootLayer = oldRootLayer;
 
137
                m_newRootLayer = newRootLayer;
 
138
            }
 
139
 
 
140
        virtual ~KisChangeLayersCmd()
 
141
            {
 
142
            }
 
143
 
 
144
    public:
 
145
        virtual void execute()
 
146
            {
 
147
                m_adapter->setUndo(false);
 
148
                m_img->setRootLayer(m_newRootLayer);
 
149
                m_adapter->setUndo(true);
 
150
                m_img->notifyLayersChanged();
 
151
            }
 
152
 
 
153
        virtual void unexecute()
 
154
            {
 
155
                m_adapter->setUndo(false);
 
156
                m_img->setRootLayer(m_oldRootLayer);
 
157
                m_adapter->setUndo(true);
 
158
                m_img->notifyLayersChanged();
 
159
            }
 
160
 
 
161
    private:
 
162
        KisUndoAdapter *m_adapter;
 
163
        KisImageSP m_img;
 
164
        KisGroupLayerSP m_oldRootLayer;
 
165
        KisGroupLayerSP m_newRootLayer;
 
166
    };
 
167
 
 
168
 
 
169
    // -------------------------------------------------------
 
170
 
 
171
    class KisConvertImageTypeCmd : public KNamedCommand {
 
172
        typedef KNamedCommand super;
 
173
 
 
174
    public:
 
175
        KisConvertImageTypeCmd(KisUndoAdapter *adapter, KisImageSP img,
 
176
                               KisColorSpace * beforeColorSpace, KisColorSpace * afterColorSpace
 
177
            ) : super(i18n("Convert Image Type"))
 
178
            {
 
179
                m_adapter = adapter;
 
180
                m_img = img;
 
181
                m_beforeColorSpace = beforeColorSpace;
 
182
                m_afterColorSpace = afterColorSpace;
 
183
            }
 
184
 
 
185
        virtual ~KisConvertImageTypeCmd()
 
186
            {
 
187
            }
 
188
 
 
189
    public:
 
190
        virtual void execute()
 
191
            {
 
192
                m_adapter->setUndo(false);
 
193
 
 
194
                m_img->setColorSpace(m_afterColorSpace);
 
195
                m_img->setProfile(m_afterColorSpace->getProfile());
 
196
 
 
197
                m_adapter->setUndo(true);
 
198
            }
 
199
 
 
200
        virtual void unexecute()
 
201
            {
 
202
                m_adapter->setUndo(false);
 
203
 
 
204
                m_img->setColorSpace(m_beforeColorSpace);
 
205
                m_img->setProfile(m_beforeColorSpace->getProfile());
 
206
 
 
207
                m_adapter->setUndo(true);
 
208
            }
 
209
 
 
210
    private:
 
211
        KisUndoAdapter *m_adapter;
 
212
        KisImageSP m_img;
 
213
        KisColorSpace * m_beforeColorSpace;
 
214
        KisColorSpace * m_afterColorSpace;
 
215
    };
 
216
 
 
217
 
 
218
    // -------------------------------------------------------
 
219
 
 
220
    class KisImageCommand : public KNamedCommand {
 
221
        typedef KNamedCommand super;
 
222
 
 
223
    public:
 
224
        KisImageCommand(const QString& name, KisImageSP image);
 
225
        virtual ~KisImageCommand() {}
 
226
 
 
227
        virtual void execute() = 0;
 
228
        virtual void unexecute() = 0;
 
229
 
 
230
    protected:
 
231
        void setUndo(bool undo);
 
232
 
 
233
        KisImageSP m_image;
 
234
    };
 
235
 
 
236
    KisImageCommand::KisImageCommand(const QString& name, KisImageSP image) :
 
237
        super(name), m_image(image)
 
238
    {
 
239
    }
 
240
 
 
241
    void KisImageCommand::setUndo(bool undo)
 
242
    {
 
243
        if (m_image->undoAdapter()) {
 
244
            m_image->undoAdapter()->setUndo(undo);
 
245
        }
 
246
    }
 
247
 
 
248
 
 
249
    // -------------------------------------------------------
 
250
 
 
251
    class KisLayerPositionCommand : public KisImageCommand {
 
252
        typedef KisImageCommand super;
 
253
 
 
254
    public:
 
255
        KisLayerPositionCommand(const QString& name, KisImageSP image, KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis) : super(name, image)
 
256
            {
 
257
                m_layer = layer;
 
258
                m_oldParent = layer->parent();
 
259
                m_oldAboveThis = layer->nextSibling();
 
260
                m_newParent = parent;
 
261
                m_newAboveThis = aboveThis;
 
262
           }
 
263
 
 
264
        virtual void execute()
 
265
            {
 
266
                setUndo(false);
 
267
                m_image->moveLayer(m_layer, m_newParent, m_newAboveThis);
 
268
                setUndo(true);
 
269
            }
 
270
 
 
271
        virtual void unexecute()
 
272
            {
 
273
                setUndo(false);
 
274
                m_image->moveLayer(m_layer, m_oldParent, m_oldAboveThis);
 
275
                setUndo(true);
 
276
            }
 
277
 
 
278
    private:
 
279
        KisLayerSP m_layer;
 
280
        KisGroupLayerSP m_oldParent;
 
281
        KisLayerSP m_oldAboveThis;
 
282
        KisGroupLayerSP m_newParent;
 
283
        KisLayerSP m_newAboveThis;
 
284
    };
 
285
 
 
286
 
 
287
    // -------------------------------------------------------
 
288
 
 
289
    class LayerAddCmd : public KisCommand {
 
290
        typedef KisCommand super;
 
291
 
 
292
    public:
 
293
        LayerAddCmd(KisUndoAdapter *adapter, KisImageSP img, KisLayerSP layer) : super(i18n("Add Layer"), adapter)
 
294
            {
 
295
                m_img = img;
 
296
                m_layer = layer;
 
297
                m_parent = layer->parent();
 
298
                m_aboveThis = layer->nextSibling();
 
299
            }
 
300
 
 
301
        virtual ~LayerAddCmd()
 
302
            {
 
303
            }
 
304
 
 
305
        virtual void execute()
 
306
            {
 
307
                adapter()->setUndo(false);
 
308
                m_img->addLayer(m_layer, m_parent.data(), m_aboveThis);
 
309
                adapter()->setUndo(true);
 
310
            }
 
311
 
 
312
        virtual void unexecute()
 
313
            {
 
314
                adapter()->setUndo(false);
 
315
                m_img->removeLayer(m_layer);
 
316
                adapter()->setUndo(true);
 
317
            }
 
318
 
 
319
    private:
 
320
        KisImageSP m_img;
 
321
        KisLayerSP m_layer;
 
322
        KisGroupLayerSP m_parent;
 
323
        KisLayerSP m_aboveThis;
 
324
    };
 
325
 
 
326
    // -------------------------------------------------------
 
327
 
 
328
    class LayerRmCmd : public KNamedCommand {
 
329
        typedef KNamedCommand super;
 
330
 
 
331
    public:
 
332
        LayerRmCmd(KisUndoAdapter *adapter, KisImageSP img,
 
333
                   KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
 
334
            : super(i18n("Remove Layer"))
 
335
            {
 
336
                m_adapter = adapter;
 
337
                m_img = img;
 
338
                m_layer = layer;
 
339
                m_prevParent = wasParent;
 
340
                m_prevAbove = wasAbove;
 
341
            }
 
342
 
 
343
        virtual ~LayerRmCmd()
 
344
            {
 
345
            }
 
346
 
 
347
        virtual void execute()
 
348
            {
 
349
                m_adapter->setUndo(false);
 
350
                m_img->removeLayer(m_layer);
 
351
                m_adapter->setUndo(true);
 
352
            }
 
353
 
 
354
        virtual void unexecute()
 
355
            {
 
356
                m_adapter->setUndo(false);
 
357
                m_img->addLayer(m_layer, m_prevParent.data(), m_prevAbove);
 
358
                m_adapter->setUndo(true);
 
359
            }
 
360
 
 
361
    private:
 
362
        KisUndoAdapter *m_adapter;
 
363
        KisImageSP m_img;
 
364
        KisLayerSP m_layer;
 
365
        KisGroupLayerSP m_prevParent;
 
366
        KisLayerSP m_prevAbove;
 
367
    };
 
368
 
 
369
    class LayerMoveCmd: public KNamedCommand {
 
370
        typedef KNamedCommand super;
 
371
 
 
372
    public:
 
373
        LayerMoveCmd(KisUndoAdapter *adapter, KisImageSP img,
 
374
                         KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
 
375
            : super(i18n("Move Layer"))
 
376
            {
 
377
                m_adapter = adapter;
 
378
                m_img = img;
 
379
                m_layer = layer;
 
380
                m_prevParent = wasParent;
 
381
                m_prevAbove = wasAbove;
 
382
                m_newParent = layer->parent();
 
383
                m_newAbove = layer->nextSibling();
 
384
            }
 
385
 
 
386
        virtual ~LayerMoveCmd()
 
387
            {
 
388
            }
 
389
 
 
390
        virtual void execute()
 
391
            {
 
392
                m_adapter->setUndo(false);
 
393
                m_img->moveLayer(m_layer, m_newParent.data(), m_newAbove);
 
394
                m_adapter->setUndo(true);
 
395
            }
 
396
 
 
397
        virtual void unexecute()
 
398
            {
 
399
                m_adapter->setUndo(false);
 
400
                m_img->moveLayer(m_layer, m_prevParent.data(), m_prevAbove);
 
401
                m_adapter->setUndo(true);
 
402
            }
 
403
 
 
404
    private:
 
405
        KisUndoAdapter *m_adapter;
 
406
        KisImageSP m_img;
 
407
        KisLayerSP m_layer;
 
408
        KisGroupLayerSP m_prevParent;
 
409
        KisLayerSP m_prevAbove;
 
410
        KisGroupLayerSP m_newParent;
 
411
        KisLayerSP m_newAbove;
 
412
    };
 
413
 
 
414
 
 
415
    // -------------------------------------------------------
 
416
 
 
417
    class LayerPropsCmd : public KNamedCommand {
 
418
        typedef KNamedCommand super;
 
419
 
 
420
    public:
 
421
        LayerPropsCmd(KisLayerSP layer,
 
422
                      KisImageSP img,
 
423
                      KisUndoAdapter *adapter,
 
424
                      const QString& name,
 
425
                      Q_INT32 opacity,
 
426
                      const KisCompositeOp& compositeOp) : super(i18n("Layer Property Changes"))
 
427
            {
 
428
                m_layer = layer;
 
429
                m_img = img;
 
430
                m_adapter = adapter;
 
431
                m_name = name;
 
432
                m_opacity = opacity;
 
433
                m_compositeOp = compositeOp;
 
434
            }
 
435
 
 
436
        virtual ~LayerPropsCmd()
 
437
            {
 
438
            }
 
439
 
 
440
    public:
 
441
        virtual void execute()
 
442
            {
 
443
                QString name = m_layer->name();
 
444
                Q_INT32 opacity = m_layer->opacity();
 
445
                KisCompositeOp compositeOp = m_layer->compositeOp();
 
446
 
 
447
                m_adapter->setUndo(false);
 
448
                m_img->setLayerProperties(m_layer,
 
449
                                            m_opacity,
 
450
                                            m_compositeOp,
 
451
                                            m_name);
 
452
                m_adapter->setUndo(true);
 
453
                m_name = name;
 
454
                m_opacity = opacity;
 
455
                m_compositeOp = compositeOp;
 
456
                m_layer->setDirty();
 
457
            }
 
458
 
 
459
        virtual void unexecute()
 
460
            {
 
461
                execute();
 
462
            }
 
463
 
 
464
    private:
 
465
        KisUndoAdapter *m_adapter;
 
466
        KisLayerSP m_layer;
 
467
        KisImageSP m_img;
 
468
        QString m_name;
 
469
        Q_INT32 m_opacity;
 
470
        KisCompositeOp m_compositeOp;
 
471
    };
 
472
 
 
473
    // -------------------------------------------------------
 
474
 
 
475
    class LockImageCommand : public KNamedCommand {
 
476
        typedef KNamedCommand super;
 
477
 
 
478
    public:
 
479
        LockImageCommand(KisImageSP img, bool lockImage) : super("lock image")  // Not for translation, this
 
480
            {                                                                   // is only ever used inside a macro command.
 
481
                m_img = img;
 
482
                m_lockImage = lockImage;
 
483
            }
 
484
 
 
485
        virtual ~LockImageCommand()
 
486
            {
 
487
            }
 
488
 
 
489
        virtual void execute()
 
490
            {
 
491
                if (m_lockImage) {
 
492
                    m_img->lock();
 
493
                } else {
 
494
                    m_img->unlock();
 
495
                }
 
496
            }
 
497
 
 
498
        virtual void unexecute()
 
499
            {
 
500
                if (m_lockImage) {
 
501
                    m_img->unlock();
 
502
                } else {
 
503
                    m_img->lock();
 
504
                }
 
505
            }
 
506
 
 
507
    private:
 
508
        KisImageSP m_img;
 
509
        bool m_lockImage;
 
510
    };
221
511
}
222
512
 
223
 
KisImage::KisImage(KisUndoAdapter *undoAdapter, Q_INT32 width, Q_INT32 height,  KisStrategyColorSpaceSP colorStrategy, const QString& name)
 
513
KisImage::KisImage(KisUndoAdapter *adapter, Q_INT32 width, Q_INT32 height,  KisColorSpace * colorSpace, const QString& name)
 
514
    : QObject(0, name.latin1()), KShared()
224
515
{
225
 
#if DEBUG_IMAGES
226
 
        numImages++;
227
 
        kdDebug() << "IMAGE " << name << " CREATED total now = " << numImages << endl;
228
 
#endif
229
 
        init(undoAdapter, width, height, colorStrategy, name);
230
 
        setName(name);
231
 
        m_dcop = 0L;
232
 
        m_profile = 0;
 
516
    init(adapter, width, height, colorSpace, name);
 
517
    setName(name);
 
518
    m_dcop = 0L;
233
519
}
234
520
 
235
521
KisImage::KisImage(const KisImage& rhs) : QObject(), KShared(rhs)
236
522
{
237
 
#if DEBUG_IMAGES
238
 
        numImages++;
239
 
        kdDebug() << "IMAGE " << rhs.m_name << " copy CREATED total now = " << numImages << endl;
240
 
#endif
241
 
        m_dcop = 0L;
242
 
        if (this != &rhs) {
243
 
                m_undoHistory = rhs.m_undoHistory;
244
 
                m_uri = rhs.m_uri;
245
 
                m_name = QString::null;
246
 
                m_width = rhs.m_width;
247
 
                m_height = rhs.m_height;
248
 
                m_xres = rhs.m_xres;
249
 
                m_yres = rhs.m_yres;
250
 
                m_unit = rhs.m_unit;
251
 
                m_colorStrategy = rhs.m_colorStrategy;
252
 
                m_dirty = rhs.m_dirty;
253
 
                m_adapter = rhs.m_adapter;
254
 
                m_profile = rhs.m_profile;
255
 
 
256
 
                m_bkg = new KisBackground(this, rhs.width(), rhs.height());
257
 
                Q_CHECK_PTR(m_bkg);
258
 
 
259
 
                m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
260
 
                Q_CHECK_PTR(m_projection);
261
 
 
262
 
                m_layers.reserve(rhs.m_layers.size());
263
 
 
264
 
                for (vKisLayerSP_cit it = rhs.m_layers.begin(); it != rhs.m_layers.end(); it++) {
265
 
                        KisLayerSP layer = new KisLayer(**it);
266
 
                        Q_CHECK_PTR(layer);
267
 
 
268
 
                        layer -> setImage(this);
269
 
                        m_layers.push_back(layer);
270
 
                        m_layerStack.push_back(layer);
271
 
                        m_activeLayer = layer;
272
 
                }
273
 
                
274
 
                m_annotations = rhs.m_annotations; // XXX the annotations would probably need to be deep-copied
275
 
 
276
 
 
277
 
                m_nserver = new KisNameServer(i18n("Layer %1"), rhs.m_nserver -> currentSeed() + 1);
278
 
                Q_CHECK_PTR(m_nserver);
279
 
 
280
 
                m_pixmap = rhs.m_pixmap;
281
 
        }
282
 
 
 
523
    m_dcop = 0L;
 
524
    if (this != &rhs) {
 
525
        m_private = new KisImagePrivate(*rhs.m_private);
 
526
        m_uri = rhs.m_uri;
 
527
        m_name = QString::null;
 
528
        m_width = rhs.m_width;
 
529
        m_height = rhs.m_height;
 
530
        m_xres = rhs.m_xres;
 
531
        m_yres = rhs.m_yres;
 
532
        m_unit = rhs.m_unit;
 
533
        m_colorSpace = rhs.m_colorSpace;
 
534
        m_dirty = rhs.m_dirty;
 
535
        m_adapter = rhs.m_adapter;
 
536
 
 
537
        m_bkg = new KisBackground();
 
538
        Q_CHECK_PTR(m_bkg);
 
539
 
 
540
        m_rootLayer = static_cast<KisGroupLayer*>(rhs.m_rootLayer->clone().data());
 
541
        connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
542
 
 
543
        m_annotations = rhs.m_annotations; // XXX the annotations would probably need to be deep-copied
 
544
 
 
545
        m_nserver = new KisNameServer(i18n("Layer %1"), rhs.m_nserver->currentSeed() + 1);
 
546
        Q_CHECK_PTR(m_nserver);
 
547
 
 
548
        //m_guides = rhs.m_guides;
 
549
    }
283
550
}
284
551
 
285
552
 
286
 
DCOPObject *KisImage::dcopObject()
 
553
 
 
554
DCOPObject * KisImage::dcopObject()
287
555
{
288
 
        if (!m_dcop) {
289
 
                m_dcop = new KIsImageIface(this);
290
 
                Q_CHECK_PTR(m_dcop);
291
 
        }
292
 
        return m_dcop;
 
556
    if (!m_dcop) {
 
557
        m_dcop = new KisImageIface(this);
 
558
        Q_CHECK_PTR(m_dcop);
 
559
    }
 
560
    return m_dcop;
293
561
}
294
562
 
295
563
KisImage::~KisImage()
296
564
{
297
 
#if DEBUG_IMAGES
298
 
        numImages--;
299
 
        kdDebug() << "IMAGE " << name() << " DESTROYED total now = " << numImages << endl;
300
 
#endif
301
 
        delete m_nserver;
302
 
        delete m_dcop;
 
565
    delete m_private;
 
566
    delete m_nserver;
 
567
    delete m_dcop;
303
568
}
304
569
 
305
570
QString KisImage::name() const
306
571
{
307
 
        return m_name;
 
572
    return m_name;
308
573
}
309
574
 
310
575
void KisImage::setName(const QString& name)
311
576
{
312
 
        if (!name.isEmpty())
313
 
                m_name = name;
 
577
    if (!name.isEmpty())
 
578
        m_name = name;
314
579
}
315
580
 
316
581
QString KisImage::description() const
317
582
{
318
 
        return m_description;
 
583
    return m_description;
319
584
}
320
585
 
321
586
void KisImage::setDescription(const QString& description)
322
587
{
323
 
        if (!description.isEmpty())
324
 
                m_description = description;
 
588
    if (!description.isEmpty())
 
589
        m_description = description;
 
590
}
 
591
 
 
592
 
 
593
KisColor KisImage::backgroundColor() const
 
594
{
 
595
    return m_private->backgroundColor;
 
596
}
 
597
 
 
598
void KisImage::setBackgroundColor(const KisColor & color)
 
599
{
 
600
    m_private->backgroundColor = color;
325
601
}
326
602
 
327
603
 
328
604
QString KisImage::nextLayerName() const
329
605
{
330
 
        if (m_nserver -> currentSeed() == 0) {
331
 
                m_nserver -> number();
332
 
                return i18n("background");
333
 
        }
334
 
 
335
 
        return m_nserver -> name();
336
 
}
337
 
 
338
 
void KisImage::init(KisUndoAdapter *adapter, Q_INT32 width, Q_INT32 height,  KisStrategyColorSpaceSP colorStrategy, const QString& name)
339
 
{
340
 
        Q_ASSERT(colorStrategy != 0);
341
 
        Q_ASSERT(adapter != 0);
342
 
 
343
 
        m_adapter = adapter;
344
 
        m_nserver = new KisNameServer(i18n("Layer %1"), 1);
345
 
        Q_CHECK_PTR(m_nserver);
346
 
        m_name = name;
347
 
 
348
 
        m_colorStrategy = colorStrategy;
349
 
        m_bkg = new KisBackground(this, width, height);
350
 
        Q_CHECK_PTR(m_bkg);
351
 
 
352
 
        m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
353
 
        Q_CHECK_PTR(m_projection);
354
 
 
355
 
        m_xres = 1.0;
356
 
        m_yres = 1.0;
357
 
        m_unit = KoUnit::U_PT;
358
 
        m_dirty = false;
359
 
        m_undoHistory = 0;
360
 
        m_width = width;
361
 
        m_height = height;
362
 
}
363
 
 
364
 
void KisImage::resize(Q_INT32 w, Q_INT32 h, bool cropLayers)
365
 
{
366
 
//      kdDebug() << "KisImage::resize. From: ("
367
 
//                << width()
368
 
//                << ", "
369
 
//                << height()
370
 
//                << ") to ("
371
 
//                << w
372
 
//                << ", "
373
 
//                << h
374
 
//                << ")\n";
375
 
 
376
 
        if (w != width() || h != height()) {
377
 
                if (m_adapter && m_adapter -> undo()) {
378
 
                        m_adapter -> beginMacro("Resize image");
379
 
                        m_adapter -> addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
380
 
                }
381
 
 
382
 
                m_width = w;
383
 
                m_height = h;
384
 
 
385
 
                m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
386
 
                Q_CHECK_PTR(m_projection);
387
 
 
388
 
                m_bkg = new KisBackground(this, w, h);
389
 
                Q_CHECK_PTR(m_bkg);
390
 
 
391
 
                if (cropLayers) {
392
 
                        vKisLayerSP_it it;
393
 
                        for ( it = m_layers.begin(); it != m_layers.end(); ++it ) {
394
 
                                KisLayerSP layer = (*it);
395
 
                                KisTransaction * t = new KisTransaction("crop", layer.data());
396
 
                                Q_CHECK_PTR(t);
397
 
                                layer -> crop(0, 0, w, h);
398
 
                                 if (m_adapter && m_adapter -> undo())
399
 
                                        m_adapter -> addCommand(t);
400
 
                        }
401
 
                }
402
 
 
403
 
                if (m_adapter && m_adapter -> undo()) {
404
 
                        m_adapter -> endMacro();
405
 
                }
406
 
 
407
 
                emit sizeChanged(KisImageSP(this), w, h);
408
 
        }
 
606
    if (m_nserver->currentSeed() == 0) {
 
607
        m_nserver->number();
 
608
        return i18n("background");
 
609
    }
 
610
 
 
611
    return m_nserver->name();
 
612
}
 
613
 
 
614
void KisImage::rollBackLayerName()
 
615
{
 
616
    m_nserver->rollback();
 
617
}
 
618
 
 
619
void KisImage::init(KisUndoAdapter *adapter, Q_INT32 width, Q_INT32 height,  KisColorSpace * colorSpace, const QString& name)
 
620
{
 
621
    Q_ASSERT(colorSpace);
 
622
 
 
623
    if (colorSpace == 0) {
 
624
        colorSpace = KisMetaRegistry::instance()->csRegistry()->getRGB8();
 
625
        kdWarning(41010) << "No colorspace specified: using RGBA\n";
 
626
    }
 
627
 
 
628
    m_private = new KisImagePrivate();
 
629
    m_private->backgroundColor = KisColor(Qt::white, colorSpace);
 
630
    m_private->lockCount = 0;
 
631
    m_private->sizeChangedWhileLocked = false;
 
632
    m_private->selectionChangedWhileLocked = false;
 
633
 
 
634
    m_adapter = adapter;
 
635
 
 
636
    m_nserver = new KisNameServer(i18n("Layer %1"), 1);
 
637
    m_name = name;
 
638
 
 
639
    m_colorSpace = colorSpace;
 
640
    m_bkg = new KisBackground();
 
641
 
 
642
    m_rootLayer = new KisGroupLayer(this,"root", OPACITY_OPAQUE);
 
643
    connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
644
 
 
645
    m_xres = 1.0;
 
646
    m_yres = 1.0;
 
647
    m_unit = KoUnit::U_PT;
 
648
    m_dirty = false;
 
649
    m_width = width;
 
650
    m_height = height;
 
651
}
 
652
 
 
653
bool KisImage::locked() const
 
654
{
 
655
    return m_private->lockCount != 0;
 
656
}
 
657
 
 
658
void KisImage::lock()
 
659
{
 
660
    if (!locked()) {
 
661
        if (m_rootLayer) disconnect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
662
        m_private->sizeChangedWhileLocked = false;
 
663
        m_private->selectionChangedWhileLocked = false;
 
664
    }
 
665
    m_private->lockCount++;
 
666
}
 
667
 
 
668
void KisImage::unlock()
 
669
{
 
670
    Q_ASSERT(locked());
 
671
 
 
672
    if (locked()) {
 
673
        m_private->lockCount--;
 
674
 
 
675
        if (m_private->lockCount == 0) {
 
676
            if (m_private->sizeChangedWhileLocked) {
 
677
                // A size change implies a full image update so only send this.
 
678
                emit sigSizeChanged(m_width, m_height);
 
679
            } else {
 
680
                if (m_rootLayer->dirty()) emit sigImageUpdated( m_rootLayer->dirtyRect() );
 
681
            }
 
682
 
 
683
            if (m_private->selectionChangedWhileLocked) {
 
684
                emit sigActiveSelectionChanged(this);
 
685
            }
 
686
 
 
687
            if (m_rootLayer) connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
688
        }
 
689
    }
 
690
}
 
691
 
 
692
void KisImage::emitSizeChanged()
 
693
{
 
694
    if (!locked()) {
 
695
        emit sigSizeChanged(m_width, m_height);
 
696
    } else {
 
697
        m_private->sizeChangedWhileLocked = true;
 
698
    }
 
699
}
 
700
 
 
701
void KisImage::notifyLayerUpdated(KisLayerSP layer, QRect rc)
 
702
{
 
703
    emit sigLayerUpdated(layer, rc);
 
704
}
 
705
 
 
706
void KisImage::resize(Q_INT32 w, Q_INT32 h, Q_INT32 x, Q_INT32 y, bool cropLayers)
 
707
{
 
708
    if (w != width() || h != height()) {
 
709
 
 
710
        lock();
 
711
 
 
712
        if (undo()) {
 
713
            if (cropLayers)
 
714
                m_adapter->beginMacro(i18n("Crop Image"));
 
715
            else
 
716
                m_adapter->beginMacro(i18n("Resize Image"));
 
717
 
 
718
            m_adapter->addCommand(new LockImageCommand(this, true));
 
719
            m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
 
720
        }
 
721
 
 
722
        m_width = w;
 
723
        m_height = h;
 
724
 
 
725
        if (cropLayers) {
 
726
            KisCropVisitor v(QRect(x, y, w, h));
 
727
            m_rootLayer->accept(v);
 
728
        }
 
729
 
 
730
        emitSizeChanged();
 
731
 
 
732
        unlock();
 
733
 
 
734
        if (undo()) {
 
735
            m_adapter->addCommand(new LockImageCommand(this, false));
 
736
            m_adapter->endMacro();
 
737
        }
 
738
    }
409
739
}
410
740
 
411
741
void KisImage::resize(const QRect& rc, bool cropLayers)
412
742
{
413
 
        resize(rc.width(), rc.height(), cropLayers);
414
 
}
415
 
 
416
 
void KisImage::scale(double sx, double sy, KisProgressDisplayInterface *m_progress, enumFilterType ftype)
417
 
{
418
 
//      kdDebug() << "KisImage::scale. SX: "
419
 
//                << sx
420
 
//                << ", SY:"
421
 
//                << sy
422
 
//                << "\n";
423
 
 
424
 
        if (m_layers.empty()) return; // Nothing to scale
425
 
 
426
 
        // New image size. XXX: Pass along to discourage rounding errors?
427
 
        Q_INT32 w, h;
428
 
        w = (Q_INT32)(( width() * sx) + 0.5);
429
 
        h = (Q_INT32)(( height() * sy) + 0.5);
430
 
 
431
 
//      kdDebug() << "Scaling from (" << m_projection -> width()
432
 
//                << ", " << m_projection -> height()
433
 
//                << "to: (" << w << ", " << h << ")\n";
434
 
 
435
 
        if (w != width() || h != height()) {
436
 
 
437
 
                undoAdapter() -> beginMacro("Scale image");
438
 
 
439
 
                vKisLayerSP_it it;
440
 
                for ( it = m_layers.begin(); it != m_layers.end(); ++it ) {
441
 
                        KisLayerSP layer = (*it);
442
 
                        KisTransaction *cmd = 0;
443
 
 
444
 
                        if (undoAdapter() -> undo()) {
445
 
                                cmd = new KisTransaction("", layer.data());
446
 
                                Q_CHECK_PTR(cmd);
447
 
                        }
448
 
 
449
 
                        layer -> scale(sx, sy, m_progress, ftype);
450
 
 
451
 
                        if (undoAdapter() -> undo()) {
452
 
                                undoAdapter() -> addCommand(cmd);
453
 
                        }
454
 
                }
455
 
 
456
 
                undoAdapter() -> addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
457
 
 
458
 
                m_width = w;
459
 
                m_height = h;
460
 
 
461
 
                m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
462
 
                Q_CHECK_PTR(m_projection);
463
 
 
464
 
                m_bkg = new KisBackground(this, w, h);
465
 
                Q_CHECK_PTR(m_bkg);
466
 
 
467
 
                undoAdapter() -> endMacro();
468
 
 
469
 
                emit sizeChanged(KisImageSP(this), w, h);
470
 
        }
471
 
}
472
 
 
473
 
void KisImage::rotate(double angle, KisProgressDisplayInterface *m_progress)
474
 
{
475
 
        const double pi=3.1415926535897932385;
476
 
 
477
 
        if (m_layers.empty()) return; // Nothing to scale
478
 
        Q_INT32 w, h;
479
 
        w = (Q_INT32)(width()*QABS(cos(angle*pi/180)) + height()*QABS(sin(angle*pi/180)) + 0.5);
480
 
        h = (Q_INT32)(height()*QABS(cos(angle*pi/180)) + width()*QABS(sin(angle*pi/180)) + 0.5);
481
 
 
482
 
        Q_INT32 oldCentreToNewCentreXOffset = (w - width()) / 2;
483
 
        Q_INT32 oldCentreToNewCentreYOffset = (h - height()) / 2;
484
 
 
485
 
        undoAdapter() -> beginMacro("Rotate image");
486
 
 
487
 
        vKisLayerSP_it it;
488
 
        for ( it = m_layers.begin(); it != m_layers.end(); ++it ) {
489
 
                KisLayerSP layer = (*it);
490
 
 
491
 
                KisTransaction * t = 0;
492
 
                if (undoAdapter() && undoAdapter() -> undo()) {
493
 
                        t = new KisTransaction("", layer.data());
494
 
                        Q_CHECK_PTR(t);
495
 
                }
496
 
 
497
 
                layer -> rotate(angle, true, m_progress);
498
 
 
499
 
                if (t) {
500
 
                        undoAdapter() -> addCommand(t);
501
 
                }
502
 
 
503
 
                //XXX: This is very ugly.
504
 
                KNamedCommand *moveCommand = layer -> moveCommand(layer -> getX() + oldCentreToNewCentreXOffset, 
505
 
                                                                  layer -> getY() + oldCentreToNewCentreYOffset);
506
 
                if (undoAdapter() && undoAdapter() -> undo()) {
507
 
                        undoAdapter() -> addCommand(moveCommand);
508
 
                } else {
509
 
                        delete moveCommand;
510
 
                }
511
 
        }
512
 
 
513
 
        m_adapter -> addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
514
 
 
515
 
        m_width = w;
516
 
        m_height = h;
517
 
 
518
 
        m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
519
 
        Q_CHECK_PTR(m_projection);
520
 
 
521
 
        m_bkg = new KisBackground(this, w, h);
522
 
        Q_CHECK_PTR(m_bkg);
523
 
 
524
 
        undoAdapter()->endMacro();
525
 
 
526
 
        emit sizeChanged(KisImageSP(this), w, h);
 
743
    resize(rc.width(), rc.height(), rc.x(), rc.y(), cropLayers);
 
744
}
 
745
 
 
746
 
 
747
void KisImage::scale(double sx, double sy, KisProgressDisplayInterface *progress, KisFilterStrategy *filterStrategy)
 
748
{
 
749
    if (nlayers() == 0) return; // Nothing to scale
 
750
 
 
751
    // New image size. XXX: Pass along to discourage rounding errors?
 
752
    Q_INT32 w, h;
 
753
    w = (Q_INT32)(( width() * sx) + 0.5);
 
754
    h = (Q_INT32)(( height() * sy) + 0.5);
 
755
 
 
756
    if (w != width() || h != height()) {
 
757
 
 
758
        lock();
 
759
 
 
760
        if (undo()) {
 
761
            m_adapter->beginMacro(i18n("Scale Image"));
 
762
            m_adapter->addCommand(new LockImageCommand(this, true));
 
763
        }
 
764
 
 
765
        {
 
766
            KisTransformVisitor visitor (this, sx, sy, 0.0, 0.0, 0.0, 0, 0, progress, filterStrategy);
 
767
            m_rootLayer->accept(visitor);
 
768
        }
 
769
 
 
770
        if (undo()) {
 
771
            m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
 
772
        }
 
773
 
 
774
        m_width = w;
 
775
        m_height = h;
 
776
 
 
777
        emitSizeChanged();
 
778
 
 
779
        unlock();
 
780
 
 
781
        if (undo()) {
 
782
            m_adapter->addCommand(new LockImageCommand(this, false));
 
783
            m_adapter->endMacro();
 
784
        }
 
785
    }
 
786
}
 
787
 
 
788
 
 
789
 
 
790
void KisImage::rotate(double angle, KisProgressDisplayInterface *progress)
 
791
{
 
792
    lock();
 
793
 
 
794
    angle *= M_PI/180;
 
795
    Q_INT32 w = width();
 
796
    Q_INT32 h = height();
 
797
    Q_INT32 tx = Q_INT32((w*cos(angle) - h*sin(angle) - w) / 2 + 0.5);
 
798
    Q_INT32 ty = Q_INT32((h*cos(angle) + w*sin(angle) - h) / 2 + 0.5);
 
799
    w = (Q_INT32)(width()*QABS(cos(angle)) + height()*QABS(sin(angle)) + 0.5);
 
800
    h = (Q_INT32)(height()*QABS(cos(angle)) + width()*QABS(sin(angle)) + 0.5);
 
801
 
 
802
    tx -= (w - width()) / 2;
 
803
    ty -= (h - height()) / 2;
 
804
 
 
805
    if (undo()) {
 
806
        m_adapter->beginMacro(i18n("Rotate Image"));
 
807
        m_adapter->addCommand(new LockImageCommand(this, true));
 
808
    }
 
809
 
 
810
    KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
 
811
    KisTransformVisitor visitor (this, 1.0, 1.0, 0, 0, angle, -tx, -ty, progress, filter);
 
812
    m_rootLayer->accept(visitor);
 
813
 
 
814
    if (undo()) m_adapter->addCommand(new KisResizeImageCmd(undoAdapter(), this, w, h, width(), height()));
 
815
 
 
816
    m_width = w;
 
817
    m_height = h;
 
818
 
 
819
    emitSizeChanged();
 
820
 
 
821
    unlock();
 
822
 
 
823
    if (undo()) {
 
824
        m_adapter->addCommand(new LockImageCommand(this, false));
 
825
        m_adapter->endMacro();
 
826
    }
527
827
}
528
828
 
529
829
void KisImage::shear(double angleX, double angleY, KisProgressDisplayInterface *m_progress)
530
830
{
531
 
        const double pi=3.1415926535897932385;
532
 
 
533
 
        if (m_layers.empty()) return; // Nothing to scale
534
 
 
535
 
        //new image size
536
 
        Q_INT32 w=width();
537
 
        Q_INT32 h=height();
538
 
 
539
 
 
540
 
        if(angleX != 0 || angleY != 0){
541
 
                double deltaY=height()*QABS(tan(angleX*pi/180)*tan(angleY*pi/180));
542
 
                w = (Q_INT32) ( width() + QABS(height()*tan(angleX*pi/180)) );
543
 
                //ugly fix for the problem of having two extra pixels if only a shear along one
544
 
                //axis is done. This has to be fixed in the cropping code in KisRotateVisitor!
545
 
                if (angleX == 0 || angleY == 0)
546
 
                        h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
547
 
                else if (angleX > 0 && angleY > 0)
548
 
                        h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
549
 
                else if (angleX < 0 && angleY < 0)
550
 
                        h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
551
 
                else
552
 
                        h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
553
 
        }
554
 
 
555
 
        if (w != width() || h != height()) {
556
 
 
557
 
                undoAdapter() -> beginMacro("Shear image");
558
 
 
559
 
                vKisLayerSP_it it;
560
 
                for ( it = m_layers.begin(); it != m_layers.end(); ++it ) {
561
 
                        KisLayerSP layer = (*it);
562
 
 
563
 
                        KisTransaction * t = 0;
564
 
                        if (undoAdapter() && undoAdapter() -> undo()) {
565
 
                                t = new KisTransaction("", layer.data());
566
 
                                Q_CHECK_PTR(t);
567
 
                        }
568
 
 
569
 
                        layer -> shear(angleX, angleY, m_progress);
570
 
 
571
 
                        if (t) {
572
 
                                undoAdapter() -> addCommand(t);
573
 
                        }
574
 
 
575
 
                }
576
 
 
577
 
                m_adapter -> addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
578
 
 
579
 
                m_width = w;
580
 
                m_height = h;
581
 
 
582
 
                m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
583
 
                Q_CHECK_PTR(m_projection);
584
 
 
585
 
                m_bkg = new KisBackground(this, w, h);
586
 
                Q_CHECK_PTR(m_bkg);
587
 
 
588
 
                undoAdapter()->endMacro();
589
 
 
590
 
                emit sizeChanged(KisImageSP(this), w, h);
591
 
        }
592
 
}
593
 
 
594
 
void KisImage::convertTo(KisStrategyColorSpaceSP dstColorStrategy, KisProfileSP dstProfile, Q_INT32 renderingIntent)
595
 
{
596
 
        // XXX profile() == profile() will mostly result in extra work being done here, but there doesn't seem to be a better way?
597
 
        if ( (m_colorStrategy -> id() == dstColorStrategy -> id())
598
 
             && profile() 
599
 
             && dstProfile 
600
 
             && (profile() -> profile() == dstProfile -> profile()) )
601
 
        {
602
 
                kdDebug() << "KisImage: NOT GOING TO CONVERT\n";
603
 
                return;
604
 
        }
605
 
 
606
 
        if (undoAdapter() && undoAdapter() -> undo()) {
607
 
                undoAdapter() -> beginMacro(i18n("&Convert Image Type...")); //XXX: fix when string freeze over
608
 
        }
609
 
 
610
 
        vKisLayerSP_it it;
611
 
        for ( it = m_layers.begin(); it != m_layers.end(); ++it ) {
612
 
                (*it) -> convertTo(dstColorStrategy, dstProfile, renderingIntent);
613
 
        }
614
 
        
615
 
        if (undoAdapter() && undoAdapter() -> undo()) {
616
 
                
617
 
                undoAdapter() -> addCommand(new KisConvertImageTypeCmd(undoAdapter(), this, m_colorStrategy, m_profile,
618
 
                                                                       dstColorStrategy, dstProfile));
619
 
                undoAdapter() -> endMacro();
620
 
        }
621
 
 
622
 
        setColorStrategy(dstColorStrategy);
623
 
        setProfile(dstProfile);
624
 
        notify();
625
 
        notifyLayersChanged();
626
 
        
627
 
}
628
 
 
629
 
KisProfileSP KisImage::profile() const
630
 
{
631
 
        return m_profile;
632
 
}
633
 
 
634
 
void KisImage::setProfile(const KisProfileSP& profile)
635
 
{
636
 
        if (profile && profile -> valid()) {
637
 
                m_profile = profile;
638
 
                m_projection -> setProfile(profile);
639
 
        }
640
 
        else {
641
 
                m_profile = 0;
642
 
                m_projection -> setProfile(m_profile);
643
 
        }
644
 
        notify();
645
 
        emit(profileChanged(m_profile));
646
 
}
647
 
 
648
 
KURL KisImage::uri() const
649
 
{
650
 
        return m_uri;
651
 
}
652
 
 
653
 
void KisImage::uri(const KURL& uri)
654
 
{
655
 
        if (uri.isValid())
656
 
                m_uri = uri;
657
 
}
658
 
 
659
 
KoUnit::Unit KisImage::unit() const
660
 
{
661
 
        return m_unit;
662
 
}
663
 
 
664
 
void KisImage::unit(const KoUnit::Unit& u)
665
 
{
666
 
        m_unit = u;
 
831
    const double pi=3.1415926535897932385;
 
832
 
 
833
    //new image size
 
834
    Q_INT32 w=width();
 
835
    Q_INT32 h=height();
 
836
 
 
837
 
 
838
    if(angleX != 0 || angleY != 0){
 
839
        double deltaY=height()*QABS(tan(angleX*pi/180)*tan(angleY*pi/180));
 
840
        w = (Q_INT32) ( width() + QABS(height()*tan(angleX*pi/180)) );
 
841
        //ugly fix for the problem of having two extra pixels if only a shear along one
 
842
        //axis is done. This has to be fixed in the cropping code in KisRotateVisitor!
 
843
        if (angleX == 0 || angleY == 0)
 
844
            h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
 
845
        else if (angleX > 0 && angleY > 0)
 
846
            h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
 
847
        else if (angleX < 0 && angleY < 0)
 
848
            h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
 
849
        else
 
850
            h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
 
851
    }
 
852
 
 
853
    if (w != width() || h != height()) {
 
854
 
 
855
        lock();
 
856
 
 
857
        if (undo()) {
 
858
            m_adapter->beginMacro(i18n("Shear Image"));
 
859
            m_adapter->addCommand(new LockImageCommand(this, true));
 
860
        }
 
861
 
 
862
        KisShearVisitor v(angleX, angleY, m_progress);
 
863
        v.setUndoAdapter(undoAdapter());
 
864
        rootLayer()->accept(v);
 
865
 
 
866
        if (undo()) m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
 
867
 
 
868
        m_width = w;
 
869
        m_height = h;
 
870
 
 
871
        emitSizeChanged();
 
872
 
 
873
        unlock();
 
874
 
 
875
        if (undo()) {
 
876
            m_adapter->addCommand(new LockImageCommand(this, false));
 
877
            m_adapter->endMacro();
 
878
        }
 
879
    }
 
880
}
 
881
 
 
882
void KisImage::convertTo(KisColorSpace * dstColorSpace, Q_INT32 renderingIntent)
 
883
{
 
884
    if ( m_colorSpace == dstColorSpace )
 
885
    {
 
886
        return;
 
887
    }
 
888
 
 
889
    lock();
 
890
 
 
891
    KisColorSpace * oldCs = m_colorSpace;
 
892
 
 
893
    if (undo()) {
 
894
        m_adapter->beginMacro(i18n("Convert Image Type"));
 
895
        m_adapter->addCommand(new LockImageCommand(this, true));
 
896
    }
 
897
 
 
898
    setColorSpace(dstColorSpace);
 
899
 
 
900
    KisColorSpaceConvertVisitor visitor(dstColorSpace, renderingIntent);
 
901
    m_rootLayer->accept(visitor);
 
902
 
 
903
    unlock();
 
904
 
 
905
    emit sigLayerPropertiesChanged( m_activeLayer );
 
906
 
 
907
    if (undo()) {
 
908
 
 
909
        m_adapter->addCommand(new KisConvertImageTypeCmd(undoAdapter(), this,
 
910
                                                         oldCs, dstColorSpace));
 
911
        m_adapter->addCommand(new LockImageCommand(this, false));
 
912
        m_adapter->endMacro();
 
913
    }
 
914
}
 
915
 
 
916
KisProfile *  KisImage::getProfile() const
 
917
{
 
918
    return colorSpace()->getProfile();
 
919
}
 
920
 
 
921
void KisImage::setProfile(const KisProfile * profile)
 
922
{
 
923
    if (profile == 0) return;
 
924
 
 
925
    KisColorSpace * dstCs= KisMetaRegistry::instance()->csRegistry()->getColorSpace( colorSpace()->id(),
 
926
                                                                                         profile);
 
927
    if (dstCs) {
 
928
 
 
929
        lock();
 
930
 
 
931
        KisColorSpace * oldCs = colorSpace();
 
932
        setColorSpace(dstCs);
 
933
        emit(sigProfileChanged(const_cast<KisProfile *>(profile)));
 
934
 
 
935
        KisChangeProfileVisitor visitor(oldCs, dstCs);
 
936
        m_rootLayer->accept(visitor);
 
937
 
 
938
        unlock();
 
939
    }
667
940
}
668
941
 
669
942
double KisImage::xRes()
670
943
{
671
 
        return m_xres;
 
944
    return m_xres;
672
945
}
673
946
 
674
947
double KisImage::yRes()
675
948
{
676
 
        return m_yres;
 
949
    return m_yres;
677
950
}
678
951
 
679
952
void KisImage::setResolution(double xres, double yres)
680
953
{
681
 
        m_xres = xres;
682
 
        m_yres = yres;
 
954
    m_xres = xres;
 
955
    m_yres = yres;
683
956
}
684
957
 
685
958
Q_INT32 KisImage::width() const
686
959
{
687
 
        return m_width;
 
960
    return m_width;
688
961
}
689
962
 
690
963
Q_INT32 KisImage::height() const
691
964
{
692
 
        return m_height;
693
 
}
694
 
 
695
 
 
696
 
bool KisImage::empty() const
697
 
{
698
 
        return m_layers.size() > 0;
699
 
}
700
 
 
701
 
vKisLayerSP KisImage::layers()
702
 
{
703
 
        return m_layers;
704
 
}
705
 
 
706
 
const vKisLayerSP& KisImage::layers() const
707
 
{
708
 
        return m_layers;
 
965
    return m_height;
709
966
}
710
967
 
711
968
KisPaintDeviceSP KisImage::activeDevice()
712
969
{
713
 
        if (m_activeLayer) {
714
 
                return m_activeLayer.data();
715
 
        }
716
 
 
717
 
        return 0;
718
 
}
719
 
 
720
 
const KisLayerSP KisImage::activeLayer() const
721
 
{
722
 
        return m_activeLayer;
723
 
}
724
 
 
725
 
KisLayerSP KisImage::activeLayer()
726
 
{
727
 
        return m_activeLayer;
 
970
    if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(m_activeLayer.data())) {
 
971
        return layer->paintDevice();
 
972
    }
 
973
    else if (KisAdjustmentLayer* layer = dynamic_cast<KisAdjustmentLayer*>(m_activeLayer.data())) {
 
974
        if (layer->selection()) {
 
975
            return layer->selection().data();
 
976
        }
 
977
    }
 
978
    else if (KisGroupLayer * layer = dynamic_cast<KisGroupLayer*>(m_activeLayer.data())) {
 
979
        // Find first child
 
980
        KisLayer * child = layer->lastChild();
 
981
        while(child)
 
982
        {
 
983
            if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(m_activeLayer.data())) {
 
984
                return layer->paintDevice();
 
985
            }
 
986
            child = child->prevSibling();
 
987
        }
 
988
    }
 
989
    // XXX: We're buggered!
 
990
    return 0;
 
991
}
 
992
 
 
993
KisLayerSP KisImage::newLayer(const QString& name, Q_UINT8 opacity, const KisCompositeOp& compositeOp, KisColorSpace * colorstrategy)
 
994
{
 
995
    KisPaintLayer * layer;
 
996
    if (colorstrategy)
 
997
        layer = new KisPaintLayer(this, name, opacity, colorstrategy);
 
998
    else
 
999
        layer = new KisPaintLayer(this, name, opacity);
 
1000
    Q_CHECK_PTR(layer);
 
1001
 
 
1002
    if (compositeOp.isValid())
 
1003
        layer->setCompositeOp(compositeOp);
 
1004
    layer->setVisible(true);
 
1005
 
 
1006
    if (m_activeLayer != 0) {
 
1007
        addLayer(layer, m_activeLayer->parent().data(), m_activeLayer->nextSibling());
 
1008
    }
 
1009
    else {
 
1010
        addLayer(layer, m_rootLayer, 0);
 
1011
    }
 
1012
    activate(layer);
 
1013
 
 
1014
    return layer;
 
1015
}
 
1016
 
 
1017
void KisImage::setLayerProperties(KisLayerSP layer, Q_UINT8 opacity, const KisCompositeOp& compositeOp, const QString& name)
 
1018
{
 
1019
    if (layer && (layer->opacity() != opacity || layer->compositeOp() != compositeOp || layer->name() != name)) {
 
1020
        if (undo()) {
 
1021
            QString oldname = layer->name();
 
1022
            Q_INT32 oldopacity = layer->opacity();
 
1023
            KisCompositeOp oldCompositeOp = layer->compositeOp();
 
1024
            layer->setName(name);
 
1025
            layer->setOpacity(opacity);
 
1026
            layer->setCompositeOp(compositeOp);
 
1027
            m_adapter->addCommand(new LayerPropsCmd(layer, this, m_adapter, oldname, oldopacity, oldCompositeOp));
 
1028
        } else {
 
1029
            layer->setName(name);
 
1030
            layer->setOpacity(opacity);
 
1031
            layer->setCompositeOp(compositeOp);
 
1032
        }
 
1033
    }
 
1034
}
 
1035
 
 
1036
KisGroupLayerSP KisImage::rootLayer() const
 
1037
{
 
1038
    return m_rootLayer;
 
1039
}
 
1040
 
 
1041
KisLayerSP KisImage::activeLayer() const
 
1042
{
 
1043
    return m_activeLayer;
 
1044
}
 
1045
 
 
1046
KisPaintDeviceSP KisImage::projection()
 
1047
{
 
1048
    return m_rootLayer->projection(QRect(0, 0, m_width, m_height));
728
1049
}
729
1050
 
730
1051
KisLayerSP KisImage::activate(KisLayerSP layer)
731
1052
{
732
 
        vKisLayerSP_it it;
733
 
 
734
 
        if (m_layers.empty() || !layer)
735
 
                return 0;
736
 
 
737
 
        it = qFind(m_layers.begin(), m_layers.end(), layer);
738
 
 
739
 
        if (it == m_layers.end()) {
740
 
                layer = m_layers[0];
741
 
                it = m_layers.begin();
742
 
        }
743
 
 
744
 
        if (layer) {
745
 
                it = qFind(m_layerStack.begin(), m_layerStack.end(), layer);
746
 
 
747
 
                if (it != m_layerStack.end())
748
 
                        m_layerStack.erase(it);
749
 
 
750
 
                m_layerStack.insert(m_layerStack.begin() + 0, layer);
751
 
        }
752
 
 
753
 
        if (layer != m_activeLayer) {
754
 
                m_activeLayer = layer;
755
 
                emit activeLayerChanged(KisImageSP(this));
756
 
        }
757
 
 
758
 
 
759
 
        return layer;
760
 
}
761
 
 
762
 
KisLayerSP KisImage::activateLayer(Q_INT32 n)
763
 
{
764
 
        if (n < 0 || static_cast<Q_UINT32>(n) > m_layers.size())
765
 
                return 0;
766
 
 
767
 
        return activate(m_layers[n]);
768
 
}
769
 
 
770
 
Q_INT32 KisImage::index(const KisLayerSP &layer)
771
 
{
772
 
        for (Q_UINT32 i = 0; i < m_layers.size(); i++) {
773
 
                if (m_layers[i] == layer)
774
 
                        return i;
775
 
        }
776
 
 
777
 
        return -1;
778
 
}
779
 
 
780
 
KisLayerSP KisImage::layer(const QString& name)
781
 
{
782
 
        for (vKisLayerSP_it it = m_layers.begin(); it != m_layers.end(); it++) {
783
 
                if ((*it) -> name() == name)
784
 
                        return *it;
785
 
        }
786
 
 
787
 
        return 0;
788
 
}
789
 
 
790
 
KisLayerSP KisImage::layer(Q_UINT32 npos)
791
 
{
792
 
        if (npos >= m_layers.size())
793
 
                return 0;
794
 
 
795
 
        return m_layers[npos];
796
 
}
797
 
 
798
 
bool KisImage::add(KisLayerSP layer, Q_INT32 position)
799
 
{
800
 
        if (layer == 0)
801
 
                return false;
802
 
 
803
 
        if (layer -> image() && layer -> image() != KisImageSP(this))
804
 
                return false;
805
 
 
806
 
        if (qFind(m_layers.begin(), m_layers.end(), layer) != m_layers.end())
807
 
                return false;
808
 
 
809
 
        layer -> setImage(KisImageSP(this));
810
 
 
811
 
        if (position == -1) {
812
 
                // Add to bottom of layer stack
813
 
                position = m_layers.size();
814
 
        }
815
 
 
816
 
        m_layers.insert(m_layers.begin() + position, layer);
817
 
        activate(layer);
818
 
 
819
 
        m_layerStack.push_back(layer);
820
 
        return true;
821
 
}
822
 
 
823
 
void KisImage::rm(KisLayerSP layer)
824
 
{
825
 
        if (layer == 0)
826
 
                return;
827
 
 
828
 
        vKisLayerSP_it it = qFind(m_layers.begin(), m_layers.end(), layer);
829
 
 
830
 
        if (it == m_layers.end())
831
 
                return;
832
 
 
833
 
        m_layers.erase(it);
834
 
        it = qFind(m_layerStack.begin(), m_layerStack.end(), layer);
835
 
 
836
 
        if (it != m_layerStack.end())
837
 
                m_layerStack.erase(it);
838
 
 
839
 
        layer -> setImage(0);
840
 
 
841
 
        if (layer == m_activeLayer) {
842
 
                if (m_layers.empty()) {
843
 
                        m_activeLayer = 0;
844
 
                        emit activeLayerChanged(KisImageSP(this));
845
 
                } else {
846
 
                        activate(m_layerStack[0]);
847
 
                }
848
 
        }
849
 
}
850
 
 
851
 
bool KisImage::raise(KisLayerSP layer)
852
 
{
853
 
        Q_INT32 position;
854
 
 
855
 
        if (layer == 0)
856
 
                return false;
857
 
 
858
 
        position = index(layer);
859
 
 
860
 
        if (position <= 0)
861
 
                return false;
862
 
 
863
 
        return pos(layer, position - 1);
864
 
}
865
 
 
866
 
bool KisImage::lower(KisLayerSP layer)
867
 
{
868
 
        Q_INT32 position;
869
 
        Q_INT32 size;
870
 
 
871
 
        if (layer == 0)
872
 
                return false;
873
 
 
874
 
        position = index(layer);
875
 
        size = m_layers.size();
876
 
 
877
 
        if (position >= size)
878
 
                return false;
879
 
 
880
 
        return pos(layer, position + 1);
881
 
}
882
 
 
883
 
bool KisImage::top(KisLayerSP layer)
884
 
{
885
 
        Q_INT32 position;
886
 
 
887
 
        if (layer == 0)
888
 
                return false;
889
 
 
890
 
        position = index(layer);
891
 
 
892
 
        if (position == 0)
893
 
                return false;
894
 
 
895
 
        return pos(layer, 0);
896
 
}
897
 
 
898
 
bool KisImage::bottom(KisLayerSP layer)
899
 
{
900
 
        Q_INT32 position;
901
 
        Q_INT32 size;
902
 
 
903
 
        if (layer == 0)
904
 
                return false;
905
 
 
906
 
        position = index(layer);
907
 
        size = m_layers.size();
908
 
 
909
 
        if (position >= size - 1)
910
 
                return false;
911
 
 
912
 
        return pos(layer, size - 1);
913
 
}
914
 
 
915
 
bool KisImage::pos(KisLayerSP layer, Q_INT32 position)
916
 
{
917
 
        Q_INT32 old;
918
 
        Q_INT32 nlayers;
919
 
 
920
 
        if (layer == 0)
921
 
                return false;
922
 
 
923
 
        old = index(layer);
924
 
 
925
 
        if (old < 0)
926
 
                return false;
927
 
 
928
 
        nlayers = m_layers.size();
929
 
 
930
 
        if (position < 0)
931
 
                position = 0;
932
 
 
933
 
        if (position >= nlayers)
934
 
                position = nlayers - 1;
935
 
 
936
 
        if (old == position)
937
 
                return true;
938
 
 
939
 
        if (position < old) {
940
 
                m_layers.erase(m_layers.begin() + old);
941
 
                m_layers.insert(m_layers.begin() + position, layer);
942
 
        }
943
 
        else {
944
 
                m_layers.insert(m_layers.begin() + position + 1, layer);
945
 
                m_layers.erase(m_layers.begin() + old);
946
 
        }
947
 
 
948
 
        return true;
 
1053
    if (layer != m_activeLayer) {
 
1054
        if (m_activeLayer) m_activeLayer->deactivate();
 
1055
        m_activeLayer = layer;
 
1056
        if (m_activeLayer) m_activeLayer->activate();
 
1057
        emit sigLayerActivated(m_activeLayer);
 
1058
    }
 
1059
 
 
1060
    return layer;
 
1061
}
 
1062
 
 
1063
KisLayerSP KisImage::findLayer(const QString& name) const
 
1064
{
 
1065
    return rootLayer()->findLayer(name);
 
1066
}
 
1067
 
 
1068
KisLayerSP KisImage::findLayer(int id) const
 
1069
{
 
1070
    return rootLayer()->findLayer(id);
 
1071
}
 
1072
 
 
1073
 
 
1074
bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent)
 
1075
{
 
1076
    return addLayer(layer, parent, parent->firstChild());
 
1077
}
 
1078
 
 
1079
bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
 
1080
{
 
1081
    if (!parent)
 
1082
        return false;
 
1083
 
 
1084
    const bool success = parent->addLayer(layer, aboveThis);
 
1085
    if (success)
 
1086
    {
 
1087
        KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>(layer.data());
 
1088
        if (player != 0) {
 
1089
 
 
1090
            // XXX: This should also be done whenever a layer grows!
 
1091
            QValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() ->
 
1092
                csRegistry()->paintDeviceActionsFor(player->paintDevice()->colorSpace());
 
1093
            for (uint i = 0; i < actions.count(); i++) {
 
1094
                actions.at(i)->act(player.data()->paintDevice(), width(), height());
 
1095
            }
 
1096
        }
 
1097
 
 
1098
        if (layer->extent().isValid()) layer->setDirty();
 
1099
 
 
1100
        if (!layer->temporary()) {
 
1101
            emit sigLayerAdded(layer);
 
1102
            activate(layer);
 
1103
        }
 
1104
 
 
1105
 
 
1106
        if (!layer->temporary() && undo()) {
 
1107
            m_adapter->addCommand(new LayerAddCmd(m_adapter, this, layer));
 
1108
        }
 
1109
    }
 
1110
 
 
1111
    return success;
 
1112
}
 
1113
 
 
1114
bool KisImage::removeLayer(KisLayerSP layer)
 
1115
{
 
1116
    if (!layer || layer->image() != this)
 
1117
        return false;
 
1118
 
 
1119
    if (KisGroupLayerSP parent = layer->parent()) {
 
1120
        // Adjustment layers should mark the layers underneath them, whose rendering
 
1121
        // they have cached, diryt on removal. Otherwise, the group won't be re-rendered.
 
1122
        KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(layer.data());
 
1123
        if (al) {
 
1124
            QRect r = al->extent();
 
1125
            lock(); // Lock the image, because we are going to dirty a lot of layers
 
1126
            KisLayerSP l = layer->nextSibling();
 
1127
            while (l) {
 
1128
                KisAdjustmentLayer * al2 = dynamic_cast<KisAdjustmentLayer*>(l.data());
 
1129
                l->setDirty(r, false);
 
1130
                if (al2 != 0) break;
 
1131
                l = l->nextSibling();
 
1132
            }
 
1133
            unlock();
 
1134
        }
 
1135
        KisLayerSP l = layer->prevSibling();
 
1136
        QRect r = layer->extent();
 
1137
        while (l) {
 
1138
            l->setDirty(r, false);
 
1139
            l = l->prevSibling();
 
1140
        }
 
1141
 
 
1142
        KisLayerSP wasAbove = layer->nextSibling();
 
1143
        KisLayerSP wasBelow = layer->prevSibling();
 
1144
        const bool wasActive = layer == activeLayer();
 
1145
        // sigLayerRemoved can set it to 0, we don't want that in the else of wasActive!
 
1146
        KisLayerSP actLayer = activeLayer();
 
1147
        const bool success = parent->removeLayer(layer);
 
1148
        if (success) {
 
1149
            layer->setImage(0);
 
1150
            if (!layer->temporary() && undo()) {
 
1151
                m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, parent, wasAbove));
 
1152
            }
 
1153
            if (!layer->temporary()) {
 
1154
                emit sigLayerRemoved(layer, parent, wasAbove);
 
1155
                if (wasActive) {
 
1156
                    if (wasBelow)
 
1157
                        activate(wasBelow);
 
1158
                    else if (wasAbove)
 
1159
                        activate(wasAbove);
 
1160
                    else if (parent != rootLayer())
 
1161
                        activate(parent.data());
 
1162
                    else
 
1163
                        activate(rootLayer()->firstChild());
 
1164
                } else {
 
1165
                    activate(actLayer);
 
1166
                }
 
1167
            }
 
1168
        }
 
1169
        return success;
 
1170
    }
 
1171
 
 
1172
    return false;
 
1173
}
 
1174
 
 
1175
bool KisImage::raiseLayer(KisLayerSP layer)
 
1176
{
 
1177
    if (!layer)
 
1178
        return false;
 
1179
    return moveLayer(layer, layer->parent().data(), layer->prevSibling());
 
1180
}
 
1181
 
 
1182
bool KisImage::lowerLayer(KisLayerSP layer)
 
1183
{
 
1184
    if (!layer)
 
1185
        return false;
 
1186
    if (KisLayerSP next = layer->nextSibling())
 
1187
        return moveLayer(layer, layer->parent().data(), next->nextSibling());
 
1188
    return false;
 
1189
}
 
1190
 
 
1191
bool KisImage::toTop(KisLayerSP layer)
 
1192
{
 
1193
    if (!layer)
 
1194
        return false;
 
1195
    return moveLayer(layer, rootLayer(), rootLayer()->firstChild());
 
1196
}
 
1197
 
 
1198
bool KisImage::toBottom(KisLayerSP layer)
 
1199
{
 
1200
    if (!layer)
 
1201
        return false;
 
1202
    return moveLayer(layer, rootLayer(), 0);
 
1203
}
 
1204
 
 
1205
bool KisImage::moveLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
 
1206
{
 
1207
    if (!parent)
 
1208
        return false;
 
1209
 
 
1210
    KisGroupLayerSP wasParent = layer->parent();
 
1211
    KisLayerSP wasAbove = layer->nextSibling();
 
1212
 
 
1213
    if (wasParent.data() == parent.data() && wasAbove.data() == aboveThis.data())
 
1214
        return false;
 
1215
 
 
1216
    lock();
 
1217
 
 
1218
    if (!wasParent->removeLayer(layer)) {
 
1219
        unlock();
 
1220
        return false;
 
1221
    }
 
1222
 
 
1223
    const bool success = parent->addLayer(layer, aboveThis);
 
1224
 
 
1225
    layer->setDirty();
 
1226
 
 
1227
    unlock();
 
1228
 
 
1229
    if (success)
 
1230
    {
 
1231
        emit sigLayerMoved(layer, wasParent, wasAbove);
 
1232
        if (undo())
 
1233
            m_adapter->addCommand(new LayerMoveCmd(m_adapter, this, layer, wasParent, wasAbove));
 
1234
    }
 
1235
    else //we already removed the layer above, but re-adding it failed, so...
 
1236
    {
 
1237
        emit sigLayerRemoved(layer, wasParent, wasAbove);
 
1238
        if (undo())
 
1239
            m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, wasParent, wasAbove));
 
1240
    }
 
1241
 
 
1242
    return success;
949
1243
}
950
1244
 
951
1245
Q_INT32 KisImage::nlayers() const
952
1246
{
953
 
        return m_layers.size();
 
1247
    return rootLayer()->numLayers() - 1;
954
1248
}
955
1249
 
956
1250
Q_INT32 KisImage::nHiddenLayers() const
957
1251
{
958
 
        Q_INT32 n = 0;
959
 
 
960
 
        for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); it++) {
961
 
                const KisLayerSP& layer = *it;
962
 
 
963
 
                if (!layer -> visible()) {
964
 
                        n++;
965
 
                }
966
 
        }
967
 
 
968
 
        return n;
969
 
}
970
 
 
971
 
Q_INT32 KisImage::nLinkedLayers() const
972
 
{
973
 
        Q_INT32 n = 0;
974
 
 
975
 
        for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); it++) {
976
 
                const KisLayerSP& layer = *it;
977
 
 
978
 
                if (layer -> linked()) {
979
 
                        n++;
980
 
                }
981
 
        }
982
 
 
983
 
        return n;
 
1252
    return rootLayer()->numLayers(KisLayer::Hidden);
984
1253
}
985
1254
 
986
1255
void KisImage::flatten()
987
1256
{
988
 
        vKisLayerSP beforeLayers = m_layers;
989
 
 
990
 
        if (m_layers.empty()) return;
991
 
 
992
 
        KisLayerSP dst = new KisLayer(this, nextLayerName(), OPACITY_OPAQUE);
993
 
        Q_CHECK_PTR(dst);
994
 
 
995
 
        KisFillPainter painter(dst.data());
996
 
 
997
 
        vKisLayerSP mergeLayers = layers();
998
 
 
999
 
        KisLayerSP bottomLayer = mergeLayers.back();
1000
 
        QString bottomName =  bottomLayer -> name();
1001
 
 
1002
 
        KisMerge<isVisible, All> visitor(this);
1003
 
        visitor(painter, mergeLayers);
1004
 
        dst -> setName(bottomName);
1005
 
 
1006
 
        add(dst, -1);
1007
 
 
1008
 
        notify();
1009
 
        notifyLayersChanged();
1010
 
 
1011
 
        if (m_adapter && m_adapter -> undo()) {
1012
 
                m_adapter -> addCommand(new KisChangeLayersCmd(m_adapter, this, beforeLayers, m_layers, i18n("Flatten Image")));
1013
 
        }
1014
 
}
1015
 
 
1016
 
void KisImage::mergeVisibleLayers()
1017
 
{
1018
 
        vKisLayerSP beforeLayers = m_layers;
1019
 
 
1020
 
        KisLayerSP dst = new KisLayer(this, nextLayerName(), OPACITY_OPAQUE);
1021
 
        Q_CHECK_PTR(dst);
1022
 
 
1023
 
        KisFillPainter painter(dst.data());
1024
 
 
1025
 
        vKisLayerSP mergeLayers = layers();
1026
 
        KisMerge<isVisible, isVisible> visitor(this);
1027
 
        visitor(painter, mergeLayers);
1028
 
 
1029
 
        int insertIndex = -1;
1030
 
 
1031
 
        if (visitor.insertMergedAboveLayer() != 0) {
1032
 
                insertIndex = index(visitor.insertMergedAboveLayer());
1033
 
        }
1034
 
 
1035
 
        add(dst, insertIndex);
1036
 
 
1037
 
        notify();
1038
 
        notifyLayersChanged();
1039
 
 
1040
 
        if (m_adapter && m_adapter -> undo()) {
1041
 
                m_adapter -> addCommand(new KisChangeLayersCmd(m_adapter, this, beforeLayers, m_layers, i18n("Merge Visible Layers")));
1042
 
        }
1043
 
}
1044
 
 
1045
 
void KisImage::mergeLinkedLayers()
1046
 
{
1047
 
        vKisLayerSP beforeLayers = m_layers;
1048
 
 
1049
 
        KisLayerSP dst = new KisLayer(this, nextLayerName(), OPACITY_OPAQUE);
1050
 
        Q_CHECK_PTR(dst);
1051
 
 
1052
 
        KisFillPainter painter(dst.data());
1053
 
 
1054
 
        vKisLayerSP mergeLayers = layers();
1055
 
        KisMerge<isLinked, isLinked> visitor(this);
1056
 
        visitor(painter, mergeLayers);
1057
 
 
1058
 
        int insertIndex = -1;
1059
 
 
1060
 
        if (visitor.insertMergedAboveLayer() != 0) {
1061
 
                insertIndex = index(visitor.insertMergedAboveLayer());
1062
 
        }
1063
 
 
1064
 
        add(dst, insertIndex);
1065
 
 
1066
 
        notify();
1067
 
        notifyLayersChanged();
1068
 
 
1069
 
        if (m_adapter && m_adapter -> undo()) {
1070
 
                m_adapter -> addCommand(new KisChangeLayersCmd(m_adapter, this, beforeLayers, m_layers, i18n("Merge Linked Layers")));
1071
 
        }
1072
 
}
1073
 
 
1074
 
void KisImage::mergeLayer(KisLayerSP l)
1075
 
{
1076
 
        vKisLayerSP beforeLayers = m_layers;
1077
 
 
1078
 
        KisLayerSP dst = new KisLayer(this, l -> name(), OPACITY_OPAQUE);
1079
 
        Q_CHECK_PTR(dst);
1080
 
 
1081
 
        KisFillPainter painter(dst.data());
1082
 
 
1083
 
        KisMerge<All, All> visitor(this);
1084
 
        visitor(painter, layer(index(l) + 1));
1085
 
        visitor(painter, l);
1086
 
 
1087
 
        int insertIndex = -1;
1088
 
 
1089
 
        if (visitor.insertMergedAboveLayer() != 0) {
1090
 
                insertIndex = index(visitor.insertMergedAboveLayer());
1091
 
        }
1092
 
 
1093
 
        add(dst, insertIndex);
1094
 
 
1095
 
        notify();
1096
 
        notifyLayersChanged();
1097
 
 
1098
 
        if (m_adapter && m_adapter -> undo())
1099
 
        {
1100
 
                m_adapter -> addCommand(new KisChangeLayersCmd(m_adapter, this, beforeLayers, m_layers, i18n("&Merge Layers")));
1101
 
//XXX fix name after string freeze
1102
 
        }
1103
 
}
1104
 
 
1105
 
 
1106
 
void KisImage::enableUndo(KoCommandHistory *history)
1107
 
{
1108
 
        m_undoHistory = history;
1109
 
}
1110
 
 
1111
 
void KisImage::renderToProjection(Q_INT32 x, Q_INT32 y, Q_INT32 w, Q_INT32 h)
1112
 
{
1113
 
        KisPainter gc;
1114
 
 
1115
 
        gc.begin(m_projection.data());
1116
 
 
1117
 
        gc.bitBlt(x, y, COMPOSITE_COPY, m_bkg.data(), x, y, w, h);
1118
 
 
1119
 
        if (!m_layers.empty()) {
1120
 
                KisFlatten<flattenAllVisible> visitor(x, y, w, h);
1121
 
 
1122
 
                visitor(gc, m_layers);
1123
 
 
1124
 
                if (m_activeLayer -> hasSelection()) {
1125
 
                        KisSelectionSP s = m_activeLayer -> selection();
1126
 
                        visitor(gc, s);
1127
 
                }
1128
 
        }
1129
 
 
1130
 
        gc.end();
 
1257
    KisGroupLayerSP oldRootLayer = m_rootLayer;
 
1258
    disconnect(oldRootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
1259
 
 
1260
    KisPaintLayer *dst = new KisPaintLayer(this, nextLayerName(), OPACITY_OPAQUE, colorSpace());
 
1261
    Q_CHECK_PTR(dst);
 
1262
 
 
1263
    QRect rc = mergedImage()->extent();
 
1264
 
 
1265
    KisPainter gc(dst->paintDevice());
 
1266
    gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, mergedImage(), OPACITY_OPAQUE, rc.left(), rc.top(), rc.width(), rc.height());
 
1267
 
 
1268
    m_rootLayer = new KisGroupLayer(this, "", OPACITY_OPAQUE);
 
1269
    connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
1270
 
 
1271
    if (undo()) {
 
1272
        m_adapter->beginMacro(i18n("Flatten Image"));
 
1273
        m_adapter->addCommand(new LockImageCommand(this, true));
 
1274
        m_adapter->addCommand(new KisChangeLayersCmd(m_adapter, this, oldRootLayer, m_rootLayer, ""));
 
1275
    }
 
1276
 
 
1277
    lock();
 
1278
 
 
1279
    addLayer(dst, m_rootLayer, 0);
 
1280
    activate(dst);
 
1281
 
 
1282
    unlock();
 
1283
 
 
1284
    notifyLayersChanged();
 
1285
 
 
1286
    if (undo()) {
 
1287
        m_adapter->addCommand(new LockImageCommand(this, false));
 
1288
        m_adapter->endMacro();
 
1289
    }
 
1290
}
 
1291
 
 
1292
 
 
1293
void KisImage::mergeLayer(KisLayerSP layer)
 
1294
{
 
1295
    KisPaintLayer *player = new KisPaintLayer(this, layer->name(), OPACITY_OPAQUE, colorSpace());
 
1296
    Q_CHECK_PTR(player);
 
1297
 
 
1298
    QRect rc = layer->extent() | layer->nextSibling()->extent();
 
1299
 
 
1300
    undoAdapter()->beginMacro(i18n("Merge with Layer Below"));
 
1301
 
 
1302
    //Abuse the merge visitor to only merge two layers (if either are groups they'll recursively merge)
 
1303
    KisMergeVisitor visitor(player->paintDevice(), rc);
 
1304
    layer->nextSibling()->accept(visitor);
 
1305
    layer->accept(visitor);
 
1306
 
 
1307
    removeLayer(layer->nextSibling());
 
1308
    addLayer(player, layer->parent(), layer);
 
1309
    removeLayer(layer);
 
1310
 
 
1311
    undoAdapter()->endMacro();
 
1312
}
 
1313
 
 
1314
 
 
1315
void KisImage::setModified()
 
1316
{
 
1317
    emit sigImageModified();
1131
1318
}
1132
1319
 
1133
1320
void KisImage::renderToPainter(Q_INT32 x1,
1134
 
                               Q_INT32 y1,
1135
 
                               Q_INT32 x2,
1136
 
                               Q_INT32 y2,
1137
 
                               QPainter &painter,
1138
 
                               KisProfileSP profile)
1139
 
{
1140
 
        Q_INT32 x;
1141
 
        Q_INT32 y;
1142
 
 
1143
 
        // Flatten the layers onto the projection layer of the current image
1144
 
        for (y = y1; y <= y2; y += RENDER_HEIGHT - (y % RENDER_HEIGHT)) {
1145
 
                for (x = x1; x <= x2; x += RENDER_WIDTH - (x % RENDER_WIDTH)) {
1146
 
                        Q_INT32 w = QMIN(x2 - x, RENDER_WIDTH);
1147
 
                        Q_INT32 h = QMIN(y2 - y, RENDER_HEIGHT);
1148
 
                        renderToProjection(x, y, w, h);
1149
 
                        QImage img = m_projection -> convertToQImage(profile, x, y, w, h);
1150
 
                        if (!img.isNull()) {
1151
 
                                m_pixmap.convertFromImage(img);
1152
 
                                painter.drawPixmap(x, y, m_pixmap, 0, 0, w, h);
1153
 
                        }
1154
 
                }
1155
 
        }
1156
 
}
1157
 
 
1158
 
void KisImage::notify()
1159
 
{
1160
 
        notify(0, 0, width(), height());
1161
 
}
1162
 
 
1163
 
void KisImage::notify(Q_INT32 x, Q_INT32 y, Q_INT32 width, Q_INT32 height)
1164
 
{
1165
 
        notify(QRect(x, y, width, height));
1166
 
}
1167
 
 
1168
 
void KisImage::notify(const QRect& rc)
1169
 
{
1170
 
        if (rc.isValid()) {
1171
 
                emit update(KisImageSP(this), rc);
1172
 
        }
1173
 
 
 
1321
                               Q_INT32 y1,
 
1322
                               Q_INT32 x2,
 
1323
                               Q_INT32 y2,
 
1324
                               QPainter &painter,
 
1325
                               KisProfile *  monitorProfile,
 
1326
                               PaintFlags paintFlags,
 
1327
                               float exposure)
 
1328
{
 
1329
 
 
1330
    QImage img = convertToQImage(x1, y1, x2, y2, monitorProfile, exposure);
 
1331
 
 
1332
    Q_INT32 w = x2 - x1 + 1;
 
1333
    Q_INT32 h = y2 - y1 + 1;
 
1334
 
 
1335
 
 
1336
    if (paintFlags & PAINT_BACKGROUND) {
 
1337
        m_bkg->paintBackground(img, x1, y1);
 
1338
        img.setAlphaBuffer(false);
 
1339
    }
 
1340
 
 
1341
    if (paintFlags & PAINT_SELECTION) {
 
1342
        if (m_activeLayer != 0) {
 
1343
            m_activeLayer->paintSelection(img, x1, y1, w, h);
 
1344
        }
 
1345
    }
 
1346
 
 
1347
    if (paintFlags & PAINT_MASKINACTIVELAYERS) {
 
1348
        if (m_activeLayer != 0) {
 
1349
            m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
 
1350
        }
 
1351
    }
 
1352
 
 
1353
    painter.drawImage(x1, y1, img, 0, 0, w, h);
 
1354
}
 
1355
 
 
1356
QImage KisImage::convertToQImage(Q_INT32 x1,
 
1357
                                 Q_INT32 y1,
 
1358
                                 Q_INT32 x2,
 
1359
                                 Q_INT32 y2,
 
1360
                                 KisProfile * profile,
 
1361
                                 float exposure)
 
1362
{
 
1363
    Q_INT32 w = x2 - x1 + 1;
 
1364
    Q_INT32 h = y2 - y1 + 1;
 
1365
 
 
1366
    KisPaintDeviceSP dev = m_rootLayer->projection(QRect(x1, y1, w, h));
 
1367
    QImage img = dev->convertToQImage(profile, x1, y1, w, h, exposure);
 
1368
 
 
1369
    if (!img.isNull()) {
 
1370
 
 
1371
#ifdef __BIG_ENDIAN__
 
1372
        uchar * data = img.bits();
 
1373
        for (int i = 0; i < w * h; ++i) {
 
1374
            uchar r, g, b, a;
 
1375
            a = data[0];
 
1376
            b = data[1];
 
1377
            g = data[2];
 
1378
            r = data[3];
 
1379
            data[0] = r;
 
1380
            data[1] = g;
 
1381
            data[2] = b;
 
1382
            data[3] = a;
 
1383
            data += 4;
 
1384
        }
 
1385
#endif
 
1386
 
 
1387
        return img;
 
1388
    }
 
1389
 
 
1390
    return QImage();
 
1391
}
 
1392
 
 
1393
QImage KisImage::convertToQImage(const QRect& r, const QSize& scaledImageSize, KisProfile *profile, PaintFlags paintFlags, float exposure)
 
1394
{
 
1395
    if (r.isEmpty() || scaledImageSize.isEmpty()) {
 
1396
        return QImage();
 
1397
    }
 
1398
 
 
1399
    Q_INT32 imageWidth = width();
 
1400
    Q_INT32 imageHeight = height();
 
1401
    Q_UINT32 pixelSize = colorSpace()->pixelSize();
 
1402
 
 
1403
    double xScale = static_cast<double>(imageWidth) / scaledImageSize.width();
 
1404
    double yScale = static_cast<double>(imageHeight) / scaledImageSize.height();
 
1405
 
 
1406
    QRect srcRect;
 
1407
 
 
1408
    srcRect.setLeft(static_cast<int>(r.left() * xScale));
 
1409
    srcRect.setRight(static_cast<int>(ceil((r.right() + 1) * xScale)) - 1);
 
1410
    srcRect.setTop(static_cast<int>(r.top() * yScale));
 
1411
    srcRect.setBottom(static_cast<int>(ceil((r.bottom() + 1) * yScale)) - 1);
 
1412
 
 
1413
    KisPaintDeviceSP mergedImage = m_rootLayer->projection(srcRect);
 
1414
    //QTime t;
 
1415
    //t.start();
 
1416
 
 
1417
    Q_UINT8 *scaledImageData = new Q_UINT8[r.width() * r.height() * pixelSize];
 
1418
 
 
1419
    Q_UINT8 *imageRow = new Q_UINT8[srcRect.width() * pixelSize];
 
1420
    const Q_INT32 imageRowX = srcRect.x();
 
1421
 
 
1422
    for (Q_INT32 y = 0; y < r.height(); ++y) {
 
1423
 
 
1424
        Q_INT32 dstY = r.y() + y;
 
1425
        Q_INT32 dstX = r.x();
 
1426
        Q_INT32 srcY = (dstY * imageHeight) / scaledImageSize.height();
 
1427
 
 
1428
        mergedImage->readBytes(imageRow, imageRowX, srcY, srcRect.width(), 1);
 
1429
 
 
1430
        Q_UINT8 *dstPixel = scaledImageData + (y * r.width() * pixelSize);
 
1431
        Q_UINT32 columnsRemaining = r.width();
 
1432
 
 
1433
        while (columnsRemaining > 0) {
 
1434
 
 
1435
            Q_INT32 srcX = (dstX * imageWidth) / scaledImageSize.width();
 
1436
 
 
1437
            memcpy(dstPixel, imageRow + ((srcX - imageRowX) * pixelSize), pixelSize);
 
1438
 
 
1439
            ++dstX;
 
1440
            dstPixel += pixelSize;
 
1441
            --columnsRemaining;
 
1442
        }
 
1443
    }
 
1444
 
 
1445
    delete [] imageRow;
 
1446
 
 
1447
    QImage image = colorSpace()->convertToQImage(scaledImageData, r.width(), r.height(), profile, INTENT_PERCEPTUAL, exposure);
 
1448
    delete [] scaledImageData;
 
1449
 
 
1450
    if (paintFlags & PAINT_BACKGROUND) {
 
1451
        m_bkg->paintBackground(image, r, scaledImageSize, QSize(imageWidth, imageHeight));
 
1452
        image.setAlphaBuffer(false);
 
1453
    }
 
1454
 
 
1455
    if (paintFlags & PAINT_SELECTION) {
 
1456
        if (m_activeLayer != 0) {
 
1457
            m_activeLayer->paintSelection(image, r, scaledImageSize, QSize(imageWidth, imageHeight));
 
1458
        }
 
1459
    }
 
1460
 
 
1461
    /*if (paintFlags & PAINT_MASKINACTIVELAYERS) {
 
1462
        if (m_activeLayer != 0) {
 
1463
            m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
 
1464
        }
 
1465
    }*/
 
1466
 
 
1467
    return image;
 
1468
}
 
1469
 
 
1470
KisPaintDeviceSP KisImage::mergedImage()
 
1471
{
 
1472
    return m_rootLayer->projection(QRect(0, 0, m_width, m_height));
 
1473
}
 
1474
 
 
1475
KisColor KisImage::mergedPixel(Q_INT32 x, Q_INT32 y)
 
1476
{
 
1477
    return m_rootLayer->projection(QRect(x, y, 1, 1))->colorAt(x, y);
1174
1478
}
1175
1479
 
1176
1480
void KisImage::notifyLayersChanged()
1177
1481
{
1178
 
        emit layersChanged(KisImageSP(this));
 
1482
    emit sigLayersChanged(rootLayer());
 
1483
}
 
1484
 
 
1485
void KisImage::notifyPropertyChanged(KisLayerSP layer)
 
1486
{
 
1487
    emit sigLayerPropertiesChanged(layer);
 
1488
}
 
1489
 
 
1490
void KisImage::notifyImageLoaded()
 
1491
{
1179
1492
}
1180
1493
 
1181
1494
QRect KisImage::bounds() const
1182
1495
{
1183
 
        return QRect(0, 0, width(), height());
1184
 
}
 
1496
    return QRect(0, 0, width(), height());
 
1497
}
 
1498
 
 
1499
 
 
1500
void KisImage::setUndoAdapter(KisUndoAdapter * adapter)
 
1501
{
 
1502
    m_adapter = adapter;
 
1503
}
 
1504
 
1185
1505
 
1186
1506
KisUndoAdapter* KisImage::undoAdapter() const
1187
1507
{
1188
 
        return m_adapter;
1189
 
}
 
1508
    return m_adapter;
 
1509
}
 
1510
 
 
1511
bool KisImage::undo() const
 
1512
{
 
1513
    return (m_adapter && m_adapter->undo());
 
1514
}
 
1515
 
 
1516
//KisGuideMgr *KisImage::guides() const
 
1517
//{
 
1518
//    return const_cast<KisGuideMgr*>(&m_guides);
 
1519
//}
1190
1520
 
1191
1521
void KisImage::slotSelectionChanged()
1192
1522
{
1193
 
        kdDebug() << "KisImage::slotSelectionChanged\n";
1194
 
        emit activeSelectionChanged(KisImageSP(this));
1195
 
}
1196
 
 
1197
 
void KisImage::slotSelectionCreated()
1198
 
{
1199
 
        kdDebug() << "KisImage::slotSelectionCreated\n";
1200
 
        notify();
1201
 
        emit selectionCreated(KisImageSP(this));
1202
 
}
1203
 
 
1204
 
 
1205
 
KisStrategyColorSpaceSP KisImage::colorStrategy() const
1206
 
{
1207
 
        return m_colorStrategy;
1208
 
}
1209
 
 
1210
 
void KisImage::setColorStrategy(KisStrategyColorSpaceSP colorStrategy)
1211
 
{
1212
 
        m_colorStrategy = colorStrategy;
1213
 
 
1214
 
        m_bkg = new KisBackground(this, m_width, m_height);
1215
 
        Q_CHECK_PTR(m_bkg);
1216
 
 
1217
 
        m_projection = new KisLayer(this, "projection", OPACITY_OPAQUE);
1218
 
        Q_CHECK_PTR(m_projection);
1219
 
        notify();
 
1523
    slotSelectionChanged(bounds());
 
1524
}
 
1525
 
 
1526
void KisImage::slotSelectionChanged(const QRect& r)
 
1527
{
 
1528
    QRect r2(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2);
 
1529
 
 
1530
    if (!locked()) {
 
1531
        emit sigActiveSelectionChanged(this);
 
1532
    } else {
 
1533
        m_private->selectionChangedWhileLocked = true;
 
1534
    }
 
1535
}
 
1536
 
 
1537
KisColorSpace * KisImage::colorSpace() const
 
1538
{
 
1539
    return m_colorSpace;
 
1540
}
 
1541
 
 
1542
void KisImage::setColorSpace(KisColorSpace * colorSpace)
 
1543
{
 
1544
    m_colorSpace = colorSpace;
 
1545
    m_rootLayer->resetProjection();
 
1546
    emit sigColorSpaceChanged(colorSpace);
 
1547
}
 
1548
 
 
1549
void KisImage::setRootLayer(KisGroupLayerSP rootLayer)
 
1550
{
 
1551
    disconnect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
1552
 
 
1553
    m_rootLayer = rootLayer;
 
1554
 
 
1555
    if (!locked()) {
 
1556
        connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
 
1557
    }
 
1558
    activate(m_rootLayer->firstChild());
1220
1559
}
1221
1560
 
1222
1561
void KisImage::addAnnotation(KisAnnotationSP annotation)
1223
1562
{
1224
 
        // Find the icc annotation, if there is one
1225
 
        vKisAnnotationSP_it it = m_annotations.begin();
1226
 
        while (it != m_annotations.end()) {
1227
 
                if ((*it) -> type() == annotation -> type()) {
1228
 
                        *it = annotation;
1229
 
                        return;
1230
 
                }
1231
 
                ++it;
1232
 
        }
1233
 
        m_annotations.push_back(annotation);
 
1563
    // Find the icc annotation, if there is one
 
1564
    vKisAnnotationSP_it it = m_annotations.begin();
 
1565
    while (it != m_annotations.end()) {
 
1566
        if ((*it)->type() == annotation->type()) {
 
1567
            *it = annotation;
 
1568
            return;
 
1569
        }
 
1570
        ++it;
 
1571
    }
 
1572
    m_annotations.push_back(annotation);
1234
1573
}
1235
1574
 
1236
1575
KisAnnotationSP KisImage::annotation(QString type)
1237
1576
{
1238
 
        vKisAnnotationSP_it it = m_annotations.begin();
1239
 
        while (it != m_annotations.end()) {
1240
 
                if ((*it) -> type() == type) {
1241
 
                        return *it;
1242
 
                }
1243
 
                ++it;
1244
 
        }
1245
 
        return 0;
 
1577
    vKisAnnotationSP_it it = m_annotations.begin();
 
1578
    while (it != m_annotations.end()) {
 
1579
        if ((*it)->type() == type) {
 
1580
            return *it;
 
1581
        }
 
1582
        ++it;
 
1583
    }
 
1584
    return 0;
1246
1585
}
1247
1586
 
1248
1587
void KisImage::removeAnnotation(QString type)
1249
1588
{
1250
 
        vKisAnnotationSP_it it = m_annotations.begin();
1251
 
        while (it != m_annotations.end()) {
1252
 
                if ((*it) -> type() == type) {
1253
 
                        m_annotations.erase(it);
1254
 
                        return;
1255
 
                }
1256
 
                ++it;
1257
 
        }
 
1589
    vKisAnnotationSP_it it = m_annotations.begin();
 
1590
    while (it != m_annotations.end()) {
 
1591
        if ((*it)->type() == type) {
 
1592
            m_annotations.erase(it);
 
1593
            return;
 
1594
        }
 
1595
        ++it;
 
1596
    }
1258
1597
}
1259
1598
 
1260
1599
vKisAnnotationSP_it KisImage::beginAnnotations()
1261
1600
{
1262
 
        if (m_profile) {
1263
 
                addAnnotation(m_profile -> annotation());
1264
 
        } else {
1265
 
                removeAnnotation("icc");
1266
 
        }
1267
 
 
1268
 
        return m_annotations.begin();
 
1601
    KisProfile * profile = colorSpace()->getProfile();
 
1602
    KisAnnotationSP annotation;
 
1603
 
 
1604
    if (profile)
 
1605
        annotation =  profile->annotation();
 
1606
 
 
1607
    if (annotation)
 
1608
         addAnnotation(annotation);
 
1609
    else
 
1610
        removeAnnotation("icc");
 
1611
 
 
1612
    return m_annotations.begin();
1269
1613
}
1270
1614
 
1271
1615
vKisAnnotationSP_it KisImage::endAnnotations()
1272
1616
{
1273
 
        return m_annotations.end();
 
1617
    return m_annotations.end();
1274
1618
}
1275
1619
 
 
1620
KisBackgroundSP KisImage::background() const
 
1621
{
 
1622
    return m_bkg;
 
1623
}
1276
1624
#include "kis_image.moc"
1277
1625