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 {
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,
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;
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 )
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
948void KisImage::setProfile(
const KisProfile * profile)
950 if (profile == 0)
return;
959 setColorSpace(dstCs);
960 emit(sigProfileChanged(
const_cast<KisProfile *
>(profile)));
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()
998 return layer->paintDeviceOrMask();
1001 if (layer->selection()) {
1002 return layer->selection().data();
1007 KisLayerSP child = layer->lastChild();
1011 return layer->paintDevice();
1013 child = child->prevSibling();
1015 KisLayerSP sibling = layer->nextSibling();
1018 return layer->paintDevice();
1020 sibling = sibling->nextSibling();
1023 else if (KisLayerSP layer = m_activeLayer) {
1025 KisLayerSP sibling = layer->nextSibling();
1028 return layer->paintDevice();
1030 sibling = sibling->nextSibling();
1037KisLayerSP KisImage::newLayer(
const TQString& name, TQ_UINT8 opacity,
const KisCompositeOp& compositeOp,
KisColorSpace * colorstrategy)
1041 layer =
new KisPaintLayer(
this, name, opacity, colorstrategy);
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()) {
1173 KisLayerSP l = layer->nextSibling();
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)));
1315 TQRect rc = mergedImage()->extent();
1318 gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, mergedImage(), OPACITY_OPAQUE, rc.left(), rc.top(), rc.width(), rc.height());
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)
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;
1610 return m_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"
Class that contains a KisFilter and optionally a KisSelection.
virtual TQRect extent() const
Returns an approximation of where the bounds on actual data are in this layer.
The Change Profile visitor walks over all layers and if the current layer has the specified colorspac...
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.
virtual TQImage convertToTQImage(const TQ_UINT8 *data, TQ_INT32 width, TQ_INT32 height, KisProfile *dstProfile, TQ_INT32 renderingIntent=INTENT_PERCEPTUAL, float exposure=0.0f)=0
Convert the pixels in data to (8-bit BGRA) TQImage using the specified profiles.
virtual TQ_UINT32 pixelSize() const =0
The size in bytes of a single pixel in this color model.
virtual KisProfile * getProfile() const =0
Return the profile of this color space.
A KisColor describes a color in a certain colorspace.
A KisLayer that bundles child layers into a single layer.
Chalk has a large number of extensible resources.
virtual void setDirty(bool propagate=true)
Set the entire layer extent dirty; this percolates up to parent layers all the way to the root layer.
This layer is of a type that can be painted on.
KisPainter contains the graphics primitives necessary to draw on a KisPaintDevice.