Fix brush and pasted image preview on empty cels (fix #3882)

Fix regression introduced in 24846eae10c7340a4e7f103b15494ea8338700a9
using the new RenderPlan structure. We have to include empty/nullptr
cels in the plan to paint the preview image in the selected
layer/frame (the preview image is the one used for the brush preview,
and for the transformation preview when we paste the clipboard content
on the canvas).
This commit is contained in:
David Capello 2023-05-18 12:56:09 -03:00
parent da70dd3892
commit 66ac837305
5 changed files with 25 additions and 19 deletions

View File

@ -231,14 +231,14 @@ void ShaderRenderer::renderPlan(SkCanvas* canvas,
{
for (const auto& item : plan.items()) {
const Cel* cel = item.cel;
const Layer* layer = cel->layer();
const Layer* layer = item.layer;
switch (layer->type()) {
case doc::ObjectType::LayerImage: {
auto imgLayer = static_cast<const LayerImage*>(layer);
if (doc::Cel* cel = imgLayer->cel(frame)) {
if (cel) {
const doc::Image* celImage = nullptr;
gfx::RectF celBounds;
@ -254,7 +254,7 @@ void ShaderRenderer::renderPlan(SkCanvas* canvas,
// If not, we use the original cel-image from the images' stock
else {
celImage = cel->image();
if (cel->layer()->isReference())
if (layer->isReference())
celBounds = cel->boundsF();
else
celBounds = cel->bounds();
@ -276,7 +276,8 @@ void ShaderRenderer::renderPlan(SkCanvas* canvas,
case doc::ObjectType::LayerTilemap: {
auto tilemapLayer = static_cast<const LayerTilemap*>(layer);
doc::Cel* cel = tilemapLayer->cel(frame);
// TODO selected layer?
if (!cel)
break;

View File

@ -39,9 +39,7 @@ void RenderPlan::addLayer(const Layer* layer,
case ObjectType::LayerImage:
case ObjectType::LayerTilemap: {
if (Cel* cel = layer->cel(frame)) {
m_items.emplace_back(m_order, cel);
}
m_items.emplace_back(m_order, layer, layer->cel(frame));
break;
}
@ -62,7 +60,7 @@ void RenderPlan::processZIndexes() const
// 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].cel->zIndex();
const int z = m_items[i].zIndex();
if (z != 0) {
noZIndex = false;
break;
@ -73,12 +71,12 @@ void RenderPlan::processZIndexes() const
// Order cels using its "order" number in m_items array + cel z-index offset
for (Item& item : m_items)
item.order = item.order + item.cel->zIndex();
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.cel->zIndex() < b.cel->zIndex()));
(a.order == b.order && (a.zIndex() < b.zIndex()));
});
}

View File

@ -8,6 +8,7 @@
#define DOC_RENDER_PLAN_H_INCLUDED
#pragma once
#include "doc/cel.h"
#include "doc/cel_list.h"
#include "doc/frame.h"
@ -21,9 +22,13 @@ namespace doc {
public:
struct Item {
int order;
Cel* cel;
Item(int order = 0, Cel* cel = nullptr)
: order(order), cel(cel) { }
const Layer* layer;
const Cel* cel;
int zIndex() const { return (cel ? cel->zIndex(): 0); }
Item(const int order = 0,
const Layer* layer = nullptr,
const Cel* cel = nullptr)
: order(order), layer(layer), cel(cel) { }
};
using Items = std::vector<Item>;

View File

@ -634,7 +634,10 @@ void Sprite::pickCels(const gfx::PointF& pos,
// bottom-most) so we pick first visible cel in the given position.
const auto& planItems = plan.items();
for (auto it=planItems.rbegin(), end=planItems.rend(); it!=end; ++it) {
Cel* cel = it->cel;
const Cel* cel = it->cel;
if (!cel)
continue;
const Image* image = cel->image();
if (!image)
continue;
@ -698,7 +701,7 @@ void Sprite::pickCels(const gfx::PointF& pos,
if (!isOpaque)
continue;
cels.push_back(cel);
cels.push_back(const_cast<Cel*>(cel));
}
}

View File

@ -1006,7 +1006,7 @@ void Render::renderPlan(
{
for (const auto& item : plan.items()) {
const Cel* cel = item.cel;
const Layer* layer = cel->layer();
const Layer* layer = item.layer;
ASSERT(layer->isVisible()); // Hidden layers shouldn't be in the plan
@ -1034,8 +1034,7 @@ void Render::renderPlan(
else {
// Check if we can draw the extra cel when we render a linked
// frame.
cel = layer->cel(frame);
Cel* cel2 = layer->cel(m_extraCel->frame());
const Cel* cel2 = layer->cel(m_extraCel->frame());
if (cel && cel2 &&
cel->data() == cel2->data()) {
drawExtra = true;
@ -1085,7 +1084,7 @@ void Render::renderPlan(
// If not, we use the original cel-image from the images' stock
else {
celImage = cel->image();
if (cel->layer()->isReference())
if (layer->isReference())
celBounds = cel->boundsF();
else
celBounds = cel->bounds();