1 // Aseprite Document Library
2 // Copyright (c) 2001-2018 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "doc/layer.h"
12 
13 #include "doc/cel.h"
14 #include "doc/image.h"
15 #include "doc/primitives.h"
16 #include "doc/sprite.h"
17 
18 #include <algorithm>
19 #include <cstring>
20 
21 namespace doc {
22 
Layer(ObjectType type,Sprite * sprite)23 Layer::Layer(ObjectType type, Sprite* sprite)
24   : WithUserData(type)
25   , m_sprite(sprite)
26   , m_parent(NULL)
27   , m_flags(LayerFlags(
28       int(LayerFlags::Visible) |
29       int(LayerFlags::Editable)))
30 {
31   ASSERT(type == ObjectType::LayerImage || type == ObjectType::LayerGroup);
32 
33   setName("Layer");
34 }
35 
~Layer()36 Layer::~Layer()
37 {
38 }
39 
getMemSize() const40 int Layer::getMemSize() const
41 {
42   return sizeof(Layer);
43 }
44 
getPrevious() const45 Layer* Layer::getPrevious() const
46 {
47   if (m_parent) {
48     auto it =
49       std::find(m_parent->layers().begin(),
50                 m_parent->layers().end(), this);
51 
52     if (it != m_parent->layers().end() &&
53         it != m_parent->layers().begin()) {
54       it--;
55       return *it;
56     }
57   }
58   return nullptr;
59 }
60 
getNext() const61 Layer* Layer::getNext() const
62 {
63   if (m_parent) {
64     auto it =
65       std::find(m_parent->layers().begin(),
66                 m_parent->layers().end(), this);
67 
68     if (it != m_parent->layers().end()) {
69       it++;
70       if (it != m_parent->layers().end())
71         return *it;
72     }
73   }
74   return nullptr;
75 }
76 
getPreviousBrowsable() const77 Layer* Layer::getPreviousBrowsable() const
78 {
79   // Go to children
80   if (isBrowsable())
81     return static_cast<const LayerGroup*>(this)->lastLayer();
82 
83   // Go to previous layer
84   if (Layer* prev = getPrevious())
85     return prev;
86 
87   // Go to previous layer in the parent
88   LayerGroup* parent = this->parent();
89   while (parent != sprite()->root() &&
90          !parent->getPrevious()) {
91     parent = parent->parent();
92   }
93   return parent->getPrevious();
94 }
95 
getNextBrowsable() const96 Layer* Layer::getNextBrowsable() const
97 {
98   // Go to next layer
99   if (Layer* next = getNext()) {
100     // Go to children
101     while (next->isBrowsable()) {
102       Layer* firstChild = static_cast<const LayerGroup*>(next)->firstLayer();
103       if (!firstChild)
104         break;
105       next = firstChild;
106     }
107     return next;
108   }
109 
110   // Go to parent
111   if (m_sprite && parent() != m_sprite->root())
112     return m_parent;
113 
114   return nullptr;
115 }
116 
getPreviousInWholeHierarchy() const117 Layer* Layer::getPreviousInWholeHierarchy() const
118 {
119   // Go to children
120   if (isGroup() && static_cast<const LayerGroup*>(this)->layersCount() > 0)
121     return static_cast<const LayerGroup*>(this)->lastLayer();
122 
123   // Go to previous layer
124   if (Layer* prev = getPrevious())
125     return prev;
126 
127   // Go to previous layer in the parent
128   LayerGroup* parent = this->parent();
129   while (parent != sprite()->root() &&
130          !parent->getPrevious()) {
131     parent = parent->parent();
132   }
133   return parent->getPrevious();
134 }
135 
getNextInWholeHierarchy() const136 Layer* Layer::getNextInWholeHierarchy() const
137 {
138   // Go to next layer
139   if (Layer* next = getNext()) {
140     // Go to children
141     while (next->isGroup() && static_cast<const LayerGroup*>(next)->layersCount() > 0) {
142       Layer* firstChild = static_cast<const LayerGroup*>(next)->firstLayer();
143       if (!firstChild)
144         break;
145       next = firstChild;
146     }
147     return next;
148   }
149 
150   // Go to parent
151   if (m_sprite && parent() != m_sprite->root())
152     return m_parent;
153 
154   return nullptr;
155 }
156 
isVisibleHierarchy() const157 bool Layer::isVisibleHierarchy() const
158 {
159   const Layer* layer = this;
160   while (layer) {
161     if (!layer->isVisible())
162       return false;
163     layer = layer->parent();
164   }
165   return true;
166 }
167 
isEditableHierarchy() const168 bool Layer::isEditableHierarchy() const
169 {
170   const Layer* layer = this;
171   while (layer) {
172     if (!layer->isEditable())
173       return false;
174     layer = layer->parent();
175   }
176   return true;
177 }
178 
cel(frame_t frame) const179 Cel* Layer::cel(frame_t frame) const
180 {
181   return nullptr;
182 }
183 
184 //////////////////////////////////////////////////////////////////////
185 // LayerImage class
186 
LayerImage(Sprite * sprite)187 LayerImage::LayerImage(Sprite* sprite)
188   : Layer(ObjectType::LayerImage, sprite)
189   , m_blendmode(BlendMode::NORMAL)
190   , m_opacity(255)
191 {
192 }
193 
~LayerImage()194 LayerImage::~LayerImage()
195 {
196   destroyAllCels();
197 }
198 
getMemSize() const199 int LayerImage::getMemSize() const
200 {
201   int size = sizeof(LayerImage);
202   CelConstIterator it = getCelBegin();
203   CelConstIterator end = getCelEnd();
204 
205   for (; it != end; ++it) {
206     const Cel* cel = *it;
207     size += cel->getMemSize();
208 
209     const Image* image = cel->image();
210     size += image->getMemSize();
211   }
212 
213   return size;
214 }
215 
destroyAllCels()216 void LayerImage::destroyAllCels()
217 {
218   CelIterator it = getCelBegin();
219   CelIterator end = getCelEnd();
220 
221   for (; it != end; ++it) {
222     Cel* cel = *it;
223     delete cel;
224   }
225   m_cels.clear();
226 }
227 
cel(frame_t frame) const228 Cel* LayerImage::cel(frame_t frame) const
229 {
230   CelConstIterator it = findCelIterator(frame);
231   if (it != getCelEnd())
232     return *it;
233   else
234     return nullptr;
235 }
236 
getCels(CelList & cels) const237 void LayerImage::getCels(CelList& cels) const
238 {
239   CelConstIterator it = getCelBegin();
240   CelConstIterator end = getCelEnd();
241 
242   for (; it != end; ++it)
243     cels.push_back(*it);
244 }
245 
getLastCel() const246 Cel* LayerImage::getLastCel() const
247 {
248   if (!m_cels.empty())
249     return m_cels.back();
250   else
251     return NULL;
252 }
253 
findCelIterator(frame_t frame) const254 CelConstIterator LayerImage::findCelIterator(frame_t frame) const
255 {
256   CelIterator it = const_cast<LayerImage*>(this)->findCelIterator(frame);
257   return CelConstIterator(it);
258 }
259 
findCelIterator(frame_t frame)260 CelIterator LayerImage::findCelIterator(frame_t frame)
261 {
262   auto first = getCelBegin();
263   auto end = getCelEnd();
264 
265   // Here we use a binary search to find the first cel equal to "frame" (or after frame)
266   first = std::lower_bound(
267     first, end, nullptr,
268     [frame](Cel* cel, Cel*) -> bool {
269       return cel->frame() < frame;
270     });
271 
272   // We return the iterator only if it's an exact match
273   if (first != end && (*first)->frame() == frame)
274     return first;
275   else
276     return end;
277 }
278 
findFirstCelIteratorAfter(frame_t firstAfterFrame)279 CelIterator LayerImage::findFirstCelIteratorAfter(frame_t firstAfterFrame)
280 {
281   auto first = getCelBegin();
282   auto end = getCelEnd();
283 
284   // Here we use a binary search to find the first cel after the given frame
285   first = std::lower_bound(
286     first, end, nullptr,
287     [firstAfterFrame](Cel* cel, Cel*) -> bool {
288       return cel->frame() <= firstAfterFrame;
289     });
290 
291   return first;
292 }
293 
addCel(Cel * cel)294 void LayerImage::addCel(Cel* cel)
295 {
296   ASSERT(cel);
297   ASSERT(cel->data() && "The cel doesn't contain CelData");
298   ASSERT(cel->image());
299   ASSERT(sprite());
300   ASSERT(cel->image()->pixelFormat() == sprite()->pixelFormat());
301 
302   CelIterator it = findFirstCelIteratorAfter(cel->frame());
303   m_cels.insert(it, cel);
304 
305   cel->setParentLayer(this);
306 }
307 
308 /**
309  * Removes the cel from the layer.
310  *
311  * It doesn't destroy the cel, you have to delete it after calling
312  * this routine.
313  */
removeCel(Cel * cel)314 void LayerImage::removeCel(Cel* cel)
315 {
316   ASSERT(cel);
317   CelIterator it = findCelIterator(cel->frame());
318   ASSERT(it != m_cels.end());
319 
320   m_cels.erase(it);
321 
322   cel->setParentLayer(NULL);
323 }
324 
moveCel(Cel * cel,frame_t frame)325 void LayerImage::moveCel(Cel* cel, frame_t frame)
326 {
327   removeCel(cel);
328   cel->setFrame(frame);
329   cel->incrementVersion();      // TODO this should be in app::cmd module
330   addCel(cel);
331 }
332 
333 /**
334  * Configures some properties of the specified layer to make it as the
335  * "Background" of the sprite.
336  *
337  * You can't use this routine if the sprite already has a background
338  * layer.
339  */
configureAsBackground()340 void LayerImage::configureAsBackground()
341 {
342   ASSERT(sprite() != NULL);
343   ASSERT(sprite()->backgroundLayer() == NULL);
344 
345   switchFlags(LayerFlags::BackgroundLayerFlags, true);
346   setName("Background");
347 
348   sprite()->root()->stackLayer(this, NULL);
349 }
350 
displaceFrames(frame_t fromThis,frame_t delta)351 void LayerImage::displaceFrames(frame_t fromThis, frame_t delta)
352 {
353   Sprite* sprite = this->sprite();
354 
355   if (delta > 0) {
356     for (frame_t c=sprite->lastFrame(); c>=fromThis; --c) {
357       if (Cel* cel = this->cel(c))
358         moveCel(cel, c+delta);
359     }
360   }
361   else {
362     for (frame_t c=fromThis; c<=sprite->lastFrame(); ++c) {
363       if (Cel* cel = this->cel(c))
364         moveCel(cel, c+delta);
365     }
366   }
367 }
368 
369 //////////////////////////////////////////////////////////////////////
370 // LayerGroup class
371 
LayerGroup(Sprite * sprite)372 LayerGroup::LayerGroup(Sprite* sprite)
373   : Layer(ObjectType::LayerGroup, sprite)
374 {
375   setName("Layer Set");
376 }
377 
~LayerGroup()378 LayerGroup::~LayerGroup()
379 {
380   destroyAllLayers();
381 }
382 
destroyAllLayers()383 void LayerGroup::destroyAllLayers()
384 {
385   for (Layer* layer : m_layers)
386     delete layer;
387   m_layers.clear();
388 }
389 
getMemSize() const390 int LayerGroup::getMemSize() const
391 {
392   int size = sizeof(LayerGroup);
393 
394   for (const Layer* layer : m_layers) {
395     size += layer->getMemSize();
396   }
397 
398   return size;
399 }
400 
firstLayerInWholeHierarchy() const401 Layer* LayerGroup::firstLayerInWholeHierarchy() const
402 {
403   Layer* layer = firstLayer();
404   if (layer) {
405     while (layer->isGroup() &&
406            static_cast<LayerGroup*>(layer)->layersCount() > 0) {
407       layer = static_cast<LayerGroup*>(layer)->firstLayer();
408     }
409   }
410   return layer;
411 }
412 
allLayers(LayerList & list) const413 void LayerGroup::allLayers(LayerList& list) const
414 {
415   for (Layer* child : m_layers) {
416     if (child->isGroup())
417       static_cast<LayerGroup*>(child)->allLayers(list);
418 
419     list.push_back(child);
420   }
421 }
422 
allLayersCount() const423 layer_t LayerGroup::allLayersCount() const
424 {
425   layer_t count = 0;
426   for (Layer* child : m_layers) {
427     if (child->isGroup())
428       count += static_cast<LayerGroup*>(child)->allLayersCount();
429     ++count;
430   }
431   return count;
432 }
433 
hasVisibleReferenceLayers() const434 bool LayerGroup::hasVisibleReferenceLayers() const
435 {
436   for (Layer* child : m_layers) {
437     if ((child->isReference() && child->isVisible())
438         || (child->isGroup()
439             && static_cast<LayerGroup*>(child)->hasVisibleReferenceLayers()))
440       return true;
441   }
442   return false;
443 }
444 
allVisibleLayers(LayerList & list) const445 void LayerGroup::allVisibleLayers(LayerList& list) const
446 {
447   for (Layer* child : m_layers) {
448     if (!child->isVisible())
449       continue;
450 
451     if (child->isGroup())
452       static_cast<LayerGroup*>(child)->allVisibleLayers(list);
453 
454     list.push_back(child);
455   }
456 }
457 
allVisibleReferenceLayers(LayerList & list) const458 void LayerGroup::allVisibleReferenceLayers(LayerList& list) const
459 {
460   for (Layer* child : m_layers) {
461     if (!child->isVisible())
462       continue;
463 
464     if (child->isGroup())
465       static_cast<LayerGroup*>(child)->allVisibleReferenceLayers(list);
466 
467     if (!child->isReference())
468       continue;
469 
470     list.push_back(child);
471   }
472 }
473 
allBrowsableLayers(LayerList & list) const474 void LayerGroup::allBrowsableLayers(LayerList& list) const
475 {
476   for (Layer* child : m_layers) {
477     if (child->isBrowsable())
478       static_cast<LayerGroup*>(child)->allBrowsableLayers(list);
479 
480     list.push_back(child);
481   }
482 }
483 
getCels(CelList & cels) const484 void LayerGroup::getCels(CelList& cels) const
485 {
486   for (const Layer* layer : m_layers)
487     layer->getCels(cels);
488 }
489 
addLayer(Layer * layer)490 void LayerGroup::addLayer(Layer* layer)
491 {
492   m_layers.push_back(layer);
493   layer->setParent(this);
494 }
495 
removeLayer(Layer * layer)496 void LayerGroup::removeLayer(Layer* layer)
497 {
498   auto it = std::find(m_layers.begin(), m_layers.end(), layer);
499   ASSERT(it != m_layers.end());
500   m_layers.erase(it);
501 
502   layer->setParent(nullptr);
503 }
504 
insertLayer(Layer * layer,Layer * after)505 void LayerGroup::insertLayer(Layer* layer, Layer* after)
506 {
507   auto after_it = m_layers.begin();
508   if (after) {
509     after_it = std::find(m_layers.begin(), m_layers.end(), after);
510     if (after_it != m_layers.end())
511       ++after_it;
512   }
513   m_layers.insert(after_it, layer);
514 
515   layer->setParent(this);
516 }
517 
stackLayer(Layer * layer,Layer * after)518 void LayerGroup::stackLayer(Layer* layer, Layer* after)
519 {
520   ASSERT(layer != after);
521   if (layer == after)
522     return;
523 
524   removeLayer(layer);
525   insertLayer(layer, after);
526 }
527 
displaceFrames(frame_t fromThis,frame_t delta)528 void LayerGroup::displaceFrames(frame_t fromThis, frame_t delta)
529 {
530   for (Layer* layer : m_layers)
531     layer->displaceFrames(fromThis, delta);
532 }
533 
534 } // namespace doc
535