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