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