From 68bf99e806ba38a06df92d736dab65e6cd17a44c Mon Sep 17 00:00:00 2001 From: Ell Date: Tue, 2 Oct 2018 21:13:16 -0400 Subject: [PATCH] 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. --- app/actions/gradient-editor-actions.c | 9 +++++++++ app/core/gimpgradient-load.c | 2 +- app/core/gimpgradient.c | 13 +++++++++++++ libgimpbase/gimpbaseenums.c | 2 ++ libgimpbase/gimpbaseenums.h | 3 ++- menus/gradient-editor-menu.xml | 1 + pdb/enums.pl | 6 ++++-- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/app/actions/gradient-editor-actions.c b/app/actions/gradient-editor-actions.c index 62eeb4dd84..fc04254684 100644 --- a/app/actions/gradient-editor-actions.c +++ b/app/actions/gradient-editor-actions.c @@ -339,6 +339,11 @@ static const GimpRadioActionEntry gradient_editor_blending_actions[] = GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, 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, NC_("gradient-editor-blending", "(Varies)"), NULL, NULL, -1, @@ -826,6 +831,7 @@ gradient_editor_actions_update (GimpActionGroup *group, SET_SENSITIVE ("gradient-editor-blending-sine", editable); SET_SENSITIVE ("gradient-editor-blending-sphere-increasing", editable); SET_SENSITIVE ("gradient-editor-blending-sphere-decreasing", editable); + SET_SENSITIVE ("gradient-editor-blending-step", editable); if (blending_equal && gradient) { @@ -846,6 +852,9 @@ gradient_editor_actions_update (GimpActionGroup *group, case GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING: SET_ACTIVE ("gradient-editor-blending-sphere-decreasing", TRUE); break; + case GIMP_GRADIENT_SEGMENT_STEP: + SET_ACTIVE ("gradient-editor-blending-step", TRUE); + break; } } else diff --git a/app/core/gimpgradient-load.c b/app/core/gimpgradient-load.c index 03527e85d4..1abe49498e 100644 --- a/app/core/gimpgradient-load.c +++ b/app/core/gimpgradient-load.c @@ -199,7 +199,7 @@ gimp_gradient_load (GimpContext *context, case 2: seg->type = (GimpGradientSegmentType) type; 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, _("Corrupt segment %d."), i); diff --git a/app/core/gimpgradient.c b/app/core/gimpgradient.c index ef09657626..b64a19a6a5 100644 --- a/app/core/gimpgradient.c +++ b/app/core/gimpgradient.c @@ -90,6 +90,8 @@ static inline gdouble gimp_gradient_calc_sphere_increasing_factor (gdouble mid gdouble pos); static inline gdouble gimp_gradient_calc_sphere_decreasing_factor (gdouble middle, 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, @@ -503,6 +505,10 @@ gimp_gradient_get_color_at (GimpGradient *gradient, factor = gimp_gradient_calc_sphere_decreasing_factor (middle, pos); break; + case GIMP_GRADIENT_SEGMENT_STEP: + factor = gimp_gradient_calc_step_factor (middle, pos); + break; + default: g_warning ("%s: Unknown gradient type %d.", G_STRFUNC, seg->type); break; @@ -2273,3 +2279,10 @@ gimp_gradient_calc_sphere_decreasing_factor (gdouble middle, /* Works for convex decreasing and concave increasing */ return 1.0 - sqrt(1.0 - pos * pos); } + +static inline gdouble +gimp_gradient_calc_step_factor (gdouble middle, + gdouble pos) +{ + return pos >= middle; +} diff --git a/libgimpbase/gimpbaseenums.c b/libgimpbase/gimpbaseenums.c index f4a65c70f6..d7af905575 100644 --- a/libgimpbase/gimpbaseenums.c +++ b/libgimpbase/gimpbaseenums.c @@ -708,6 +708,7 @@ gimp_gradient_segment_type_get_type (void) { 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_DECREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING", "sphere-decreasing" }, + { GIMP_GRADIENT_SEGMENT_STEP, "GIMP_GRADIENT_SEGMENT_STEP", "step" }, { 0, NULL, NULL } }; @@ -724,6 +725,7 @@ gimp_gradient_segment_type_get_type (void) /* Translators: this is an abbreviated version of "Spherical (decreasing)". Keep it short. */ { 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 } }; diff --git a/libgimpbase/gimpbaseenums.h b/libgimpbase/gimpbaseenums.h index 4ae8ed6a5c..2f41cccde5 100644 --- a/libgimpbase/gimpbaseenums.h +++ b/libgimpbase/gimpbaseenums.h @@ -506,7 +506,8 @@ typedef enum GIMP_GRADIENT_SEGMENT_CURVED, /*< desc="Curved" >*/ GIMP_GRADIENT_SEGMENT_SINE, /*< desc="Sinusoidal" >*/ 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; diff --git a/menus/gradient-editor-menu.xml b/menus/gradient-editor-menu.xml index 85fcbb17e4..4d2db9a0ae 100644 --- a/menus/gradient-editor-menu.xml +++ b/menus/gradient-editor-menu.xml @@ -85,6 +85,7 @@ + diff --git a/pdb/enums.pl b/pdb/enums.pl index 906cedf344..06dfd46571 100644 --- a/pdb/enums.pl +++ b/pdb/enums.pl @@ -230,12 +230,14 @@ package Gimp::CodeGen::enums; GIMP_GRADIENT_SEGMENT_CURVED GIMP_GRADIENT_SEGMENT_SINE 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', GIMP_GRADIENT_SEGMENT_CURVED => '1', GIMP_GRADIENT_SEGMENT_SINE => '2', GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING => '3', - GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING => '4' } + GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING => '4', + GIMP_GRADIENT_SEGMENT_STEP => '5' } }, GimpGradientType => { contig => 1,