Commit 99e80ca5 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

app/apptypes.h app/brush_select_cmds.c app/brushes_cmds.c app/layer_cmds.c

2001-01-09  Sven Neumann  <sven@gimp.org>

	* app/apptypes.h
	* app/brush_select_cmds.c
	* app/brushes_cmds.c
	* app/layer_cmds.c
	* app/layers_dialog.c
	* app/paint_funcs.c
	* app/tool_options.c
	* app/tools_cmds.c
	* libgimp/gimpenums.h
	* plug-ins/script-fu/script-fu-constants.c
	* tools/pdbgen/enums.pl: applied patch from <oliver@zeroknowledge.com>
	that adds new blending modes (Dodge/Burn/Hardlight). Please play with
	these new modes and check if they are useful and well-implemented.
parent d701e442
2001-01-09 Sven Neumann <sven@gimp.org>
* app/apptypes.h
* app/brush_select_cmds.c
* app/brushes_cmds.c
* app/layer_cmds.c
* app/layers_dialog.c
* app/paint_funcs.c
* app/tool_options.c
* app/tools_cmds.c
* libgimp/gimpenums.h
* plug-ins/script-fu/script-fu-constants.c
* tools/pdbgen/enums.pl: applied patch from <oliver@zeroknowledge.com>
that adds new blending modes (Dodge/Burn/Hardlight). Please play with
these new modes and check if they are useful and well-implemented.
2001-01-09 Sven Neumann <sven@gimp.org> 2001-01-09 Sven Neumann <sven@gimp.org>
* HACKING: added notice about autogenerated files. * HACKING: added notice about autogenerated files.
......
...@@ -88,6 +88,9 @@ typedef enum ...@@ -88,6 +88,9 @@ typedef enum
COLOR_MODE, COLOR_MODE,
VALUE_MODE, VALUE_MODE,
DIVIDE_MODE, DIVIDE_MODE,
DODGE_MODE,
BURN_MODE,
HARDLIGHT_MODE,
ERASE_MODE, /*< skip >*/ ERASE_MODE, /*< skip >*/
REPLACE_MODE, /*< skip >*/ REPLACE_MODE, /*< skip >*/
ANTI_ERASE_MODE /*< skip >*/ ANTI_ERASE_MODE /*< skip >*/
......
...@@ -88,7 +88,7 @@ brushes_popup_invoker (Argument *args) ...@@ -88,7 +88,7 @@ brushes_popup_invoker (Argument *args)
spacing = args[4].value.pdb_int; spacing = args[4].value.pdb_int;
paint_mode = args[5].value.pdb_int; paint_mode = args[5].value.pdb_int;
if (paint_mode < NORMAL_MODE || paint_mode > DIVIDE_MODE) if (paint_mode < NORMAL_MODE || paint_mode > HARDLIGHT_MODE)
success = FALSE; success = FALSE;
if (success) if (success)
...@@ -141,7 +141,7 @@ static ProcArg brushes_popup_inargs[] = ...@@ -141,7 +141,7 @@ static ProcArg brushes_popup_inargs[] =
{ {
PDB_INT32, PDB_INT32,
"paint_mode", "paint_mode",
"The initial paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The initial paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
} }
}; };
...@@ -245,7 +245,7 @@ brushes_set_popup_invoker (Argument *args) ...@@ -245,7 +245,7 @@ brushes_set_popup_invoker (Argument *args)
spacing = args[3].value.pdb_int; spacing = args[3].value.pdb_int;
paint_mode = args[4].value.pdb_int; paint_mode = args[4].value.pdb_int;
if (paint_mode < NORMAL_MODE || paint_mode > DIVIDE_MODE) if (paint_mode < NORMAL_MODE || paint_mode > HARDLIGHT_MODE)
success = FALSE; success = FALSE;
if (success) if (success)
...@@ -300,7 +300,7 @@ static ProcArg brushes_set_popup_inargs[] = ...@@ -300,7 +300,7 @@ static ProcArg brushes_set_popup_inargs[] =
{ {
PDB_INT32, PDB_INT32,
"paint_mode", "paint_mode",
"The initial paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The initial paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
} }
}; };
......
...@@ -374,7 +374,7 @@ static ProcArg brushes_get_paint_mode_outargs[] = ...@@ -374,7 +374,7 @@ static ProcArg brushes_get_paint_mode_outargs[] =
{ {
PDB_INT32, PDB_INT32,
"paint_mode", "paint_mode",
"The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
} }
}; };
...@@ -401,7 +401,7 @@ brushes_set_paint_mode_invoker (Argument *args) ...@@ -401,7 +401,7 @@ brushes_set_paint_mode_invoker (Argument *args)
gint32 paint_mode; gint32 paint_mode;
paint_mode = args[0].value.pdb_int; paint_mode = args[0].value.pdb_int;
if (paint_mode < NORMAL_MODE || paint_mode > DIVIDE_MODE) if (paint_mode < NORMAL_MODE || paint_mode > HARDLIGHT_MODE)
success = FALSE; success = FALSE;
if (success) if (success)
...@@ -415,7 +415,7 @@ static ProcArg brushes_set_paint_mode_inargs[] = ...@@ -415,7 +415,7 @@ static ProcArg brushes_set_paint_mode_inargs[] =
{ {
PDB_INT32, PDB_INT32,
"paint_mode", "paint_mode",
"The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
} }
}; };
...@@ -585,7 +585,7 @@ static ProcArg brushes_get_brush_data_outargs[] = ...@@ -585,7 +585,7 @@ static ProcArg brushes_get_brush_data_outargs[] =
{ {
PDB_INT32, PDB_INT32,
"paint_mode", "paint_mode",
"The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The paint mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
}, },
{ {
PDB_INT32, PDB_INT32,
......
...@@ -948,10 +948,13 @@ paint_mode_menu_new (GtkSignalFunc callback, ...@@ -948,10 +948,13 @@ paint_mode_menu_new (GtkSignalFunc callback,
_("Normal"), (gpointer) NORMAL_MODE, NULL, _("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL, _("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Behind"), (gpointer) BEHIND_MODE, NULL, _("Behind"), (gpointer) BEHIND_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL, _("Multiply"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL, _("Divide"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL, _("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL, _("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Dodge"), (gpointer) DODGE_MODE, NULL,
_("Burn"), (gpointer) BURN_MODE, NULL,
_("Hard Light"), (gpointer) HARDLIGHT_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL, _("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL, _("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL, _("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
......
...@@ -378,10 +378,13 @@ layers_dialog_create (void) ...@@ -378,10 +378,13 @@ layers_dialog_create (void)
NULL, (gpointer) NORMAL_MODE, NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL, _("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL, _("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL, _("Multiply"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL, _("Divide"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL, _("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL, _("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Dodge"), (gpointer) DODGE_MODE, NULL,
_("Burn"), (gpointer) BURN_MODE, NULL,
_("Hard Light"), (gpointer) HARDLIGHT_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL, _("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL, _("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL, _("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
......
...@@ -139,7 +139,7 @@ layer_new_invoker (Argument *args) ...@@ -139,7 +139,7 @@ layer_new_invoker (Argument *args)
success = FALSE; success = FALSE;
mode = args[6].value.pdb_int; mode = args[6].value.pdb_int;
if (mode < NORMAL_MODE || mode > DIVIDE_MODE) if (mode < NORMAL_MODE || mode > HARDLIGHT_MODE)
success = FALSE; success = FALSE;
if (success) if (success)
...@@ -192,7 +192,7 @@ static ProcArg layer_new_inargs[] = ...@@ -192,7 +192,7 @@ static ProcArg layer_new_inargs[] =
{ {
PDB_INT32, PDB_INT32,
"mode", "mode",
"The layer combination mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15) }" "The layer combination mode: { NORMAL_MODE (0), DISSOLVE_MODE (1), BEHIND_MODE (2), MULTIPLY_MODE (3), SCREEN_MODE (4), OVERLAY_MODE (5), DIFFERENCE_MODE (6), ADDITION_MODE (7), SUBTRACT_MODE (8), DARKEN_ONLY_MODE (9), LIGHTEN_ONLY_MODE (10), HUE_MODE (11), SATURATION_MODE (12), COLOR_MODE (13), VALUE_MODE (14), DIVIDE_MODE (15), DODGE_MODE (16), BURN_MODE (17), HARDLIGHT_MODE (18) }"
} }
}; };
...@@ -1688,7 +1688,7 @@ layer_set_mode_invoker (Argument *args) ...@@ -1688,7 +1688,7 @@ layer_set_mode_invoker (Argument *args)
success = FALSE; success = FALSE;
mode = args[1].value.pdb_int; mode = args[1].value.pdb_int;
if (mode < NORMAL_MODE || mode > DIVIDE_MODE) if (mode < NORMAL_MODE || mode > HARDLIGHT_MODE)
success = FALSE; success = FALSE;
if (success) if (success)
......
...@@ -378,10 +378,13 @@ layers_dialog_create (void) ...@@ -378,10 +378,13 @@ layers_dialog_create (void)
NULL, (gpointer) NORMAL_MODE, NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL, _("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL, _("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL, _("Multiply"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL, _("Divide"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL, _("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL, _("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Dodge"), (gpointer) DODGE_MODE, NULL,
_("Burn"), (gpointer) BURN_MODE, NULL,
_("Hard Light"), (gpointer) HARDLIGHT_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL, _("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL, _("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL, _("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
......
...@@ -106,7 +106,10 @@ LayerMode layer_modes[] = /* This must obviously be in the same ...@@ -106,7 +106,10 @@ LayerMode layer_modes[] = /* This must obviously be in the same
{ 0, 0, 0, N_("Divide (Dodge)") }, { 0, 0, 0, N_("Divide (Dodge)") },
{ 1, 0, 1, N_("Erase") }, { 1, 0, 1, N_("Erase") },
{ 1, 1, 1, N_("Replace") }, { 1, 1, 1, N_("Replace") },
{ 1, 0, 1, N_("Anti Erase") } { 1, 0, 1, N_("Anti Erase") },
{ 0, 0, 0, N_("Dodge") },
{ 0, 0, 0, N_("Burn") },
{ 0, 0, 0, N_("Hard Light") }
}; };
/* ColorHash structure */ /* ColorHash structure */
...@@ -1026,6 +1029,118 @@ overlay_pixels (const guchar *src1, ...@@ -1026,6 +1029,118 @@ overlay_pixels (const guchar *src1,
} }
void
dodge_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
int tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
tmp1 = src1[b] << 8;
tmp1 /= 256 - src2[b];
dest[b] = (guchar) CLAMP (tmp1, 0, 255);
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void
burn_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
gint tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
tmp1 = (255 - src1[b]) << 8;
tmp1 /= src2[b] + 1;
dest[b] = (guchar) CLAMP (255 - tmp1, 0, 255);
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void
hardlight_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
gint tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
if (src2[b] > 128) {
tmp1 = ((gint)255 - src1[b]) * ((gint)255 - ((src2[b] - 128) << 1));
dest[b] = (guchar)CLAMP(255 - (tmp1 >> 8), 0, 255);
} else {
tmp1 = (gint)src1[b] * ((gint)src2[b] << 1);
dest[b] = (guchar)CLAMP(tmp1 >> 8, 0, 255);
}
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void void
add_pixels (const guchar *src1, add_pixels (const guchar *src1,
const guchar *src2, const guchar *src2,
...@@ -5957,6 +6072,18 @@ apply_layer_mode (guchar *src1, ...@@ -5957,6 +6072,18 @@ apply_layer_mode (guchar *src1,
combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine; combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine;
break; break;
case DODGE_MODE:
dodge_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
case BURN_MODE:
burn_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
case HARDLIGHT_MODE:
hardlight_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
default : default :
break; break;
} }
......
...@@ -106,7 +106,10 @@ LayerMode layer_modes[] = /* This must obviously be in the same ...@@ -106,7 +106,10 @@ LayerMode layer_modes[] = /* This must obviously be in the same
{ 0, 0, 0, N_("Divide (Dodge)") }, { 0, 0, 0, N_("Divide (Dodge)") },
{ 1, 0, 1, N_("Erase") }, { 1, 0, 1, N_("Erase") },
{ 1, 1, 1, N_("Replace") }, { 1, 1, 1, N_("Replace") },
{ 1, 0, 1, N_("Anti Erase") } { 1, 0, 1, N_("Anti Erase") },
{ 0, 0, 0, N_("Dodge") },
{ 0, 0, 0, N_("Burn") },
{ 0, 0, 0, N_("Hard Light") }
}; };
/* ColorHash structure */ /* ColorHash structure */
...@@ -1026,6 +1029,118 @@ overlay_pixels (const guchar *src1, ...@@ -1026,6 +1029,118 @@ overlay_pixels (const guchar *src1,
} }
void
dodge_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
int tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
tmp1 = src1[b] << 8;
tmp1 /= 256 - src2[b];
dest[b] = (guchar) CLAMP (tmp1, 0, 255);
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void
burn_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
gint tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
tmp1 = (255 - src1[b]) << 8;
tmp1 /= src2[b] + 1;
dest[b] = (guchar) CLAMP (255 - tmp1, 0, 255);
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void
hardlight_pixels (const guchar *src1,
const guchar *src2,
guchar *dest,
gint length,
gint b1,
gint b2,
gint ha1,
gint ha2)
{
gint alpha, b;
gint tmp1;
alpha = (ha1 || ha2) ? MAX (b1, b2) - 1 : b1;
while (length --)
{
for (b = 0; b < alpha; b++)
{
if (src2[b] > 128) {
tmp1 = ((gint)255 - src1[b]) * ((gint)255 - ((src2[b] - 128) << 1));
dest[b] = (guchar)CLAMP(255 - (tmp1 >> 8), 0, 255);
} else {
tmp1 = (gint)src1[b] * ((gint)src2[b] << 1);
dest[b] = (guchar)CLAMP(tmp1 >> 8, 0, 255);
}
}
if (ha1 && ha2)
dest[alpha] = MIN (src1[alpha], src2[alpha]);
else if (ha2)
dest[alpha] = src2[alpha];
src1 += b1;
src2 += b2;
dest += b2;
}
}
void void
add_pixels (const guchar *src1, add_pixels (const guchar *src1,
const guchar *src2, const guchar *src2,
...@@ -5957,6 +6072,18 @@ apply_layer_mode (guchar *src1, ...@@ -5957,6 +6072,18 @@ apply_layer_mode (guchar *src1,
combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine; combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine;
break; break;
case DODGE_MODE:
dodge_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
case BURN_MODE:
burn_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
case HARDLIGHT_MODE:
hardlight_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
break;
default : default :
break; break;
} }
......
...@@ -948,10 +948,13 @@ paint_mode_menu_new (GtkSignalFunc callback, ...@@ -948,10 +948,13 @@ paint_mode_menu_new (GtkSignalFunc callback,
_("Normal"), (gpointer) NORMAL_MODE, NULL, _("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL, _("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Behind"), (gpointer) BEHIND_MODE, NULL, _("Behind"), (gpointer) BEHIND_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL, _("Multiply"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL, _("Divide"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL, _("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL, _("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Dodge"), (gpointer) DODGE_MODE, NULL,
_("Burn"), (gpointer) BURN_MODE, NULL,
_("Hard Light"), (gpointer) HARDLIGHT_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL, _("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL, _("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL, _("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
......