Change custom brush color when we change fg/bg colors

This commit is contained in:
David Capello 2016-02-25 18:48:59 -03:00
parent d10dd157e7
commit 5c61e92193
4 changed files with 142 additions and 6 deletions

View File

@ -1344,11 +1344,15 @@ ContextBar::ContextBar()
m_freehandAlgo->setupTooltips(tooltipManager);
m_symmetry->setupTooltips(tooltipManager);
Preferences::instance().toolBox.activeTool.AfterChange.connect(
auto& pref = Preferences::instance();
pref.toolBox.activeTool.AfterChange.connect(
base::Bind<void>(&ContextBar::onCurrentToolChange, this));
Preferences::instance().symmetryMode.enabled.AfterChange.connect(
pref.symmetryMode.enabled.AfterChange.connect(
base::Bind<void>(&ContextBar::onSymmetryModeChange, this));
pref.colorBar.fgColor.AfterChange.connect(
base::Bind<void>(&ContextBar::onFgOrBgColorChange, this, doc::Brush::ImageColor::MainColor));
pref.colorBar.bgColor.AfterChange.connect(
base::Bind<void>(&ContextBar::onFgOrBgColorChange, this, doc::Brush::ImageColor::BackgroundColor));
m_dropPixels->DropPixels.connect(&ContextBar::onDropPixels, this);
@ -1405,6 +1409,25 @@ void ContextBar::onSymmetryModeChange()
updateForCurrentTool();
}
void ContextBar::onFgOrBgColorChange(doc::Brush::ImageColor imageColor)
{
if (!m_activeBrush)
return;
if (m_activeBrush->type() == kImageBrushType) {
ASSERT(m_activeBrush->image());
auto& pref = Preferences::instance();
m_activeBrush->setImageColor(
imageColor,
color_utils::color_for_image(
(imageColor == doc::Brush::ImageColor::MainColor ?
pref.colorBar.fgColor():
pref.colorBar.bgColor()),
m_activeBrush->image()->pixelFormat()));
}
}
void ContextBar::onDropPixels(ContextBarObserver::DropAction action)
{
notifyObservers(&ContextBarObserver::onDropPixels, action);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -79,6 +79,7 @@ namespace app {
void onBrushAngleChange();
void onCurrentToolChange();
void onSymmetryModeChange();
void onFgOrBgColorChange(doc::Brush::ImageColor imageColor);
void onDropPixels(ContextBarObserver::DropAction action);
class BrushTypeField;

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -14,6 +14,7 @@
#include "doc/algo.h"
#include "doc/algorithm/polygon.h"
#include "doc/image.h"
#include "doc/image_impl.h"
#include "doc/primitives.h"
#include <cmath>
@ -92,6 +93,113 @@ void Brush::setImage(const Image* image)
m_image.get()->width(), m_image.get()->height());
}
template<class ImageTraits,
color_t color_mask,
color_t alpha_mask>
static void replace_image_colors(Image* image,
Brush::ImageColor imageColor,
color_t color)
{
typename LockImageBits<ImageTraits> bits(image, Image::ReadWriteLock);
bool hasAlpha = false; // True if "image" has a pixel with alpha < 255
color_t mainColor, bgColor;
color_t maskColor = image->maskColor();
mainColor = bgColor = 0;
for (const auto& pixel : bits) {
if ((pixel & alpha_mask) != alpha_mask) { // If alpha != 255
hasAlpha = true;
}
else if (bgColor == 0) {
mainColor = bgColor = pixel;
}
else if (pixel != bgColor && mainColor == bgColor) {
mainColor = pixel;
}
}
color &= color_mask;
if (hasAlpha) {
for (auto& pixel : bits)
pixel = (pixel & alpha_mask) | color;
}
else {
for (auto& pixel : bits) {
if ((mainColor == bgColor) ||
(pixel != bgColor && imageColor == Brush::ImageColor::MainColor) ||
(pixel == bgColor && imageColor == Brush::ImageColor::BackgroundColor)) {
pixel = (pixel & alpha_mask) | color;
}
}
}
}
static void replace_image_colors_indexed(Image* image,
Brush::ImageColor imageColor,
color_t color)
{
LockImageBits<IndexedTraits> bits(image, Image::ReadWriteLock);
bool hasAlpha = false; // True if "image" has a pixel with the mask color
color_t mainColor, bgColor;
color_t maskColor = image->maskColor();
mainColor = bgColor = maskColor;
for (const auto& pixel : bits) {
if (pixel == maskColor) {
hasAlpha = true;
}
else if (bgColor == maskColor) {
mainColor = bgColor = pixel;
}
else if (pixel != bgColor && mainColor == bgColor) {
mainColor = pixel;
}
}
if (hasAlpha) {
for (auto& pixel : bits)
if (pixel != maskColor)
pixel = color;
}
else {
for (auto& pixel : bits) {
if ((mainColor == bgColor) ||
(pixel != bgColor && imageColor == Brush::ImageColor::MainColor) ||
(pixel == bgColor && imageColor == Brush::ImageColor::BackgroundColor)) {
pixel = color;
}
}
}
}
void Brush::setImageColor(ImageColor imageColor, color_t color)
{
ASSERT(m_image);
if (!m_image)
return;
switch (m_image->pixelFormat()) {
case IMAGE_RGB:
replace_image_colors<RgbTraits, rgba_rgb_mask, rgba_a_mask>(
m_image.get(), imageColor, color);
break;
case IMAGE_GRAYSCALE:
replace_image_colors<GrayscaleTraits, graya_v_mask, graya_a_mask>(
m_image.get(), imageColor, color);
break;
case IMAGE_INDEXED:
replace_image_colors_indexed(
m_image.get(), imageColor, color);
break;
}
}
// Cleans the brush's data (image and region).
void Brush::clean()
{

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -10,6 +10,7 @@
#include "doc/brush_pattern.h"
#include "doc/brush_type.h"
#include "doc/color.h"
#include "doc/image_ref.h"
#include "gfx/point.h"
#include "gfx/rect.h"
@ -23,6 +24,8 @@ namespace doc {
static const int kMinBrushSize = 1;
static const int kMaxBrushSize = 64;
enum class ImageColor { MainColor, BackgroundColor };
Brush();
Brush(BrushType type, int size, int angle);
Brush(const Brush& brush);
@ -43,6 +46,7 @@ namespace doc {
void setSize(int size);
void setAngle(int angle);
void setImage(const Image* image);
void setImageColor(ImageColor imageColor, color_t color);
void setPattern(BrushPattern pattern) {
m_pattern = pattern;
}