diff --git a/src/app/cmd/flatten_layers.cpp b/src/app/cmd/flatten_layers.cpp index d2e42515a..147f748be 100644 --- a/src/app/cmd/flatten_layers.cpp +++ b/src/app/cmd/flatten_layers.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2022 Igara Studio S.A. +// Copyright (C) 2019-2024 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -35,6 +35,8 @@ #include "doc/sprite.h" #include "render/render.h" +#include + namespace app { namespace cmd { @@ -128,11 +130,24 @@ void FlattenLayers::onExecute() RestoreVisibleLayers restore; restore.showSelectedLayers(sprite, layers); + const LayerList visibleLayers = sprite->allVisibleLayers(); + // Map draw area to image coords const gfx::ClipF area_to_image(0, 0, area); // Copy all frames to the background. for (frame_t frame(0); frametotalFrames(); ++frame) { + // If the flatLayer is the only cel in this frame, we can skip + // this frame to keep existing links in the flatLayer. + const bool anotherCelExists = + std::any_of(visibleLayers.begin(), + visibleLayers.end(), + [flatLayer, frame](const Layer* other) { + return (flatLayer != other && other->cel(frame)); + }); + if (!anotherCelExists) + continue; + // Clear the image and render this frame. clear_image(image.get(), bgcolor); render.renderSprite(image.get(), sprite, frame, area_to_image); diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp index 959d77075..527cf8524 100644 --- a/src/app/commands/cmd_options.cpp +++ b/src/app/commands/cmd_options.cpp @@ -376,11 +376,13 @@ public: uiWindows()->setSelectedItem(multipleWindows()->isSelected() ? 1: 0); }); -#ifndef ENABLE_DEVMODE // TODO enable this on Release when Aseprite supports - // GPU-acceleration properly +#ifdef ENABLE_DEVMODE // TODO enable this on Release when Aseprite supports + // GPU-acceleration properly if (!m_system->hasCapability(os::Capabilities::GpuAccelerationSwitch)) - gpuAcceleration()->setVisible(false); #endif + { + gpuAcceleration()->setVisible(false); + } // If the platform does support native menus, we show the option, // in other case, the option doesn't make sense for this platform. @@ -636,9 +638,11 @@ public: // Scaling selectScalingItems(); +#ifdef ENABLE_DEVMODE if (m_system->hasCapability(os::Capabilities::GpuAccelerationSwitch)) { gpuAcceleration()->setSelected(m_pref.general.gpuAcceleration()); } +#endif if (m_system->menus()) showMenuBar()->setSelected(m_pref.general.showMenuBar()); @@ -905,11 +909,13 @@ public: reset_screen = true; } +#ifdef ENABLE_DEVMODE const bool newGpuAccel = gpuAcceleration()->isSelected(); if (newGpuAccel != m_pref.general.gpuAcceleration()) { m_pref.general.gpuAcceleration(newGpuAccel); reset_screen = true; } +#endif if (m_system->menus() && m_pref.general.showMenuBar() != showMenuBar()->isSelected()) { diff --git a/src/app/script/api_version.h b/src/app/script/api_version.h index a9684b278..2c46870dd 100644 --- a/src/app/script/api_version.h +++ b/src/app/script/api_version.h @@ -10,6 +10,6 @@ // Increment this value if the scripting API is modified between two // released Aseprite versions. -#define API_VERSION 28 +#define API_VERSION 29 #endif diff --git a/src/app/sentry_wrapper.cpp b/src/app/sentry_wrapper.cpp index 30e7838d9..3545f362a 100644 --- a/src/app/sentry_wrapper.cpp +++ b/src/app/sentry_wrapper.cpp @@ -109,7 +109,7 @@ bool Sentry::areThereCrashesToReport() // At least one .dmp file in the completed/ directory means that // there was at least one crash in the past (this is for macOS). - if (!base::join_path(m_dbdir, "completed"), base::ItemType::Files, "*.dmp").empty()) + if (!base::list_files(base::join_path(m_dbdir, "completed"), base::ItemType::Files, "*.dmp").empty()) return true; // In case that "last_crash" doesn't exist we can check for some diff --git a/src/doc/rgbmap_base.cpp b/src/doc/rgbmap_base.cpp index 53d97256d..e0c28bd9e 100644 --- a/src/doc/rgbmap_base.cpp +++ b/src/doc/rgbmap_base.cpp @@ -120,7 +120,7 @@ int RgbMapBase::findBestfit(int r, int g, int b, int a, const double aDiff = double(a - rgba_geta(rgb)) / 128.0; double diff = xDiff * xDiff + yDiff * yDiff + zDiff * zDiff + aDiff * aDiff; - if (diff < lowest) { + if (diff < lowest && i != mask_index) { lowest = diff; bestfit = i; } diff --git a/tests/scripts/merge_down_bugs.lua b/tests/scripts/merge_down_bugs.lua index 6930cfa2b..537d396e7 100644 --- a/tests/scripts/merge_down_bugs.lua +++ b/tests/scripts/merge_down_bugs.lua @@ -1,4 +1,4 @@ --- Copyright (C) 2019 Igara Studio S.A. +-- Copyright (C) 2019-2024 Igara Studio S.A. -- -- This file is released under the terms of the MIT license. -- Read LICENSE.txt for more information. @@ -46,3 +46,25 @@ do local after = s.cels[1].image assert(before:isEqual(after)) end + +-- Check that linked cels are not broken (regression in issue #4685) +-- We create two layers, the bottom one with 4 linked frames, and the +-- top one with one cel at 2nd frame, when we merge them, the +-- resulting layer should have frame 1, 3, and 4 linked. +do + local s = Sprite(32, 32) + app.useTool{ color=Color(255, 0, 0), points={ {0,0}, {32,32} } } + app.layer.isContinuous = true + app.command.NewFrame{ content=cellinked } + app.command.NewFrame{ content=cellinked } + app.command.NewFrame{ content=cellinked } + s:newLayer() + app.frame = 2 + app.useTool{ color=Color(0, 0, 255), points={ {32,0}, {0,32} } } + app.command.MergeDownLayer() + local cels = app.layer.cels + -- Check that frame 1, 3, and 4 have the same image (linked cels) + assert(cels[1].image ~= cels[2].image) + assert(cels[1].image == cels[3].image) + assert(cels[1].image == cels[4].image) +end