KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kis_group_layer.cc 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /*
  2. * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
  3. *
  4. * this program is free software; you can redistribute it and/or modify
  5. * it under the terms of the gnu general public license as published by
  6. * the free software foundation; either version 2 of the license, or
  7. * (at your option) any later version.
  8. *
  9. * this program is distributed in the hope that it will be useful,
  10. * but without any warranty; without even the implied warranty of
  11. * merchantability or fitness for a particular purpose. see the
  12. * gnu general public license for more details.
  13. *
  14. * you should have received a copy of the gnu general public license
  15. * along with this program; if not, write to the free software
  16. * foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
  17. */
  18. #include <kdebug.h>
  19. #include <tdeglobal.h>
  20. #include <tqimage.h>
  21. #include <tqdatetime.h>
  22. #include "kis_types.h"
  23. #include "kis_layer.h"
  24. #include "kis_group_layer.h"
  25. #include "kis_layer_visitor.h"
  26. #include "kis_debug_areas.h"
  27. #include "kis_image.h"
  28. #include "kis_paint_device.h"
  29. #include "kis_merge_visitor.h"
  30. #include "kis_fill_painter.h"
  31. KisGroupLayer::KisGroupLayer(KisImage *img, const TQString &name, TQ_UINT8 opacity) :
  32. super(img, name, opacity),
  33. m_x(0),
  34. m_y(0)
  35. {
  36. m_projection = new KisPaintDevice(this, img->colorSpace(), name.latin1());
  37. }
  38. KisGroupLayer::KisGroupLayer(const KisGroupLayer &rhs) :
  39. super(rhs),
  40. m_x(rhs.m_x),
  41. m_y(rhs.m_y)
  42. {
  43. for(vKisLayerSP_cit it = rhs.m_layers.begin(); it != rhs.m_layers.end(); ++it)
  44. {
  45. this->addLayer(it->data()->clone(), 0);
  46. }
  47. m_projection = new KisPaintDevice(*rhs.m_projection.data());
  48. m_projection->setParentLayer(this);
  49. }
  50. KisLayerSP KisGroupLayer::clone() const
  51. {
  52. return new KisGroupLayer(*this);
  53. }
  54. KisGroupLayer::~KisGroupLayer()
  55. {
  56. m_layers.clear();
  57. }
  58. void KisGroupLayer::setDirty(bool propagate)
  59. {
  60. KisLayer::setDirty(propagate);
  61. if (propagate) emit (sigDirty(m_dirtyRect));
  62. }
  63. void KisGroupLayer::setDirty(const TQRect & rc, bool propagate)
  64. {
  65. KisLayer::setDirty(rc, propagate);
  66. if (propagate) emit sigDirty(rc);
  67. }
  68. void KisGroupLayer::resetProjection(KisPaintDevice* to)
  69. {
  70. if (to)
  71. m_projection = new KisPaintDevice(*to); /// XXX ### look into Copy on Write here (CoW)
  72. else
  73. m_projection = new KisPaintDevice(this, image()->colorSpace(), name().latin1());
  74. }
  75. bool KisGroupLayer::paintLayerInducesProjectionOptimization(KisPaintLayer* l) {
  76. return l && l->paintDevice()->colorSpace() == m_image->colorSpace() && l->visible()
  77. && l->opacity() == OPACITY_OPAQUE && !l->temporaryTarget() && !l->hasMask();
  78. }
  79. KisPaintDeviceSP KisGroupLayer::projection(const TQRect & rect)
  80. {
  81. // We don't have a parent, and we've got only one child: abuse the child's
  82. // paint device as the projection if the child is visible and 100% opaque
  83. if (parent() == 0 && childCount() == 1) {
  84. KisPaintLayerSP l = dynamic_cast<KisPaintLayer*>(firstChild().data());
  85. if (paintLayerInducesProjectionOptimization(l)) {
  86. l->setClean(rect);
  87. setClean(rect);
  88. return l->paintDevice();
  89. }
  90. }
  91. // No need for updates, we're clean
  92. if (!dirty()) {
  93. return m_projection;
  94. }
  95. // No need for updates -- the desired area wasn't dirty
  96. if (!rect.intersects(m_dirtyRect)) {
  97. return m_projection;
  98. }
  99. // Okay, we need to update the intersection between
  100. // what's dirty and what's asked us to be updated.
  101. // XXX Nooo, that doesn't work, since the call to setClean following this, is actually:
  102. // m_dirtyRect = TQRect(); So the non-intersecting part gets brilliantly lost otherwise.
  103. const TQRect rc = m_dirtyRect;//rect.intersect(m_dirtyRect);
  104. updateProjection(rc);
  105. setClean(rect);
  106. return m_projection;
  107. }
  108. uint KisGroupLayer::childCount() const
  109. {
  110. return m_layers.count();
  111. }
  112. KisLayerSP KisGroupLayer::firstChild() const
  113. {
  114. return at(0);
  115. }
  116. KisLayerSP KisGroupLayer::lastChild() const
  117. {
  118. return at(childCount() - 1);
  119. }
  120. KisLayerSP KisGroupLayer::at(int index) const
  121. {
  122. if (childCount() && index >= 0 && kClamp(uint(index), uint(0), childCount() - 1) == uint(index))
  123. return m_layers.at(reverseIndex(index));
  124. return 0;
  125. }
  126. int KisGroupLayer::index(KisLayerSP layer) const
  127. {
  128. if (layer->parent().data() == this)
  129. return layer->index();
  130. return -1;
  131. }
  132. void KisGroupLayer::setIndex(KisLayerSP layer, int index)
  133. {
  134. if (layer->parent().data() != this)
  135. return;
  136. //TODO optimize
  137. removeLayer(layer);
  138. addLayer(layer, index);
  139. }
  140. bool KisGroupLayer::addLayer(KisLayerSP newLayer, int x)
  141. {
  142. if (x < 0 || kClamp(uint(x), uint(0), childCount()) != uint(x) ||
  143. newLayer->parent() || m_layers.contains(newLayer))
  144. {
  145. kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, int x)!" << endl;
  146. return false;
  147. }
  148. uint index(x);
  149. if (index == 0)
  150. m_layers.append(newLayer);
  151. else
  152. m_layers.insert(m_layers.begin() + reverseIndex(index) + 1, newLayer);
  153. for (uint i = childCount() - 1; i > index; i--)
  154. at(i)->m_index++;
  155. newLayer->m_parent = this;
  156. newLayer->m_index = index;
  157. newLayer->setImage(image());
  158. newLayer->setDirty(newLayer->extent());
  159. setDirty();
  160. return true;
  161. }
  162. bool KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)
  163. {
  164. if (aboveThis && aboveThis->parent().data() != this)
  165. {
  166. kdWarning() << "invalid input to KisGroupLayer::addLayer(KisLayerSP newLayer, KisLayerSP aboveThis)!" << endl;
  167. return false;
  168. }
  169. return addLayer(newLayer, aboveThis ? aboveThis->index() : childCount());
  170. }
  171. bool KisGroupLayer::removeLayer(int x)
  172. {
  173. if (x >= 0 && kClamp(uint(x), uint(0), childCount() - 1) == uint(x))
  174. {
  175. uint index(x);
  176. for (uint i = childCount() - 1; i > index; i--)
  177. at(i)->m_index--;
  178. KisLayerSP removedLayer = at(index);
  179. removedLayer->m_parent = 0;
  180. removedLayer->m_index = -1;
  181. m_layers.erase(m_layers.begin() + reverseIndex(index));
  182. setDirty(removedLayer->extent());
  183. if (childCount() < 1) {
  184. // No children, nothing to show for it.
  185. m_projection->clear();
  186. setDirty();
  187. }
  188. return true;
  189. }
  190. kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
  191. return false;
  192. }
  193. bool KisGroupLayer::removeLayer(KisLayerSP layer)
  194. {
  195. if (layer->parent().data() != this)
  196. {
  197. kdWarning() << "invalid input to KisGroupLayer::removeLayer()!" << endl;
  198. return false;
  199. }
  200. return removeLayer(layer->index());
  201. }
  202. void KisGroupLayer::setImage(KisImage *image)
  203. {
  204. super::setImage(image);
  205. for (vKisLayerSP_it it = m_layers.begin(); it != m_layers.end(); ++it)
  206. {
  207. (*it)->setImage(image);
  208. }
  209. }
  210. TQRect KisGroupLayer::extent() const
  211. {
  212. TQRect groupExtent;
  213. for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
  214. {
  215. groupExtent |= (*it)->extent();
  216. }
  217. return groupExtent;
  218. }
  219. TQRect KisGroupLayer::exactBounds() const
  220. {
  221. TQRect groupExactBounds;
  222. for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
  223. {
  224. groupExactBounds |= (*it)->exactBounds();
  225. }
  226. return groupExactBounds;
  227. }
  228. TQ_INT32 KisGroupLayer::x() const
  229. {
  230. return m_x;
  231. }
  232. void KisGroupLayer::setX(TQ_INT32 x)
  233. {
  234. TQ_INT32 delta = x - m_x;
  235. for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
  236. {
  237. KisLayerSP layer = *it;
  238. layer->setX(layer->x() + delta);
  239. }
  240. m_x = x;
  241. }
  242. TQ_INT32 KisGroupLayer::y() const
  243. {
  244. return m_y;
  245. }
  246. void KisGroupLayer::setY(TQ_INT32 y)
  247. {
  248. TQ_INT32 delta = y - m_y;
  249. for (vKisLayerSP_cit it = m_layers.begin(); it != m_layers.end(); ++it)
  250. {
  251. KisLayerSP layer = *it;
  252. layer->setY(layer->y() + delta);
  253. }
  254. m_y = y;
  255. }
  256. TQImage KisGroupLayer::createThumbnail(TQ_INT32 w, TQ_INT32 h)
  257. {
  258. return m_projection->createThumbnail(w, h);
  259. }
  260. void KisGroupLayer::updateProjection(const TQRect & rc)
  261. {
  262. if (!m_dirtyRect.isValid()) return;
  263. // Get the first layer in this group to start compositing with
  264. KisLayerSP child = lastChild();
  265. // No child -- clear the projection. Without children, a group layer is empty.
  266. if (!child) m_projection->clear();
  267. KisLayerSP startWith = 0;
  268. KisAdjustmentLayerSP adjLayer = 0;
  269. KisLayerSP tmpPaintLayer = 0;
  270. // If this is the rootlayer, don't do anything with adj. layers that are below the
  271. // first paintlayer
  272. bool gotPaintLayer = (parent() != 0);
  273. // Look through all the child layers, searching for the first dirty layer
  274. // if it's found, and if we have found an adj. layer before the the dirty layer,
  275. // composite from the first adjustment layer searching back from the first dirty layer
  276. while (child) {
  277. KisAdjustmentLayerSP tmpAdjLayer = dynamic_cast<KisAdjustmentLayer*>(child.data());
  278. if (tmpAdjLayer) {
  279. if (gotPaintLayer) {
  280. // If this adjustment layer is dirty, start compositing with the
  281. // previous layer, if there's one.
  282. if (tmpAdjLayer->dirty(rc) && adjLayer != 0 && adjLayer->visible()) {
  283. startWith = adjLayer->prevSibling();
  284. break;
  285. }
  286. else if (tmpAdjLayer->visible() && !tmpAdjLayer->dirty(rc)) {
  287. // This is the first adj. layer that is not dirty -- the perfect starting point
  288. adjLayer = tmpAdjLayer;
  289. }
  290. else {
  291. startWith = tmpPaintLayer;
  292. }
  293. }
  294. }
  295. else {
  296. tmpPaintLayer = child;
  297. gotPaintLayer = true;
  298. // A non-adjustmentlayer that's dirty; if there's an adjustmentlayer
  299. // with a cache, we'll start from there.
  300. if (child->dirty(rc)) {
  301. if (adjLayer != 0 && adjLayer->visible()) {
  302. // the first layer on top of the adj. layer
  303. startWith = adjLayer->prevSibling();
  304. }
  305. else {
  306. startWith = child;
  307. }
  308. // break here: if there's no adj layer, we'll start with the layer->lastChild
  309. break;
  310. }
  311. }
  312. child = child->prevSibling();
  313. }
  314. if (adjLayer != 0 && startWith == 0 && gotPaintLayer && adjLayer->prevSibling()) {
  315. startWith = adjLayer->prevSibling();
  316. }
  317. // No adj layer -- all layers inside the group must be recomposited
  318. if (adjLayer == 0) {
  319. startWith = lastChild();
  320. }
  321. if (startWith == 0) {
  322. return;
  323. }
  324. bool first = true; // The first layer in a stack needs special compositing
  325. // Fill the projection either with the cached data, or erase it.
  326. KisFillPainter gc(m_projection);
  327. if (adjLayer != 0) {
  328. gc.bitBlt(rc.left(), rc.top(),
  329. COMPOSITE_COPY, adjLayer->cachedPaintDevice(), OPACITY_OPAQUE,
  330. rc.left(), rc.top(), rc.width(), rc.height());
  331. first = false;
  332. }
  333. else {
  334. gc.eraseRect(rc);
  335. first = true;
  336. }
  337. gc.end();
  338. KisMergeVisitor visitor(m_projection, rc);
  339. child = startWith;
  340. while(child)
  341. {
  342. if(first)
  343. {
  344. // Copy the lowest layer rather than compositing it with the background
  345. // or an empty image. This means the layer's composite op is ignored,
  346. // which is consistent with Photoshop and gimp.
  347. const KisCompositeOp cop = child->compositeOp();
  348. const bool block = child->signalsBlocked();
  349. child->blockSignals(true);
  350. // Composite op copy doesn't take a mask/selection into account, so we need
  351. // to make a difference between a paintlayer with a mask, and one without
  352. KisPaintLayer* l = dynamic_cast<KisPaintLayer*>(child.data());
  353. if (l && l->hasMask())
  354. child->m_compositeOp = COMPOSITE_OVER;
  355. else
  356. child->m_compositeOp = COMPOSITE_COPY;
  357. child->blockSignals(block);
  358. child->accept(visitor);
  359. child->blockSignals(true);
  360. child->m_compositeOp = cop;
  361. child->blockSignals(block);
  362. first = false;
  363. }
  364. else
  365. child->accept(visitor);
  366. child = child->prevSibling();
  367. }
  368. }
  369. #include "kis_group_layer.moc"