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 #if 0
00774 if ( colorSpace()->id() == KisID("RGBA") || colorSpace()->id() == KisID("CMYK") || colorSpace()->id() == KisID("GRAYA")) {
00775 KisScaleVisitor v (this, sx, sy, progress, filterStrategy);
00776 m_rootLayer->accept( v );
00777 }
00778 else {
00779 #endif
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 radians, KisProgressDisplayInterface *progress)
00805 {
00806 lock();
00807
00808 Q_INT32 w = width();
00809 Q_INT32 h = height();
00810 Q_INT32 tx = Q_INT32((w*cos(radians) - h*sin(radians) - w) / 2 + 0.5);
00811 Q_INT32 ty = Q_INT32((h*cos(radians) + w*sin(radians) - h) / 2 + 0.5);
00812 w = (Q_INT32)(width()*QABS(cos(radians)) + height()*QABS(sin(radians)) + 0.5);
00813 h = (Q_INT32)(height()*QABS(cos(radians)) + width()*QABS(sin(radians)) + 0.5);
00814
00815 tx -= (w - width()) / 2;
00816 ty -= (h - height()) / 2;
00817
00818 if (undo()) {
00819 m_adapter->beginMacro(i18n("Rotate Image"));
00820 m_adapter->addCommand(new LockImageCommand(this, true));
00821 }
00822
00823 KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
00824 KisTransformVisitor visitor (this, 1.0, 1.0, 0, 0, radians, -tx, -ty, progress, filter);
00825 m_rootLayer->accept(visitor);
00826
00827 if (undo()) m_adapter->addCommand(new KisResizeImageCmd(undoAdapter(), this, w, h, width(), height()));
00828
00829 m_width = w;
00830 m_height = h;
00831
00832 emitSizeChanged();
00833
00834 unlock();
00835
00836 if (undo()) {
00837 m_adapter->addCommand(new LockImageCommand(this, false));
00838 m_adapter->endMacro();
00839 }
00840 }
00841
00842 void KisImage::shear(double angleX, double angleY, KisProgressDisplayInterface *m_progress)
00843 {
00844 const double pi=3.1415926535897932385;
00845
00846
00847 Q_INT32 w=width();
00848 Q_INT32 h=height();
00849
00850
00851 if(angleX != 0 || angleY != 0){
00852 double deltaY=height()*QABS(tan(angleX*pi/180)*tan(angleY*pi/180));
00853 w = (Q_INT32) ( width() + QABS(height()*tan(angleX*pi/180)) );
00854
00855
00856 if (angleX == 0 || angleY == 0)
00857 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
00858 else if (angleX > 0 && angleY > 0)
00859 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
00860 else if (angleX < 0 && angleY < 0)
00861 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
00862 else
00863 h = (Q_INT32) ( height() + QABS(w*tan(angleY*pi/180)) );
00864 }
00865
00866 if (w != width() || h != height()) {
00867
00868 lock();
00869
00870 if (undo()) {
00871 m_adapter->beginMacro(i18n("Shear Image"));
00872 m_adapter->addCommand(new LockImageCommand(this, true));
00873 }
00874
00875 KisShearVisitor v(angleX, angleY, m_progress);
00876 v.setUndoAdapter(undoAdapter());
00877 rootLayer()->accept(v);
00878
00879 if (undo()) m_adapter->addCommand(new KisResizeImageCmd(m_adapter, this, w, h, width(), height()));
00880
00881 m_width = w;
00882 m_height = h;
00883
00884 emitSizeChanged();
00885
00886 unlock();
00887
00888 if (undo()) {
00889 m_adapter->addCommand(new LockImageCommand(this, false));
00890 m_adapter->endMacro();
00891 }
00892 }
00893 }
00894
00895 void KisImage::convertTo(KisColorSpace * dstColorSpace, Q_INT32 renderingIntent)
00896 {
00897 if ( m_colorSpace == dstColorSpace )
00898 {
00899 return;
00900 }
00901
00902 lock();
00903
00904 KisColorSpace * oldCs = m_colorSpace;
00905
00906 if (undo()) {
00907 m_adapter->beginMacro(i18n("Convert Image Type"));
00908 m_adapter->addCommand(new LockImageCommand(this, true));
00909 }
00910
00911 setColorSpace(dstColorSpace);
00912
00913 KisColorSpaceConvertVisitor visitor(dstColorSpace, renderingIntent);
00914 m_rootLayer->accept(visitor);
00915
00916 unlock();
00917
00918 emit sigLayerPropertiesChanged( m_activeLayer );
00919
00920 if (undo()) {
00921
00922 m_adapter->addCommand(new KisConvertImageTypeCmd(undoAdapter(), this,
00923 oldCs, dstColorSpace));
00924 m_adapter->addCommand(new LockImageCommand(this, false));
00925 m_adapter->endMacro();
00926 }
00927 }
00928
00929 KisProfile * KisImage::getProfile() const
00930 {
00931 return colorSpace()->getProfile();
00932 }
00933
00934 void KisImage::setProfile(const KisProfile * profile)
00935 {
00936 if (profile == 0) return;
00937
00938 KisColorSpace * dstCs= KisMetaRegistry::instance()->csRegistry()->getColorSpace( colorSpace()->id(),
00939 profile);
00940 if (dstCs) {
00941
00942 lock();
00943
00944 KisColorSpace * oldCs = colorSpace();
00945 setColorSpace(dstCs);
00946 emit(sigProfileChanged(const_cast<KisProfile *>(profile)));
00947
00948 KisChangeProfileVisitor visitor(oldCs, dstCs);
00949 m_rootLayer->accept(visitor);
00950
00951 unlock();
00952 }
00953 }
00954
00955 double KisImage::xRes()
00956 {
00957 return m_xres;
00958 }
00959
00960 double KisImage::yRes()
00961 {
00962 return m_yres;
00963 }
00964
00965 void KisImage::setResolution(double xres, double yres)
00966 {
00967 m_xres = xres;
00968 m_yres = yres;
00969 }
00970
00971 Q_INT32 KisImage::width() const
00972 {
00973 return m_width;
00974 }
00975
00976 Q_INT32 KisImage::height() const
00977 {
00978 return m_height;
00979 }
00980
00981 KisPaintDeviceSP KisImage::activeDevice()
00982 {
00983 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(m_activeLayer.data())) {
00984 return layer->paintDeviceOrMask();
00985 }
00986 else if (KisAdjustmentLayer* layer = dynamic_cast<KisAdjustmentLayer*>(m_activeLayer.data())) {
00987 if (layer->selection()) {
00988 return layer->selection().data();
00989 }
00990 }
00991 else if (KisGroupLayer * layer = dynamic_cast<KisGroupLayer*>(m_activeLayer.data())) {
00992
00993 KisLayerSP child = layer->lastChild();
00994 while(child)
00995 {
00996 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(child.data())) {
00997 return layer->paintDevice();
00998 }
00999 child = child->prevSibling();
01000 }
01001 KisLayerSP sibling = layer->nextSibling();
01002 while (sibling) {
01003 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(sibling.data())) {
01004 return layer->paintDevice();
01005 }
01006 sibling = sibling->nextSibling();
01007 }
01008 }
01009 else if (KisLayerSP layer = m_activeLayer) {
01010
01011 KisLayerSP sibling = layer->nextSibling();
01012 while (sibling) {
01013 if (KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(sibling.data())) {
01014 return layer->paintDevice();
01015 }
01016 sibling = sibling->nextSibling();
01017 }
01018 }
01019
01020 return 0;
01021 }
01022
01023 KisLayerSP KisImage::newLayer(const QString& name, Q_UINT8 opacity, const KisCompositeOp& compositeOp, KisColorSpace * colorstrategy)
01024 {
01025 KisPaintLayer * layer;
01026 if (colorstrategy)
01027 layer = new KisPaintLayer(this, name, opacity, colorstrategy);
01028 else
01029 layer = new KisPaintLayer(this, name, opacity);
01030 Q_CHECK_PTR(layer);
01031
01032 if (compositeOp.isValid())
01033 layer->setCompositeOp(compositeOp);
01034 layer->setVisible(true);
01035
01036 if (m_activeLayer != 0) {
01037 addLayer(layer, m_activeLayer->parent().data(), m_activeLayer->nextSibling());
01038 }
01039 else {
01040 addLayer(layer, m_rootLayer, 0);
01041 }
01042 activate(layer);
01043
01044 return layer;
01045 }
01046
01047 void KisImage::setLayerProperties(KisLayerSP layer, Q_UINT8 opacity, const KisCompositeOp& compositeOp, const QString& name)
01048 {
01049 if (layer && (layer->opacity() != opacity || layer->compositeOp() != compositeOp || layer->name() != name)) {
01050 if (undo()) {
01051 QString oldname = layer->name();
01052 Q_INT32 oldopacity = layer->opacity();
01053 KisCompositeOp oldCompositeOp = layer->compositeOp();
01054 layer->setName(name);
01055 layer->setOpacity(opacity);
01056 layer->setCompositeOp(compositeOp);
01057 m_adapter->addCommand(new LayerPropsCmd(layer, this, m_adapter, oldname, oldopacity, oldCompositeOp));
01058 } else {
01059 layer->setName(name);
01060 layer->setOpacity(opacity);
01061 layer->setCompositeOp(compositeOp);
01062 }
01063 }
01064 }
01065
01066 KisGroupLayerSP KisImage::rootLayer() const
01067 {
01068 return m_rootLayer;
01069 }
01070
01071 KisLayerSP KisImage::activeLayer() const
01072 {
01073 return m_activeLayer;
01074 }
01075
01076 KisPaintDeviceSP KisImage::projection()
01077 {
01078 return m_rootLayer->projection(QRect(0, 0, m_width, m_height));
01079 }
01080
01081 KisLayerSP KisImage::activate(KisLayerSP layer)
01082 {
01083 if (layer != m_activeLayer) {
01084 if (m_activeLayer) m_activeLayer->deactivate();
01085 m_activeLayer = layer;
01086 if (m_activeLayer) m_activeLayer->activate();
01087 emit sigLayerActivated(m_activeLayer);
01088 emit sigMaskInfoChanged();
01089 }
01090
01091 return layer;
01092 }
01093
01094 KisLayerSP KisImage::findLayer(const QString& name) const
01095 {
01096 return rootLayer()->findLayer(name);
01097 }
01098
01099 KisLayerSP KisImage::findLayer(int id) const
01100 {
01101 return rootLayer()->findLayer(id);
01102 }
01103
01104
01105 bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent)
01106 {
01107 return addLayer(layer, parent, parent->firstChild());
01108 }
01109
01110 bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
01111 {
01112 if (!parent)
01113 return false;
01114
01115 const bool success = parent->addLayer(layer, aboveThis);
01116 if (success)
01117 {
01118 KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>(layer.data());
01119 if (player != 0) {
01120
01121
01122 QValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() ->
01123 csRegistry()->paintDeviceActionsFor(player->paintDevice()->colorSpace());
01124 for (uint i = 0; i < actions.count(); i++) {
01125 actions.at(i)->act(player.data()->paintDevice(), width(), height());
01126 }
01127
01128 connect(player, SIGNAL(sigMaskInfoChanged()), this, SIGNAL(sigMaskInfoChanged()));
01129 }
01130
01131 if (layer->extent().isValid()) layer->setDirty();
01132
01133 if (!layer->temporary()) {
01134 emit sigLayerAdded(layer);
01135 activate(layer);
01136 }
01137
01138
01139 if (!layer->temporary() && undo()) {
01140 m_adapter->addCommand(new LayerAddCmd(m_adapter, this, layer));
01141 }
01142 }
01143
01144 return success;
01145 }
01146
01147 bool KisImage::removeLayer(KisLayerSP layer)
01148 {
01149 if (!layer || layer->image() != this)
01150 return false;
01151
01152 if (KisGroupLayerSP parent = layer->parent()) {
01153
01154
01155 KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(layer.data());
01156 if (al) {
01157 QRect r = al->extent();
01158 lock();
01159 KisLayerSP l = layer->nextSibling();
01160 while (l) {
01161 KisAdjustmentLayer * al2 = dynamic_cast<KisAdjustmentLayer*>(l.data());
01162 l->setDirty(r, false);
01163 if (al2 != 0) break;
01164 l = l->nextSibling();
01165 }
01166 unlock();
01167 }
01168 KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>(layer.data());
01169 if (player != 0) {
01170 disconnect(player, SIGNAL(sigMaskInfoChanged()),
01171 this, SIGNAL(sigMaskInfoChanged()));
01172 }
01173 KisLayerSP l = layer->prevSibling();
01174 QRect r = layer->extent();
01175 while (l) {
01176 l->setDirty(r, false);
01177 l = l->prevSibling();
01178 }
01179
01180 KisLayerSP wasAbove = layer->nextSibling();
01181 KisLayerSP wasBelow = layer->prevSibling();
01182 const bool wasActive = layer == activeLayer();
01183
01184 KisLayerSP actLayer = activeLayer();
01185 const bool success = parent->removeLayer(layer);
01186 if (success) {
01187 layer->setImage(0);
01188 if (!layer->temporary() && undo()) {
01189 m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, parent, wasAbove));
01190 }
01191 if (!layer->temporary()) {
01192 emit sigLayerRemoved(layer, parent, wasAbove);
01193 if (wasActive) {
01194 if (wasBelow)
01195 activate(wasBelow);
01196 else if (wasAbove)
01197 activate(wasAbove);
01198 else if (parent != rootLayer())
01199 activate(parent.data());
01200 else
01201 activate(rootLayer()->firstChild());
01202 } else {
01203 activate(actLayer);
01204 }
01205 }
01206 }
01207 return success;
01208 }
01209
01210 return false;
01211 }
01212
01213 bool KisImage::raiseLayer(KisLayerSP layer)
01214 {
01215 if (!layer)
01216 return false;
01217 return moveLayer(layer, layer->parent().data(), layer->prevSibling());
01218 }
01219
01220 bool KisImage::lowerLayer(KisLayerSP layer)
01221 {
01222 if (!layer)
01223 return false;
01224 if (KisLayerSP next = layer->nextSibling())
01225 return moveLayer(layer, layer->parent().data(), next->nextSibling());
01226 return false;
01227 }
01228
01229 bool KisImage::toTop(KisLayerSP layer)
01230 {
01231 if (!layer)
01232 return false;
01233 return moveLayer(layer, rootLayer(), rootLayer()->firstChild());
01234 }
01235
01236 bool KisImage::toBottom(KisLayerSP layer)
01237 {
01238 if (!layer)
01239 return false;
01240 return moveLayer(layer, rootLayer(), 0);
01241 }
01242
01243 bool KisImage::moveLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
01244 {
01245 if (!parent)
01246 return false;
01247
01248 KisGroupLayerSP wasParent = layer->parent();
01249 KisLayerSP wasAbove = layer->nextSibling();
01250
01251 if (wasParent.data() == parent.data() && wasAbove.data() == aboveThis.data())
01252 return false;
01253
01254 lock();
01255
01256 if (!wasParent->removeLayer(layer)) {
01257 unlock();
01258 return false;
01259 }
01260
01261 const bool success = parent->addLayer(layer, aboveThis);
01262
01263 layer->setDirty();
01264
01265 unlock();
01266
01267 if (success)
01268 {
01269 emit sigLayerMoved(layer, wasParent, wasAbove);
01270 if (undo())
01271 m_adapter->addCommand(new LayerMoveCmd(m_adapter, this, layer, wasParent, wasAbove));
01272 }
01273 else
01274 {
01275 emit sigLayerRemoved(layer, wasParent, wasAbove);
01276 if (undo())
01277 m_adapter->addCommand(new LayerRmCmd(m_adapter, this, layer, wasParent, wasAbove));
01278 }
01279
01280 return success;
01281 }
01282
01283 Q_INT32 KisImage::nlayers() const
01284 {
01285 return rootLayer()->numLayers() - 1;
01286 }
01287
01288 Q_INT32 KisImage::nHiddenLayers() const
01289 {
01290 return rootLayer()->numLayers(KisLayer::Hidden);
01291 }
01292
01293 void KisImage::flatten()
01294 {
01295 KisGroupLayerSP oldRootLayer = m_rootLayer;
01296 disconnect(oldRootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01297
01298 KisPaintLayer *dst = new KisPaintLayer(this, nextLayerName(), OPACITY_OPAQUE, colorSpace());
01299 Q_CHECK_PTR(dst);
01300
01301 QRect rc = mergedImage()->extent();
01302
01303 KisPainter gc(dst->paintDevice());
01304 gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, mergedImage(), OPACITY_OPAQUE, rc.left(), rc.top(), rc.width(), rc.height());
01305
01306 m_rootLayer = new KisGroupLayer(this, "", OPACITY_OPAQUE);
01307 connect(m_rootLayer, SIGNAL(sigDirty(QRect)), this, SIGNAL(sigImageUpdated(QRect)));
01308
01309 if (undo()) {
01310 m_adapter->beginMacro(i18n("Flatten Image"));
01311 m_adapter->addCommand(new LockImageCommand(this, true));
01312 m_adapter->addCommand(new KisChangeLayersCmd(m_adapter, this, oldRootLayer, m_rootLayer, ""));
01313 }
01314
01315 lock();
01316
01317 addLayer(dst, m_rootLayer, 0);
01318 activate(dst);
01319
01320 unlock();
01321
01322 notifyLayersChanged();
01323
01324 if (undo()) {
01325 m_adapter->addCommand(new LockImageCommand(this, false));
01326 m_adapter->endMacro();
01327 }
01328 }
01329
01330
01331 void KisImage::mergeLayer(KisLayerSP layer)
01332 {
01333 KisPaintLayer *player = new KisPaintLayer(this, layer->name(), OPACITY_OPAQUE, colorSpace());
01334 Q_CHECK_PTR(player);
01335
01336 QRect rc = layer->extent() | layer->nextSibling()->extent();
01337
01338 undoAdapter()->beginMacro(i18n("Merge with Layer Below"));
01339
01340
01341 KisMergeVisitor visitor(player->paintDevice(), rc);
01342 layer->nextSibling()->accept(visitor);
01343 layer->accept(visitor);
01344
01345 removeLayer(layer->nextSibling());
01346 addLayer(player, layer->parent(), layer);
01347 removeLayer(layer);
01348
01349 undoAdapter()->endMacro();
01350 }
01351
01352
01353 void KisImage::setModified()
01354 {
01355 emit sigImageModified();
01356 }
01357
01358 void KisImage::renderToPainter(Q_INT32 x1,
01359 Q_INT32 y1,
01360 Q_INT32 x2,
01361 Q_INT32 y2,
01362 QPainter &painter,
01363 KisProfile * monitorProfile,
01364 PaintFlags paintFlags,
01365 float exposure)
01366 {
01367
01368 QImage img = convertToQImage(x1, y1, x2, y2, monitorProfile, exposure);
01369
01370 Q_INT32 w = x2 - x1 + 1;
01371 Q_INT32 h = y2 - y1 + 1;
01372
01373
01374 if (paintFlags & PAINT_BACKGROUND) {
01375 m_bkg->paintBackground(img, x1, y1);
01376 img.setAlphaBuffer(false);
01377 }
01378
01379 if (paintFlags & PAINT_SELECTION) {
01380 if (m_activeLayer != 0) {
01381 m_activeLayer->paintSelection(img, x1, y1, w, h);
01382 }
01383 }
01384
01385 if (paintFlags & PAINT_MASKINACTIVELAYERS) {
01386 if (m_activeLayer != 0) {
01387 m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
01388 }
01389 }
01390
01391 painter.drawImage(x1, y1, img, 0, 0, w, h);
01392 }
01393
01394 QImage KisImage::convertToQImage(Q_INT32 x1,
01395 Q_INT32 y1,
01396 Q_INT32 x2,
01397 Q_INT32 y2,
01398 KisProfile * profile,
01399 float exposure)
01400 {
01401 Q_INT32 w = x2 - x1 + 1;
01402 Q_INT32 h = y2 - y1 + 1;
01403
01404 KisPaintDeviceSP dev = m_rootLayer->projection(QRect(x1, y1, w, h));
01405 QImage img = dev->convertToQImage(profile, x1, y1, w, h, exposure);
01406
01407 if (!img.isNull()) {
01408
01409 #ifdef __BIG_ENDIAN__
01410 uchar * data = img.bits();
01411 for (int i = 0; i < w * h; ++i) {
01412 uchar r, g, b, a;
01413 a = data[0];
01414 b = data[1];
01415 g = data[2];
01416 r = data[3];
01417 data[0] = r;
01418 data[1] = g;
01419 data[2] = b;
01420 data[3] = a;
01421 data += 4;
01422 }
01423 #endif
01424
01425 return img;
01426 }
01427
01428 return QImage();
01429 }
01430
01431 QImage KisImage::convertToQImage(const QRect& r, const QSize& scaledImageSize, KisProfile *profile, PaintFlags paintFlags, float exposure)
01432 {
01433
01434 if (r.isEmpty() || scaledImageSize.isEmpty()) {
01435 return QImage();
01436 }
01437
01438 Q_INT32 imageWidth = width();
01439 Q_INT32 imageHeight = height();
01440 Q_UINT32 pixelSize = colorSpace()->pixelSize();
01441
01442 double xScale = static_cast<double>(imageWidth) / scaledImageSize.width();
01443 double yScale = static_cast<double>(imageHeight) / scaledImageSize.height();
01444
01445 QRect srcRect;
01446
01447 srcRect.setLeft(static_cast<int>(r.left() * xScale));
01448 srcRect.setRight(static_cast<int>(ceil((r.right() + 1) * xScale)) - 1);
01449 srcRect.setTop(static_cast<int>(r.top() * yScale));
01450 srcRect.setBottom(static_cast<int>(ceil((r.bottom() + 1) * yScale)) - 1);
01451
01452 KisPaintDeviceSP mergedImage = m_rootLayer->projection(srcRect);
01453 QTime t;
01454 t.start();
01455
01456 Q_UINT8 *scaledImageData = new Q_UINT8[r.width() * r.height() * pixelSize];
01457
01458 Q_UINT8 *imageRow = new Q_UINT8[srcRect.width() * pixelSize];
01459 const Q_INT32 imageRowX = srcRect.x();
01460
01461 for (Q_INT32 y = 0; y < r.height(); ++y) {
01462
01463 Q_INT32 dstY = r.y() + y;
01464 Q_INT32 dstX = r.x();
01465 Q_INT32 srcY = (dstY * imageHeight) / scaledImageSize.height();
01466
01467 mergedImage->readBytes(imageRow, imageRowX, srcY, srcRect.width(), 1);
01468
01469 Q_UINT8 *dstPixel = scaledImageData + (y * r.width() * pixelSize);
01470 Q_UINT32 columnsRemaining = r.width();
01471
01472 while (columnsRemaining > 0) {
01473
01474 Q_INT32 srcX = (dstX * imageWidth) / scaledImageSize.width();
01475
01476 memcpy(dstPixel, imageRow + ((srcX - imageRowX) * pixelSize), pixelSize);
01477
01478 ++dstX;
01479 dstPixel += pixelSize;
01480 --columnsRemaining;
01481 }
01482 }
01483 kdDebug() << "Time elapsed scaling image: " << t.elapsed() << endl;
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