Commit 5d7bf3ca authored by Martin Nordholts's avatar Martin Nordholts
Browse files

Implemented Erase, Anti Erase, Color Erase and Replace. These are not

* app/gegl/gimpoperationpointlayermode.c
(gimp_operation_point_layer_mode_process): Implemented Erase, Anti
Erase, Color Erase and Replace. These are not normal layer modes
and handle alpha in their own way. In addition to this, the
behavior of Replace doesn't map very well to GEGL which uses
infinite sized "layers".

Completely works the same:
 o Erase
 o Anti Erase
 o Color Erase

Works different but similar:
 o Replace

* app/paint-funcs/paint-funcs.[ch]: Expose
paint_funcs_color_erase_helper() so it can be used in the
GimpOperationPointLayerMode implementation. Once the migration is
complete this function can be moved entirely to the op and be
tailored to work on premultiplied data.

svn path=/trunk/; revision=27502
parent 2fe030bd
2008-10-31 Martin Nordholts <martinn@svn.gnome.org>
* app/gegl/gimpoperationpointlayermode.c
(gimp_operation_point_layer_mode_process): Implemented Erase, Anti
Erase, Color Erase and Replace. These are not normal layer modes
and handle alpha in their own way. In addition to this, the
behavior of Replace doesn't map very well to GEGL which uses
infinite sized "layers".
Completely works the same:
o Erase
o Anti Erase
o Color Erase
Works different but similar:
o Replace
* app/paint-funcs/paint-funcs.[ch]: Expose
paint_funcs_color_erase_helper() so it can be used in the
GimpOperationPointLayerMode implementation. Once the migration is
complete this function can be moved entirely to the op and be
tailored to work on premultiplied data.
2008-10-31 Sven Neumann <sven@gimp.org> 2008-10-31 Sven Neumann <sven@gimp.org>
Bug 558660 – help behavior for locales without manual translation Bug 558660 – help behavior for locales without manual translation
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include "gegl-types.h" #include "gegl-types.h"
#include "paint-funcs/paint-funcs.h"
#include "gimpoperationpointlayermode.h" #include "gimpoperationpointlayermode.h"
...@@ -270,6 +272,32 @@ gimp_operation_point_layer_mode_get_new_color_hsl (GimpLayerModeEffects blend_m ...@@ -270,6 +272,32 @@ gimp_operation_point_layer_mode_get_new_color_hsl (GimpLayerModeEffects blend_m
new[B] = newRGB.b; new[B] = newRGB.b;
} }
static void
gimp_operation_point_layer_mode_get_color_erase_color (const gfloat *in,
const gfloat *lay,
gfloat *out)
{
GimpRGB inRGB;
GimpRGB layRGB;
if (inA <= 0.0)
gimp_rgba_set (&inRGB, 0.0, 0.0, 0.0, inA);
else
gimp_rgba_set (&inRGB, in[R] / inA, in[G] / inA, in[B] / inA, inA);
if (layA <= 0.0)
gimp_rgba_set (&layRGB, 0.0, 0.0, 0.0, layA);
else
gimp_rgba_set (&layRGB, lay[R] / layA, lay[G] / layA, lay[B] / layA, layA);
paint_funcs_color_erase_helper (&inRGB, &layRGB);
out[A] = inRGB.a;
out[R] = inRGB.r * out[A];
out[G] = inRGB.g * out[A];
out[B] = inRGB.b * out[A];
}
static gboolean static gboolean
gimp_operation_point_layer_mode_process (GeglOperation *operation, gimp_operation_point_layer_mode_process (GeglOperation *operation,
void *in_buf, void *in_buf,
...@@ -296,6 +324,77 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation, ...@@ -296,6 +324,77 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation,
{ {
switch (blend_mode) switch (blend_mode)
{ {
case GIMP_ERASE_MODE:
case GIMP_ANTI_ERASE_MODE:
case GIMP_COLOR_ERASE_MODE:
case GIMP_REPLACE_MODE:
case GIMP_DISSOLVE_MODE:
/* These modes handle alpha themselves */
break;
default:
/* Porter-Duff model for the rest */
outA = layA + inA - layA * inA;
}
switch (blend_mode)
{
case GIMP_ERASE_MODE:
/* Eraser mode */
outA = inA - inA * layA;
if (inA <= 0.0)
EACH_CHANNEL (
outC = 0.0)
else
EACH_CHANNEL (
outC = (inC / inA) * outA);
break;
case GIMP_ANTI_ERASE_MODE:
/* Eraser mode */
outA = inA + (1 - inA) * layA;
if (inA <= 0.0)
EACH_CHANNEL (
outC = 0.0)
else
EACH_CHANNEL (
outC = inC / inA * outA);
break;
case GIMP_COLOR_ERASE_MODE:
/* Paint mode */
gimp_operation_point_layer_mode_get_color_erase_color (in, lay, out);
break;
case GIMP_REPLACE_MODE:
/* Filter fade mode */
outA = layA;
EACH_CHANNEL(
outC = layC);
break;
case GIMP_DISSOLVE_MODE:
/* We need a deterministic result from Dissolve so let the
* seed depend on the pixel position (modulo 1024)
*/
g_rand_set_seed (rand,
((roi->x + sample - (sample / roi->width) * roi->width) % 1024) *
((roi->y + sample / roi->width) % 1024));
if (layA * G_MAXUINT32 >= g_rand_int (rand))
{
outA = 1.0;
EACH_CHANNEL (
outC = layC / layA);
}
else
{
outA = inA;
EACH_CHANNEL (
outC = inC);
}
break;
case GIMP_NORMAL_MODE: case GIMP_NORMAL_MODE:
/* Porter-Duff A over B */ /* Porter-Duff A over B */
EACH_CHANNEL ( EACH_CHANNEL (
...@@ -497,47 +596,11 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation, ...@@ -497,47 +596,11 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation,
outC = newC * layA * inA + layC * (1 - inA) + inC * (1 - layA)); outC = newC * layA * inA + layC * (1 - inA) + inC * (1 - layA));
break; break;
case GIMP_ERASE_MODE:
case GIMP_ANTI_ERASE_MODE:
case GIMP_COLOR_ERASE_MODE:
case GIMP_REPLACE_MODE:
/* Icky eraser and paint modes */
break;
case GIMP_DISSOLVE_MODE:
/* We need a deterministic result from Dissolve so let the
* seed depend on the pixel position (modulo 1024)
*/
g_rand_set_seed (rand,
((roi->x + sample - (sample / roi->width) * roi->width) % 1024) *
((roi->y + sample / roi->width) % 1024));
if (layA * G_MAXUINT32 >= g_rand_int (rand))
{
EACH_CHANNEL(
outC = layC / layA);
/* Use general outA calculation */
layA = 1.0;
}
else
{
EACH_CHANNEL(
outC = inC);
/* Use general outA calculation */
layA = 0.0;
}
break;
default: default:
g_error ("Unknown layer mode"); g_error ("Unknown layer mode");
break; break;
} }
/* Alpha is treated the same */
outA = layA + inA - layA * inA;
in += 4; in += 4;
lay += 4; lay += 4;
out += 4; out += 4;
......
...@@ -1599,8 +1599,8 @@ anti_erase_indexed_pixels (const guchar *src1, ...@@ -1599,8 +1599,8 @@ anti_erase_indexed_pixels (const guchar *src1,
} }
static inline void void
color_erase_helper (GimpRGB *src, paint_funcs_color_erase_helper (GimpRGB *src,
const GimpRGB *color) const GimpRGB *color)
{ {
GimpRGB alpha; GimpRGB alpha;
...@@ -1692,7 +1692,7 @@ color_erase_inten_pixels (const guchar *src1, ...@@ -1692,7 +1692,7 @@ color_erase_inten_pixels (const guchar *src1,
gimp_rgba_set_uchar (&bgcolor, gimp_rgba_set_uchar (&bgcolor,
src2[0], src2[0], src2[0], src2_alpha); src2[0], src2[0], src2[0], src2_alpha);
color_erase_helper (&color, &bgcolor); paint_funcs_color_erase_helper (&color, &bgcolor);
gimp_rgba_get_uchar (&color, dest, NULL, NULL, dest + 1); gimp_rgba_get_uchar (&color, dest, NULL, NULL, dest + 1);
break; break;
...@@ -1706,7 +1706,7 @@ color_erase_inten_pixels (const guchar *src1, ...@@ -1706,7 +1706,7 @@ color_erase_inten_pixels (const guchar *src1,
gimp_rgba_set_uchar (&bgcolor, gimp_rgba_set_uchar (&bgcolor,
src2[0], src2[1], src2[2], src2_alpha); src2[0], src2[1], src2[2], src2_alpha);
color_erase_helper (&color, &bgcolor); paint_funcs_color_erase_helper (&color, &bgcolor);
gimp_rgba_get_uchar (&color, dest, dest + 1, dest + 2, dest + 3); gimp_rgba_get_uchar (&color, dest, dest + 1, dest + 2, dest + 3);
break; break;
......
...@@ -312,6 +312,10 @@ void combine_inten_a_and_channel_selection_pixels(const guchar *src, ...@@ -312,6 +312,10 @@ void combine_inten_a_and_channel_selection_pixels(const guchar *src,
guint length, guint length,
guint bytes); guint bytes);
void paint_funcs_color_erase_helper (GimpRGB *src,
const GimpRGB *color);
/* extract information from intensity pixels based on /* extract information from intensity pixels based on
* a mask. * a mask.
*/ */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment