Add special mode (xor black/white) for selection tool (fix #301)

This change includes a blend mode for the document extra cel, but it's not
used to fix the issue.
This commit is contained in:
David Capello 2014-08-27 09:43:42 -03:00
parent 877d498160
commit 5ea5d0d92f
11 changed files with 118 additions and 18 deletions

View File

@ -75,8 +75,9 @@ bool FilterPreview::onProcessMessage(Message* msg)
switch (msg->type()) {
case kOpenMessage:
RenderEngine::setPreviewImage(m_filterMgr->layer(),
m_filterMgr->destinationImage());
RenderEngine::setPreviewImage(
m_filterMgr->layer(),
m_filterMgr->destinationImage());
break;
case kCloseMessage:

View File

@ -59,6 +59,7 @@ Document::Document(Sprite* sprite)
// Extra cel
, m_extraCel(NULL)
, m_extraImage(NULL)
, m_extraCelBlendMode(BLEND_MODE_NORMAL)
// Mask
, m_mask(new Mask())
, m_maskVisible(true)

View File

@ -129,6 +129,9 @@ namespace app {
Cel* getExtraCel() const;
Image* getExtraCelImage() const;
int getExtraCelBlendMode() const { return m_extraCelBlendMode; }
void setExtraCelBlendMode(int mode) { m_extraCelBlendMode = mode; }
//////////////////////////////////////////////////////////////////////
// Mask
@ -214,6 +217,7 @@ namespace app {
// Image of the extra cel.
Image* m_extraImage;
int m_extraCelBlendMode;
// Current mask.
base::UniquePtr<Mask> m_mask;

View File

@ -648,6 +648,51 @@ private:
bool m_left;
};
//////////////////////////////////////////////////////////////////////
// Xor Ink
//////////////////////////////////////////////////////////////////////
template<typename ImageTraits>
class XorInkProcessing : public DoubleInkProcessing<XorInkProcessing<ImageTraits>, ImageTraits> {
public:
XorInkProcessing(ToolLoop* loop) { }
void processPixel(int x, int y) {
// Do nothing
}
};
template<>
void XorInkProcessing<RgbTraits>::processPixel(int x, int y) {
*m_dstAddress = rgba_blend_blackandwhite(*m_srcAddress, 0, 255);
}
template<>
void XorInkProcessing<GrayscaleTraits>::processPixel(int x, int y) {
*m_dstAddress = graya_blend_blackandwhite(*m_srcAddress, 0, 255);
}
template<>
class XorInkProcessing<IndexedTraits> : public DoubleInkProcessing<XorInkProcessing<IndexedTraits>, IndexedTraits> {
public:
XorInkProcessing(ToolLoop* loop) :
m_palette(get_current_palette()),
m_rgbmap(loop->getRgbMap()),
m_color(m_palette->getEntry(loop->getPrimaryColor())) {
}
void processPixel(int x, int y) {
color_t c = rgba_blend_blackandwhite(m_palette->getEntry(*m_srcAddress), m_color, 255);
*m_dstAddress = m_rgbmap->mapColor(rgba_getr(c),
rgba_getg(c),
rgba_getb(c));
}
private:
const Palette* m_palette;
const RgbMap* m_rgbmap;
color_t m_color;
};
//////////////////////////////////////////////////////////////////////
enum {
@ -659,6 +704,7 @@ enum {
INK_REPLACE,
INK_JUMBLE,
INK_SHADING,
INK_XOR,
MAX_INKS
};
@ -672,7 +718,7 @@ void ink_processing_algo(int x1, int y, int x2, void* data)
AlgoHLine ink_processing[][3] =
{
#define DEFINE_INK(name) \
#define DEFINE_INK(name) \
{ ink_processing_algo<name<RgbTraits> >, \
ink_processing_algo<name<GrayscaleTraits> >, \
ink_processing_algo<name<IndexedTraits> > }
@ -684,7 +730,8 @@ AlgoHLine ink_processing[][3] =
DEFINE_INK(BlurInkProcessing),
DEFINE_INK(ReplaceInkProcessing),
DEFINE_INK(JumbleInkProcessing),
DEFINE_INK(ShadingInkProcessing)
DEFINE_INK(ShadingInkProcessing),
DEFINE_INK(XorInkProcessing)
};
} // anonymous namespace

View File

@ -278,7 +278,8 @@ public:
}
// TODO show the selection-preview with a XOR color or something like that
else {
draw_hline(loop->getDstImage(), x1, y, x2, loop->getPrimaryColor());
ink_processing[INK_XOR][MID(0, loop->sprite()->pixelFormat(), 2)]
(x1, y, x2, loop);
}
}

View File

@ -72,8 +72,9 @@ void ToolLoopManager::prepareLoop(const Pointer& pointer)
// Prepare preview image (the destination image will be our preview
// in the tool-loop time, so we can see what we are drawing)
RenderEngine::setPreviewImage(m_toolLoop->getLayer(),
m_toolLoop->getDstImage());
RenderEngine::setPreviewImage(
m_toolLoop->getLayer(),
m_toolLoop->getDstImage());
}
void ToolLoopManager::releaseLoop(const Pointer& pointer)

View File

@ -32,6 +32,7 @@
#include "app/tools/tool_loop_manager.h"
#include "app/ui/editor/editor.h"
#include "app/ui_context.h"
#include "raster/blend.h"
#include "ui/message.h"
#include "ui/system.h"

View File

@ -151,7 +151,10 @@ public:
brush_settings->getSize(),
brush_settings->getAngle());
m_useMask = m_document->isMaskVisible();
if (m_ink->isSelection())
m_useMask = false;
else
m_useMask = m_document->isMaskVisible();
// Selection ink
if (getInk()->isSelection() &&

View File

@ -289,7 +289,8 @@ static app::Color checked_bg_color2;
static int global_opacity = 255;
static const Layer* selected_layer = NULL;
static Image* rastering_image = NULL;
static Image* preview_image = NULL;
static int preview_blendmode = BLEND_MODE_NORMAL;
// static
void RenderEngine::loadConfig()
@ -370,7 +371,7 @@ RenderEngine::RenderEngine(const Document* document,
void RenderEngine::setPreviewImage(const Layer* layer, Image* image)
{
selected_layer = layer;
rastering_image = image;
preview_image = image;
}
/**
@ -585,11 +586,11 @@ void RenderEngine::renderLayer(
if (cel != NULL) {
Image* src_image;
// Is the 'rastering_image' set to be used with this layer?
// Is the 'preview_image' set to be used with this layer?
if ((frame == m_currentFrame) &&
(selected_layer == layer) &&
(rastering_image != NULL)) {
src_image = rastering_image;
(preview_image != NULL)) {
src_image = preview_image;
}
// If not, we use the original cel-image from the images' stock
else {
@ -608,9 +609,9 @@ void RenderEngine::renderLayer(
(cel->x() << zoom) - source_x,
(cel->y() << zoom) - source_y,
output_opacity,
blend_mode < 0 ?
(blend_mode < 0 ?
static_cast<const LayerImage*>(layer)->getBlendMode():
blend_mode,
blend_mode),
zoom);
}
}
@ -642,9 +643,10 @@ void RenderEngine::renderLayer(
Image* extraImage = m_document->getExtraCelImage();
(*zoomed_func)(image, extraImage, m_sprite->getPalette(frame),
(extraCel->x() << zoom) - source_x,
(extraCel->y() << zoom) - source_y,
extraCel->opacity(), BLEND_MODE_NORMAL, zoom);
(extraCel->x() << zoom) - source_x,
(extraCel->y() << zoom) - source_y,
extraCel->opacity(),
m_document->getExtraCelBlendMode(), zoom);
}
}
}

View File

@ -32,6 +32,7 @@ BLEND_COLOR rgba_blenders[] =
rgba_blend_merge,
rgba_blend_red_tint,
rgba_blend_blue_tint,
rgba_blend_blackandwhite,
};
BLEND_COLOR graya_blenders[] =
@ -41,6 +42,7 @@ BLEND_COLOR graya_blenders[] =
graya_blend_copy,
graya_blend_copy,
graya_blend_copy,
graya_blend_blackandwhite,
};
/**********************************************************************/
@ -195,6 +197,24 @@ int rgba_blend_blue_tint(int back, int front, int opacity)
return rgba_blend_color_tint(back, front, opacity, rgba(0, 0, 255, 128));
}
int rgba_blend_blackandwhite(int back, int front, int opacity)
{
int B_r, B_g, B_b, B_a;
int D_v;
B_r = rgba_getr(back);
B_g = rgba_getg(back);
B_b = rgba_getb(back);
B_a = rgba_geta(back);
if ((B_r*30 + B_g*59 + B_b*11)/100 < 128)
D_v = 255;
else
D_v = 0;
return rgba(D_v, D_v, D_v, B_a);
}
/**********************************************************************/
/* Grayscale blenders */
/**********************************************************************/
@ -272,4 +292,20 @@ int graya_blend_merge(int back, int front, int opacity)
return graya(D_k, D_a);
}
int graya_blend_blackandwhite(int back, int front, int opacity)
{
int B_k, B_a;
int D_k;
B_k = graya_getv(back);
B_a = graya_geta(back);
if (B_k < 128)
D_k = 255;
else
D_k = 0;
return graya(D_k, B_a);
}
} // namespace raster

View File

@ -31,6 +31,7 @@ namespace raster {
BLEND_MODE_MERGE,
BLEND_MODE_RED_TINT,
BLEND_MODE_BLUE_TINT,
BLEND_MODE_BLACKANDWHITE,
BLEND_MODE_MAX,
};
@ -45,11 +46,13 @@ namespace raster {
int rgba_blend_merge(int back, int front, int opacity);
int rgba_blend_red_tint(int back, int front, int opacity);
int rgba_blend_blue_tint(int back, int front, int opacity);
int rgba_blend_blackandwhite(int back, int front, int opacity);
int graya_blend_normal(int back, int front, int opacity);
int graya_blend_copy(int back, int front, int opacity);
int graya_blend_forpath(int back, int front, int opacity);
int graya_blend_merge(int back, int front, int opacity);
int graya_blend_blackandwhite(int back, int front, int opacity);
} // namespace raster