diff --git a/app/text/gimptext.c b/app/text/gimptext.c index 2968c1835c..e821a4933b 100644 --- a/app/text/gimptext.c +++ b/app/text/gimptext.c @@ -71,6 +71,7 @@ enum PROP_BOX_MODE, PROP_BOX_WIDTH, PROP_BOX_HEIGHT, + PROP_OUTLINE_DIRECTION, PROP_BOX_UNIT, PROP_TRANSFORMATION, PROP_OFFSET_X, @@ -348,6 +349,11 @@ gimp_text_class_init (GimpTextClass *klass) 0.0, 8192.0, 4.0, GIMP_PARAM_STATIC_STRINGS | GIMP_CONFIG_PARAM_DEFAULTS); + GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_DIRECTION, + "outline-direction", NULL, NULL, + GIMP_TYPE_TEXT_OUTLINE_DIRECTION, + GIMP_TEXT_OUTLINE_DIRECTION_OUTER, + GIMP_PARAM_STATIC_STRINGS); GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_CAP_STYLE, "outline-cap-style", NULL, NULL, GIMP_TYPE_CAP_STYLE, GIMP_CAP_BUTT, @@ -359,7 +365,7 @@ gimp_text_class_init (GimpTextClass *klass) GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_MITER_LIMIT, "outline-miter-limit", NULL, NULL, - 0.0, 100.0, 10.0, + 0.0, 100.0, 2.0, GIMP_PARAM_STATIC_STRINGS); GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OUTLINE_ANTIALIAS, "outline-antialias", NULL, NULL, @@ -516,6 +522,9 @@ gimp_text_get_property (GObject *object, case PROP_OUTLINE_WIDTH: g_value_set_double (value, text->outline_width); break; + case PROP_OUTLINE_DIRECTION: + g_value_set_enum (value, text->outline_direction); + break; case PROP_OUTLINE_CAP_STYLE: g_value_set_enum (value, text->outline_cap_style); break; @@ -676,6 +685,9 @@ gimp_text_set_property (GObject *object, case PROP_OUTLINE_WIDTH: text->outline_width = g_value_get_double (value); break; + case PROP_OUTLINE_DIRECTION: + text->outline_direction = g_value_get_enum (value); + break; case PROP_OUTLINE_CAP_STYLE: text->outline_cap_style = g_value_get_enum (value); break; diff --git a/app/text/gimptext.h b/app/text/gimptext.h index 117b237767..adf7e3fd86 100644 --- a/app/text/gimptext.h +++ b/app/text/gimptext.h @@ -37,44 +37,45 @@ typedef struct _GimpTextClass GimpTextClass; struct _GimpText { - GimpObject parent_instance; + GimpObject parent_instance; - gchar *text; - gchar *markup; - GimpFont *font; - GimpUnit *unit; - gdouble font_size; - gboolean antialias; - GimpTextHintStyle hint_style; - gboolean kerning; - gchar *language; - GimpTextDirection base_dir; - GeglColor *color; - GimpCustomStyle outline_style; - GimpPattern *outline_pattern; - GeglColor *outline_foreground; - gdouble outline_width; - GimpCapStyle outline_cap_style; - GimpJoinStyle outline_join_style; - gdouble outline_miter_limit; - gboolean outline_antialias; - gdouble outline_dash_offset; - GArray *outline_dash_info; - GimpTextOutline outline; - GimpTextJustification justify; - gdouble indent; - gdouble line_spacing; - gdouble letter_spacing; - GimpTextBoxMode box_mode; - gdouble box_width; - gdouble box_height; - GimpUnit *box_unit; - GimpMatrix2 transformation; - gdouble offset_x; - gdouble offset_y; + gchar *text; + gchar *markup; + GimpFont *font; + GimpUnit *unit; + gdouble font_size; + gboolean antialias; + GimpTextHintStyle hint_style; + gboolean kerning; + gchar *language; + GimpTextDirection base_dir; + GeglColor *color; + GimpCustomStyle outline_style; + GimpPattern *outline_pattern; + GeglColor *outline_foreground; + gdouble outline_width; + GimpTextOutlineDirection outline_direction; + GimpCapStyle outline_cap_style; + GimpJoinStyle outline_join_style; + gdouble outline_miter_limit; + gboolean outline_antialias; + gdouble outline_dash_offset; + GArray *outline_dash_info; + GimpTextOutline outline; + GimpTextJustification justify; + gdouble indent; + gdouble line_spacing; + gdouble letter_spacing; + GimpTextBoxMode box_mode; + gdouble box_width; + gdouble box_height; + GimpUnit *box_unit; + GimpMatrix2 transformation; + gdouble offset_x; + gdouble offset_y; - gdouble border; - Gimp *gimp; + gdouble border; + Gimp *gimp; }; struct _GimpTextClass diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c index 7900a22518..d5b06dd294 100644 --- a/app/text/gimptextlayer.c +++ b/app/text/gimptextlayer.c @@ -1014,10 +1014,31 @@ gimp_text_layer_render_layout (GimpTextLayer *layer, cairo_set_line_width (cr, text->outline_width * 2); gimp_text_layout_render (layout, cr, text->base_dir, TRUE); - cairo_clip_preserve (cr); - cairo_stroke (cr); + + if (text->outline_direction == GIMP_TEXT_OUTLINE_DIRECTION_INNER) + cairo_clip_preserve (cr); + + cairo_stroke_preserve (cr); + + /* Clears inner outline if outline direction is outward */ + if (text->outline_direction == GIMP_TEXT_OUTLINE_DIRECTION_OUTER && + text->outline == GIMP_TEXT_OUTLINE_STROKE_ONLY) + { + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_fill_preserve (cr); + } cairo_restore (cr); + + if (text->outline_direction == GIMP_TEXT_OUTLINE_DIRECTION_OUTER && + text->outline != GIMP_TEXT_OUTLINE_STROKE_ONLY) + { + cairo_save (cr); + + gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE); + + cairo_restore (cr); + } } cairo_destroy (cr); diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c index 27c015cb6c..d73cff10c0 100644 --- a/app/text/gimptextlayout.c +++ b/app/text/gimptextlayout.c @@ -718,6 +718,7 @@ gimp_text_layout_position (GimpTextLayout *layout) PangoContext *context; gint x1, y1; gint x2, y2; + gint border; layout->extents.x = 0; layout->extents.y = 0; @@ -783,10 +784,14 @@ gimp_text_layout_position (GimpTextLayout *layout) } } - if (layout->text->border > 0) - { - gint border = layout->text->border; + border = (layout->text->border > 0) ? layout->text->border : 0; + if (layout->text->outline != GIMP_TEXT_OUTLINE_NONE && + layout->text->outline_direction != GIMP_TEXT_OUTLINE_DIRECTION_INNER) + border += layout->text->outline_width; + + if (border > 0) + { layout->extents.x += border; layout->extents.y += border; layout->extents.width += 2 * border; diff --git a/app/text/text-enums.c b/app/text/text-enums.c index 271b2065dd..698176cb25 100644 --- a/app/text/text-enums.c +++ b/app/text/text-enums.c @@ -69,6 +69,37 @@ gimp_text_outline_get_type (void) return type; } +GType +gimp_text_outline_direction_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TEXT_OUTLINE_DIRECTION_OUTER, "GIMP_TEXT_OUTLINE_DIRECTION_OUTER", "outer" }, + { GIMP_TEXT_OUTLINE_DIRECTION_INNER, "GIMP_TEXT_OUTLINE_DIRECTION_INNER", "inner" }, + { GIMP_TEXT_OUTLINE_DIRECTION_CENTERED, "GIMP_TEXT_OUTLINE_DIRECTION_CENTERED", "centered" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TEXT_OUTLINE_DIRECTION_OUTER, NC_("text-outline-direction", "Outer"), NULL }, + { GIMP_TEXT_OUTLINE_DIRECTION_INNER, NC_("text-outline-direction", "Inner"), NULL }, + { GIMP_TEXT_OUTLINE_DIRECTION_CENTERED, NC_("text-outline-direction", "Centered"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTextOutlineDirection", values); + gimp_type_set_translation_context (type, "text-outline-direction"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + /* Generated data ends here */ diff --git a/app/text/text-enums.h b/app/text/text-enums.h index f032ce690b..ad3538a4c3 100644 --- a/app/text/text-enums.h +++ b/app/text/text-enums.h @@ -41,5 +41,15 @@ typedef enum GIMP_TEXT_OUTLINE_STROKE_FILL /*< desc="Outlined and filled" >*/ } GimpTextOutline; +#define GIMP_TYPE_TEXT_OUTLINE_DIRECTION (gimp_text_outline_direction_get_type ()) + +GType gimp_text_outline_direction_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TEXT_OUTLINE_DIRECTION_OUTER, /*< desc="Outer" >*/ + GIMP_TEXT_OUTLINE_DIRECTION_INNER, /*< desc="Inner" >*/ + GIMP_TEXT_OUTLINE_DIRECTION_CENTERED /*< desc="Centered" >*/ +} GimpTextOutlineDirection; #endif /* __TEXT_ENUMS_H__ */ diff --git a/app/tools/gimptextoptions.c b/app/tools/gimptextoptions.c index b6d0c13b15..43f6d9a685 100644 --- a/app/tools/gimptextoptions.c +++ b/app/tools/gimptextoptions.c @@ -79,6 +79,7 @@ enum PROP_OUTLINE_PATTERN, /* context */ PROP_OUTLINE_WIDTH, /* stroke-options */ PROP_OUTLINE_UNIT, + PROP_OUTLINE_DIRECTION, PROP_OUTLINE_CAP_STYLE, PROP_OUTLINE_JOIN_STYLE, PROP_OUTLINE_MITER_LIMIT, @@ -308,6 +309,11 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass) _("Outline width unit"), TRUE, FALSE, gimp_unit_pixel (), GIMP_PARAM_STATIC_STRINGS); + GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_DIRECTION, + "outline-direction", NULL, NULL, + GIMP_TYPE_TEXT_OUTLINE_DIRECTION, + GIMP_TEXT_OUTLINE_DIRECTION_OUTER, + GIMP_PARAM_STATIC_STRINGS); GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_CAP_STYLE, "outline-cap-style", NULL, NULL, @@ -325,7 +331,7 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass) "join if the miter would extend to a " "distance of more than miter-limit * " "line-width from the actual join point."), - 0.0, 100.0, 10.0, + 0.0, 100.0, 2.0, GIMP_PARAM_STATIC_STRINGS); GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OUTLINE_ANTIALIAS, "outline-antialias", @@ -445,6 +451,9 @@ gimp_text_options_get_property (GObject *object, case PROP_OUTLINE_UNIT: g_value_set_object (value, options->outline_unit); break; + case PROP_OUTLINE_DIRECTION: + g_value_set_enum (value, options->outline_direction); + break; case PROP_OUTLINE_CAP_STYLE: g_value_set_enum (value, options->outline_cap_style); break; @@ -562,6 +571,9 @@ gimp_text_options_set_property (GObject *object, case PROP_OUTLINE_UNIT: options->outline_unit = g_value_get_object (value); break; + case PROP_OUTLINE_DIRECTION: + options->outline_direction = g_value_get_enum (value); + break; case PROP_OUTLINE_CAP_STYLE: options->outline_cap_style = g_value_get_enum (value); break; @@ -637,6 +649,7 @@ gimp_text_options_reset (GimpConfig *config) gimp_config_reset_property (object, "outline-pattern"); gimp_config_reset_property (object, "outline-width"); gimp_config_reset_property (object, "outline-unit"); + gimp_config_reset_property (object, "outline-direction"); gimp_config_reset_property (object, "outline-cap-style"); gimp_config_reset_property (object, "outline-join-style"); gimp_config_reset_property (object, "outline-miter-limit"); @@ -760,6 +773,7 @@ gimp_text_options_gui (GimpToolOptions *tool_options) GtkWidget *main_vbox = gimp_tool_options_gui (tool_options); GimpAsyncSet *async_set; GtkWidget *options_vbox; + GtkWidget *outline_grid; GtkWidget *grid; GtkWidget *vbox; GtkWidget *hbox; @@ -872,6 +886,18 @@ gimp_text_options_gui (GimpToolOptions *tool_options) outline_frame); gimp_text_options_outline_changed (button, outline_frame); + outline_grid = gtk_grid_new (); + gtk_grid_set_column_spacing (GTK_GRID (outline_grid), 2); + gtk_grid_set_row_spacing (GTK_GRID (outline_grid), 2); + gtk_container_add (GTK_CONTAINER (outline_frame), outline_grid); + gtk_widget_show (outline_grid); + + button = gimp_prop_enum_combo_box_new (config, "outline-direction", -1, -1); + gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (button), _("Outline Direction:")); + gimp_grid_attach_aligned (GTK_GRID (outline_grid), 0, 0, + NULL, 0.0, 0.5, + button, 1); + grid = gtk_grid_new (); gtk_grid_set_column_spacing (GTK_GRID (grid), 2); gtk_grid_set_row_spacing (GTK_GRID (grid), 2); @@ -934,8 +960,10 @@ gimp_text_options_gui (GimpToolOptions *tool_options) BIND (dash-info); editor = gimp_stroke_editor_new (stroke_options, 72.0, TRUE, TRUE); - gtk_container_add (GTK_CONTAINER (outline_frame), editor); - gtk_widget_show (editor); + gimp_grid_attach_aligned (GTK_GRID (outline_grid), 0, 1, + NULL, 0.0, 0.5, + editor, 1); + gtk_widget_set_visible (editor, TRUE); g_object_unref (stroke_options); diff --git a/app/tools/gimptextoptions.h b/app/tools/gimptextoptions.h index d0ae0daef9..8b5cde7ead 100644 --- a/app/tools/gimptextoptions.h +++ b/app/tools/gimptextoptions.h @@ -35,41 +35,42 @@ typedef struct _GimpToolOptionsClass GimpTextOptionsClass; struct _GimpTextOptions { - GimpToolOptions tool_options; + GimpToolOptions tool_options; - GimpUnit *unit; - gdouble font_size; - gboolean antialias; - GimpTextHintStyle hint_style; - gchar *language; - GimpTextDirection base_dir; - GimpTextJustification justify; - gdouble indent; - gdouble line_spacing; - gdouble letter_spacing; - GimpTextBoxMode box_mode; + GimpUnit *unit; + gdouble font_size; + gboolean antialias; + GimpTextHintStyle hint_style; + gchar *language; + GimpTextDirection base_dir; + GimpTextJustification justify; + gdouble indent; + gdouble line_spacing; + gdouble letter_spacing; + GimpTextBoxMode box_mode; - GimpTextOutline outline; - GimpCustomStyle outline_style; - GeglColor *outline_foreground; - GimpPattern *outline_pattern; - gdouble outline_width; - GimpUnit *outline_unit; - GimpCapStyle outline_cap_style; - GimpJoinStyle outline_join_style; - gdouble outline_miter_limit; - gboolean outline_antialias; - gdouble outline_dash_offset; - GArray *outline_dash_info; + GimpTextOutline outline; + GimpCustomStyle outline_style; + GeglColor *outline_foreground; + GimpPattern *outline_pattern; + gdouble outline_width; + GimpUnit *outline_unit; + GimpTextOutlineDirection outline_direction; + GimpCapStyle outline_cap_style; + GimpJoinStyle outline_join_style; + gdouble outline_miter_limit; + gboolean outline_antialias; + gdouble outline_dash_offset; + GArray *outline_dash_info; - GimpViewType font_view_type; - GimpViewSize font_view_size; + GimpViewType font_view_type; + GimpViewSize font_view_size; - gboolean use_editor; - gboolean show_on_canvas; + gboolean use_editor; + gboolean show_on_canvas; /* options gui */ - GtkWidget *size_entry; + GtkWidget *size_entry; };