Issue #2303 - Please add Constant type of gradient interpolation ...

... to make multi-color hard-edge gradient fills possible

Add a new "step" gradient-segment blending function, which is 0
before the midpoint, and 1 at, and after, the midpoint.  This
creates a hard-edge transition between the two adjacent color stops
at the midpoint.  Creating such a transition was already possible,
but required duplicating the same color at the opposing ends of two
adjacent stops, which is cumbersome.
This commit is contained in:
Ell 2018-10-02 21:13:16 -04:00
parent be84c6e766
commit 68bf99e806
7 changed files with 32 additions and 4 deletions

View File

@ -339,6 +339,11 @@ static const GimpRadioActionEntry gradient_editor_blending_actions[] =
GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING,
GIMP_HELP_GRADIENT_EDITOR_BLENDING }, GIMP_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-step", NULL,
NC_("gradient-editor-blending", "S_tep"), NULL, NULL,
GIMP_GRADIENT_SEGMENT_STEP,
GIMP_HELP_GRADIENT_EDITOR_BLENDING },
{ "gradient-editor-blending-varies", NULL, { "gradient-editor-blending-varies", NULL,
NC_("gradient-editor-blending", "(Varies)"), NULL, NULL, NC_("gradient-editor-blending", "(Varies)"), NULL, NULL,
-1, -1,
@ -826,6 +831,7 @@ gradient_editor_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("gradient-editor-blending-sine", editable); SET_SENSITIVE ("gradient-editor-blending-sine", editable);
SET_SENSITIVE ("gradient-editor-blending-sphere-increasing", editable); SET_SENSITIVE ("gradient-editor-blending-sphere-increasing", editable);
SET_SENSITIVE ("gradient-editor-blending-sphere-decreasing", editable); SET_SENSITIVE ("gradient-editor-blending-sphere-decreasing", editable);
SET_SENSITIVE ("gradient-editor-blending-step", editable);
if (blending_equal && gradient) if (blending_equal && gradient)
{ {
@ -846,6 +852,9 @@ gradient_editor_actions_update (GimpActionGroup *group,
case GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING: case GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING:
SET_ACTIVE ("gradient-editor-blending-sphere-decreasing", TRUE); SET_ACTIVE ("gradient-editor-blending-sphere-decreasing", TRUE);
break; break;
case GIMP_GRADIENT_SEGMENT_STEP:
SET_ACTIVE ("gradient-editor-blending-step", TRUE);
break;
} }
} }
else else

View File

@ -199,7 +199,7 @@ gimp_gradient_load (GimpContext *context,
case 2: case 2:
seg->type = (GimpGradientSegmentType) type; seg->type = (GimpGradientSegmentType) type;
if (seg->type < GIMP_GRADIENT_SEGMENT_LINEAR || if (seg->type < GIMP_GRADIENT_SEGMENT_LINEAR ||
seg->type > GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING) seg->type > GIMP_GRADIENT_SEGMENT_STEP)
{ {
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
_("Corrupt segment %d."), i); _("Corrupt segment %d."), i);

View File

@ -90,6 +90,8 @@ static inline gdouble gimp_gradient_calc_sphere_increasing_factor (gdouble mid
gdouble pos); gdouble pos);
static inline gdouble gimp_gradient_calc_sphere_decreasing_factor (gdouble middle, static inline gdouble gimp_gradient_calc_sphere_decreasing_factor (gdouble middle,
gdouble pos); gdouble pos);
static inline gdouble gimp_gradient_calc_step_factor (gdouble middle,
gdouble pos);
G_DEFINE_TYPE_WITH_CODE (GimpGradient, gimp_gradient, GIMP_TYPE_DATA, G_DEFINE_TYPE_WITH_CODE (GimpGradient, gimp_gradient, GIMP_TYPE_DATA,
@ -503,6 +505,10 @@ gimp_gradient_get_color_at (GimpGradient *gradient,
factor = gimp_gradient_calc_sphere_decreasing_factor (middle, pos); factor = gimp_gradient_calc_sphere_decreasing_factor (middle, pos);
break; break;
case GIMP_GRADIENT_SEGMENT_STEP:
factor = gimp_gradient_calc_step_factor (middle, pos);
break;
default: default:
g_warning ("%s: Unknown gradient type %d.", G_STRFUNC, seg->type); g_warning ("%s: Unknown gradient type %d.", G_STRFUNC, seg->type);
break; break;
@ -2273,3 +2279,10 @@ gimp_gradient_calc_sphere_decreasing_factor (gdouble middle,
/* Works for convex decreasing and concave increasing */ /* Works for convex decreasing and concave increasing */
return 1.0 - sqrt(1.0 - pos * pos); return 1.0 - sqrt(1.0 - pos * pos);
} }
static inline gdouble
gimp_gradient_calc_step_factor (gdouble middle,
gdouble pos)
{
return pos >= middle;
}

View File

@ -708,6 +708,7 @@ gimp_gradient_segment_type_get_type (void)
{ GIMP_GRADIENT_SEGMENT_SINE, "GIMP_GRADIENT_SEGMENT_SINE", "sine" }, { GIMP_GRADIENT_SEGMENT_SINE, "GIMP_GRADIENT_SEGMENT_SINE", "sine" },
{ GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING", "sphere-increasing" }, { GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING", "sphere-increasing" },
{ GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING", "sphere-decreasing" }, { GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING", "sphere-decreasing" },
{ GIMP_GRADIENT_SEGMENT_STEP, "GIMP_GRADIENT_SEGMENT_STEP", "step" },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };
@ -724,6 +725,7 @@ gimp_gradient_segment_type_get_type (void)
/* Translators: this is an abbreviated version of "Spherical (decreasing)". /* Translators: this is an abbreviated version of "Spherical (decreasing)".
Keep it short. */ Keep it short. */
{ GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, NC_("gradient-segment-type", "Spherical (dec)"), NULL }, { GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, NC_("gradient-segment-type", "Spherical (dec)"), NULL },
{ GIMP_GRADIENT_SEGMENT_STEP, NC_("gradient-segment-type", "Step"), NULL },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };

View File

@ -506,7 +506,8 @@ typedef enum
GIMP_GRADIENT_SEGMENT_CURVED, /*< desc="Curved" >*/ GIMP_GRADIENT_SEGMENT_CURVED, /*< desc="Curved" >*/
GIMP_GRADIENT_SEGMENT_SINE, /*< desc="Sinusoidal" >*/ GIMP_GRADIENT_SEGMENT_SINE, /*< desc="Sinusoidal" >*/
GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, /*< desc="Spherical (increasing)", abbrev="Spherical (inc)" >*/ GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, /*< desc="Spherical (increasing)", abbrev="Spherical (inc)" >*/
GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING /*< desc="Spherical (decreasing)", abbrev="Spherical (dec)" >*/ GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, /*< desc="Spherical (decreasing)", abbrev="Spherical (dec)" >*/
GIMP_GRADIENT_SEGMENT_STEP /*< desc="Step" >*/
} GimpGradientSegmentType; } GimpGradientSegmentType;

View File

@ -85,6 +85,7 @@
<menuitem action="gradient-editor-blending-sine" /> <menuitem action="gradient-editor-blending-sine" />
<menuitem action="gradient-editor-blending-sphere-increasing" /> <menuitem action="gradient-editor-blending-sphere-increasing" />
<menuitem action="gradient-editor-blending-sphere-decreasing" /> <menuitem action="gradient-editor-blending-sphere-decreasing" />
<menuitem action="gradient-editor-blending-step" />
<menuitem action="gradient-editor-blending-varies" /> <menuitem action="gradient-editor-blending-varies" />
</menu> </menu>
<menu action="gradient-editor-coloring-type"> <menu action="gradient-editor-coloring-type">

View File

@ -230,12 +230,14 @@ package Gimp::CodeGen::enums;
GIMP_GRADIENT_SEGMENT_CURVED GIMP_GRADIENT_SEGMENT_CURVED
GIMP_GRADIENT_SEGMENT_SINE GIMP_GRADIENT_SEGMENT_SINE
GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING
GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING) ], GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING
GIMP_GRADIENT_SEGMENT_STEP) ],
mapping => { GIMP_GRADIENT_SEGMENT_LINEAR => '0', mapping => { GIMP_GRADIENT_SEGMENT_LINEAR => '0',
GIMP_GRADIENT_SEGMENT_CURVED => '1', GIMP_GRADIENT_SEGMENT_CURVED => '1',
GIMP_GRADIENT_SEGMENT_SINE => '2', GIMP_GRADIENT_SEGMENT_SINE => '2',
GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING => '3', GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING => '3',
GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING => '4' } GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING => '4',
GIMP_GRADIENT_SEGMENT_STEP => '5' }
}, },
GimpGradientType => GimpGradientType =>
{ contig => 1, { contig => 1,