mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-05 13:20:21 +00:00
Maintain hierarchical structure of sprite groups instead of flattening. Allows opacity and blend mode to be applied correctly to groups. Sets the foundation for future features like mask layers. Note: Requires full image rendering and impacts performance in some scenarios. Avoids complex code changes for minor performance gains. Co-authored-by: Guilherme Marcondes <guilherme.marcondes@tecnico.ulisboa.pt>
75 lines
1.7 KiB
C++
75 lines
1.7 KiB
C++
// Aseprite Document Library
|
|
// Copyright (c) 2023 Igara Studio S.A.
|
|
//
|
|
// This file is released under the terms of the MIT license.
|
|
// Read LICENSE.txt for more information.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "doc/render_plan.h"
|
|
|
|
#include "doc/cel.h"
|
|
#include "doc/layer.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
namespace doc {
|
|
|
|
RenderPlan::RenderPlan()
|
|
{
|
|
}
|
|
|
|
void RenderPlan::addLayer(const Layer* layer,
|
|
const frame_t frame)
|
|
{
|
|
// We cannot add new layers after using processZIndexes()/modified
|
|
// m_items array using z-indexes.
|
|
ASSERT(m_processZIndex == true);
|
|
|
|
++m_order;
|
|
|
|
// We can't read this layer
|
|
if (!layer->isVisible())
|
|
return;
|
|
|
|
if (layer->isGroup() && !m_composeGroups) {
|
|
for (auto *const child : static_cast<const LayerGroup*>(layer)->layers()) {
|
|
addLayer(child, frame);
|
|
}
|
|
} else {
|
|
m_items.emplace_back(m_order, layer, layer->cel(frame));
|
|
}
|
|
}
|
|
|
|
void RenderPlan::processZIndexes() const
|
|
{
|
|
m_processZIndex = false;
|
|
|
|
// If all cels has a z-index = 0, we can just use the m_items as it is
|
|
bool noZIndex = true;
|
|
for (int i=0; i<int(m_items.size()); ++i) {
|
|
const int z = m_items[i].zIndex();
|
|
if (z != 0) {
|
|
noZIndex = false;
|
|
break;
|
|
}
|
|
}
|
|
if (noZIndex)
|
|
return;
|
|
|
|
// Order cels using its "order" number in m_items array + cel z-index offset
|
|
for (Item& item : m_items)
|
|
item.order = item.order + item.zIndex();
|
|
std::sort(m_items.begin(), m_items.end(),
|
|
[](const Item& a, const Item& b){
|
|
return
|
|
(a.order < b.order) ||
|
|
(a.order == b.order && (a.zIndex() < b.zIndex()));
|
|
});
|
|
}
|
|
|
|
} // namespace doc
|