1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00

text: Add additional outline options

This creates a new "outline direction" property, that determines whether
the text outline grows outward, inward, or centered from the text.
This commit is contained in:
Alx Sa
2025-05-24 16:12:39 +00:00
parent 073adebd0a
commit 3edafcc7bc
8 changed files with 183 additions and 74 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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__ */

View File

@@ -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);

View File

@@ -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;
};