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