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 | |
23 | namespace doc { |
24 | |
25 | Layer::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 | |
40 | Layer::~Layer() |
41 | { |
42 | } |
43 | |
44 | int Layer::getMemSize() const |
45 | { |
46 | return sizeof(Layer); |
47 | } |
48 | |
49 | Layer* 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 | |
65 | Layer* 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 | |
81 | Layer* 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 | |
100 | Layer* 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 | |
121 | Layer* 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 | |
140 | Layer* 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 | |
161 | bool 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 | |
172 | bool 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). |
187 | bool 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 | |
201 | bool 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 | |
212 | Grid 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 | |
221 | Cel* Layer::cel(frame_t frame) const |
222 | { |
223 | return nullptr; |
224 | } |
225 | |
226 | ////////////////////////////////////////////////////////////////////// |
227 | // LayerImage class |
228 | |
229 | LayerImage::LayerImage(ObjectType type, Sprite* sprite) |
230 | : Layer(type, sprite) |
231 | , m_blendmode(BlendMode::NORMAL) |
232 | , m_opacity(255) |
233 | { |
234 | } |
235 | |
236 | LayerImage::LayerImage(Sprite* sprite) |
237 | : LayerImage(ObjectType::LayerImage, sprite) |
238 | { |
239 | } |
240 | |
241 | LayerImage::~LayerImage() |
242 | { |
243 | destroyAllCels(); |
244 | } |
245 | |
246 | int 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 | |
263 | void 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 | |
275 | Cel* 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 | |
284 | void 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 | |
293 | Cel* LayerImage::getLastCel() const |
294 | { |
295 | if (!m_cels.empty()) |
296 | return m_cels.back(); |
297 | else |
298 | return NULL; |
299 | } |
300 | |
301 | CelConstIterator LayerImage::findCelIterator(frame_t frame) const |
302 | { |
303 | CelIterator it = const_cast<LayerImage*>(this)->findCelIterator(frame); |
304 | return CelConstIterator(it); |
305 | } |
306 | |
307 | CelIterator 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 | |
326 | CelIterator 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 | |
341 | void 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 | */ |
362 | void 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 | |
373 | void 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 | */ |
388 | void 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 | |
399 | void 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 | |
420 | LayerGroup::LayerGroup(Sprite* sprite) |
421 | : Layer(ObjectType::LayerGroup, sprite) |
422 | { |
423 | setName("Group" ); |
424 | } |
425 | |
426 | LayerGroup::~LayerGroup() |
427 | { |
428 | destroyAllLayers(); |
429 | } |
430 | |
431 | void LayerGroup::destroyAllLayers() |
432 | { |
433 | for (Layer* layer : m_layers) |
434 | delete layer; |
435 | m_layers.clear(); |
436 | } |
437 | |
438 | int 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 | |
449 | Layer* 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 | |
461 | void 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 | |
471 | layer_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 | |
482 | bool 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 | |
493 | void 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 | |
506 | void 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 | |
522 | void 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 | |
532 | void LayerGroup::getCels(CelList& cels) const |
533 | { |
534 | for (const Layer* layer : m_layers) |
535 | layer->getCels(cels); |
536 | } |
537 | |
538 | void LayerGroup::addLayer(Layer* layer) |
539 | { |
540 | m_layers.push_back(layer); |
541 | layer->setParent(this); |
542 | } |
543 | |
544 | void 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 | |
553 | void 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 | |
566 | void 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 | |
576 | void 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 | |