From b8c3d39c358a9cf652ba5b5d40473ec6ef445077 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 2 Apr 2013 21:02:18 -0300 Subject: [PATCH] Add shading ink (for indexed images only) and color swatches (no UI yet) --- src/CMakeLists.txt | 2 + src/app/color_swatches.cpp | 45 ++++++++++++++++++ src/app/color_swatches.h | 53 +++++++++++++++++++++ src/settings/settings.h | 15 +++++- src/settings/ui_settings_impl.cpp | 53 ++++++++++++++++++++- src/settings/ui_settings_impl.h | 24 ++++++---- src/tools/ink_processing.h | 33 ++++++++++++- src/tools/inks.h | 22 +++++++++ src/tools/shade_table.cpp | 67 +++++++++++++++++++++++++++ src/tools/shade_table.h | 47 +++++++++++++++++++ src/tools/shading_mode.h | 36 ++++++++++++++ src/tools/shading_options.h | 35 ++++++++++++++ src/tools/tool_box.cpp | 2 + src/tools/tool_box.h | 1 + src/tools/tool_loop.h | 3 ++ src/widgets/editor/tool_loop_impl.cpp | 23 ++++++++- 16 files changed, 446 insertions(+), 15 deletions(-) create mode 100644 src/app/color_swatches.cpp create mode 100644 src/app/color_swatches.h create mode 100644 src/tools/shade_table.cpp create mode 100644 src/tools/shade_table.h create mode 100644 src/tools/shading_mode.h create mode 100644 src/tools/shading_options.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d5be8ca0..e03012980 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -200,6 +200,7 @@ add_library(aseprite-library app/backup.cpp app/check_update.cpp app/color.cpp + app/color_swatches.cpp app/color_utils.cpp app/data_recovery.cpp app/file_selector.cpp @@ -338,6 +339,7 @@ add_library(aseprite-library skin/skin_slider_property.cpp tools/intertwine.cpp tools/point_shape.cpp + tools/shade_table.cpp tools/tool_box.cpp tools/tool_loop_manager.cpp undoers/add_cel.cpp diff --git a/src/app/color_swatches.cpp b/src/app/color_swatches.cpp new file mode 100644 index 000000000..1800f3173 --- /dev/null +++ b/src/app/color_swatches.cpp @@ -0,0 +1,45 @@ +/* ASEPRITE + * Copyright (C) 2001-2013 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "app/color_swatches.h" + +namespace app { + +ColorSwatches::ColorSwatches(const std::string& name) + : m_name(name) +{ +} + +void ColorSwatches::addColor(Color& color) +{ + m_colors.push_back(color); +} + +void ColorSwatches::insertColor(size_t index, Color& color) +{ + m_colors.insert(m_colors.begin() + index, color); +} + +void ColorSwatches::removeColor(size_t index) +{ + m_colors.erase(m_colors.begin() + index); +} + +} // namespace app diff --git a/src/app/color_swatches.h b/src/app/color_swatches.h new file mode 100644 index 000000000..c8d88cfd9 --- /dev/null +++ b/src/app/color_swatches.h @@ -0,0 +1,53 @@ +/* ASEPRITE + * Copyright (C) 2001-2013 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef APP_COLOR_SWATCHES_H_INCLUDED +#define APP_COLOR_SWATCHES_H_INCLUDED + +#include + +#include "app/color.h" + +namespace app { + +class ColorSwatches +{ +public: + ColorSwatches(const std::string& name); + + size_t size() const { return m_colors.size(); } + + const std::string& getName() const { return m_name; } + void setName(std::string& name) { m_name = name; } + + void addColor(Color& color); + void insertColor(size_t index, Color& color); + void removeColor(size_t index); + + const Color& operator[](size_t index) const { + return m_colors[index]; + } + +private: + std::string m_name; + std::vector m_colors; +}; + +} // namespace app + +#endif diff --git a/src/settings/settings.h b/src/settings/settings.h index 2814a959d..c0676bce0 100644 --- a/src/settings/settings.h +++ b/src/settings/settings.h @@ -26,10 +26,12 @@ #include "settings/ink_type.h" class Document; +class IColorSwatchesStore; class IDocumentSettings; -class IToolSettings; class IPenSettings; +class IToolSettings; +namespace app { class ColorSwatches; } namespace tools { class Tool; } class ISettings @@ -42,10 +44,12 @@ public: virtual app::Color getFgColor() = 0; virtual app::Color getBgColor() = 0; virtual tools::Tool* getCurrentTool() = 0; + virtual app::ColorSwatches* getColorSwatches() = 0; virtual void setFgColor(const app::Color& color) = 0; virtual void setBgColor(const app::Color& color) = 0; virtual void setCurrentTool(tools::Tool* tool) = 0; + virtual void setColorSwatches(app::ColorSwatches* colorSwatches) = 0; // Returns the specific settings for the given document. If the // document is null, it should return an interface for @@ -55,6 +59,7 @@ public: // Specific configuration for the given tool. virtual IToolSettings* getToolSettings(tools::Tool* tool) = 0; + virtual IColorSwatchesStore* getColorSwatchesStore() = 0; }; // Tool's settings @@ -97,4 +102,12 @@ public: virtual void setAngle(int angle) = 0; }; +class IColorSwatchesStore +{ +public: + virtual ~IColorSwatchesStore() { } + virtual void addColorSwatches(app::ColorSwatches* colorSwatches) = 0; + virtual void removeColorSwatches(app::ColorSwatches* colorSwatches) = 0; +}; + #endif diff --git a/src/settings/ui_settings_impl.cpp b/src/settings/ui_settings_impl.cpp index 47a77c830..36d33b8f1 100644 --- a/src/settings/ui_settings_impl.cpp +++ b/src/settings/ui_settings_impl.cpp @@ -21,6 +21,7 @@ #include "settings/ui_settings_impl.h" #include "app.h" +#include "app/color_swatches.h" #include "ini_file.h" #include "settings/document_settings.h" #include "tools/point_shape.h" @@ -32,6 +33,7 @@ #include "widgets/main_window.h" #include "widgets/workspace.h" +#include #include #include @@ -141,7 +143,13 @@ private: UISettingsImpl::UISettingsImpl() : m_currentTool(NULL) , m_globalDocumentSettings(new UIDocumentSettingsImpl) + , m_colorSwatches(NULL) { + m_colorSwatches = new app::ColorSwatches("Default"); + for (size_t i=0; i<16; ++i) + m_colorSwatches->addColor(app::Color::fromIndex(i)); + + addColorSwatches(m_colorSwatches); } UISettingsImpl::~UISettingsImpl() @@ -149,9 +157,17 @@ UISettingsImpl::~UISettingsImpl() delete m_globalDocumentSettings; // Delete all tool settings. - std::map::iterator it; - for (it = m_toolSettings.begin(); it != m_toolSettings.end(); ++it) + for (std::map::iterator + it = m_toolSettings.begin(), end = m_toolSettings.end(); it != end; ++it) { delete it->second; + } + + // Delete all color swatches + for (std::vector::iterator + it = m_colorSwatchesStore.begin(), end = m_colorSwatchesStore.end(); + it != end; ++it) { + delete *it; + } } ////////////////////////////////////////////////////////////////////// @@ -175,6 +191,11 @@ tools::Tool* UISettingsImpl::getCurrentTool() return m_currentTool; } +app::ColorSwatches* UISettingsImpl::getColorSwatches() +{ + return m_colorSwatches; +} + void UISettingsImpl::setFgColor(const app::Color& color) { ColorBar::instance()->setFgColor(color); @@ -199,11 +220,39 @@ void UISettingsImpl::setCurrentTool(tools::Tool* tool) } } +void UISettingsImpl::setColorSwatches(app::ColorSwatches* colorSwatches) +{ + m_colorSwatches = colorSwatches; +} + IDocumentSettings* UISettingsImpl::getDocumentSettings(const Document* document) { return m_globalDocumentSettings; } +IColorSwatchesStore* UISettingsImpl::getColorSwatchesStore() +{ + return this; +} + +void UISettingsImpl::addColorSwatches(app::ColorSwatches* colorSwatches) +{ + m_colorSwatchesStore.push_back(colorSwatches); +} + +void UISettingsImpl::removeColorSwatches(app::ColorSwatches* colorSwatches) +{ + std::vector::iterator it = + std::find(m_colorSwatchesStore.begin(), + m_colorSwatchesStore.end(), + colorSwatches); + + ASSERT(it != m_colorSwatchesStore.end()); + + if (it != m_colorSwatchesStore.end()) + m_colorSwatchesStore.erase(it); +} + ////////////////////////////////////////////////////////////////////// // IDocumentSettings implementation diff --git a/src/settings/ui_settings_impl.h b/src/settings/ui_settings_impl.h index 1d70f03fa..859fd7e83 100644 --- a/src/settings/ui_settings_impl.h +++ b/src/settings/ui_settings_impl.h @@ -21,37 +21,43 @@ #include #include +#include + #include "base/compiler_specific.h" #include "settings/settings.h" -class UISettingsImpl : public ISettings +class UISettingsImpl : public ISettings, + public IColorSwatchesStore { public: UISettingsImpl(); ~UISettingsImpl(); - // General settings + // ISettings implementation app::Color getFgColor() OVERRIDE; app::Color getBgColor() OVERRIDE; tools::Tool* getCurrentTool() OVERRIDE; - + app::ColorSwatches* getColorSwatches() OVERRIDE; void setFgColor(const app::Color& color) OVERRIDE; void setBgColor(const app::Color& color) OVERRIDE; void setCurrentTool(tools::Tool* tool) OVERRIDE; - - // Document settings - + void setColorSwatches(app::ColorSwatches* colorSwatches) OVERRIDE; IDocumentSettings* getDocumentSettings(const Document* document) OVERRIDE; - - // Tools settings - IToolSettings* getToolSettings(tools::Tool* tool) OVERRIDE; + IColorSwatchesStore* getColorSwatchesStore() OVERRIDE; + + // IColorSwatchesStore implementation + + void addColorSwatches(app::ColorSwatches* colorSwatches) OVERRIDE; + void removeColorSwatches(app::ColorSwatches* colorSwatches) OVERRIDE; private: tools::Tool* m_currentTool; IDocumentSettings* m_globalDocumentSettings; std::map m_toolSettings; + app::ColorSwatches* m_colorSwatches; + std::vector m_colorSwatchesStore; }; #endif diff --git a/src/tools/ink_processing.h b/src/tools/ink_processing.h index 53ff73471..cd8fd16b8 100644 --- a/src/tools/ink_processing.h +++ b/src/tools/ink_processing.h @@ -22,6 +22,8 @@ #include "raster/rgbmap.h" #include "raster/sprite.h" #include "settings/document_settings.h" +#include "tools/shade_table.h" +#include "tools/shading_options.h" ////////////////////////////////////////////////////////////////////// // Ink Processing @@ -451,6 +453,33 @@ static void ink_hline8_jumble(int x1, int y, int x2, ToolLoop* loop) ); } +////////////////////////////////////////////////////////////////////// +// Shading Ink +////////////////////////////////////////////////////////////////////// + +static void ink_hline32_shading(int x1, int y, int x2, ToolLoop* loop) +{ +} + +static void ink_hline16_shading(int x1, int y, int x2, ToolLoop* loop) +{ +} + +static void ink_hline8_shading(int x1, int y, int x2, ToolLoop* loop) +{ + const Palette* pal = get_current_palette(); + tools::ShadeTable8* shadeTable = loop->getShadingOptions()->getShadeTable(); + bool left = (loop->getMouseButton() == ToolLoop::Left); + + DEFINE_INK_PROCESSING_SRCDST + (IndexedTraits, + if (left) + *dst_address = shadeTable->left(*src_address); + else + *dst_address = shadeTable->right(*src_address); + ); +} + ////////////////////////////////////////////////////////////////////// enum { @@ -459,6 +488,7 @@ enum { INK_BLUR, INK_REPLACE, INK_JUMBLE, + INK_SHADING, MAX_INKS }; @@ -473,5 +503,6 @@ static AlgoHLine ink_processing[][3] = DEF_INK(transparent), DEF_INK(blur), DEF_INK(replace), - DEF_INK(jumble) + DEF_INK(jumble), + DEF_INK(shading) }; diff --git a/src/tools/inks.h b/src/tools/inks.h index 053163427..253b6742a 100644 --- a/src/tools/inks.h +++ b/src/tools/inks.h @@ -76,6 +76,28 @@ public: }; +class ShadingInk : public Ink +{ +private: + AlgoHLine m_proc; + +public: + ShadingInk() { } + + bool isPaint() const { return true; } + + void prepareInk(ToolLoop* loop) + { + m_proc = ink_processing[INK_SHADING][MID(0, loop->getSprite()->getPixelFormat(), 2)]; + } + + void inkHline(int x1, int y, int x2, ToolLoop* loop) + { + (*m_proc)(x1, y, x2, loop); + } +}; + + class PickInk : public Ink { public: diff --git a/src/tools/shade_table.cpp b/src/tools/shade_table.cpp new file mode 100644 index 000000000..ffa7343a6 --- /dev/null +++ b/src/tools/shade_table.cpp @@ -0,0 +1,67 @@ +/* ASEPRITE + * Copyright (C) 2001-2013 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "tools/shade_table.h" + +#include "app/color_swatches.h" +#include "raster/palette.h" + +namespace tools { + +ShadeTable8::ShadeTable8(const app::ColorSwatches& colorSwatches, ShadingMode mode) +{ + m_left.resize(Palette::MaxColors); + m_right.resize(Palette::MaxColors); + + for (size_t i=0; i +#include "tools/shading_mode.h" + +namespace app { class ColorSwatches; } + +namespace tools { + +// Converts a ColorSwatches table to a temporary "shade table" used in +// shading ink so we can quickly rotate colors with left/right mouse +// buttons. +class ShadeTable8 +{ +public: + ShadeTable8(const app::ColorSwatches& colorSwatches, ShadingMode mode); + + uint8_t left(uint8_t index) { return m_left[index]; } + uint8_t right(uint8_t index) { return m_right[index]; } + +private: + std::vector m_left; + std::vector m_right; +}; + +} // namespace tools + +#endif // TOOLS_SHADE_TABLE_H_INCLUDED diff --git a/src/tools/shading_mode.h b/src/tools/shading_mode.h new file mode 100644 index 000000000..b9bacfce3 --- /dev/null +++ b/src/tools/shading_mode.h @@ -0,0 +1,36 @@ +/* ASEPRITE + * Copyright (C) 2001-2013 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TOOLS_SHADING_MODE_H_INCLUDED +#define TOOLS_SHADING_MODE_H_INCLUDED + +namespace tools { + +enum ShadingMode +{ + // When we reach the left/right side of the table, we stay there. + kDrainShadingMode, + + // Rotate colors (the leftmost is converted to the rightmost and + // viceversa). + kRotateShadingMode +}; + +} // namespace tools + +#endif // TOOLS_SHADING_MODE_H_INCLUDED diff --git a/src/tools/shading_options.h b/src/tools/shading_options.h new file mode 100644 index 000000000..31d15d22d --- /dev/null +++ b/src/tools/shading_options.h @@ -0,0 +1,35 @@ +/* ASEPRITE + * Copyright (C) 2001-2013 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TOOLS_SHADING_OPTIONS_H_INCLUDED +#define TOOLS_SHADING_OPTIONS_H_INCLUDED + +namespace tools { + +class ShadeTable8; + +class ShadingOptions +{ +public: + virtual ~ShadingOptions() { } + virtual ShadeTable8* getShadeTable() = 0; +}; + +} // namespace tools + +#endif // TOOLS_SHADING_OPTIONS_H_INCLUDED diff --git a/src/tools/tool_box.cpp b/src/tools/tool_box.cpp index cd05799b9..a8e4939d3 100644 --- a/src/tools/tool_box.cpp +++ b/src/tools/tool_box.cpp @@ -51,6 +51,7 @@ const char* WellKnownInks::Selection = "selection"; const char* WellKnownInks::Paint = "paint"; const char* WellKnownInks::PaintFg = "paint_fg"; const char* WellKnownInks::PaintBg = "paint_bg"; +const char* WellKnownInks::Shading = "shading"; const char* WellKnownInks::Eraser = "eraser"; const char* WellKnownInks::ReplaceFgWithBg = "replace_fg_with_bg"; const char* WellKnownInks::ReplaceBgWithFg = "replace_bg_with_fg"; @@ -71,6 +72,7 @@ ToolBox::ToolBox() m_inks[WellKnownInks::Paint] = new PaintInk(PaintInk::Normal); m_inks[WellKnownInks::PaintFg] = new PaintInk(PaintInk::WithFg); m_inks[WellKnownInks::PaintBg] = new PaintInk(PaintInk::WithBg); + m_inks[WellKnownInks::Shading] = new ShadingInk(); m_inks[WellKnownInks::Eraser] = new EraserInk(EraserInk::Eraser); m_inks[WellKnownInks::ReplaceFgWithBg] = new EraserInk(EraserInk::ReplaceFgWithBg); m_inks[WellKnownInks::ReplaceBgWithFg] = new EraserInk(EraserInk::ReplaceBgWithFg); diff --git a/src/tools/tool_box.h b/src/tools/tool_box.h index c28cb17e7..d6e2b1494 100644 --- a/src/tools/tool_box.h +++ b/src/tools/tool_box.h @@ -38,6 +38,7 @@ namespace WellKnownInks { extern const char* Paint; extern const char* PaintFg; extern const char* PaintBg; + extern const char* Shading; extern const char* Eraser; extern const char* ReplaceFgWithBg; extern const char* ReplaceBgWithFg; diff --git a/src/tools/tool_loop.h b/src/tools/tool_loop.h index 3af47c056..c88c87159 100644 --- a/src/tools/tool_loop.h +++ b/src/tools/tool_loop.h @@ -42,6 +42,7 @@ class Controller; class Ink; class Intertwine; class PointShape; +class ShadingOptions; class Tool; // Interface to communicate the sprite editor with the tool when the user @@ -161,6 +162,8 @@ public: virtual Intertwine* getIntertwine() = 0; virtual TracePolicy getTracePolicy() = 0; + virtual ShadingOptions* getShadingOptions() = 0; + // Used by the tool when the user cancels the operation pressing the // other mouse button. virtual void cancel() = 0; diff --git a/src/widgets/editor/tool_loop_impl.cpp b/src/widgets/editor/tool_loop_impl.cpp index 5068f5d21..1fd6cebc1 100644 --- a/src/widgets/editor/tool_loop_impl.cpp +++ b/src/widgets/editor/tool_loop_impl.cpp @@ -33,6 +33,8 @@ #include "settings/document_settings.h" #include "settings/settings.h" #include "tools/ink.h" +#include "tools/shade_table.h" +#include "tools/shading_options.h" #include "tools/tool.h" #include "tools/tool_box.h" #include "tools/tool_loop.h" @@ -47,7 +49,8 @@ using namespace ui; -class ToolLoopImpl : public tools::ToolLoop +class ToolLoopImpl : public tools::ToolLoop, + public tools::ShadingOptions { Editor* m_editor; Context* m_context; @@ -80,6 +83,7 @@ class ToolLoopImpl : public tools::ToolLoop UndoTransaction m_undoTransaction; ExpandCelCanvas m_expandCelCanvas; gfx::Region m_dirtyArea; + tools::ShadeTable8* m_shadeTable; public: ToolLoopImpl(Editor* editor, @@ -111,6 +115,7 @@ public: getInk()->isScrollMovement()) ? undo::DoesntModifyDocument: undo::ModifyDocument)) , m_expandCelCanvas(m_context, m_docSettings->getTiledMode(), m_undoTransaction) + , m_shadeTable(NULL) { // Settings switch (tool->getFill(m_button)) { @@ -183,6 +188,7 @@ public: } delete m_pen; + delete m_shadeTable; } // IToolLoop interface @@ -218,6 +224,7 @@ public: tools::PointShape* getPointShape() OVERRIDE { return m_tool->getPointShape(m_button); } tools::Intertwine* getIntertwine() OVERRIDE { return m_tool->getIntertwine(m_button); } tools::TracePolicy getTracePolicy() OVERRIDE { return m_tool->getTracePolicy(m_button); } + tools::ShadingOptions* getShadingOptions() OVERRIDE { return this; } void cancel() OVERRIDE { m_canceled = true; } bool isCanceled() OVERRIDE { return m_canceled; } @@ -245,6 +252,18 @@ public: StatusBar::instance()->setStatusText(0, text); } + // ShadingOptions implementation + tools::ShadeTable8* getShadeTable() OVERRIDE + { + if (m_shadeTable == NULL) { + app::ColorSwatches* colorSwatches = m_settings->getColorSwatches(); + ASSERT(colorSwatches != NULL); + m_shadeTable = new tools::ShadeTable8(*colorSwatches, + tools::kRotateShadingMode); + } + return m_shadeTable; + } + private: tools::Ink* getInkFromType() { @@ -263,7 +282,7 @@ private: id = WellKnownInks::Paint; break; case kShadingInk: - id = WellKnownInks::Paint; + id = WellKnownInks::Shading; break; case kReplaceInk: if (m_button == ToolLoop::Left)