From bbec09c752d89efe5a64996d89549b4fd70356fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Capello?= Date: Tue, 24 Aug 2021 11:14:53 -0300 Subject: [PATCH 1/9] Fix typo in CMakeLists.txt file --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34580e62d..749f8359c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,8 @@ if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/laf/CMakeLists.txt) message(FATAL_ERROR "Your Aseprite repository is incomplete, initialize submodules using:\n git submodule update --init --recursive") endif() -# This required for KDE/Qt destop integration, which sets BUILD_SHARED_LIBS to -# TRUE by default +# This is required for KDE/Qt destop integration, which sets +# BUILD_SHARED_LIBS to TRUE by default set(BUILD_SHARED_LIBS off) enable_testing() From 33d0187dabae89974058bd75fb6ccd2f7f502946 Mon Sep 17 00:00:00 2001 From: Joshua Ogunyinka Date: Thu, 26 Aug 2021 07:35:10 +0400 Subject: [PATCH 2/9] Continue playing the same tag in the Preview window after switching sprites (fix #2797) --- src/app/ui_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/ui_context.cpp b/src/app/ui_context.cpp index d20ce042e..e2f1a5438 100644 --- a/src/app/ui_context.cpp +++ b/src/app/ui_context.cpp @@ -112,8 +112,8 @@ void UIContext::setActiveView(DocView* docView) else current_editor = nullptr; - mainWin->getPreviewEditor()->updateUsingEditor(current_editor); mainWin->getTimeline()->updateUsingEditor(current_editor); + mainWin->getPreviewEditor()->updateUsingEditor(current_editor); // Change the image-type of color bar. ColorBar::instance()->setPixelFormat(app_get_current_pixel_format()); From 6d67d91335a06ada0f861e1318413613f0abb941 Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 27 Aug 2021 17:42:44 -0300 Subject: [PATCH 3/9] Add note about const usage in coding style --- docs/CODING_STYLE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CODING_STYLE.md b/docs/CODING_STYLE.md index b0d5d8f78..007b52165 100644 --- a/docs/CODING_STYLE.md +++ b/docs/CODING_STYLE.md @@ -126,6 +126,10 @@ protected: }; ``` +## Const + +* [NL.26: Use conventional const notation](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#nl26-use-conventional-const-notation) + ## C++11 We are using some modern C++ (C++11, C++14, etc.) features, mainly: From dc1c41f1762eb80c5e679a21977a7cdfe9dd6c1e Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 27 Aug 2021 19:17:27 -0300 Subject: [PATCH 4/9] Add initial .clang-format Maybe it's not the final version, but it's a good start. We cannot match the coding style that we were using, but it's pretty close. We'll start applying clang-format incrementally in a near future. --- .clang-format | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..c58c9e249 --- /dev/null +++ b/.clang-format @@ -0,0 +1,125 @@ +--- +Language: Cpp +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: AcrossEmptyLines +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeComma +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: false +ColumnLimit: 80 +CompactNamespaces: true +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: BeforeHash +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 1000 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +ReflowComments: false +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +TabWidth: 8 +UseCRLF: false +UseTab: Never +... From f85f24e847d285840883b417d3c0e9337cfaaaaa Mon Sep 17 00:00:00 2001 From: Joshua Ogunyinka Date: Sat, 28 Aug 2021 08:54:00 +0400 Subject: [PATCH 5/9] fixed restoring grid preference on undo/redo (fix #2872) --- src/app/cmd/set_grid_bounds.cpp | 7 +++++++ src/app/commands/cmd_grid.cpp | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/cmd/set_grid_bounds.cpp b/src/app/cmd/set_grid_bounds.cpp index 63fc86fea..8011dca50 100644 --- a/src/app/cmd/set_grid_bounds.cpp +++ b/src/app/cmd/set_grid_bounds.cpp @@ -13,6 +13,7 @@ #include "app/doc.h" #include "app/doc_event.h" #include "app/doc_observer.h" +#include "app/pref/preferences.h" #include "doc/sprite.h" namespace app { @@ -31,6 +32,9 @@ void SetGridBounds::onExecute() { Sprite* spr = sprite(); spr->setGridBounds(m_newBounds); + Doc* doc = static_cast(spr->document()); + auto& docPref = Preferences::instance().document(doc); + docPref.grid.bounds(m_newBounds); spr->incrementVersion(); } @@ -38,6 +42,9 @@ void SetGridBounds::onUndo() { Sprite* spr = sprite(); spr->setGridBounds(m_oldBounds); + Doc* doc = static_cast(spr->document()); + auto& docPref = Preferences::instance().document(doc); + docPref.grid.bounds(m_oldBounds); spr->incrementVersion(); } diff --git a/src/app/commands/cmd_grid.cpp b/src/app/commands/cmd_grid.cpp index ee2f00e8c..4dff7bda3 100644 --- a/src/app/commands/cmd_grid.cpp +++ b/src/app/commands/cmd_grid.cpp @@ -131,7 +131,6 @@ void GridSettingsCommand::onExecute(Context* context) tx.commit(); auto& docPref = Preferences::instance().document(site.document()); - docPref.grid.bounds(bounds); if (!docPref.show.grid()) // Make grid visible docPref.show.grid(true); } From 1f6c6951af35737a8c132c8c5a92b21fb90ac1d0 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 30 Aug 2021 10:52:40 -0300 Subject: [PATCH 6/9] Add SetGridBounds::setGrid() to avoid some duplicated code --- src/app/cmd/set_grid_bounds.cpp | 18 ++++++++++-------- src/app/cmd/set_grid_bounds.h | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/app/cmd/set_grid_bounds.cpp b/src/app/cmd/set_grid_bounds.cpp index 8011dca50..59c6ca419 100644 --- a/src/app/cmd/set_grid_bounds.cpp +++ b/src/app/cmd/set_grid_bounds.cpp @@ -30,21 +30,23 @@ SetGridBounds::SetGridBounds(Sprite* sprite, const gfx::Rect& bounds) void SetGridBounds::onExecute() { - Sprite* spr = sprite(); - spr->setGridBounds(m_newBounds); - Doc* doc = static_cast(spr->document()); - auto& docPref = Preferences::instance().document(doc); - docPref.grid.bounds(m_newBounds); - spr->incrementVersion(); + setGrid(m_newBounds); } void SetGridBounds::onUndo() +{ + setGrid(m_oldBounds); +} + +void SetGridBounds::setGrid(const gfx::Rect& grid) { Sprite* spr = sprite(); - spr->setGridBounds(m_oldBounds); + spr->setGridBounds(grid); + Doc* doc = static_cast(spr->document()); auto& docPref = Preferences::instance().document(doc); - docPref.grid.bounds(m_oldBounds); + docPref.grid.bounds(grid); + spr->incrementVersion(); } diff --git a/src/app/cmd/set_grid_bounds.h b/src/app/cmd/set_grid_bounds.h index eadb03fcb..a894363bc 100644 --- a/src/app/cmd/set_grid_bounds.h +++ b/src/app/cmd/set_grid_bounds.h @@ -33,6 +33,8 @@ namespace cmd { } private: + void setGrid(const gfx::Rect& grid); + gfx::Rect m_oldBounds; gfx::Rect m_newBounds; }; From 971ba323380b91d8403f89af8f0a99c1181e09ff Mon Sep 17 00:00:00 2001 From: Joshua Ogunyinka Date: Sat, 28 Aug 2021 09:51:13 +0400 Subject: [PATCH 7/9] added support for loading/saving alpha channels in palette files --- src/doc/file/pal_file.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/doc/file/pal_file.cpp b/src/doc/file/pal_file.cpp index f9a165442..b16d753cb 100644 --- a/src/doc/file/pal_file.cpp +++ b/src/doc/file/pal_file.cpp @@ -59,10 +59,10 @@ Palette* load_pal_file(const char *filename) if (line.empty()) continue; - int r, g, b; + int r, g, b, a=255; std::istringstream lineIn(line); - lineIn >> r >> g >> b; - pal->addEntry(rgba(r, g, b, 255)); + lineIn >> r >> g >> b >> a; + pal->addEntry(rgba(r, g, b, a)); } return pal.release(); @@ -77,11 +77,16 @@ bool save_pal_file(const Palette *pal, const char *filename) << "0100\n" << pal->size() << "\n"; + const bool hasAlpha = pal->hasAlpha(); for (int i=0; isize(); ++i) { uint32_t col = pal->getEntry(i); f << ((int)rgba_getr(col)) << " " << ((int)rgba_getg(col)) << " " - << ((int)rgba_getb(col)) << "\n"; + << ((int)rgba_getb(col)); + if (hasAlpha) { + f << " " << ((int)rgba_geta(col)); + } + f << "\n"; } return true; From d14cf4038da99ea6e12a953b3d82ea3fea986911 Mon Sep 17 00:00:00 2001 From: Jeremy Behreandt Date: Sat, 28 Aug 2021 03:28:28 -0500 Subject: [PATCH 8/9] Color Sort For Hue, Alpha Removes switch case with fall through. Removes nested switch cases. Refactors color sorting method to 1. push zero alpha colors to the front of the palette; 2. resort to value as a criterion for gray colors; 3. use saturation and value as back up comparisons for each other for equivalent values; 4. approximate gamma-to-linear when perceptual lightness is chosen. Partial fix for #2901. --- src/doc/sort_palette.cpp | 165 ++++++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 55 deletions(-) diff --git a/src/doc/sort_palette.cpp b/src/doc/sort_palette.cpp index 29d892eb1..27e111794 100644 --- a/src/doc/sort_palette.cpp +++ b/src/doc/sort_palette.cpp @@ -40,82 +40,137 @@ struct PalEntryWithIndexPredicate { } bool operator()(const PalEntryWithIndex& a, const PalEntryWithIndex& b) { - color_t c1 = a.color; - color_t c2 = b.color; - int value1 = 0, value2 = 0; + const color_t c1 = a.color; + const color_t c2 = b.color; + + // Handle cases where, e.g., transparent yellow + // is visually indistinguishable from transparent + // black. Push 0 alpha toward index 0, regardless + // of sort order being ascending or descending. + const uint8_t a1 = rgba_geta(c1); + const uint8_t a2 = rgba_geta(c2); + + if (a1 == 0 && a2 == 0) { + return true; + } + else if (a1 == 0) { + return true; + } + else if (a2 == 0) { + return false; + } + + const uint8_t r1 = rgba_getr(c1); + const uint8_t g1 = rgba_getg(c1); + const uint8_t b1 = rgba_getb(c1); + + const uint8_t r2 = rgba_getr(c2); + const uint8_t g2 = rgba_getg(c2); + const uint8_t b2 = rgba_getb(c2); switch (channel) { case SortPaletteBy::RED: - value1 = rgba_getr(c1); - value2 = rgba_getr(c2); - break; + return (ascending ? r1 < r2: r2 < r1); case SortPaletteBy::GREEN: - value1 = rgba_getg(c1); - value2 = rgba_getg(c2); - break; + return (ascending ? g1 < g2: g2 < g1); case SortPaletteBy::BLUE: - value1 = rgba_getb(c1); - value2 = rgba_getb(c2); - break; + return (ascending ? b1 < b2: b2 < b1); case SortPaletteBy::ALPHA: - value1 = rgba_geta(c1); - value2 = rgba_geta(c2); - break; + return (ascending ? a1 < a2: a2 < a1); - case SortPaletteBy::HUE: - case SortPaletteBy::SATURATION: - case SortPaletteBy::VALUE: { - Hsv hsv1(Rgb(rgba_getr(c1), - rgba_getg(c1), - rgba_getb(c1))); - Hsv hsv2(Rgb(rgba_getr(c2), - rgba_getg(c2), - rgba_getb(c2))); + case SortPaletteBy::HUE: { + const Hsv hsv1(Rgb(r1, g1, b1)); + const Hsv hsv2(Rgb(r2, g2, b2)); - switch (channel) { - case SortPaletteBy::HUE: - value1 = hsv1.hueInt(); - value2 = hsv2.hueInt(); - break; - case SortPaletteBy::SATURATION: - value1 = hsv1.saturationInt(); - value2 = hsv2.saturationInt(); - break; - case SortPaletteBy::VALUE: - value1 = hsv1.valueInt(); - value2 = hsv2.valueInt(); - break; - default: - ASSERT(false); - break; + // When a color is desaturated, its hue + // is the quotient of division by zero. + // It is not zero, which is red. + const int sat1 = hsv1.saturationInt(); + const int sat2 = hsv2.saturationInt(); + + if (sat1 == 0 && sat2 == 0) { + const int val1 = hsv1.valueInt(); + const int val2 = hsv2.valueInt(); + return (ascending ? val1 < val2: val2 < val1); } - break; + else if (sat1 == 0) { + return ascending; + } + else if (sat2 == 0) { + return !ascending; + } + + const int hue1 = hsv1.hueInt(); + const int hue2 = hsv2.hueInt(); + return (ascending ? hue1 < hue2: hue2 < hue1); } - case SortPaletteBy::LIGHTNESS: { - value1 = (std::max(rgba_getr(c1), std::max(rgba_getg(c1), rgba_getb(c1))) + - std::min(rgba_getr(c1), std::min(rgba_getg(c1), rgba_getb(c1)))) / 2; - value2 = (std::max(rgba_getr(c2), std::max(rgba_getg(c2), rgba_getb(c2))) + - std::min(rgba_getr(c2), std::min(rgba_getg(c2), rgba_getb(c2)))) / 2; - break; + case SortPaletteBy::SATURATION: { + // This could be inlined with + // (max(r, g, b) - min(r, g, b)) / max(r, g, b) + // but (1.) there is already opportunity for + // confusion: HSV and HSL saturation share + // the same name but arise from different + // calculations; (2.) HSV components can + // almost never be compared in isolation. + const Hsv hsv1(Rgb(r1, g1, b1)); + const Hsv hsv2(Rgb(r2, g2, b2)); + const int sat1 = hsv1.saturationInt(); + const int sat2 = hsv2.saturationInt(); + if (sat1 == sat2) { + const int val1 = hsv1.valueInt(); + const int val2 = hsv2.valueInt(); + return (ascending ? val1 < val2: val2 < val1); + } + return (ascending ? sat1 < sat2: sat2 < sat1); + } + + case SortPaletteBy::VALUE: { + const Hsv hsv1(Rgb(r1, g1, b1)); + const Hsv hsv2(Rgb(r2, g2, b2)); + const int val1 = hsv1.valueInt(); + const int val2 = hsv2.valueInt(); + if (val1 == val2) { + const int sat1 = hsv1.saturationInt(); + const int sat2 = hsv2.saturationInt(); + return (ascending ? sat1 < sat2: sat2 < sat1); + } + return (ascending ? val1 < val2: val2 < val1); } case SortPaletteBy::LUMA: { - value1 = rgb_luma(rgba_getr(c1), rgba_getg(c1), rgba_getb(c1)); - value2 = rgb_luma(rgba_getr(c2), rgba_getg(c2), rgba_getb(c2)); - break; + // Perceptual, or relative, luminance. + // Finds the square for fast approximation + // of 2.4 or 2.2 exponent needed to convert + // from gamma to linear. Assumes that the + // source for palette colors is sRGB. + const int lum1 = rgb_luma(r1 * r1, g1 * g1, b1 * b1); + const int lum2 = rgb_luma(r2 * r2, g2 * g2, b2 * b2); + return (ascending ? lum1 < lum2: lum2 < lum1); } + case SortPaletteBy::LIGHTNESS: { + // HSL Lightness + const int mn1 = std::min(r1, std::min(g1, b1)); + const int mx1 = std::max(r1, std::max(g1, b1)); + const int light1 = (mn1 + mx1) / 2; + + const int mn2 = std::min(r2, std::min(g2, b2)); + const int mx2 = std::max(r2, std::max(g2, b2)); + const int light2 = (mn2 + mx2) / 2; + + return (ascending ? light1 < light2: light2 < light1); + } + + default: { + ASSERT(false); + return false; + } } - - if (!ascending) - std::swap(value1, value2); - - return (value1 < value2); } }; From dd2d226264b0960145a7e04a97a4aa3669330ad3 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Tue, 24 Aug 2021 16:29:18 -0300 Subject: [PATCH 9/9] Fix crash after saving a GIF file from an indexed image which transparent index is gone Before this fix, it was possible to lose the transparent index at Indexed Color Mode. It was reproducible doing: - New file, Indexed mode, Black background. - Erase all the palette, add 40 colors slots (these all will be black) - Press Remap button - Go to Sprite > Properties... set transparent color to 11. - Erase color entries 2 to 20 - Press Remap button You'll see the transparent index is gone (transparent index = -1) To reproduce the crash, additional steps are needed: - Right click to layer and select 'Layer from Background' - Make a color RGBA(0, 0, 0, 0) and add to the palette - Paint on canvas with this color (it'll act like a eraser) - File > Save As... save in GIF format. - Press OK Crash! This crash was reported on ticket 2620 and 2621. --- src/app/cmd/set_palette.cpp | 11 ++++++++++- src/app/cmd/set_palette.h | 4 +++- src/app/ui/color_bar.cpp | 4 +++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/app/cmd/set_palette.cpp b/src/app/cmd/set_palette.cpp index aa8b1be10..bfda55dd5 100644 --- a/src/app/cmd/set_palette.cpp +++ b/src/app/cmd/set_palette.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2015 David Capello // // This program is distributed under the terms of @@ -53,6 +53,13 @@ SetPalette::SetPalette(Sprite* sprite, frame_t frame, const Palette* newPalette) m_newColors[i] = newPalette->getEntry(m_from+i); } } + if (sprite->pixelFormat() == IMAGE_INDEXED) { + m_oldTransparentIndex = sprite->transparentColor(); + if (m_oldTransparentIndex >= newPalette->size()) + m_newTransparentIndex = newPalette->size() -1; + else + m_newTransparentIndex = m_oldTransparentIndex; + } } void SetPalette::onExecute() @@ -64,6 +71,7 @@ void SetPalette::onExecute() for (size_t i=0; isetEntry(m_from+i, m_newColors[i]); + sprite->setTransparentColor(m_newTransparentIndex); palette->incrementVersion(); } @@ -76,6 +84,7 @@ void SetPalette::onUndo() for (size_t i=0; isetEntry(m_from+i, m_oldColors[i]); + sprite->setTransparentColor(m_oldTransparentIndex); palette->incrementVersion(); } diff --git a/src/app/cmd/set_palette.h b/src/app/cmd/set_palette.h index bd8a6a9a9..9bcab58e3 100644 --- a/src/app/cmd/set_palette.h +++ b/src/app/cmd/set_palette.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2015 David Capello // // This program is distributed under the terms of @@ -45,6 +45,8 @@ namespace cmd { int m_from, m_to; int m_oldNColors; int m_newNColors; + int m_oldTransparentIndex; + int m_newTransparentIndex; std::vector m_oldColors; std::vector m_newColors; }; diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp index 7435600da..c235e95c0 100644 --- a/src/app/ui/color_bar.cpp +++ b/src/app/ui/color_bar.cpp @@ -578,7 +578,9 @@ void ColorBar::onRemapButtonClick() } color_t oldTransparent = sprite->transparentColor(); - color_t newTransparent = remap[oldTransparent]; + color_t newTransparent = (remap[oldTransparent] >= 0) ? remap[oldTransparent] : oldTransparent; + if (newTransparent >= get_current_palette()->size()) + newTransparent = get_current_palette()->size() - 1; if (oldTransparent != newTransparent) tx(new cmd::SetTransparentColor(sprite, newTransparent));