29#include <tqapplication.h>
31#include <tqdatetime.h>
37#include "kis_image_iface.h"
39#include "kis_annotation.h"
40#include "kis_colorspace_factory_registry.h"
42#include "kis_command.h"
46#include "kis_paint_device.h"
47#include "kis_paint_device_action.h"
48#include "kis_selection.h"
49#include "kis_painter.h"
50#include "kis_fill_painter.h"
52#include "kis_group_layer.h"
53#include "kis_adjustment_layer.h"
54#include "kis_paint_layer.h"
55#include "kis_colorspace_convert_visitor.h"
56#include "kis_background.h"
57#include "kis_substrate.h"
58#include "kis_scale_visitor.h"
59#include "kis_nameserver.h"
60#include "kis_undo_adapter.h"
61#include "kis_merge_visitor.h"
62#include "kis_transaction.h"
63#include "kis_crop_visitor.h"
64#include "kis_transform_visitor.h"
65#include "kis_filter_strategy.h"
66#include "kis_profile.h"
67#include "kis_paint_layer.h"
68#include "kis_perspective_grid.h"
69#include "kis_change_profile_visitor.h"
70#include "kis_group_layer.h"
71#include "kis_iterators_pixel.h"
72#include "kis_shear_visitor.h"
74class KisImage::KisImagePrivate {
76 KisColor backgroundColor;
78 bool sizeChangedWhileLocked;
79 bool selectionChangedWhileLocked;
80 KisSubstrateSP substrate;
81 KisPerspectiveGrid* perspectiveGrid;
87 class KisResizeImageCmd :
public KNamedCommand {
88 typedef KNamedCommand super;
91 KisResizeImageCmd(KisUndoAdapter *adapter,
96 TQ_INT32 oldHeight) : super(i18n(
"Resize Image"))
100 m_before = TQSize(oldWidth, oldHeight);
101 m_after = TQSize(width, height);
104 virtual ~KisResizeImageCmd()
109 virtual void execute()
111 m_adapter->setUndo(
false);
112 m_img->resize(m_after.width(), m_after.height());
113 m_adapter->setUndo(
true);
116 virtual void unexecute()
118 m_adapter->setUndo(
false);
119 m_img->resize(m_before.width(), m_before.height());
120 m_adapter->setUndo(
true);
124 KisUndoAdapter *m_adapter;
132 class KisChangeLayersCmd :
public KNamedCommand {
133 typedef KNamedCommand super;
136 KisChangeLayersCmd(KisUndoAdapter *adapter, KisImageSP img,
137 KisGroupLayerSP oldRootLayer, KisGroupLayerSP newRootLayer,
const TQString& name)
142 m_oldRootLayer = oldRootLayer;
143 m_newRootLayer = newRootLayer;
146 virtual ~KisChangeLayersCmd()
151 virtual void execute()
153 m_adapter->setUndo(
false);
154 m_img->setRootLayer(m_newRootLayer);
155 m_adapter->setUndo(
true);
156 m_img->notifyLayersChanged();
159 virtual void unexecute()
161 m_adapter->setUndo(
false);
162 m_img->setRootLayer(m_oldRootLayer);
163 m_adapter->setUndo(
true);
164 m_img->notifyLayersChanged();
168 KisUndoAdapter *m_adapter;
170 KisGroupLayerSP m_oldRootLayer;
171 KisGroupLayerSP m_newRootLayer;
177 class KisConvertImageTypeCmd :
public KNamedCommand {
178 typedef KNamedCommand super;
181 KisConvertImageTypeCmd(KisUndoAdapter *adapter, KisImageSP img,
182 KisColorSpace * beforeColorSpace, KisColorSpace * afterColorSpace
183 ) : super(i18n(
"Convert Image Type"))
187 m_beforeColorSpace = beforeColorSpace;
188 m_afterColorSpace = afterColorSpace;
191 virtual ~KisConvertImageTypeCmd()
196 virtual void execute()
198 m_adapter->setUndo(
false);
200 m_img->setColorSpace(m_afterColorSpace);
201 m_img->setProfile(m_afterColorSpace->getProfile());
203 m_adapter->setUndo(
true);
206 virtual void unexecute()
208 m_adapter->setUndo(
false);
210 m_img->setColorSpace(m_beforeColorSpace);
211 m_img->setProfile(m_beforeColorSpace->getProfile());
213 m_adapter->setUndo(
true);
217 KisUndoAdapter *m_adapter;
219 KisColorSpace * m_beforeColorSpace;
220 KisColorSpace * m_afterColorSpace;
226 class KisImageCommand :
public KNamedCommand {
227 typedef KNamedCommand super;
230 KisImageCommand(
const TQString& name, KisImageSP image);
231 virtual ~KisImageCommand() {}
233 virtual void execute() = 0;
234 virtual void unexecute() = 0;
237 void setUndo(
bool undo);
242 KisImageCommand::KisImageCommand(
const TQString& name, KisImageSP image) :
243 super(name), m_image(image)
247 void KisImageCommand::setUndo(
bool undo)
249 if (m_image->undoAdapter()) {
250 m_image->undoAdapter()->setUndo(undo);
257 class KisLayerPositionCommand :
public KisImageCommand {
258 typedef KisImageCommand super;
261 KisLayerPositionCommand(
const TQString& name, KisImageSP image, KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis) : super(name, image)
264 m_oldParent = layer->parent();
265 m_oldAboveThis = layer->nextSibling();
266 m_newParent = parent;
267 m_newAboveThis = aboveThis;
270 virtual void execute()
273 m_image->moveLayer(m_layer, m_newParent, m_newAboveThis);
277 virtual void unexecute()
280 m_image->moveLayer(m_layer, m_oldParent, m_oldAboveThis);
286 KisGroupLayerSP m_oldParent;
287 KisLayerSP m_oldAboveThis;
288 KisGroupLayerSP m_newParent;
289 KisLayerSP m_newAboveThis;
295 class LayerAddCmd :
public KisCommand {
296 typedef KisCommand super;
299 LayerAddCmd(KisUndoAdapter *adapter, KisImageSP img, KisLayerSP layer) : super(i18n(
"Add Layer"), adapter)
303 m_parent = layer->parent();
304 m_aboveThis = layer->nextSibling();
307 virtual ~LayerAddCmd()
311 virtual void execute()
313 adapter()->setUndo(
false);
314 m_img->addLayer(m_layer, m_parent.data(), m_aboveThis);
315 adapter()->setUndo(
true);
318 virtual void unexecute()
320 adapter()->setUndo(
false);
321 m_img->removeLayer(m_layer);
322 adapter()->setUndo(
true);
328 KisGroupLayerSP m_parent;
329 KisLayerSP m_aboveThis;
334 class LayerRmCmd :
public KNamedCommand {
335 typedef KNamedCommand super;
338 LayerRmCmd(KisUndoAdapter *adapter, KisImageSP img,
339 KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
340 : super(i18n(
"Remove Layer"))
345 m_prevParent = wasParent;
346 m_prevAbove = wasAbove;
349 virtual ~LayerRmCmd()
353 virtual void execute()
355 m_adapter->setUndo(
false);
356 m_img->removeLayer(m_layer);
357 m_adapter->setUndo(
true);
360 virtual void unexecute()
362 m_adapter->setUndo(
false);
363 m_img->addLayer(m_layer, m_prevParent.data(), m_prevAbove);
364 m_adapter->setUndo(
true);
368 KisUndoAdapter *m_adapter;
371 KisGroupLayerSP m_prevParent;
372 KisLayerSP m_prevAbove;
375 class LayerMoveCmd:
public KNamedCommand {
376 typedef KNamedCommand super;
379 LayerMoveCmd(KisUndoAdapter *adapter, KisImageSP img,
380 KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAbove)
381 : super(i18n(
"Move Layer"))
386 m_prevParent = wasParent;
387 m_prevAbove = wasAbove;
388 m_newParent = layer->parent();
389 m_newAbove = layer->nextSibling();
392 virtual ~LayerMoveCmd()
396 virtual void execute()
398 m_adapter->setUndo(
false);
399 m_img->moveLayer(m_layer, m_newParent.data(), m_newAbove);
400 m_adapter->setUndo(
true);
403 virtual void unexecute()
405 m_adapter->setUndo(
false);
406 m_img->moveLayer(m_layer, m_prevParent.data(), m_prevAbove);
407 m_adapter->setUndo(
true);
411 KisUndoAdapter *m_adapter;
414 KisGroupLayerSP m_prevParent;
415 KisLayerSP m_prevAbove;
416 KisGroupLayerSP m_newParent;
417 KisLayerSP m_newAbove;
423 class LayerPropsCmd :
public KNamedCommand {
424 typedef KNamedCommand super;
427 LayerPropsCmd(KisLayerSP layer,
429 KisUndoAdapter *adapter,
430 const TQString& name,
432 const KisCompositeOp& compositeOp) : super(i18n(
"Layer Property Changes"))
439 m_compositeOp = compositeOp;
442 virtual ~LayerPropsCmd()
447 virtual void execute()
449 TQString name = m_layer->name();
450 TQ_INT32 opacity = m_layer->opacity();
451 KisCompositeOp compositeOp = m_layer->compositeOp();
453 m_adapter->setUndo(
false);
454 m_img->setLayerProperties(m_layer,
458 m_adapter->setUndo(
true);
461 m_compositeOp = compositeOp;
465 virtual void unexecute()
471 KisUndoAdapter *m_adapter;
476 KisCompositeOp m_compositeOp;
481 class LockImageCommand :
public KNamedCommand {
482 typedef KNamedCommand super;
485 LockImageCommand(KisImageSP img,
bool lockImage) : super(
"lock image")
488 m_lockImage = lockImage;
491 virtual ~LockImageCommand()
495 virtual void execute()
504 virtual void unexecute()
519KisImage::KisImage(KisUndoAdapter *adapter, TQ_INT32 width, TQ_INT32 height, KisColorSpace * colorSpace,
const TQString& name)
520 : TQObject(0, name.latin1()), TDEShared()
522 init(adapter, width, height, colorSpace, name);
527KisImage::KisImage(
const KisImage& rhs) : TQObject(), TDEShared(rhs)
531 m_private =
new KisImagePrivate(*rhs.m_private);
532 m_private->perspectiveGrid =
new KisPerspectiveGrid(*rhs.m_private->perspectiveGrid);
535 m_width = rhs.m_width;
536 m_height = rhs.m_height;
540 m_colorSpace = rhs.m_colorSpace;
541 m_dirty = rhs.m_dirty;
542 m_adapter = rhs.m_adapter;
544 m_bkg =
new KisBackground();
547 m_rootLayer =
static_cast<KisGroupLayer*
>(rhs.m_rootLayer->clone().data());
548 connect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
550 m_annotations = rhs.m_annotations;
552 m_nserver =
new KisNameServer(i18n(
"Layer %1"), rhs.m_nserver->currentSeed() + 1);
553 TQ_CHECK_PTR(m_nserver);
558 m_rootLayer->setImage(
this);
560 if(rhs.activeLayer() != NULL) {
561 TQString layerName = rhs.activeLayer()->name();
563 KisLayerSP activeLayer = rootLayer()->findLayer(layerName);
564 Q_ASSERT(activeLayer);
565 activate(activeLayer);
574DCOPObject * KisImage::dcopObject()
577 m_dcop =
new KisImageIface(
this);
578 TQ_CHECK_PTR(m_dcop);
585 delete m_private->perspectiveGrid;
591TQString KisImage::name()
const
596void KisImage::setName(
const TQString& name)
602TQString KisImage::description()
const
604 return m_description;
607void KisImage::setDescription(
const TQString& description)
609 if (!description.isEmpty())
610 m_description = description;
614KisColor KisImage::backgroundColor()
const
616 return m_private->backgroundColor;
619void KisImage::setBackgroundColor(
const KisColor & color)
621 m_private->backgroundColor = color;
625TQString KisImage::nextLayerName()
const
627 if (m_nserver->currentSeed() == 0) {
629 return i18n(
"background");
632 return m_nserver->name();
635void KisImage::rollBackLayerName()
637 m_nserver->rollback();
640void KisImage::init(KisUndoAdapter *adapter, TQ_INT32 width, TQ_INT32 height,
KisColorSpace * colorSpace,
const TQString& name)
642 Q_ASSERT(colorSpace);
644 if (colorSpace == 0) {
645 colorSpace = KisMetaRegistry::instance()->csRegistry()->
getRGB8();
646 kdWarning(41010) <<
"No colorspace specified: using RGBA\n";
649 m_private =
new KisImagePrivate();
650 m_private->backgroundColor = KisColor(TQt::white, colorSpace);
651 m_private->lockCount = 0;
652 m_private->sizeChangedWhileLocked =
false;
653 m_private->selectionChangedWhileLocked =
false;
654 m_private->substrate = 0;
655 m_private->perspectiveGrid =
new KisPerspectiveGrid();
659 m_nserver =
new KisNameServer(i18n(
"Layer %1"), 1);
662 m_colorSpace = colorSpace;
663 m_bkg =
new KisBackground();
665 m_rootLayer =
new KisGroupLayer(
this,
"root", OPACITY_OPAQUE);
666 connect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
670 m_unit = KoUnit::U_PT;
676bool KisImage::locked()
const
678 return m_private->lockCount != 0;
684 if (m_rootLayer) disconnect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
685 m_private->sizeChangedWhileLocked =
false;
686 m_private->selectionChangedWhileLocked =
false;
688 m_private->lockCount++;
691void KisImage::unlock()
696 m_private->lockCount--;
698 if (m_private->lockCount == 0) {
699 if (m_private->sizeChangedWhileLocked) {
701 emit sigSizeChanged(m_width, m_height);
703 if (m_rootLayer->dirty()) emit sigImageUpdated( m_rootLayer->dirtyRect() );
706 if (m_private->selectionChangedWhileLocked) {
707 emit sigActiveSelectionChanged(
this);
710 if (m_rootLayer) connect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
715void KisImage::emitSizeChanged()
718 emit sigSizeChanged(m_width, m_height);
720 m_private->sizeChangedWhileLocked =
true;
724void KisImage::notifyLayerUpdated(KisLayerSP layer, TQRect rc)
726 emit sigLayerUpdated(layer, rc);
729void KisImage::resize(TQ_INT32 w, TQ_INT32 h, TQ_INT32 x, TQ_INT32 y,
bool cropLayers)
731 if (w != width() || h != height()) {
737 m_adapter->beginMacro(i18n(
"Crop Image"));
739 m_adapter->beginMacro(i18n(
"Resize Image"));
741 m_adapter->addCommand(
new LockImageCommand(
this,
true));
742 m_adapter->addCommand(
new KisResizeImageCmd(m_adapter,
this, w, h, width(), height()));
749 KisCropVisitor v(TQRect(x, y, w, h));
750 m_rootLayer->accept(v);
758 m_adapter->addCommand(
new LockImageCommand(
this,
false));
759 m_adapter->endMacro();
764void KisImage::resize(
const TQRect& rc,
bool cropLayers)
766 resize(rc.width(), rc.height(), rc.x(), rc.y(), cropLayers);
770void KisImage::scale(
double sx,
double sy, KisProgressDisplayInterface *progress, KisFilterStrategy *filterStrategy)
772 if (nlayers() == 0)
return;
776 w = (TQ_INT32)(( width() * sx) + 0.5);
777 h = (TQ_INT32)(( height() * sy) + 0.5);
779 if (w != width() || h != height()) {
784 m_adapter->beginMacro(i18n(
"Scale Image"));
785 m_adapter->addCommand(
new LockImageCommand(
this,
true));
788 if ( colorSpace()->
id() == KisID(
"RGBA") || colorSpace()->
id() == KisID(
"CMYK") || colorSpace()->
id() == KisID(
"GRAYA")) {
789 KisScaleVisitor v (
this, sx, sy, progress, filterStrategy);
790 m_rootLayer->accept( v );
794 KisTransformVisitor visitor (
this, sx, sy, 0.0, 0.0, 0.0, 0, 0, progress, filterStrategy);
795 m_rootLayer->accept(visitor);
799 m_adapter->addCommand(
new KisResizeImageCmd(m_adapter,
this, w, h, width(), height()));
810 m_adapter->addCommand(
new LockImageCommand(
this,
false));
811 m_adapter->endMacro();
818void KisImage::rotate(
double radians, KisProgressDisplayInterface *progress)
822 TQ_INT32 w = width();
823 TQ_INT32 h = height();
824 TQ_INT32 tx = TQ_INT32((w*cos(radians) - h*sin(radians) - w) / 2 + 0.5);
825 TQ_INT32 ty = TQ_INT32((h*cos(radians) + w*sin(radians) - h) / 2 + 0.5);
826 w = (TQ_INT32)(width()*TQABS(cos(radians)) + height()*TQABS(sin(radians)) + 0.5);
827 h = (TQ_INT32)(height()*TQABS(cos(radians)) + width()*TQABS(sin(radians)) + 0.5);
829 tx -= (w - width()) / 2;
830 ty -= (h - height()) / 2;
833 m_adapter->beginMacro(i18n(
"Rotate Image"));
834 m_adapter->addCommand(
new LockImageCommand(
this,
true));
837 KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->
get(KisID(
"Triangle"));
838 KisTransformVisitor visitor (
this, 1.0, 1.0, 0, 0, radians, -tx, -ty, progress, filter);
839 m_rootLayer->accept(visitor);
841 if (undo()) m_adapter->addCommand(
new KisResizeImageCmd(undoAdapter(),
this, w, h, width(), height()));
851 m_adapter->addCommand(
new LockImageCommand(
this,
false));
852 m_adapter->endMacro();
856void KisImage::shear(
double angleX,
double angleY, KisProgressDisplayInterface *m_progress)
858 const double pi=3.1415926535897932385;
865 if(angleX != 0 || angleY != 0){
866 double deltaY=height()*TQABS(tan(angleX*pi/180)*tan(angleY*pi/180));
867 w = (TQ_INT32) ( width() + TQABS(height()*tan(angleX*pi/180)) );
870 if (angleX == 0 || angleY == 0)
871 h = (TQ_INT32) ( height() + TQABS(w*tan(angleY*pi/180)) );
872 else if (angleX > 0 && angleY > 0)
873 h = (TQ_INT32) ( height() + TQABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
874 else if (angleX < 0 && angleY < 0)
875 h = (TQ_INT32) ( height() + TQABS(w*tan(angleY*pi/180))- 2 * deltaY + 2 );
877 h = (TQ_INT32) ( height() + TQABS(w*tan(angleY*pi/180)) );
880 if (w != width() || h != height()) {
885 m_adapter->beginMacro(i18n(
"Shear Image"));
886 m_adapter->addCommand(
new LockImageCommand(
this,
true));
889 KisShearVisitor v(angleX, angleY, m_progress);
890 v.setUndoAdapter(undoAdapter());
891 rootLayer()->accept(v);
893 if (undo()) m_adapter->addCommand(
new KisResizeImageCmd(m_adapter,
this, w, h, width(), height()));
903 m_adapter->addCommand(
new LockImageCommand(
this,
false));
904 m_adapter->endMacro();
909void KisImage::convertTo(KisColorSpace * dstColorSpace, TQ_INT32 renderingIntent)
911 if ( m_colorSpace == dstColorSpace )
918 KisColorSpace * oldCs = m_colorSpace;
921 m_adapter->beginMacro(i18n(
"Convert Image Type"));
922 m_adapter->addCommand(
new LockImageCommand(
this,
true));
925 setColorSpace(dstColorSpace);
927 KisColorSpaceConvertVisitor visitor(dstColorSpace, renderingIntent);
928 m_rootLayer->accept(visitor);
932 emit sigLayerPropertiesChanged( m_activeLayer );
936 m_adapter->addCommand(
new KisConvertImageTypeCmd(undoAdapter(),
this,
937 oldCs, dstColorSpace));
938 m_adapter->addCommand(
new LockImageCommand(
this,
false));
939 m_adapter->endMacro();
943KisProfile * KisImage::getProfile()
const
945 return colorSpace()->getProfile();
948void KisImage::setProfile(
const KisProfile * profile)
950 if (profile == 0)
return;
952 KisColorSpace * dstCs= KisMetaRegistry::instance()->csRegistry()->
getColorSpace( colorSpace()->
id(),
958 KisColorSpace * oldCs = colorSpace();
959 setColorSpace(dstCs);
960 emit(sigProfileChanged(
const_cast<KisProfile *
>(profile)));
962 KisChangeProfileVisitor visitor(oldCs, dstCs);
963 m_rootLayer->accept(visitor);
969double KisImage::xRes()
974double KisImage::yRes()
979void KisImage::setResolution(
double xres,
double yres)
985TQ_INT32 KisImage::width()
const
990TQ_INT32 KisImage::height()
const
995KisPaintDeviceSP KisImage::activeDevice()
997 if (KisPaintLayer* layer =
dynamic_cast<KisPaintLayer*
>(m_activeLayer.data())) {
998 return layer->paintDeviceOrMask();
1000 else if (KisAdjustmentLayer* layer =
dynamic_cast<KisAdjustmentLayer*
>(m_activeLayer.data())) {
1001 if (layer->selection()) {
1002 return layer->selection().data();
1005 else if (KisGroupLayer * layer =
dynamic_cast<KisGroupLayer*
>(m_activeLayer.data())) {
1007 KisLayerSP child = layer->lastChild();
1010 if (KisPaintLayer* layer =
dynamic_cast<KisPaintLayer*
>(child.data())) {
1011 return layer->paintDevice();
1013 child = child->prevSibling();
1015 KisLayerSP sibling = layer->nextSibling();
1017 if (KisPaintLayer* layer =
dynamic_cast<KisPaintLayer*
>(sibling.data())) {
1018 return layer->paintDevice();
1020 sibling = sibling->nextSibling();
1023 else if (KisLayerSP layer = m_activeLayer) {
1025 KisLayerSP sibling = layer->nextSibling();
1027 if (KisPaintLayer* layer =
dynamic_cast<KisPaintLayer*
>(sibling.data())) {
1028 return layer->paintDevice();
1030 sibling = sibling->nextSibling();
1037KisLayerSP KisImage::newLayer(
const TQString& name, TQ_UINT8 opacity,
const KisCompositeOp& compositeOp, KisColorSpace * colorstrategy)
1039 KisPaintLayer * layer;
1041 layer =
new KisPaintLayer(
this, name, opacity, colorstrategy);
1043 layer =
new KisPaintLayer(
this, name, opacity);
1044 TQ_CHECK_PTR(layer);
1046 if (compositeOp.isValid())
1047 layer->setCompositeOp(compositeOp);
1048 layer->setVisible(
true);
1050 if (m_activeLayer != 0) {
1051 addLayer(layer, m_activeLayer->parent().data(), m_activeLayer->nextSibling());
1054 addLayer(layer, m_rootLayer, 0);
1061void KisImage::setLayerProperties(KisLayerSP layer, TQ_UINT8 opacity,
const KisCompositeOp& compositeOp,
const TQString& name)
1063 if (layer && (layer->opacity() != opacity || layer->compositeOp() != compositeOp || layer->name() != name)) {
1065 TQString oldname = layer->name();
1066 TQ_INT32 oldopacity = layer->opacity();
1067 KisCompositeOp oldCompositeOp = layer->compositeOp();
1068 layer->setName(name);
1069 layer->setOpacity(opacity);
1070 layer->setCompositeOp(compositeOp);
1071 m_adapter->addCommand(
new LayerPropsCmd(layer,
this, m_adapter, oldname, oldopacity, oldCompositeOp));
1073 layer->setName(name);
1074 layer->setOpacity(opacity);
1075 layer->setCompositeOp(compositeOp);
1080KisGroupLayerSP KisImage::rootLayer()
const
1085KisLayerSP KisImage::activeLayer()
const
1087 return m_activeLayer;
1090KisPaintDeviceSP KisImage::projection()
1092 return m_rootLayer->projection(TQRect(0, 0, m_width, m_height));
1095KisLayerSP KisImage::activate(KisLayerSP layer)
1097 if (layer != m_activeLayer) {
1098 if (m_activeLayer) m_activeLayer->deactivate();
1099 m_activeLayer = layer;
1100 if (m_activeLayer) m_activeLayer->activate();
1101 emit sigLayerActivated(m_activeLayer);
1102 emit sigMaskInfoChanged();
1108KisLayerSP KisImage::findLayer(
const TQString& name)
const
1110 return rootLayer()->findLayer(name);
1113KisLayerSP KisImage::findLayer(
int id)
const
1115 return rootLayer()->findLayer(
id);
1119bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent)
1121 return addLayer(layer, parent, parent->firstChild());
1124bool KisImage::addLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
1129 const bool success = parent->addLayer(layer, aboveThis);
1132 KisPaintLayerSP player =
dynamic_cast<KisPaintLayer*
>(layer.data());
1136 TQValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() ->
1137 csRegistry()->paintDeviceActionsFor(player->paintDevice()->colorSpace());
1138 for (uint i = 0; i < actions.count(); i++) {
1139 actions.at(i)->act(player.data()->paintDevice(), width(), height());
1142 connect(player, TQ_SIGNAL(sigMaskInfoChanged()),
this, TQ_SIGNAL(sigMaskInfoChanged()));
1145 if (layer->extent().isValid()) layer->setDirty();
1147 if (!layer->temporary()) {
1148 emit sigLayerAdded(layer);
1153 if (!layer->temporary() && undo()) {
1154 m_adapter->addCommand(
new LayerAddCmd(m_adapter,
this, layer));
1161bool KisImage::removeLayer(KisLayerSP layer)
1163 if (!layer || layer->image() !=
this)
1166 if (KisGroupLayerSP parent = layer->parent()) {
1169 KisAdjustmentLayer * al =
dynamic_cast<KisAdjustmentLayer*
>(layer.data());
1173 KisLayerSP l = layer->nextSibling();
1175 KisAdjustmentLayer * al2 =
dynamic_cast<KisAdjustmentLayer*
>(l.data());
1176 l->setDirty(r,
false);
1177 if (al2 != 0)
break;
1178 l = l->nextSibling();
1182 KisPaintLayerSP player =
dynamic_cast<KisPaintLayer*
>(layer.data());
1184 disconnect(player, TQ_SIGNAL(sigMaskInfoChanged()),
1185 this, TQ_SIGNAL(sigMaskInfoChanged()));
1187 KisLayerSP l = layer->prevSibling();
1188 TQRect r = layer->extent();
1190 l->setDirty(r,
false);
1191 l = l->prevSibling();
1194 KisLayerSP wasAbove = layer->nextSibling();
1195 KisLayerSP wasBelow = layer->prevSibling();
1196 const bool wasActive = layer == activeLayer();
1198 KisLayerSP actLayer = activeLayer();
1199 const bool success = parent->removeLayer(layer);
1202 if (!layer->temporary() && undo()) {
1203 m_adapter->addCommand(
new LayerRmCmd(m_adapter,
this, layer, parent, wasAbove));
1205 if (!layer->temporary()) {
1206 emit sigLayerRemoved(layer, parent, wasAbove);
1212 else if (parent != rootLayer())
1213 activate(parent.data());
1215 activate(rootLayer()->firstChild());
1227bool KisImage::raiseLayer(KisLayerSP layer)
1231 return moveLayer(layer, layer->parent().data(), layer->prevSibling());
1234bool KisImage::lowerLayer(KisLayerSP layer)
1238 if (KisLayerSP next = layer->nextSibling())
1239 return moveLayer(layer, layer->parent().data(), next->nextSibling());
1243bool KisImage::toTop(KisLayerSP layer)
1247 return moveLayer(layer, rootLayer(), rootLayer()->firstChild());
1250bool KisImage::toBottom(KisLayerSP layer)
1254 return moveLayer(layer, rootLayer(), 0);
1257bool KisImage::moveLayer(KisLayerSP layer, KisGroupLayerSP parent, KisLayerSP aboveThis)
1262 KisGroupLayerSP wasParent = layer->parent();
1263 KisLayerSP wasAbove = layer->nextSibling();
1265 if (wasParent.data() == parent.data() && wasAbove.data() == aboveThis.data())
1270 if (!wasParent->removeLayer(layer)) {
1275 const bool success = parent->addLayer(layer, aboveThis);
1283 emit sigLayerMoved(layer, wasParent, wasAbove);
1285 m_adapter->addCommand(
new LayerMoveCmd(m_adapter,
this, layer, wasParent, wasAbove));
1289 emit sigLayerRemoved(layer, wasParent, wasAbove);
1291 m_adapter->addCommand(
new LayerRmCmd(m_adapter,
this, layer, wasParent, wasAbove));
1297TQ_INT32 KisImage::nlayers()
const
1299 return rootLayer()->numLayers() - 1;
1302TQ_INT32 KisImage::nHiddenLayers()
const
1304 return rootLayer()->numLayers(KisLayer::Hidden);
1307void KisImage::flatten()
1309 KisGroupLayerSP oldRootLayer = m_rootLayer;
1310 disconnect(oldRootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
1312 KisPaintLayer *dst =
new KisPaintLayer(
this, nextLayerName(), OPACITY_OPAQUE, colorSpace());
1315 TQRect rc = mergedImage()->extent();
1317 KisPainter gc(dst->paintDevice());
1318 gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, mergedImage(), OPACITY_OPAQUE, rc.left(), rc.top(), rc.width(), rc.height());
1320 m_rootLayer =
new KisGroupLayer(
this,
"", OPACITY_OPAQUE);
1321 connect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
1324 m_adapter->beginMacro(i18n(
"Flatten Image"));
1325 m_adapter->addCommand(
new LockImageCommand(
this,
true));
1326 m_adapter->addCommand(
new KisChangeLayersCmd(m_adapter,
this, oldRootLayer, m_rootLayer,
""));
1331 addLayer(dst, m_rootLayer, 0);
1336 notifyLayersChanged();
1339 m_adapter->addCommand(
new LockImageCommand(
this,
false));
1340 m_adapter->endMacro();
1345void KisImage::mergeLayer(KisLayerSP layer)
1347 KisPaintLayer *player =
new KisPaintLayer(
this, layer->name(), OPACITY_OPAQUE, colorSpace());
1348 TQ_CHECK_PTR(player);
1350 TQRect rc = layer->extent() | layer->nextSibling()->extent();
1352 undoAdapter()->beginMacro(i18n(
"Merge with Layer Below"));
1355 KisMergeVisitor visitor(player->paintDevice(), rc);
1356 layer->nextSibling()->accept(visitor);
1357 layer->accept(visitor);
1359 removeLayer(layer->nextSibling());
1360 addLayer(player, layer->parent(), layer);
1363 undoAdapter()->endMacro();
1367void KisImage::setModified()
1369 emit sigImageModified();
1372void KisImage::renderToPainter(TQ_INT32 x1,
1377 KisProfile * monitorProfile,
1378 PaintFlags paintFlags,
1382 TQImage img = convertToTQImage(x1, y1, x2, y2, monitorProfile, exposure);
1384 TQ_INT32 w = x2 - x1 + 1;
1385 TQ_INT32 h = y2 - y1 + 1;
1388 if (paintFlags & PAINT_BACKGROUND) {
1389 m_bkg->paintBackground(img, x1, y1);
1390 img.setAlphaBuffer(
false);
1393 if (paintFlags & PAINT_SELECTION) {
1394 if (m_activeLayer != 0) {
1395 m_activeLayer->paintSelection(img, x1, y1, w, h);
1399 if (paintFlags & PAINT_MASKINACTIVELAYERS) {
1400 if (m_activeLayer != 0) {
1401 m_activeLayer->paintMaskInactiveLayers(img, x1, y1, w, h);
1405 painter.drawImage(x1, y1, img, 0, 0, w, h);
1408TQImage KisImage::convertToTQImage(TQ_INT32 x1,
1412 KisProfile * profile,
1415 TQ_INT32 w = x2 - x1 + 1;
1416 TQ_INT32 h = y2 - y1 + 1;
1418 KisPaintDeviceSP dev = m_rootLayer->projection(TQRect(x1, y1, w, h));
1419 TQImage img = dev->convertToTQImage(profile, x1, y1, w, h, exposure);
1421 if (!img.isNull()) {
1423#ifdef __BIG_ENDIAN__
1424 uchar * data = img.bits();
1425 for (
int i = 0; i < w * h; ++i) {
1445TQImage KisImage::convertToTQImage(
const TQRect& r,
const TQSize& scaledImageSize, KisProfile *profile, PaintFlags paintFlags,
float exposure)
1448 if (r.isEmpty() || scaledImageSize.isEmpty()) {
1452 TQ_INT32 imageWidth = width();
1453 TQ_INT32 imageHeight = height();
1454 TQ_UINT32 pixelSize = colorSpace()->pixelSize();
1456 double xScale =
static_cast<double>(imageWidth) / scaledImageSize.width();
1457 double yScale =
static_cast<double>(imageHeight) / scaledImageSize.height();
1461 srcRect.setLeft(
static_cast<int>(r.left() * xScale));
1462 srcRect.setRight(
static_cast<int>(ceil((r.right() + 1) * xScale)) - 1);
1463 srcRect.setTop(
static_cast<int>(r.top() * yScale));
1464 srcRect.setBottom(
static_cast<int>(ceil((r.bottom() + 1) * yScale)) - 1);
1466 KisPaintDeviceSP mergedImage = m_rootLayer->projection(srcRect);
1470 TQ_UINT8 *scaledImageData =
new TQ_UINT8[r.width() * r.height() * pixelSize];
1472 TQ_UINT8 *imageRow =
new TQ_UINT8[srcRect.width() * pixelSize];
1473 const TQ_INT32 imageRowX = srcRect.x();
1475 for (TQ_INT32 y = 0; y < r.height(); ++y) {
1477 TQ_INT32 dstY = r.y() + y;
1478 TQ_INT32 dstX = r.x();
1479 TQ_INT32 srcY = (dstY * imageHeight) / scaledImageSize.height();
1481 mergedImage->readBytes(imageRow, imageRowX, srcY, srcRect.width(), 1);
1483 TQ_UINT8 *dstPixel = scaledImageData + (y * r.width() * pixelSize);
1484 TQ_UINT32 columnsRemaining = r.width();
1486 while (columnsRemaining > 0) {
1488 TQ_INT32 srcX = (dstX * imageWidth) / scaledImageSize.width();
1490 memcpy(dstPixel, imageRow + ((srcX - imageRowX) * pixelSize), pixelSize);
1493 dstPixel += pixelSize;
1497 kdDebug() <<
"Time elapsed scaling image: " << t.elapsed() << endl;
1501 TQImage image = colorSpace()->convertToTQImage(scaledImageData, r.width(), r.height(), profile, INTENT_PERCEPTUAL, exposure);
1502 delete [] scaledImageData;
1504#ifdef __BIG_ENDIAN__
1505 uchar * data = image.bits();
1506 for (
int i = 0; i < image.width() * image.height(); ++i) {
1520 if (paintFlags & PAINT_BACKGROUND) {
1521 m_bkg->paintBackground(image, r, scaledImageSize, TQSize(imageWidth, imageHeight));
1522 image.setAlphaBuffer(
false);
1525 if (paintFlags & PAINT_SELECTION) {
1526 if (m_activeLayer != 0) {
1527 m_activeLayer->paintSelection(image, r, scaledImageSize, TQSize(imageWidth, imageHeight));
1540KisPaintDeviceSP KisImage::mergedImage()
1542 return m_rootLayer->projection(TQRect(0, 0, m_width, m_height));
1545KisColor KisImage::mergedPixel(TQ_INT32 x, TQ_INT32 y)
1547 return m_rootLayer->projection(TQRect(x, y, 1, 1))->colorAt(x, y);
1550void KisImage::notifyLayersChanged()
1552 emit sigLayersChanged(rootLayer());
1555void KisImage::notifyPropertyChanged(KisLayerSP layer)
1557 emit sigLayerPropertiesChanged(layer);
1560void KisImage::notifyImageLoaded()
1564TQRect KisImage::bounds()
const
1566 return TQRect(0, 0, width(), height());
1570void KisImage::setUndoAdapter(KisUndoAdapter * adapter)
1572 m_adapter = adapter;
1576KisUndoAdapter* KisImage::undoAdapter()
const
1581bool KisImage::undo()
const
1583 return (m_adapter && m_adapter->undo());
1591void KisImage::slotSelectionChanged()
1593 slotSelectionChanged(bounds());
1596void KisImage::slotSelectionChanged(
const TQRect& r)
1598 TQRect r2(r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2);
1601 emit sigActiveSelectionChanged(
this);
1602 emit sigSelectionChanged(
this);
1604 m_private->selectionChangedWhileLocked =
true;
1608KisColorSpace * KisImage::colorSpace()
const
1610 return m_colorSpace;
1613void KisImage::setColorSpace(KisColorSpace * colorSpace)
1615 m_colorSpace = colorSpace;
1616 m_rootLayer->resetProjection();
1617 emit sigColorSpaceChanged(colorSpace);
1620void KisImage::setRootLayer(KisGroupLayerSP rootLayer)
1622 disconnect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
1624 m_rootLayer = rootLayer;
1627 connect(m_rootLayer, TQ_SIGNAL(sigDirty(TQRect)),
this, TQ_SIGNAL(sigImageUpdated(TQRect)));
1629 activate(m_rootLayer->firstChild());
1632void KisImage::addAnnotation(KisAnnotationSP annotation)
1635 vKisAnnotationSP_it it = m_annotations.begin();
1636 while (it != m_annotations.end()) {
1637 if ((*it)->type() == annotation->type()) {
1643 m_annotations.push_back(annotation);
1646KisAnnotationSP KisImage::annotation(TQString type)
1648 vKisAnnotationSP_it it = m_annotations.begin();
1649 while (it != m_annotations.end()) {
1650 if ((*it)->type() == type) {
1658void KisImage::removeAnnotation(TQString type)
1660 vKisAnnotationSP_it it = m_annotations.begin();
1661 while (it != m_annotations.end()) {
1662 if ((*it)->type() == type) {
1663 m_annotations.erase(it);
1670vKisAnnotationSP_it KisImage::beginAnnotations()
1672 KisProfile * profile = colorSpace()->getProfile();
1673 KisAnnotationSP annotation;
1676 annotation = profile->annotation();
1679 addAnnotation(annotation);
1681 removeAnnotation(
"icc");
1683 return m_annotations.begin();
1686vKisAnnotationSP_it KisImage::endAnnotations()
1688 return m_annotations.end();
1691KisBackgroundSP KisImage::background()
const
1696KisPerspectiveGrid* KisImage::perspectiveGrid()
1698 return m_private->perspectiveGrid;
1701#include "kis_image.moc"
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
KisColorSpace * getRGB8()
Convenience method to get an RGB colorspace with the default lcms profile.
KisColorSpace * getColorSpace(const KisID &csID, const TQString &profileName)
Return the colorspace + profile as named, or NULL if impossible combination.
A colorspace is the definition of a certain color model in Chalk.
A KisColor describes a color in a certain colorspace.
_T get(const KisID &name) const
This function allow to get an object from its KisID.
A KisLayer that bundles child layers into a single layer.