00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <math.h>
00020
00021 #include <config.h>
00022 #include LCMS_HEADER
00023
00024 #include <qimage.h>
00025 #include <qpainter.h>
00026 #include <qsize.h>
00027 #include <qtl.h>
00028 #include <qapplication.h>
00029 #include <qthread.h>
00030 #include <qdatetime.h>
00031
00032 #include <kcommand.h>
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035
00036 #include "kis_image_iface.h"
00037
00038 #include "kis_annotation.h"
00039 #include "kis_colorspace_factory_registry.h"
00040 #include "kis_color.h"
00041 #include "kis_command.h"
00042 #include "kis_types.h"
00043
00044 #include "kis_image.h"
00045 #include "kis_paint_device.h"
00046 #include "kis_paint_device_action.h"
00047 #include "kis_selection.h"
00048 #include "kis_painter.h"
00049 #include "kis_fill_painter.h"
00050 #include "kis_layer.h"
00051 #include "kis_group_layer.h"
00052 #include "kis_adjustment_layer.h"
00053 #include "kis_paint_layer.h"
00054 #include "kis_colorspace_convert_visitor.h"
00055 #include "kis_background.h"
00056 #include "kis_nameserver.h"
00057 #include "kis_undo_adapter.h"
00058 #include "kis_merge_visitor.h"
00059 #include "kis_transaction.h"
00060 #include "kis_crop_visitor.h"
00061 #include "kis_transform_visitor.h"
00062 #include "kis_filter_strategy.h"
00063 #include "kis_profile.h"
00064 #include "kis_paint_layer.h"
00065 #include "kis_change_profile_visitor.h"
00066 #include "kis_group_layer.h"
00067 #include "kis_iterators_pixel.h"
00068 #include "kis_shear_visitor.h"
00069
00070 class KisImage::KisImagePrivate {
00071 public:
00072 KisColor backgroundColor;
00073 Q_UINT32 lockCount;
00074 bool sizeChangedWhileLocked;
00075 bool selectionChangedWhileLocked;
00076 };
00077
00078
00079 namespace {
00080
00081 class KisResizeImageCmd : public KNamedCommand {
00082 typedef KNamedCommand super;
00083
00084 public:
00085 KisResizeImageCmd(KisUndoAdapter *adapter,
00086 KisImageSP img,
00087 Q_INT32 width,
00088 Q_INT32 height,
00089 Q_INT32 oldWidth,
00090 Q_INT32 oldHeight) : super(i18n("Resize Image"))
00091 {
00092 m_adapter = adapter;
00093 m_img = img;
00094 m_before = QSize(oldWidth, oldHeight);
00095 m_after = QSize(width, height);
00096 }
00097
00098 virtual ~KisResizeImageCmd()
00099 {
00100 }
00101
00102 public:
00103 virtual void execute()
00104 {
00105 m_adapter->setUndo(false);
00106 m_img->resize(m_after.width(), m_after.height());
00107 m_adapter->setUndo(true);
00108 }
00109
00110 virtual void unexecute()
00111 {
00112 m_adapter->setUndo(false);
00113 m_img->resize(m_before.width(), m_before.height());
00114 m_adapter->setUndo(true);
00115 }
00116
00117 private:
00118 KisUndoAdapter *m_adapter;
00119 KisImageSP m_img;
00120 QSize m_before;
00121 QSize m_after;
00122 };
00123
00124
00125
00126 class KisChangeLayersCmd : public KNamedCommand {
00127 typedef KNamedCommand super;
00128
00129 public:
00130 KisChangeLayersCmd(KisUndoAdapter *adapter, KisImageSP img,
00131 KisGroupLayerSP oldRootLayer, KisGroupLayerSP newRootLayer, const QString& name)
00132 : super(name)
00133 {
00134 m_adapter = adapter;
00135 m_img = img;
00136 m_oldRootLayer = oldRootLayer;
00137 m_newRootLayer = newRootLayer;
00138 }
00139
00140 virtual ~KisChangeLayersCmd()
00141 {
00142 }
00143
00144 public:
00145 virtual void execute()
00146 {
00147 m_adapter->setUndo(false);
00148 m_img->setRootLayer(m_newRootLayer);
00149 m_adapter->setUndo(true);
00150 m_img->notifyLayersChanged();
00151 }
00152
00153 virtual void unexecute()
00154 {
00155 m_adapter->setUndo(false);
00156 m_img->setRootLayer(m_oldRootLayer);
00157 m_adapter->setUndo(true);
00158 m_img->notifyLayersChanged();
00159 }
00160
00161 private:
00162 KisUndoAdapter *m_adapter;
00163 KisImageSP m_img;
00164 KisGroupLayerSP m_oldRootLayer;
00165 KisGroupLayerSP m_newRootLayer;
00166 };
00167
00168
00169
00170
00171 class KisConvertImageTypeCmd : public KNamedCommand {
00172 typedef KNamedCommand super;
00173
00174 public:
00175 KisConvertImageTypeCmd(KisUndoAdapter *adapter, KisImageSP img,
00176 KisColorSpace * beforeColorSpace, KisColorSpace * afterColorSpace
00177 ) : super(i18n("Convert Image Type"))
00178 {
00179 m_adapter = adapter;
00180 m_img = img;
00181 m_beforeColorSpace = beforeColorSpace;
00182 m_afterColorSpace = afterColorSpace;
00183 }
00184
00185 virtual ~KisConvertImageTypeCmd()
00186 {
00187 }
00188
00189 public:
00190 virtual void execute()
00191 {
00192 m_adapter->setUndo(false);
00193
00194 m_img->setColorSpace(m_afterColorSpace);
00195 m_img->setProfile(m_afterColorSpace->getProfile());
00196
00197 m_adapter->setUndo(true);
00198 }
00199
00200 virtual void unexecute()
00201 {
00202 m_adapter->setUndo(false);
00203
00204 m_img->setColorSpace(m_beforeColorSpace);
00205 m_img->setProfile(m_beforeColorSpace->getProfile());
00206
00207 m_adapter->setUndo(true);
00208 }
00209
00210 private:
00211 KisUndoAdapter *m_adapter;
00212 KisImageSP m_img;
00213 KisColorSpace * m_beforeColorSpace;
00214 KisColorSpace * m_afterColorSpace;
00215 };
00216
00217
00218
00219
00220 class KisImageCommand : public KNamedCommand {
00221 typedef KNamedCommand super;
00222
00223 public:
00224 KisImageCommand(const QString& name, KisImageSP image);
00225 virtual ~KisImageCommand() {}
00226
00227 virtual void execute() = 0;
00228 virtual void unexecute() = 0;
00229
00230 protected:
00231 void setUndo(bool undo);
00232
00233 KisImageSP m_image;
00234 };
00235
00236 KisImageCommand::KisImageCommand(const QString& name, KisImageSP image) :
00237 super(name), m_image(image)
00238 {
00239 }
00240
00241 void KisImageCommand::setUndo(bool undo)
00242 {
00243 if (m_image->undoAdapter()) {
00244 m_image->undoAdapter()->setUndo(undo);
00245 }
00246 }
00247
00248
00249
00250
00251 class KisLayerPositionCommand : public KisImageCommand {
00252 typedef KisImageCommand super;
00253
00254 public:
00255 KisLayerPositionCommand(const QString& name, KisImageSP image, KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis) : super(name, image)
00256 {
00257 m_layer = layer;
00258 m_oldParent = layer->parent();
00259 m_oldAboveThis = layer->nextSibling();
00260 m_newParent = parent;
00261 m_newAboveThis = aboveThis;
00262 }
00263
00264 virtual void execute()
00265 {
00266 setUndo(false);
00267 m_image->moveLayer(m_layer, m_newParent, m_newAboveThis);
00268 setUndo(true);
00269 }
00270
00271 virtual void unexecute()
00272 {
00273 setUndo(false);
00274 m_image->moveLayer(m_layer, m_oldParent, m_oldAboveThis);
00275 setUndo(true);
00276 }
00277
00278 private:
00279 KisLayerSP m_layer;
00280 KisGroupLayerSP m_oldParent;
00281 KisLayerSP m_oldAboveThis;
00282 KisGroupLayerSP m_newParent;
00283 KisLayerSP m_newAboveThis;
00284 };
00285
00286
00287
00288
00289 class LayerAddCmd : public KisCommand {
00290 typedef KisCommand super;
00291
00292 public:
00293 LayerAddCmd(KisUndoAdapter *adapter, KisImageSP img, KisLayerSP layer) : super(i18n("Add Layer"), adapter)
00294 {
00295 m_img = img;
00296 m_layer = layer;
00297 m_parent = layer->parent();
00298 m_aboveThis = layer->nextSibling();
00299 }
00300
00301 virtual ~LayerAddCmd()
00302 {
00303 }
00304
00305 virtual void execute()
00306 {
00307 adapter()->setUndo(false);
00308 m_img->addLayer(m_layer, m_parent.data(), m_aboveThis);
00309 adapter()->setUndo(true);
00310 }
00311
00312 virtual void unexecute()
00313 {
00314 adapter()->setUndo(false);
00315 m_img->removeLayer(m_layer);
00316 adapter()->setUndo(true);
00317 }
00318
00319 private:
00320 KisImageSP m_img;
00321 KisLayerSP m_layer;
00322 KisGroupLayerSP m_parent;
00323 KisLayerSP m_aboveThis;
00324 };
00325
00326
00327
00328 class LayerRmCmd : public KNamedCommand {
00329 typedef KNamedCommand super;
00330
00331 public:
00332 LayerRmCmd(KisUndoAdapter *adapter, KisImageSP img,
00333 KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
00334 : super(i18n("Remove Layer"))
00335 {
00336 m_adapter = adapter;
00337 m_img = img;
00338 m_layer = layer;
00339 m_prevParent = wasParent;
00340 m_prevAbove = wasAbove;
00341 }
00342
00343 virtual ~LayerRmCmd()
00344 {
00345 }
00346
00347 virtual void execute()
00348 {
00349 m_adapter->setUndo(false);
00350 m_img->removeLayer(m_layer);
00351 m_adapter->setUndo(true);
00352 }
00353
00354 virtual void unexecute()
00355 {
00356 m_adapter->setUndo(false);
00357 m_img->addLayer(m_layer, m_prevParent.data(), m_prevAbove);
00358 m_adapter->setUndo(true);
00359 }
00360
00361 private:
00362 KisUndoAdapter *m_adapter;
00363 KisImageSP m_img;
00364 KisLayerSP m_layer;
00365 KisGroupLayerSP m_prevParent;
00366 KisLayerSP m_prevAbove;
00367 };
00368
00369 class LayerMoveCmd: public KNamedCommand {
00370 typedef KNamedCommand super;
00371
00372 public:
00373 LayerMoveCmd(KisUndoAdapter *adapter, KisImageSP img,
00374 KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
00375 : super(i18n("Move Layer"))
00376 {
00377 m_adapter = adapter;
00378 m_img = img;
00379 m_layer = layer;
00380 m_prevParent = wasParent;
00381 m_prevAbove = wasAbove;
00382 m_newParent = layer->parent();
00383 m_newAbove = layer->nextSibling();
00384 }
00385
00386 virtual ~LayerMoveCmd()
00387 {
00388 }
00389
00390 virtual void execute()
00391 {
00392 m_adapter->setUndo(false);
00393 m_img->moveLayer(m_layer, m_newParent.data(), m_newAbove);
00394 m_adapter->setUndo(true);
00395 }
00396
00397 virtual void unexecute()
00398 {
00399 m_adapter->setUndo(false);
00400 m_img->moveLayer(m_layer, m_prevParent.data(), m_prevAbove);
00401 m_adapter->setUndo(true);
00402 }
00403
00404 private:
00405 KisUndoAdapter *m_adapter;
00406 KisImageSP m_img;
00407 KisLayerSP m_layer;
00408 KisGroupLayerSP m_prevParent;
00409 KisLayerSP m_prevAbove;
00410 KisGroupLayerSP m_newParent;
00411 KisLayerSP m_newAbove;
00412 };
00413
00414
00415
00416
00417 class LayerPropsCmd : public KNamedCommand {
00418 typedef KNamedCommand super;
00419
00420 public:
00421 LayerPropsCmd(KisLayerSP layer,
00422 KisImageSP img,
00423 KisUndoAdapter *adapter,
00424 const QString& name,
00425 Q_INT32 opacity,
00426 const KisCompositeOp& compositeOp) : super(i18n("Layer Property Changes"))
00427 {
00428 m_layer = layer;
00429 m_img = img;
00430 m_adapter = adapter;
00431 m_name = name;
00432 m_opacity = opacity;
00433 m_compositeOp = compositeOp;
00434 }
00435
00436 virtual ~LayerPropsCmd()
00437 {
00438 }
00439
00440 public:
00441 virtual void execute()
00442 {
00443 QString name = m_layer->name();
00444 Q_INT32 opacity = m_layer->opacity();
00445 KisCompositeOp compositeOp = m_layer->compositeOp();
00446
00447 m_adapter->setUndo(false);
00448 m_img->setLayerProperties(m_layer,
00449 m_opacity,
00450 m_compositeOp,
00451 m_name);
00452 m_adapter->setUndo(true);
00453 m_name = name;
00454 m_opacity = opacity;
00455 m_compositeOp = compositeOp;
00456 m_layer->setDirty();
00457 }
00458
00459 virtual void unexecute()
00460 {
00461 execute();
00462 }
00463
00464 private:
00465 KisUndoAdapter *m_adapter;
00466 KisLayerSP m_layer;
00467 KisImageSP m_img;
00468 QString m_name;
00469 Q_INT32 m_opacity;
00470 KisCompositeOp m_compositeOp;
00471 };
00472
00473
00474
00475 class LockImageCommand : public KNamedCommand {
00476 typedef KNamedCommand super;
00477
00478 public:
00479 LockImageCommand(KisImageSP img, bool lockImage) : super("lock image")
00480 {
00481 m_img = img;
00482 m_lockImage = lockImage;
00483 }
00484
00485 virtual ~LockImageCommand()
00486 {
00487 }
00488
00489 virtual void execute()
00490 {
00491 if (m_lockImage) {
00492 m_img->lock();
00493 } else {
00494 m_img->unlock();
00495 }
00496 }
00497
00498 virtual void unexecute()
00499 {
00500 if (m_lockImage) {
00501 m_img->unlock();
00502 } else {
00503 m_img->lock();
00504 }
00505 }
00506
00507 private:
00508 KisImageSP m_img;
00509 bool m_lockImage;
00510 };
00511 }
00512
00513 KisImage::KisImage(KisUndoAdapter *adapter, Q_INT32 width, Q_INT32 height, KisColorSpace * colorSpace, const QString& name)
00514 : QObject(0, name.latin1()), KShared()
00515 {
00516 init(adapter, width, height, colorSpace, name);
00517 setName(name);
00518 m_dcop = 0L;
00519 }
00520
00521 KisImage::KisImage(const KisImage& rhs) : QObject(), KShared(rhs)
00522 {
00523 m_dcop = 0L;
00524 if (this != &rhs) {
00525 m_private = new KisImagePrivate(*rhs.m_private);
00526 m_uri = rhs.m_uri;
00527 m_name = QString::null;
00528 m_width = rhs.m_width;
00529 m_height = rhs.m_height;
00530 m_xres = rhs.m_xres;
00531 m_yres = rhs.m_yres;
00532 m_unit = rhs.m_unit;
00533 m_colorSpace = rhs.m_colorSpace;
00534 m_dirty = rhs.m_dirty;
00535 m_adapter = rhs.m_adapter;
00536
00537 m_bkg = new KisBackground();
00538 Q_CHECK_PTR(m_bkg);
00539
00540 m_rootLayer = static_cast<KisGroupLayer*>(rhs.m_rootLayer->clone().data());
00541 connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
00542
00543 m_annotations = rhs.m_annotations;
00544
00545 m_nserver = new KisNameServer(i18n("Layer %1"), rhs.m_nserver->currentSeed() + 1);
00546 Q_CHECK_PTR(m_nserver);
00547
00548
00549 }
00550 }
00551
00552
00553
00554 DCOPObject * KisImage::dcopObject()
00555 {
00556 if (!m_dcop) {
00557 m_dcop = new KisImageIface(this);
00558 Q_CHECK_PTR(m_dcop);
00559 }
00560 return m_dcop;
00561 }
00562
00563 KisImage::~KisImage()
00564 {
00565 delete m_private;
00566 delete m_nserver;
00567 delete m_dcop;
00568 }
00569
00570 QString KisImage::name() const
00571 {
00572 return m_name;
00573 }
00574
00575 void KisImage::setName(const QString& name)
00576 {
00577 if (!name.isEmpty())
00578 m_name = name;
00579 }
00580
00581 QString KisImage::description() const
00582 {
00583 return m_description;
00584 }
00585
00586 void KisImage::setDescription(const QString& description)
00587 {
00588 if (!description.isEmpty())
00589 m_description = description;
00590 }
00591
00592
00593 KisColor KisImage::backgroundColor() const
00594 {
00595 return m_private->backgroundColor;
00596 }
00597
00598 void KisImage::setBackgroundColor(const KisColor & color)
00599 {
00600 m_private->backgroundColor = color;
00601 }
00602
00603
00604 QString KisImage::nextLayerName() const
00605 {
00606 if (m_nserver->currentSeed() == 0) {
00607 m_nserver->number();
00608 return i18n("background");
00609 }
00610
00611 return m_nserver->name();
00612 }
00613
00614 void KisImage::rollBackLayerName()
00615 {
00616 m_nserver->rollback();
00617 }
00618
00619 void KisImage::init(KisUndoAdapter *adapter, Q_INT32 width, Q_INT32 height, KisColorSpace * colorSpace, const QString& name)
00620 {
00621 Q_ASSERT(colorSpace);
00622
00623 if (colorSpace == 0) {
00624 colorSpace = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00625 kdWarning(41010) << "No colorspace specified: using RGBA\n";
00626 }
00627
00628 m_private = new KisImagePrivate();
00629 m_private->backgroundColor = KisColor(Qt::white, colorSpace);
00630 m_private->lockCount = 0;
00631 m_private->sizeChangedWhileLocked = false;
00632 m_private->selectionChangedWhileLocked = false;
00633
00634 m_adapter = adapter;
00635
00636 m_nserver = new KisNameServer(i18n("Layer %1"), 1);
00637 m_name = name;
00638
00639 m_colorSpace = colorSpace;
00640 m_bkg = new KisBackground();
00641
00642 m_rootLayer = new KisGroupLayer(this,"root", OPACITY_OPAQUE);
00643 connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
00644
00645 m_xres = 1.0;
00646 m_yres = 1.0;
00647 m_unit = KoUnit::U_PT;
00648 m_dirty = false;
00649 m_width = width;
00650 m_height = height;
00651 }
00652
00653 bool KisImage::locked() const
00654 {
00655 return m_private->lockCount != 0;
00656 }
00657
00658 void KisImage::lock()
00659 {
00660 if (!locked()) {
00661 if (m_rootLayer) disconnect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
00662 m_private->sizeChangedWhileLocked = false;
00663 m_private->selectionChangedWhileLocked = false;
00664 }
00665 m_private->lockCount++;
00666 }
00667
00668 void KisImage::unlock()
00669 {
00670 Q_ASSERT(locked());
00671
00672 if (locked()) {
00673 m_private->lockCount--;
00674
00675 if (m_private->lockCount == 0) {
00676 if (m_private->sizeChangedWhileLocked) {
00677
00678 emit sigSizeChanged(m_width, m_height);
00679 } else {
00680 if (m_rootLayer->dirty()) emit sigImageUpdated( m_rootLayer->dirtyRect() );
00681 }
00682
00683 if (m_private->selectionChangedWhileLocked) {
00684 emit sigActiveSelectionChanged(this);
00685 }
00686
00687 if (m_rootLayer) connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
00688 }
00689 }
00690 }
00691
00692 void KisImage::emitSizeChanged()
00693 {
00694 if (!locked()) {
00695 emit sigSizeChanged(m_width, m_height);
00696 } else {
00697 m_private->sizeChangedWhileLocked = true;
00698 }
00699 }
00700
00701 void KisImage::notifyLayerUpdated(KisLayerSP layer, QRect rc)
00702 {
00703 emit sigLayerUpdated(layer, rc);
00704 }
00705
00706 void KisImage::resize(Q_INT32 w, Q_INT32 h, Q_INT32 x, Q_INT32 y, bool cropLayers)
00707 {
00708 if (w != width() || h != height()) {
00709
00710 lock();
00711
00712 if (undo()) {
00713 if (cropLayers)
00714 m_adapter->beginMacro(i18n("Crop Image"));
00715 else
00716 m_adapter->beginMacro(i18n("Resize Image"));
00717
00718 m_adapter->addCommand(new LockImageCommand(this, true));
00719 m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
00720 }
00721
00722 m_width = w;
00723 m_height = h;
00724
00725 if (cropLayers) {
00726 KisCropVisitor v(QRect(x, y, w, h));
00727 m_rootLayer->accept(v);
00728 }
00729
00730 emitSizeChanged();
00731
00732 unlock();
00733
00734 if (undo()) {
00735 m_adapter->addCommand(new LockImageCommand(this, false));
00736 m_adapter->endMacro();
00737 }
00738 }
00739 }
00740
00741 void KisImage::resize(const QRect& rc, bool cropLayers)
00742 {
00743 resize(rc.width(), rc.height(), rc.x(), rc.y(), cropLayers);
00744 }
00745
00746
00747 void KisImage::scale(double sx, double sy, KisProgressDisplayInterface *progress, KisFilterStrategy *filterStrategy)
00748 {
00749 if (nlayers() == 0) return;
00750
00751
00752 Q_INT32 w, h;
00753 w = (Q_INT32)(( width() * sx) + 0.5);
00754 h = (Q_INT32)(( height() * sy) + 0.5);
00755
00756 if (w != width() || h != height()) {
00757
00758 lock();
00759
00760 if (undo()) {
00761 m_adapter->beginMacro(i18n("Scale Image"));
00762 m_adapter->addCommand(new LockImageCommand(this, true));
00763 }
00764
00765 {
00766 KisTransformVisitor visitor (this, sx, sy, 0.0, 0.0, 0.0, 0, 0, progress, filterStrategy);
00767 m_rootLayer->accept(visitor);
00768 }
00769
00770 if (undo()) {
00771 m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
00772 }
00773
00774 m_width = w;
00775 m_height = h;
00776
00777 emitSizeChanged();
00778
00779 unlock();
00780
00781 if (undo()) {
00782 m_adapter->addCommand(new LockImageCommand(this, false));
00783 m_adapter->endMacro();
00784 }
00785 }
00786 }
00787
00788
00789
00790 void KisImage::rotate(double angle, KisProgressDisplayInterface *progress)
00791 {
00792 lock();
00793
00794 angle *= M_PI/180;
00795 Q_INT32 w = width();
00796 Q_INT32 h = height();
00797 Q_INT32 tx = Q_INT32((w*cos(angle) - h*sin(angle) - w) / 2 + 0.5);
00798 Q_INT32 ty = Q_INT32((h*cos(angle) + w*sin(angle) - h) / 2 + 0.5);
00799 w = (Q_INT32)(width()*QABS(cos(angle)) + height()*QABS(sin(angle)) + 0.5);
00800 h = (Q_INT32)(height()*QABS(cos(angle)) + width()*QABS(sin(angle)) + 0.5);
00801
00802 tx -= (w - width()) / 2;
00803 ty -= (h - height()) / 2;
00804
00805 if (undo()) {
00806 m_adapter->beginMacro(i18n("Rotate Image"));
00807 m_adapter->addCommand(new LockImageCommand(this, true));
00808 }
00809
00810 KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
00811 KisTransformVisitor visitor (this, 1.0, 1.0, 0, 0, angle, -tx, -ty, progress, filter);
00812 m_rootLayer->accept(visitor);
00813
00814 if (undo()) m_adapter->addCommand(new KisResizeImageCmd(undoAdapter(), this, w, h, width(), height()));
00815
00816 m_width = w;
00817 m_height = h;
00818
00819 emitSizeChanged();
00820
00821 unlock();
00822
00823 if (undo()) {
00824 m_adapter->addCommand(new LockImageCommand(this, false));
00825 m_adapter->endMacro();
00826 }
00827 }
00828
00829 void KisImage::shear(double angleX, double angleY, KisProgressDisplayInterface *m_progress)
00830 {
00831 const double pi=3.1415926535897932385;
00832
00833
00834 Q_INT32 w=width();
00835 Q_INT32 h=height();
00836
00837
00838 if(angleX != 0 || angleY != 0){
00839 double deltaY=height()*QABS(tan(angleX*pi/180)*tan(angleY*pi/180));
00840 w = (Q_INT32) ( width() + QABS(height()*tan(angleX*pi/180)) );
00841
00842
00843 if (angleX == 0 || angleY == 0)
00844 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
00845 else if (angleX > 0 && angleY > 0)
00846 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
00847 else if (angleX < 0 && angleY < 0)
00848 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
00849 else
00850 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
00851 }
00852
00853 if (w != width() || h != height()) {
00854
00855 lock();
00856
00857 if (undo()) {
00858 m_adapter->beginMacro(i18n("Shear Image"));
00859 m_adapter->addCommand(new LockImageCommand(this, true));
00860 }
00861
00862 KisShearVisitor v(angleX, angleY, m_progress);
00863 v.setUndoAdapter(undoAdapter());
00864 rootLayer()->accept(v);
00865
00866 if (undo()) m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
00867
00868 m_width = w;
00869 m_height = h;
00870
00871 emitSizeChanged();
00872
00873 unlock();
00874
00875 if (undo()) {
00876 m_adapter->addCommand(new LockImageCommand(this, false));
00877 m_adapter->endMacro();
00878 }
00879 }
00880 }
00881
00882 void KisImage::convertTo(KisColorSpace * dstColorSpace, Q_INT32 renderingIntent)
00883 {
00884 if ( m_colorSpace == dstColorSpace )
00885 {
00886 return;
00887 }
00888
00889 lock();
00890
00891 KisColorSpace * oldCs = m_colorSpace;
00892
00893 if (undo()) {
00894 m_adapter->beginMacro(i18n("Convert Image Type"));
00895 m_adapter->addCommand(new LockImageCommand(this, true));
00896 }
00897
00898 setColorSpace(dstColorSpace);
00899
00900 KisColorSpaceConvertVisitor visitor(dstColorSpace, renderingIntent);
00901 m_rootLayer->accept(visitor);
00902
00903 unlock();
00904
00905 emit sigLayerPropertiesChanged( m_activeLayer );
00906
00907 if (undo()) {
00908
00909 m_adapter->addCommand(new KisConvertImageTypeCmd(undoAdapter(), this,
00910 oldCs, dstColorSpace));
00911 m_adapter->addCommand(new LockImageCommand(this, false));
00912 m_adapter->endMacro();
00913 }
00914 }
00915
00916 KisProfile * KisImage::getProfile() const
00917 {
00918 return colorSpace()->getProfile();
00919 }
00920
00921 void KisImage::setProfile(const KisProfile * profile)
00922 {
00923 if (profile == 0) return;
00924
00925 KisColorSpace * dstCs= KisMetaRegistry::instance()->csRegistry()->getColorSpace( colorSpace()->id(),
00926 profile);
00927 if (dstCs) {
00928
00929 lock();
00930
00931 KisColorSpace * oldCs = colorSpace();
00932 setColorSpace(dstCs);
00933 emit(sigProfileChanged(const_cast<KisProfile *>(profile)));
00934
00935 KisChangeProfileVisitor visitor(oldCs, dstCs);
00936 m_rootLayer->accept(visitor);
00937
00938 unlock();
00939 }
00940 }
00941
00942 double KisImage::xRes()
00943 {
00944 return m_xres;
00945 }
00946
00947 double KisImage::yRes()
00948 {
00949 return m_yres;
00950 }
00951
00952 void KisImage::setResolution(double xres, double yres)
00953 {
00954 m_xres = xres;
00955 m_yres = yres;
00956 }
00957
00958 Q_INT32 KisImage::width() const
00959 {
00960 return m_width;
00961 }
00962
00963 Q_INT32 KisImage::height() const
00964 {
00965 return m_height;
00966 }
00967
00968 KisPaintDeviceSP KisImage::activeDevice()
00969 {
00970 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(m_activeLayer.data())) {
00971 return layer->paintDevice();
00972 }
00973 else if (KisAdjustmentLayer* layer = dynamic_cast<KisAdjustmentLayer*>(m_activeLayer.data())) {
00974 if (layer->selection()) {
00975 return layer->selection().data();
00976 }
00977 }
00978 else if (KisGroupLayer * layer = dynamic_cast<KisGroupLayer*>(m_activeLayer.data())) {
00979
00980 KisLayer * child = layer->lastChild();
00981 while(child)
00982 {
00983 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(m_activeLayer.data())) {
00984 return layer->paintDevice();
00985 }
00986 child = child->prevSibling();
00987 }
00988 }
00989
00990 return 0;
00991 }
00992
00993 KisLayerSP KisImage::newLayer(const QString& name, Q_UINT8 opacity, const KisCompositeOp& compositeOp, KisColorSpace * colorstrategy)
00994 {
00995 KisPaintLayer * layer;
00996 if (colorstrategy)
00997 layer = new KisPaintLayer(this, name, opacity, colorstrategy);
00998 else
00999 layer = new KisPaintLayer(this, name, opacity);
01000 Q_CHECK_PTR(layer);
01001
01002 if (compositeOp.isValid())
01003 layer->setCompositeOp(compositeOp);
01004 layer->setVisible(true);
01005
01006 if (m_activeLayer != 0) {
01007 addLayer(layer, m_activeLayer->parent().data(), m_activeLayer->nextSibling());
01008 }
01009 else {
01010 addLayer(layer, m_rootLayer, 0);
01011 }
01012 activate(layer);
01013
01014 return layer;
01015 }
01016
01017 void KisImage::setLayerProperties(KisLayerSP layer, Q_UINT8 opacity, const KisCompositeOp& compositeOp, const QString& name)
01018 {
01019 if (layer && (layer->opacity() != opacity || layer->compositeOp() != compositeOp || layer->name() != name)) {
01020 if (undo()) {
01021 QString oldname = layer->name();
01022 Q_INT32 oldopacity = layer->opacity();
01023 KisCompositeOp oldCompositeOp = layer->compositeOp();
01024 layer->setName(name);
01025 layer->setOpacity(opacity);
01026 layer->setCompositeOp(compositeOp);
01027 m_adapter->addCommand(new LayerPropsCmd(layer, this, m_adapter, oldname, oldopacity, oldCompositeOp));
01028 } else {
01029 layer->setName(name);
01030 layer->setOpacity(opacity);
01031 layer->setCompositeOp(compositeOp);
01032 }
01033 }
01034 }
01035
01036 KisGroupLayerSP KisImage::rootLayer() const
01037 {
01038 return m_rootLayer;
01039 }
01040
01041 KisLayerSP KisImage::activeLayer() const
01042 {
01043 return m_activeLayer;
01044 }
01045
01046 KisPaintDeviceSP KisImage::projection()
01047 {
01048 return m_rootLayer->projection(QRect(0, 0, m_width, m_height));
01049 }
01050
01051 KisLayerSP KisImage::activate(KisLayerSP layer)
01052 {
01053 if (layer != m_activeLayer) {
01054 if (m_activeLayer) m_activeLayer->deactivate();
01055 m_activeLayer = layer;
01056 if (m_activeLayer) m_activeLayer->activate();
01057 emit sigLayerActivated(m_activeLayer);
01058 }
01059
01060 return layer;
01061 }
01062
01063 KisLayerSP KisImage::findLayer(const QString& name) const
01064 {
01065 return rootLayer()->findLayer(name);
01066 }
01067
01068 KisLayerSP KisImage::findLayer(int id) const
01069 {
01070 return rootLayer()->findLayer(id);
01071 }
01072
01073
01074 bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent)
01075 {
01076 return addLayer(layer, parent, parent->firstChild());
01077 }
01078
01079 bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
01080 {
01081 if (!parent)
01082 return false;
01083
01084 const bool success = parent->addLayer(layer, aboveThis);
01085 if (success)
01086 {
01087 KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>(layer.data());
01088 if (player != 0) {
01089
01090
01091 QValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() ->
01092 csRegistry()->paintDeviceActionsFor(player->paintDevice()->colorSpace());
01093 for (uint i = 0; i < actions.count(); i++) {
01094 actions.at(i)->act(player.data()->paintDevice(), width(), height());
01095 }
01096 }
01097
01098 if (layer->extent().isValid()) layer->setDirty();
01099
01100 if (!layer->temporary()) {
01101 emit sigLayerAdded(layer);
01102 activate(layer);
01103 }
01104
01105
01106 if (!layer->temporary() && undo()) {
01107 m_adapter->addCommand(new LayerAddCmd(m_adapter, this, layer));
01108 }
01109 }
01110
01111 return success;
01112 }
01113
01114 bool KisImage::removeLayer(KisLayerSP layer)
01115 {
01116 if (!layer || layer->image() != this)
01117 return false;
01118
01119 if (KisGroupLayerSP parent = layer->parent()) {
01120
01121
01122 KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(layer.data());
01123 if (al) {
01124 QRect r = al->extent();
01125 lock();
01126 KisLayerSP l = layer->nextSibling();
01127 while (l) {
01128 KisAdjustmentLayer * al2 = dynamic_cast<KisAdjustmentLayer*>(l.data());
01129 l->setDirty(r, false);
01130 if (al2 != 0) break;
01131 l = l->nextSibling();
01132 }
01133 unlock();
01134 }
01135 KisLayerSP l = layer->prevSibling();
01136 QRect r = layer->extent();
01137 while (l) {
01138 l->setDirty(r, false);
01139 l = l->prevSibling();
01140 }
01141
01142 KisLayerSP wasAbove = layer->nextSibling();
01143 KisLayerSP wasBelow = layer->prevSibling();
01144 const bool wasActive = layer == activeLayer();
01145
01146 KisLayerSP actLayer = activeLayer();
01147 const bool success = parent->removeLayer(layer);
01148 if (success) {
01149 layer->setImage(0);
01150 if (!layer->temporary() && undo()) {
01151 m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, parent, wasAbove));
01152 }
01153 if (!layer->temporary()) {
01154 emit sigLayerRemoved(layer, parent, wasAbove);
01155 if (wasActive) {
01156 if (wasBelow)
01157 activate(wasBelow);
01158 else if (wasAbove)
01159 activate(wasAbove);
01160 else if (parent != rootLayer())
01161 activate(parent.data());
01162 else
01163 activate(rootLayer()->firstChild());
01164 } else {
01165 activate(actLayer);
01166 }
01167 }
01168 }
01169 return success;
01170 }
01171
01172 return false;
01173 }
01174
01175 bool KisImage::raiseLayer(KisLayerSP layer)
01176 {
01177 if (!layer)
01178 return false;
01179 return moveLayer(layer, layer->parent().data(), layer->prevSibling());
01180 }
01181
01182 bool KisImage::lowerLayer(KisLayerSP layer)
01183 {
01184 if (!layer)
01185 return false;
01186 if (KisLayerSP next = layer->nextSibling())
01187 return moveLayer(layer, layer->parent().data(), next->nextSibling());
01188 return false;
01189 }
01190
01191 bool KisImage::toTop(KisLayerSP layer)
01192 {
01193 if (!layer)
01194 return false;
01195 return moveLayer(layer, rootLayer(), rootLayer()->firstChild());
01196 }
01197
01198 bool KisImage::toBottom(KisLayerSP layer)
01199 {
01200 if (!layer)
01201 return false;
01202 return moveLayer(layer, rootLayer(), 0);
01203 }
01204
01205 bool KisImage::moveLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
01206 {
01207 if (!parent)
01208 return false;
01209
01210 KisGroupLayerSP wasParent = layer->parent();
01211 KisLayerSP wasAbove = layer->nextSibling();
01212
01213 if (wasParent.data() == parent.data() && wasAbove.data() == aboveThis.data())
01214 return false;
01215
01216 lock();
01217
01218 if (!wasParent->removeLayer(layer)) {
01219 unlock();
01220 return false;
01221 }
01222
01223 const bool success = parent->addLayer(layer, aboveThis);
01224
01225 layer->setDirty();
01226
01227 unlock();
01228
01229 if (success)
01230 {
01231 emit sigLayerMoved(layer, wasParent, wasAbove);
01232 if (undo())
01233 m_adapter->addCommand(new LayerMoveCmd(m_adapter, this, layer, wasParent, wasAbove));
01234 }
01235 else
01236 {
01237 emit sigLayerRemoved(layer, wasParent, wasAbove);
01238 if (undo())
01239 m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, wasParent, wasAbove));
01240 }
01241
01242 return success;
01243 }
01244
01245 Q_INT32 KisImage::nlayers() const
01246 {
01247 return rootLayer()->numLayers() - 1;
01248 }
01249
01250 Q_INT32 KisImage::nHiddenLayers() const
01251 {
01252 return rootLayer()->numLayers(KisLayer::Hidden);
01253 }
01254
01255 void KisImage::flatten()
01256 {
01257 KisGroupLayerSP oldRootLayer = m_rootLayer;
01258 disconnect(oldRootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01259
01260 KisPaintLayer *dst = new KisPaintLayer(this, nextLayerName(), OPACITY_OPAQUE, colorSpace());
01261 Q_CHECK_PTR(dst);
01262
01263 QRect rc = mergedImage()->extent();
01264
01265 KisPainter gc(dst->paintDevice());
01266 gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, mergedImage(), OPACITY_OPAQUE, rc.left(), rc.top(), rc.width(), rc.height());
01267
01268 m_rootLayer = new KisGroupLayer(this, "", OPACITY_OPAQUE);
01269 connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01270
01271 if (undo()) {
01272 m_adapter->beginMacro(i18n("Flatten Image"));
01273 m_adapter->addCommand(new LockImageCommand(this, true));
01274 m_adapter->addCommand(new KisChangeLayersCmd(m_adapter, this, oldRootLayer, m_rootLayer, ""));
01275 }
01276
01277 lock();
01278
01279 addLayer(dst, m_rootLayer, 0);
01280 activate(dst);
01281
01282 unlock();
01283
01284 notifyLayersChanged();
01285
01286 if (undo()) {
01287 m_adapter->addCommand(new LockImageCommand(this, false));
01288 m_adapter->endMacro();
01289 }
01290 }
01291
01292
01293 void KisImage::mergeLayer(KisLayerSP layer)
01294 {
01295 KisPaintLayer *player = new KisPaintLayer(this, layer->name(), OPACITY_OPAQUE, colorSpace());
01296 Q_CHECK_PTR(player);
01297
01298 QRect rc = layer->extent() | layer->nextSibling()->extent();
01299
01300 undoAdapter()->beginMacro(i18n("Merge with Layer Below"));
01301
01302
01303 KisMergeVisitor visitor(player->paintDevice(), rc);
01304 layer->nextSibling()->accept(visitor);
01305 layer->accept(visitor);
01306
01307 removeLayer(layer->nextSibling());
01308 addLayer(player, layer->parent(), layer);
01309 removeLayer(layer);
01310
01311 undoAdapter()->endMacro();
01312 }
01313
01314
01315 void KisImage::setModified()
01316 {
01317 emit sigImageModified();
01318 }
01319
01320 void KisImage::renderToPainter(Q_INT32 x1,
01321 Q_INT32 y1,
01322 Q_INT32 x2,
01323 Q_INT32 y2,
01324 QPainter &painter,
01325 KisProfile * monitorProfile,
01326 PaintFlags paintFlags,
01327 float exposure)
01328 {
01329
01330 QImage img = convertToQImage(x1, y1, x2, y2, monitorProfile, exposure);
01331
01332 Q_INT32 w = x2 - x1 + 1;
01333 Q_INT32 h = y2 - y1 + 1;
01334
01335
01336 if (paintFlags & PAINT_BACKGROUND) {
01337 m_bkg->paintBackground(img, x1, y1);
01338 img.setAlphaBuffer(false);
01339 }
01340
01341 if (paintFlags & PAINT_SELECTION) {
01342 if (m_activeLayer != 0) {
01343 m_activeLayer->paintSelection(img, x1, y1, w, h);
01344 }
01345 }
01346
01347 if (paintFlags & PAINT_MASKINACTIVELAYERS) {
01348 if (m_activeLayer != 0) {
01349 m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
01350 }
01351 }
01352
01353 painter.drawImage(x1, y1, img, 0, 0, w, h);
01354 }
01355
01356 QImage KisImage::convertToQImage(Q_INT32 x1,
01357 Q_INT32 y1,
01358 Q_INT32 x2,
01359 Q_INT32 y2,
01360 KisProfile * profile,
01361 float exposure)
01362 {
01363 Q_INT32 w = x2 - x1 + 1;
01364 Q_INT32 h = y2 - y1 + 1;
01365
01366 KisPaintDeviceSP dev = m_rootLayer->projection(QRect(x1, y1, w, h));
01367 QImage img = dev->convertToQImage(profile, x1, y1, w, h, exposure);
01368
01369 if (!img.isNull()) {
01370 #ifdef __BIG_ENDIAN__
01371 uchar * data = img.bits();
01372 for (int i = 0; i < w * h; ++i) {
01373 uchar r, g, b, a;
01374 a = data[0];
01375 b = data[1];
01376 g = data[2];
01377 r = data[3];
01378 data[0] = r;
01379 data[1] = g;
01380 data[2] = b;
01381 data[3] = a;
01382 data += 4;
01383 }
01384 #endif
01385
01386 return img;
01387 }
01388
01389 return QImage();
01390 }
01391
01392 QImage KisImage::convertToQImage(const QRect& r, const QSize& scaledImageSize, KisProfile *profile, PaintFlags paintFlags, float exposure)
01393 {
01394 if (r.isEmpty() || scaledImageSize.isEmpty()) {
01395 return QImage();
01396 }
01397
01398 Q_INT32 imageWidth = width();
01399 Q_INT32 imageHeight = height();
01400 Q_UINT32 pixelSize = colorSpace()->pixelSize();
01401
01402 double xScale = static_cast<double>(imageWidth) / scaledImageSize.width();
01403 double yScale = static_cast<double>(imageHeight) / scaledImageSize.height();
01404
01405 QRect srcRect;
01406
01407 srcRect.setLeft(static_cast<int>(r.left() * xScale));
01408 srcRect.setRight(static_cast<int>(ceil((r.right() + 1) * xScale)) - 1);
01409 srcRect.setTop(static_cast<int>(r.top() * yScale));
01410 srcRect.setBottom(static_cast<int>(ceil((r.bottom() + 1) * yScale)) - 1);
01411
01412 KisPaintDeviceSP mergedImage = m_rootLayer->projection(srcRect);
01413
01414
01415
01416 Q_UINT8 *scaledImageData = new Q_UINT8[r.width() * r.height() * pixelSize];
01417
01418 Q_UINT8 *imageRow = new Q_UINT8[srcRect.width() * pixelSize];
01419 const Q_INT32 imageRowX = srcRect.x();
01420
01421 for (Q_INT32 y = 0; y < r.height(); ++y) {
01422
01423 Q_INT32 dstY = r.y() + y;
01424 Q_INT32 dstX = r.x();
01425 Q_INT32 srcY = (dstY * imageHeight) / scaledImageSize.height();
01426
01427 mergedImage->readBytes(imageRow, imageRowX, srcY, srcRect.width(), 1);
01428
01429 Q_UINT8 *dstPixel = scaledImageData + (y * r.width() * pixelSize);
01430 Q_UINT32 columnsRemaining = r.width();
01431
01432 while (columnsRemaining > 0) {
01433
01434 Q_INT32 srcX = (dstX * imageWidth) / scaledImageSize.width();
01435
01436 memcpy(dstPixel, imageRow + ((srcX - imageRowX) * pixelSize), pixelSize);
01437
01438 ++dstX;
01439 dstPixel += pixelSize;
01440 --columnsRemaining;
01441 }
01442 }
01443
01444 delete [] imageRow;
01445
01446 QImage image = colorSpace()->convertToQImage(scaledImageData, r.width(), r.height(), profile, INTENT_PERCEPTUAL, exposure);
01447 delete [] scaledImageData;
01448
01449 #ifdef __BIG_ENDIAN__
01450 uchar * data = image.bits();
01451 for (int i = 0; i < image.width() * image.height(); ++i) {
01452 uchar r, g, b, a;
01453 a = data[0];
01454 b = data[1];
01455 g = data[2];
01456 r = data[3];
01457 data[0] = r;
01458 data[1] = g;
01459 data[2] = b;
01460 data[3] = a;
01461 data += 4;
01462 }
01463 #endif
01464
01465 if (paintFlags & PAINT_BACKGROUND) {
01466 m_bkg->paintBackground(image, r, scaledImageSize, QSize(imageWidth, imageHeight));
01467 image.setAlphaBuffer(false);
01468 }
01469
01470 if (paintFlags & PAINT_SELECTION) {
01471 if (m_activeLayer != 0) {
01472 m_activeLayer->paintSelection(image, r, scaledImageSize, QSize(imageWidth, imageHeight));
01473 }
01474 }
01475
01476
01477
01478
01479
01480
01481
01482 return image;
01483 }
01484
01485 KisPaintDeviceSP KisImage::mergedImage()
01486 {
01487 return m_rootLayer->projection(QRect(0, 0, m_width, m_height));
01488 }
01489
01490 KisColor KisImage::mergedPixel(Q_INT32 x, Q_INT32 y)
01491 {
01492 return m_rootLayer->projection(QRect(x, y, 1, 1))->colorAt(x, y);
01493 }
01494
01495 void KisImage::notifyLayersChanged()
01496 {
01497 emit sigLayersChanged(rootLayer());
01498 }
01499
01500 void KisImage::notifyPropertyChanged(KisLayerSP layer)
01501 {
01502 emit sigLayerPropertiesChanged(layer);
01503 }
01504
01505 void KisImage::notifyImageLoaded()
01506 {
01507 }
01508
01509 QRect KisImage::bounds() const
01510 {
01511 return QRect(0, 0, width(), height());
01512 }
01513
01514
01515 void KisImage::setUndoAdapter(KisUndoAdapter * adapter)
01516 {
01517 m_adapter = adapter;
01518 }
01519
01520
01521 KisUndoAdapter* KisImage::undoAdapter() const
01522 {
01523 return m_adapter;
01524 }
01525
01526 bool KisImage::undo() const
01527 {
01528 return (m_adapter && m_adapter->undo());
01529 }
01530
01531
01532
01533
01534
01535
01536 void KisImage::slotSelectionChanged()
01537 {
01538 slotSelectionChanged(bounds());
01539 }
01540
01541 void KisImage::slotSelectionChanged(const QRect& r)
01542 {
01543 QRect r2(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2);
01544
01545 if (!locked()) {
01546 emit sigActiveSelectionChanged(this);
01547 } else {
01548 m_private->selectionChangedWhileLocked = true;
01549 }
01550 }
01551
01552 KisColorSpace * KisImage::colorSpace() const
01553 {
01554 return m_colorSpace;
01555 }
01556
01557 void KisImage::setColorSpace(KisColorSpace * colorSpace)
01558 {
01559 m_colorSpace = colorSpace;
01560 m_rootLayer->resetProjection();
01561 emit sigColorSpaceChanged(colorSpace);
01562 }
01563
01564 void KisImage::setRootLayer(KisGroupLayerSP rootLayer)
01565 {
01566 disconnect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01567
01568 m_rootLayer = rootLayer;
01569
01570 if (!locked()) {
01571 connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01572 }
01573 activate(m_rootLayer->firstChild());
01574 }
01575
01576 void KisImage::addAnnotation(KisAnnotationSP annotation)
01577 {
01578
01579 vKisAnnotationSP_it it = m_annotations.begin();
01580 while (it != m_annotations.end()) {
01581 if ((*it)->type() == annotation->type()) {
01582 *it = annotation;
01583 return;
01584 }
01585 ++it;
01586 }
01587 m_annotations.push_back(annotation);
01588 }
01589
01590 KisAnnotationSP KisImage::annotation(QString type)
01591 {
01592 vKisAnnotationSP_it it = m_annotations.begin();
01593 while (it != m_annotations.end()) {
01594 if ((*it)->type() == type) {
01595 return *it;
01596 }
01597 ++it;
01598 }
01599 return 0;
01600 }
01601
01602 void KisImage::removeAnnotation(QString type)
01603 {
01604 vKisAnnotationSP_it it = m_annotations.begin();
01605 while (it != m_annotations.end()) {
01606 if ((*it)->type() == type) {
01607 m_annotations.erase(it);
01608 return;
01609 }
01610 ++it;
01611 }
01612 }
01613
01614 vKisAnnotationSP_it KisImage::beginAnnotations()
01615 {
01616 KisProfile * profile = colorSpace()->getProfile();
01617 KisAnnotationSP annotation;
01618
01619 if (profile)
01620 annotation = profile->annotation();
01621
01622 if (annotation)
01623 addAnnotation(annotation);
01624 else
01625 removeAnnotation("icc");
01626
01627 return m_annotations.begin();
01628 }
01629
01630 vKisAnnotationSP_it KisImage::endAnnotations()
01631 {
01632 return m_annotations.end();
01633 }
01634
01635 KisBackgroundSP KisImage::background() const
01636 {
01637 return m_bkg;
01638 }
01639 #include "kis_image.moc"
01640