diff --git a/app/core/core-enums.c b/app/core/core-enums.c index 90646ec1f5..222d678915 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -360,6 +360,35 @@ gimp_convolution_type_get_type (void) return type; } +GType +gimp_curve_point_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CURVE_POINT_SMOOTH, "GIMP_CURVE_POINT_SMOOTH", "smooth" }, + { GIMP_CURVE_POINT_CORNER, "GIMP_CURVE_POINT_CORNER", "corner" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CURVE_POINT_SMOOTH, NC_("curve-point-type", "Smooth"), NULL }, + { GIMP_CURVE_POINT_CORNER, NC_("curve-point-type", "Corner"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCurvePointType", values); + gimp_type_set_translation_context (type, "curve-point-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + GType gimp_curve_type_get_type (void) { diff --git a/app/core/core-enums.h b/app/core/core-enums.h index 2f7c53ab7c..d10068c6b3 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -196,6 +196,17 @@ typedef enum /*< pdb-skip >*/ } GimpConvolutionType; +#define GIMP_TYPE_CURVE_POINT_TYPE (gimp_curve_point_type_get_type ()) + +GType gimp_curve_point_type_get_type (void) G_GNUC_CONST; + +typedef enum /*< pdb-skip >*/ +{ + GIMP_CURVE_POINT_SMOOTH, /*< desc="Smooth" >*/ + GIMP_CURVE_POINT_CORNER /*< desc="Corner" >*/ +} GimpCurvePointType; + + #define GIMP_TYPE_CURVE_TYPE (gimp_curve_type_get_type ()) GType gimp_curve_type_get_type (void) G_GNUC_CONST; diff --git a/app/core/gimpcurve.c b/app/core/gimpcurve.c index 2a8e1f4302..ae12d15af3 100644 --- a/app/core/gimpcurve.c +++ b/app/core/gimpcurve.c @@ -46,6 +46,7 @@ enum PROP_CURVE_TYPE, PROP_N_POINTS, PROP_POINTS, + PROP_POINT_TYPES, PROP_N_SAMPLES, PROP_SAMPLES }; @@ -171,6 +172,17 @@ gimp_curve_class_init (GimpCurveClass *klass) GIMP_PARAM_STATIC_STRINGS | GIMP_CONFIG_PARAM_FLAGS)); + array_spec = g_param_spec_enum ("point-type", NULL, NULL, + GIMP_TYPE_CURVE_POINT_TYPE, + GIMP_CURVE_POINT_SMOOTH, + GIMP_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_POINT_TYPES, + gimp_param_spec_value_array ("point-types", + NULL, NULL, + array_spec, + GIMP_PARAM_STATIC_STRINGS | + GIMP_CONFIG_PARAM_FLAGS)); + GIMP_CONFIG_PROP_INT (object_class, PROP_N_SAMPLES, "n-samples", "Number of Samples", @@ -248,18 +260,22 @@ gimp_curve_set_property (GObject *object, case PROP_POINTS: { GimpValueArray *array = g_value_get_boxed (value); + GimpCurvePoint *points; gint length; + gint n_points; gint i; - curve->n_points = 0; - g_clear_pointer (&curve->points, g_free); - if (! array) - break; + { + gimp_curve_clear_points (curve); + + break; + } length = gimp_value_array_length (array) / 2; - curve->points = g_new (GimpVector2, length); + n_points = 0; + points = g_new (GimpCurvePoint, length); for (i = 0; i < length; i++) { @@ -270,22 +286,76 @@ gimp_curve_set_property (GObject *object, if (g_value_get_double (x) < 0.0) continue; - curve->points[curve->n_points].x = CLAMP (g_value_get_double (x), - 0.0, 1.0); - curve->points[curve->n_points].y = CLAMP (g_value_get_double (y), - 0.0, 1.0); + points[n_points].x = CLAMP (g_value_get_double (x), 0.0, 1.0); + points[n_points].y = CLAMP (g_value_get_double (y), 0.0, 1.0); - if (curve->n_points > 0) + if (n_points > 0) { - curve->points[curve->n_points].x = MAX ( - curve->points[curve->n_points].x, - curve->points[curve->n_points - 1].x); + points[n_points].x = MAX (points[n_points].x, + points[n_points - 1].x); } - curve->n_points++; + if (n_points < curve->n_points) + points[n_points].type = curve->points[n_points].type; + else + points[n_points].type = GIMP_CURVE_POINT_SMOOTH; + + n_points++; } + g_free (curve->points); + + curve->n_points = n_points; + curve->points = points; + g_object_notify (object, "n-points"); + g_object_notify (object, "point-types"); + } + break; + + case PROP_POINT_TYPES: + { + GimpValueArray *array = g_value_get_boxed (value); + GimpCurvePoint *points; + gint length; + gdouble x = 0.0; + gdouble y = 0.0; + gint i; + + if (! array) + { + gimp_curve_clear_points (curve); + + break; + } + + length = gimp_value_array_length (array); + + points = g_new (GimpCurvePoint, length); + + for (i = 0; i < length; i++) + { + GValue *type = gimp_value_array_index (array, i); + + points[i].type = g_value_get_enum (type); + + if (i < curve->n_points) + { + x = curve->points[i].x; + y = curve->points[i].y; + } + + points[i].x = x; + points[i].y = y; + } + + g_free (curve->points); + + curve->n_points = length; + curve->points = points; + + g_object_notify (object, "n-points"); + g_object_notify (object, "points"); } break; @@ -360,6 +430,26 @@ gimp_curve_get_property (GObject *object, } break; + case PROP_POINT_TYPES: + { + GimpValueArray *array = gimp_value_array_new (curve->n_points); + GValue v = G_VALUE_INIT; + gint i; + + g_value_init (&v, GIMP_TYPE_CURVE_POINT_TYPE); + + for (i = 0; i < curve->n_points; i++) + { + g_value_set_enum (&v, curve->points[i].type); + gimp_value_array_append (array, &v); + } + + g_value_unset (&v); + + g_value_take_boxed (value, array); + } + break; + case PROP_N_SAMPLES: g_value_set_int (value, curve->n_samples); break; @@ -397,7 +487,7 @@ gimp_curve_get_memsize (GimpObject *object, GimpCurve *curve = GIMP_CURVE (object); gint64 memsize = 0; - memsize += curve->n_points * sizeof (GimpVector2); + memsize += curve->n_points * sizeof (GimpCurvePoint); memsize += curve->n_samples * sizeof (gdouble); return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, @@ -513,7 +603,7 @@ gimp_curve_equal (GimpConfig *a, if (a_curve->n_points != b_curve->n_points || memcmp (a_curve->points, b_curve->points, - sizeof (GimpVector2) * a_curve->n_points)) + sizeof (GimpCurvePoint) * a_curve->n_points)) { return FALSE; } @@ -602,16 +692,19 @@ gimp_curve_reset (GimpCurve *curve, g_free (curve->points); curve->n_points = 2; - curve->points = g_new (GimpVector2, 2); + curve->points = g_new (GimpCurvePoint, 2); - curve->points[0].x = 0.0; - curve->points[0].y = 0.0; + curve->points[0].x = 0.0; + curve->points[0].y = 0.0; + curve->points[0].type = GIMP_CURVE_POINT_SMOOTH; - curve->points[1].x = 1.0; - curve->points[1].y = 1.0; + curve->points[1].x = 1.0; + curve->points[1].y = 1.0; + curve->points[1].type = GIMP_CURVE_POINT_SMOOTH; g_object_notify (G_OBJECT (curve), "n-points"); g_object_notify (G_OBJECT (curve), "points"); + g_object_notify (G_OBJECT (curve), "point-types"); if (reset_type) { @@ -650,19 +743,21 @@ gimp_curve_set_curve_type (GimpCurve *curve, * points */ curve->n_points = 9; - curve->points = g_new (GimpVector2, 9); + curve->points = g_new (GimpCurvePoint, 9); for (i = 0; i < curve->n_points; i++) { gint sample = i * (curve->n_samples - 1) / (curve->n_points - 1); - curve->points[i].x = (gdouble) sample / - (gdouble) (curve->n_samples - 1); - curve->points[i].y = curve->samples[sample]; + curve->points[i].x = (gdouble) sample / + (gdouble) (curve->n_samples - 1); + curve->points[i].y = curve->samples[sample]; + curve->points[i].type = GIMP_CURVE_POINT_SMOOTH; } g_object_notify (G_OBJECT (curve), "n-points"); g_object_notify (G_OBJECT (curve), "points"); + g_object_notify (G_OBJECT (curve), "point-types"); } else { @@ -795,8 +890,8 @@ gimp_curve_add_point (GimpCurve *curve, gdouble x, gdouble y) { - GimpVector2 *points; - gint point; + GimpCurvePoint *points; + gint point; g_return_val_if_fail (GIMP_IS_CURVE (curve), -1); @@ -812,15 +907,16 @@ gimp_curve_add_point (GimpCurve *curve, break; } - points = g_new (GimpVector2, curve->n_points + 1); + points = g_new (GimpCurvePoint, curve->n_points + 1); memcpy (points, curve->points, - point * sizeof (GimpVector2)); + point * sizeof (GimpCurvePoint)); memcpy (points + point + 1, curve->points + point, - (curve->n_points - point) * sizeof (GimpVector2)); + (curve->n_points - point) * sizeof (GimpCurvePoint)); - points[point].x = x; - points[point].y = y; + points[point].x = x; + points[point].y = y; + points[point].type = GIMP_CURVE_POINT_SMOOTH; g_free (curve->points); @@ -829,6 +925,7 @@ gimp_curve_add_point (GimpCurve *curve, g_object_notify (G_OBJECT (curve), "n-points"); g_object_notify (G_OBJECT (curve), "points"); + g_object_notify (G_OBJECT (curve), "point-types"); gimp_data_dirty (GIMP_DATA (curve)); @@ -839,17 +936,17 @@ void gimp_curve_delete_point (GimpCurve *curve, gint point) { - GimpVector2 *points; + GimpCurvePoint *points; g_return_if_fail (GIMP_IS_CURVE (curve)); g_return_if_fail (point >= 0 && point < curve->n_points); - points = g_new (GimpVector2, curve->n_points - 1); + points = g_new (GimpCurvePoint, curve->n_points - 1); memcpy (points, curve->points, - point * sizeof (GimpVector2)); + point * sizeof (GimpCurvePoint)); memcpy (points + point, curve->points + point + 1, - (curve->n_points - point - 1) * sizeof (GimpVector2)); + (curve->n_points - point - 1) * sizeof (GimpCurvePoint)); g_free (curve->points); @@ -858,6 +955,7 @@ gimp_curve_delete_point (GimpCurve *curve, g_object_notify (G_OBJECT (curve), "n-points"); g_object_notify (G_OBJECT (curve), "points"); + g_object_notify (G_OBJECT (curve), "point-types"); gimp_data_dirty (GIMP_DATA (curve)); } @@ -913,6 +1011,31 @@ gimp_curve_get_point (GimpCurve *curve, if (y) *y = curve->points[point].y; } +void +gimp_curve_set_point_type (GimpCurve *curve, + gint point, + GimpCurvePointType type) +{ + g_return_if_fail (GIMP_IS_CURVE (curve)); + g_return_if_fail (point >= 0 && point < curve->n_points); + + curve->points[point].type = type; + + g_object_notify (G_OBJECT (curve), "point-types"); + + gimp_data_dirty (GIMP_DATA (curve)); +} + +GimpCurvePointType +gimp_curve_get_point_type (GimpCurve *curve, + gint point) +{ + g_return_val_if_fail (GIMP_IS_CURVE (curve), GIMP_CURVE_POINT_SMOOTH); + g_return_val_if_fail (point >= 0 && point < curve->n_points, GIMP_CURVE_POINT_SMOOTH); + + return curve->points[point].type; +} + void gimp_curve_clear_points (GimpCurve *curve) { @@ -925,6 +1048,7 @@ gimp_curve_clear_points (GimpCurve *curve) g_object_notify (G_OBJECT (curve), "n-points"); g_object_notify (G_OBJECT (curve), "points"); + g_object_notify (G_OBJECT (curve), "point-types"); gimp_data_dirty (GIMP_DATA (curve)); } @@ -1000,8 +1124,8 @@ gimp_curve_calculate (GimpCurve *curve) /* Initialize boundary curve points */ if (curve->n_points > 0) { - GimpVector2 point; - gint boundary; + GimpCurvePoint point; + gint boundary; point = curve->points[0]; boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1)); @@ -1023,6 +1147,12 @@ gimp_curve_calculate (GimpCurve *curve) p3 = i + 1; p4 = MIN (i + 2, curve->n_points - 1); + if (curve->points[p2].type == GIMP_CURVE_POINT_CORNER) + p1 = p2; + + if (curve->points[p3].type == GIMP_CURVE_POINT_CORNER) + p4 = p3; + gimp_curve_plot (curve, p1, p2, p3, p4); } diff --git a/app/core/gimpcurve.h b/app/core/gimpcurve.h index b41794c168..71654aa184 100644 --- a/app/core/gimpcurve.h +++ b/app/core/gimpcurve.h @@ -30,21 +30,30 @@ #define GIMP_CURVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CURVE, GimpCurveClass)) +typedef struct _GimpCurvePoint GimpCurvePoint; typedef struct _GimpCurveClass GimpCurveClass; +struct _GimpCurvePoint +{ + gdouble x; + gdouble y; + + GimpCurvePointType type; +}; + struct _GimpCurve { - GimpData parent_instance; + GimpData parent_instance; - GimpCurveType curve_type; + GimpCurveType curve_type; - gint n_points; - GimpVector2 *points; + gint n_points; + GimpCurvePoint *points; - gint n_samples; - gdouble *samples; + gint n_samples; + gdouble *samples; - gboolean identity; /* whether the curve is an identity mapping */ + gboolean identity; /* whether the curve is an identity mapping */ }; struct _GimpCurveClass @@ -53,58 +62,63 @@ struct _GimpCurveClass }; -GType gimp_curve_get_type (void) G_GNUC_CONST; +GType gimp_curve_get_type (void) G_GNUC_CONST; -GimpData * gimp_curve_new (const gchar *name); -GimpData * gimp_curve_get_standard (void); +GimpData * gimp_curve_new (const gchar *name); +GimpData * gimp_curve_get_standard (void); -void gimp_curve_reset (GimpCurve *curve, - gboolean reset_type); +void gimp_curve_reset (GimpCurve *curve, + gboolean reset_type); -void gimp_curve_set_curve_type (GimpCurve *curve, - GimpCurveType curve_type); -GimpCurveType gimp_curve_get_curve_type (GimpCurve *curve); +void gimp_curve_set_curve_type (GimpCurve *curve, + GimpCurveType curve_type); +GimpCurveType gimp_curve_get_curve_type (GimpCurve *curve); -gint gimp_curve_get_n_points (GimpCurve *curve); +gint gimp_curve_get_n_points (GimpCurve *curve); -void gimp_curve_set_n_samples (GimpCurve *curve, - gint n_samples); -gint gimp_curve_get_n_samples (GimpCurve *curve); +void gimp_curve_set_n_samples (GimpCurve *curve, + gint n_samples); +gint gimp_curve_get_n_samples (GimpCurve *curve); -gint gimp_curve_get_point_at (GimpCurve *curve, - gdouble x); -gint gimp_curve_get_closest_point (GimpCurve *curve, - gdouble x, - gdouble y, - gdouble max_distance); +gint gimp_curve_get_point_at (GimpCurve *curve, + gdouble x); +gint gimp_curve_get_closest_point (GimpCurve *curve, + gdouble x, + gdouble y, + gdouble max_distance); -gint gimp_curve_add_point (GimpCurve *curve, - gdouble x, - gdouble y); -void gimp_curve_delete_point (GimpCurve *curve, - gint point); -void gimp_curve_set_point (GimpCurve *curve, - gint point, - gdouble x, - gdouble y); -void gimp_curve_move_point (GimpCurve *curve, - gint point, - gdouble y); -void gimp_curve_get_point (GimpCurve *curve, - gint point, - gdouble *x, - gdouble *y); -void gimp_curve_clear_points (GimpCurve *curve); +gint gimp_curve_add_point (GimpCurve *curve, + gdouble x, + gdouble y); +void gimp_curve_delete_point (GimpCurve *curve, + gint point); +void gimp_curve_set_point (GimpCurve *curve, + gint point, + gdouble x, + gdouble y); +void gimp_curve_move_point (GimpCurve *curve, + gint point, + gdouble y); +void gimp_curve_get_point (GimpCurve *curve, + gint point, + gdouble *x, + gdouble *y); +void gimp_curve_set_point_type (GimpCurve *curve, + gint point, + GimpCurvePointType type); +GimpCurvePointType gimp_curve_get_point_type (GimpCurve *curve, + gint point); +void gimp_curve_clear_points (GimpCurve *curve); -void gimp_curve_set_curve (GimpCurve *curve, - gdouble x, - gdouble y); +void gimp_curve_set_curve (GimpCurve *curve, + gdouble x, + gdouble y); -gboolean gimp_curve_is_identity (GimpCurve *curve); +gboolean gimp_curve_is_identity (GimpCurve *curve); -void gimp_curve_get_uchar (GimpCurve *curve, - gint n_samples, - guchar *samples); +void gimp_curve_get_uchar (GimpCurve *curve, + gint n_samples, + guchar *samples); #endif /* __GIMP_CURVE_H__ */ diff --git a/app/tools/gimpcurvestool.c b/app/tools/gimpcurvestool.c index 8f20bd0824..47eecc3808 100644 --- a/app/tools/gimpcurvestool.c +++ b/app/tools/gimpcurvestool.c @@ -124,6 +124,8 @@ static void curves_graph_selection_callback (GtkWidget *widget static void curves_point_coords_callback (GtkWidget *widget, GimpCurvesTool *tool); +static void curves_point_type_callback (GtkWidget *widget, + GimpCurvesTool *tool); static void curves_curve_type_callback (GtkWidget *widget, GimpCurvesTool *tool); @@ -268,9 +270,19 @@ gimp_curves_tool_button_release (GimpTool *tool, if (point < 0) { + GimpCurvePointType type = GIMP_CURVE_POINT_SMOOTH; + + point = gimp_curve_view_get_selected ( + GIMP_CURVE_VIEW (c_tool->graph)); + + if (point >= 0) + type = gimp_curve_get_point_type (curve, point); + point = gimp_curve_add_point ( curve, value, gimp_curve_map_value (curve, value)); + + gimp_curve_set_point_type (curve, point, type); } gimp_curve_view_set_selected (GIMP_CURVE_VIEW (c_tool->graph), point); @@ -278,6 +290,16 @@ gimp_curves_tool_button_release (GimpTool *tool, else if (state & gimp_get_toggle_behavior_mask ()) { GimpHistogramChannel channel; + GimpCurvePointType type = GIMP_CURVE_POINT_SMOOTH; + gint point; + + point = gimp_curve_view_get_selected (GIMP_CURVE_VIEW (c_tool->graph)); + + if (point >= 0) + { + type = gimp_curve_get_point_type (config->curve[config->channel], + point); + } for (channel = GIMP_HISTOGRAM_VALUE; channel <= GIMP_HISTOGRAM_ALPHA; @@ -288,8 +310,6 @@ gimp_curves_tool_button_release (GimpTool *tool, if (value != -1) { - gint point; - point = gimp_curve_get_point_at (curve, value); if (point < 0) @@ -297,6 +317,8 @@ gimp_curves_tool_button_release (GimpTool *tool, point = gimp_curve_add_point ( curve, value, gimp_curve_map_value (curve, value)); + + gimp_curve_set_point_type (curve, point, type); } if (channel == config->channel) @@ -600,10 +622,25 @@ gimp_curves_tool_dialog (GimpFilterTool *filter_tool) gtk_label_set_mnemonic_widget (GTK_LABEL (label), tool->point_output); + label = gtk_label_new_with_mnemonic (_("T_ype:")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + hbox2 = gimp_enum_icon_box_new (GIMP_TYPE_CURVE_POINT_TYPE, + "gimp-curve-point", + GTK_ICON_SIZE_MENU, + G_CALLBACK (curves_point_type_callback), + tool, + &tool->point_type); + gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0); + gtk_widget_show (hbox2); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start (GTK_BOX (frame_vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), tool->point_type); + label = gtk_label_new_with_mnemonic (_("Curve _type:")); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_widget_show (label); @@ -938,6 +975,18 @@ gimp_curves_tool_update_point (GimpCurvesTool *tool) g_signal_handlers_unblock_by_func (tool->point_output, curves_point_coords_callback, tool); + + g_signal_handlers_block_by_func (tool->point_type, + curves_point_type_callback, + tool); + + gimp_int_radio_group_set_active ( + GTK_RADIO_BUTTON (tool->point_type), + gimp_curve_get_point_type (curve, point)); + + g_signal_handlers_unblock_by_func (tool->point_type, + curves_point_type_callback, + tool); } } @@ -1045,6 +1094,28 @@ curves_point_coords_callback (GtkWidget *widget, } } +static void +curves_point_type_callback (GtkWidget *widget, + GimpCurvesTool *tool) +{ + GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (tool); + GimpCurvesConfig *config = GIMP_CURVES_CONFIG (filter_tool->config); + GimpCurve *curve = config->curve[config->channel]; + gint point; + + point = gimp_curve_view_get_selected (GIMP_CURVE_VIEW (tool->graph)); + + if (point >= 0 && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) + { + GimpCurvePointType type; + + type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), + "gimp-item-data")); + + gimp_curve_set_point_type (curve, point, type); + } +} + static void curves_curve_type_callback (GtkWidget *widget, GimpCurvesTool *tool) diff --git a/app/tools/gimpcurvestool.h b/app/tools/gimpcurvestool.h index ba897ec008..e80f776cb7 100644 --- a/app/tools/gimpcurvestool.h +++ b/app/tools/gimpcurvestool.h @@ -46,6 +46,7 @@ struct _GimpCurvesTool GtkWidget *point_box; GtkWidget *point_input; GtkWidget *point_output; + GtkWidget *point_type; GtkWidget *curve_type; /* export dialog */ diff --git a/app/widgets/gimpcurveview.c b/app/widgets/gimpcurveview.c index bd6c46df10..cf09aa2bc7 100644 --- a/app/widgets/gimpcurveview.c +++ b/app/widgets/gimpcurveview.c @@ -440,16 +440,38 @@ gimp_curve_view_draw_point (GimpCurveView *view, y = 1.0 - y; -#define RADIUS 3 +#define CIRCLE_RADIUS 3 +#define DIAMOND_RADIUS (G_SQRT2 * CIRCLE_RADIUS) - cairo_move_to (cr, - border + (gdouble) (width - 1) * x + RADIUS, - border + (gdouble) (height - 1) * y); - cairo_arc (cr, - border + (gdouble) (width - 1) * x, - border + (gdouble) (height - 1) * y, - RADIUS, - 0, 2 * G_PI); + switch (gimp_curve_get_point_type (view->curve, i)) + { + case GIMP_CURVE_POINT_SMOOTH: + cairo_move_to (cr, + border + (gdouble) (width - 1) * x + CIRCLE_RADIUS, + border + (gdouble) (height - 1) * y); + cairo_arc (cr, + border + (gdouble) (width - 1) * x, + border + (gdouble) (height - 1) * y, + CIRCLE_RADIUS, + 0, 2 * G_PI); + break; + + case GIMP_CURVE_POINT_CORNER: + cairo_move_to (cr, + border + (gdouble) (width - 1) * x, + border + (gdouble) (height - 1) * y - DIAMOND_RADIUS); + cairo_line_to (cr, + border + (gdouble) (width - 1) * x + DIAMOND_RADIUS, + border + (gdouble) (height - 1) * y); + cairo_line_to (cr, + border + (gdouble) (width - 1) * x, + border + (gdouble) (height - 1) * y + DIAMOND_RADIUS); + cairo_line_to (cr, + border + (gdouble) (width - 1) * x - DIAMOND_RADIUS, + border + (gdouble) (height - 1) * y); + cairo_close_path (cr); + break; + } } static void @@ -840,10 +862,17 @@ gimp_curve_view_button_press (GtkWidget *widget, if (point < 0) { + GimpCurvePointType type = GIMP_CURVE_POINT_SMOOTH; + if (bevent->state & gimp_get_constrain_behavior_mask ()) y = 1.0 - gimp_curve_map_value (view->orig_curve, x); + if (view->selected >= 0) + type = gimp_curve_get_point_type (curve, view->selected); + point = gimp_curve_add_point (curve, x, 1.0 - y); + + gimp_curve_set_point_type (curve, point, type); } if (point > 0) @@ -862,6 +891,8 @@ gimp_curve_view_button_press (GtkWidget *widget, view->offset_x = point_x - x; view->offset_y = (1.0 - point_y) - y; + + view->point_type = gimp_curve_get_point_type (curve, point); break; case GIMP_CURVE_FREE: @@ -975,6 +1006,9 @@ gimp_curve_view_motion_notify (GtkWidget *widget, gimp_curve_view_set_selected ( view, gimp_curve_add_point (curve, x, 1.0 - y)); + + gimp_curve_set_point_type (curve, + view->selected, view->point_type); } else { diff --git a/app/widgets/gimpcurveview.h b/app/widgets/gimpcurveview.h index 903c8ec393..add6048b89 100644 --- a/app/widgets/gimpcurveview.h +++ b/app/widgets/gimpcurveview.h @@ -50,6 +50,7 @@ struct _GimpCurveView gint selected; gdouble offset_x; gdouble offset_y; + GimpCurvePointType point_type; gdouble last_x; gdouble last_y; gdouble leftmost; diff --git a/icons/Color/16/gimp-curve-point-corner.png b/icons/Color/16/gimp-curve-point-corner.png new file mode 100644 index 0000000000..2274faa1c8 Binary files /dev/null and b/icons/Color/16/gimp-curve-point-corner.png differ diff --git a/icons/Color/16/gimp-curve-point-smooth.png b/icons/Color/16/gimp-curve-point-smooth.png new file mode 100644 index 0000000000..aaf78b74f0 Binary files /dev/null and b/icons/Color/16/gimp-curve-point-smooth.png differ diff --git a/icons/Color/icon-list.mk b/icons/Color/icon-list.mk index 1c3edea6c6..8708736f94 100644 --- a/icons/Color/icon-list.mk +++ b/icons/Color/icon-list.mk @@ -110,6 +110,8 @@ scalable_images = \ scalable/gimp-convert-rgb.svg \ scalable/gimp-cursor.svg \ scalable/gimp-curve-free.svg \ + scalable/gimp-curve-point-corner.svg \ + scalable/gimp-curve-point-smooth.svg \ scalable/gimp-curve-smooth.svg \ scalable/gimp-dashboard.svg \ scalable/gimp-default-colors.svg \ @@ -615,6 +617,8 @@ icons16_images = \ 16/gimp-convert-rgb.png \ 16/gimp-cursor.png \ 16/gimp-curve-free.png \ + 16/gimp-curve-point-corner.png \ + 16/gimp-curve-point-smooth.png \ 16/gimp-curve-smooth.png \ 16/gimp-dashboard.png \ 16/gimp-device-status.png \ diff --git a/icons/Color/scalable/gimp-curve-point-corner.svg b/icons/Color/scalable/gimp-curve-point-corner.svg new file mode 100644 index 0000000000..0f92e061a1 --- /dev/null +++ b/icons/Color/scalable/gimp-curve-point-corner.svg @@ -0,0 +1,113 @@ + + + + + + + image/svg+xml + + Gimp Color Icon Theme + + + many unknown and unnamed, Andrew Chadwick, Alexandre Prokoudine, Aryeom Han, Benoit Touchette, Jakub Steiner, Jehan, Johannes Matschke, Kevin Payne, Klaus Staedtler, Marek Dvoroznak, Michael Natterer + + + Enhanced, extended tango-art-libre for GIMP + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/Color/scalable/gimp-curve-point-smooth.svg b/icons/Color/scalable/gimp-curve-point-smooth.svg new file mode 100644 index 0000000000..cf5806d416 --- /dev/null +++ b/icons/Color/scalable/gimp-curve-point-smooth.svg @@ -0,0 +1,115 @@ + + + + + + + image/svg+xml + + Gimp Color Icon Theme + + + many unknown and unnamed, Andrew Chadwick, Alexandre Prokoudine, Aryeom Han, Benoit Touchette, Jakub Steiner, Jehan, Johannes Matschke, Kevin Payne, Klaus Staedtler, Marek Dvoroznak, Michael Natterer + + + Enhanced, extended tango-art-libre for GIMP + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/Legacy/16/gimp-curve-point-corner.png b/icons/Legacy/16/gimp-curve-point-corner.png new file mode 100644 index 0000000000..12fc694030 Binary files /dev/null and b/icons/Legacy/16/gimp-curve-point-corner.png differ diff --git a/icons/Legacy/16/gimp-curve-point-smooth.png b/icons/Legacy/16/gimp-curve-point-smooth.png new file mode 100644 index 0000000000..c0a8ff41d7 Binary files /dev/null and b/icons/Legacy/16/gimp-curve-point-smooth.png differ diff --git a/icons/Symbolic/16/gimp-curve-point-corner.png b/icons/Symbolic/16/gimp-curve-point-corner.png new file mode 100644 index 0000000000..e878973608 Binary files /dev/null and b/icons/Symbolic/16/gimp-curve-point-corner.png differ diff --git a/icons/Symbolic/16/gimp-curve-point-smooth.png b/icons/Symbolic/16/gimp-curve-point-smooth.png new file mode 100644 index 0000000000..2bc58cbb87 Binary files /dev/null and b/icons/Symbolic/16/gimp-curve-point-smooth.png differ diff --git a/icons/Symbolic/scalable/gimp-curve-point-corner.svg b/icons/Symbolic/scalable/gimp-curve-point-corner.svg new file mode 100644 index 0000000000..1a74071ecb --- /dev/null +++ b/icons/Symbolic/scalable/gimp-curve-point-corner.svg @@ -0,0 +1,94 @@ + + + + + + + image/svg+xml + + + + + Barbara Muraus, Jakub Steiner, Klaus Staedtler + + + Images originally created as the "Art Libre" icon set. Extended and adopted for GIMP + + + + + + + + + + + + + + + diff --git a/icons/Symbolic/scalable/gimp-curve-point-smooth.svg b/icons/Symbolic/scalable/gimp-curve-point-smooth.svg new file mode 100644 index 0000000000..aee5c7ecc7 --- /dev/null +++ b/icons/Symbolic/scalable/gimp-curve-point-smooth.svg @@ -0,0 +1,95 @@ + + + + + + + image/svg+xml + + + + + Barbara Muraus, Jakub Steiner, Klaus Staedtler + + + Images originally created as the "Art Libre" icon set. Extended and adopted for GIMP + + + + + + + + + + + + + + +