[gimp/alxsa-outline-text-massimo] text: Add outline options to text editor
- From: Alx Sa <sawyeralex src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/alxsa-outline-text-massimo] text: Add outline options to text editor
- Date: Mon, 3 Oct 2022 19:45:53 +0000 (UTC)
commit 5be7bd666094639b420dcfd4aa6a0f309c623ac6
Author: Alx Sa <cmyk student gmail com>
Date: Mon Oct 3 19:45:52 2022 +0000
text: Add outline options to text editor
This ports Massimo's patch to work on 2.99.x
app/core/gimp-memsize.c | 21 ++-
app/text/gimptext-parasite.c | 3 +-
app/text/gimptext-parasite.h | 1 +
app/text/gimptext.c | 273 ++++++++++++++++++++++++++-
app/text/gimptext.h | 11 ++
app/text/gimptextlayer-xcf.c | 4 +-
app/text/gimptextlayer.c | 172 ++++++++++++++++-
app/text/text-enums.c | 6 +-
app/text/text-enums.h | 6 +-
app/tools/gimptextoptions.c | 425 ++++++++++++++++++++++++++++++++++++++-----
app/tools/gimptextoptions.h | 13 ++
app/tools/gimptexttool.c | 3 +-
app/widgets/gimpfilleditor.c | 2 +-
13 files changed, 884 insertions(+), 56 deletions(-)
---
diff --git a/app/core/gimp-memsize.c b/app/core/gimp-memsize.c
index fc674d0842..c14436b490 100644
--- a/app/core/gimp-memsize.c
+++ b/app/core/gimp-memsize.c
@@ -243,6 +243,20 @@ gimp_g_value_get_memsize (GValue *value)
memsize += gimp_string_get_memsize (array[i]);
}
}
+ else if (strcmp ("GimpValueArray", G_VALUE_TYPE_NAME (value)) == 0)
+ {
+ GimpValueArray *array = g_value_get_boxed (value);
+
+ if (array)
+ {
+ gint n_values = gimp_value_array_length (array), i;
+
+ memsize += /* sizeof (GimpValueArray) */ sizeof (GValue *) + 3 * sizeof (gint);
+
+ for (i = 0; i < n_values; i++)
+ memsize += gimp_g_value_get_memsize (gimp_value_array_index (array, i));
+ }
+ }
else
{
g_printerr ("%s: unhandled boxed value type: %s\n",
@@ -251,8 +265,11 @@ gimp_g_value_get_memsize (GValue *value)
}
else if (G_VALUE_HOLDS_OBJECT (value))
{
- g_printerr ("%s: unhandled object value type: %s\n",
- G_STRFUNC, G_VALUE_TYPE_NAME (value));
+ if (strcmp ("GimpPattern", G_VALUE_TYPE_NAME (value)) == 0)
+ memsize += gimp_g_object_get_memsize (g_value_get_object (value));
+ else
+ g_printerr ("%s: unhandled object value type: %s\n",
+ G_STRFUNC, G_VALUE_TYPE_NAME (value));
}
return memsize + sizeof (GValue);
diff --git a/app/text/gimptext-parasite.c b/app/text/gimptext-parasite.c
index bc0f7d0363..b6a113013c 100644
--- a/app/text/gimptext-parasite.c
+++ b/app/text/gimptext-parasite.c
@@ -65,6 +65,7 @@ gimp_text_to_parasite (GimpText *text)
GimpText *
gimp_text_from_parasite (const GimpParasite *parasite,
+ Gimp *gimp,
GError **error)
{
GimpText *text;
@@ -76,7 +77,7 @@ gimp_text_from_parasite (const GimpParasite *parasite,
gimp_text_parasite_name ()) == 0, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- text = g_object_new (GIMP_TYPE_TEXT, NULL);
+ text = g_object_new (GIMP_TYPE_TEXT, "gimp", gimp, NULL);
parasite_data = (gchar *) gimp_parasite_get_data (parasite, ¶site_data_size);
if (parasite_data)
diff --git a/app/text/gimptext-parasite.h b/app/text/gimptext-parasite.h
index 2e2847a497..eae1087b0d 100644
--- a/app/text/gimptext-parasite.h
+++ b/app/text/gimptext-parasite.h
@@ -25,6 +25,7 @@
const gchar * gimp_text_parasite_name (void) G_GNUC_CONST;
GimpParasite * gimp_text_to_parasite (GimpText *text);
GimpText * gimp_text_from_parasite (const GimpParasite *parasite,
+ Gimp *gimp,
GError **error);
const gchar * gimp_text_gdyntext_parasite_name (void) G_GNUC_CONST;
diff --git a/app/text/gimptext.c b/app/text/gimptext.c
index ed2f041294..31ef2f46bf 100644
--- a/app/text/gimptext.c
+++ b/app/text/gimptext.c
@@ -34,9 +34,14 @@
#include "text-types.h"
+#include "core/gimp.h"
#include "core/gimp-memsize.h"
#include "core/gimp-utils.h"
+#include "core/gimpcontainer.h"
+#include "core/gimpdashpattern.h"
+#include "core/gimpdatafactory.h"
#include "core/gimpstrokeoptions.h"
+#include "core/gimppattern.h"
#include "gimptext.h"
@@ -68,8 +73,23 @@ enum
PROP_OFFSET_X,
PROP_OFFSET_Y,
PROP_BORDER,
+
+ PROP_OUTLINE_STYLE, /* fill-options */
+ PROP_OUTLINE_FOREGROUND, /* context */
+ PROP_OUTLINE_PATTERN, /* context */
+ PROP_OUTLINE_WIDTH, /* stroke-options */
+ PROP_OUTLINE_UNIT,
+ PROP_OUTLINE_CAP_STYLE,
+ PROP_OUTLINE_JOIN_STYLE,
+ PROP_OUTLINE_MITER_LIMIT,
+ PROP_OUTLINE_ANTIALIAS, /* fill-options */
+ PROP_OUTLINE_DASH_UNIT, /* NOT USED */
+ PROP_OUTLINE_DASH_OFFSET,
+ PROP_OUTLINE_DASH_INFO,
/* for backward compatibility */
- PROP_HINTING
+ PROP_HINTING,
+
+ PROP_GIMP
};
enum
@@ -78,6 +98,18 @@ enum
LAST_SIGNAL
};
+static void gimp_text_config_iface_init (GimpConfigInterface *iface);
+static gboolean gimp_text_serialize_property (GimpConfig *config,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec,
+ GimpConfigWriter *writer);
+static gboolean gimp_text_deserialize_property (GimpConfig *config,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected);
static void gimp_text_finalize (GObject *object);
static void gimp_text_get_property (GObject *object,
@@ -96,7 +128,8 @@ static gint64 gimp_text_get_memsize (GimpObject *object,
G_DEFINE_TYPE_WITH_CODE (GimpText, gimp_text, GIMP_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
+ gimp_text_config_iface_init))
#define parent_class gimp_text_parent_class
@@ -109,8 +142,10 @@ gimp_text_class_init (GimpTextClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpRGB black;
+ GimpRGB gray;
GimpMatrix2 identity;
gchar *language;
+ GParamSpec *array_spec;
text_signals[CHANGED] =
g_signal_new ("changed",
@@ -128,6 +163,7 @@ gimp_text_class_init (GimpTextClass *klass)
gimp_object_class->get_memsize = gimp_text_get_memsize;
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
+ gimp_rgba_set (&gray, 0.75, 0.75, 0.75, GIMP_OPACITY_OPAQUE);
gimp_matrix2_identity (&identity);
GIMP_CONFIG_PROP_STRING (object_class, PROP_TEXT,
@@ -298,12 +334,68 @@ gimp_text_class_init (GimpTextClass *klass)
G_PARAM_CONSTRUCT |
GIMP_PARAM_WRITABLE));
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_STYLE,
+ "outline-style", NULL, NULL,
+ GIMP_TYPE_FILL_STYLE,
+ GIMP_FILL_STYLE_SOLID,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_OUTLINE_PATTERN,
+ "outline-pattern", NULL, NULL,
+ GIMP_TYPE_PATTERN,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_OUTLINE_FOREGROUND,
+ "outline-foreground", NULL, NULL,
+ FALSE, &gray,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_WIDTH,
+ "outline-width", NULL, NULL,
+ 0.0, 8192.0, 4.0,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_DEFAULTS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_CAP_STYLE,
+ "outline-cap-style", NULL, NULL,
+ GIMP_TYPE_CAP_STYLE, GIMP_CAP_BUTT,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_JOIN_STYLE,
+ "outline-join-style", NULL, NULL,
+ GIMP_TYPE_JOIN_STYLE, GIMP_JOIN_MITER,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_MITER_LIMIT,
+ "outline-miter-limit",
+ NULL, NULL,
+ 0.0, 100.0, 10.0,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OUTLINE_ANTIALIAS,
+ "outline-antialias", NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_DASH_OFFSET,
+ "outline-dash-offset", NULL, NULL,
+ 0.0, 2000.0, 0.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ array_spec = g_param_spec_double ("outline-dash-length", NULL, NULL,
+ 0.0, 2000.0, 1.0, GIMP_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_OUTLINE_DASH_INFO,
+ gimp_param_spec_value_array ("outline-dash-info",
+ NULL, NULL,
+ array_spec,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_FLAGS));
+
/* the old hinting options have been replaced by 'hint-style' */
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_HINTING,
"hinting",
NULL, NULL,
TRUE,
GIMP_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp", NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
}
static void
@@ -311,6 +403,13 @@ gimp_text_init (GimpText *text)
{
}
+static void
+gimp_text_config_iface_init (GimpConfigInterface *iface)
+{
+ iface->serialize_property = gimp_text_serialize_property;
+ iface->deserialize_property = gimp_text_deserialize_property;
+}
+
static void
gimp_text_finalize (GObject *object)
{
@@ -403,10 +502,51 @@ gimp_text_get_property (GObject *object,
case PROP_OFFSET_Y:
g_value_set_double (value, text->offset_y);
break;
+ case PROP_OUTLINE_STYLE:
+ g_value_set_enum (value, text->outline_style);
+ break;
+ case PROP_OUTLINE_FOREGROUND:
+ g_value_set_boxed (value, &text->outline_foreground);
+ break;
+ case PROP_OUTLINE_PATTERN:
+ g_value_set_object (value, text->outline_pattern);
+ break;
+ case PROP_OUTLINE_WIDTH:
+ g_value_set_double (value, text->outline_width);
+ break;
+ case PROP_OUTLINE_CAP_STYLE:
+ g_value_set_enum (value, text->outline_cap_style);
+ break;
+ case PROP_OUTLINE_JOIN_STYLE:
+ g_value_set_enum (value, text->outline_join_style);
+ break;
+ case PROP_OUTLINE_MITER_LIMIT:
+ g_value_set_double (value, text->outline_miter_limit);
+ break;
+ case PROP_OUTLINE_ANTIALIAS:
+ g_value_set_boolean (value, text->outline_antialias);
+ break;
+ case PROP_OUTLINE_DASH_UNIT:
+ /* NOT USED */
+ break;
+ case PROP_OUTLINE_DASH_OFFSET:
+ g_value_set_double (value, text->outline_dash_offset);
+ break;
+ case PROP_OUTLINE_DASH_INFO:
+ {
+ GimpValueArray *value_array;
+
+ value_array = gimp_dash_pattern_to_value_array (text->outline_dash_info);
+ g_value_take_boxed (value, value_array);
+ }
+ break;
case PROP_HINTING:
g_value_set_boolean (value,
text->hint_style != GIMP_TEXT_HINT_STYLE_NONE);
break;
+ case PROP_GIMP:
+ g_value_set_object (value, text->gimp);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -527,6 +667,53 @@ gimp_text_set_property (GObject *object,
case PROP_OFFSET_Y:
text->offset_y = g_value_get_double (value);
break;
+ case PROP_OUTLINE_STYLE:
+ text->outline_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_FOREGROUND:
+ color = g_value_get_boxed (value);
+ text->outline_foreground = *color;
+ break;
+ case PROP_OUTLINE_PATTERN:
+ {
+ GimpPattern *pattern = g_value_get_object (value);
+
+ if (text->outline_pattern != pattern)
+ {
+ if (text->outline_pattern)
+ g_object_unref (text->outline_pattern);
+
+ text->outline_pattern = pattern ? g_object_ref (pattern) : pattern;
+ }
+ break;
+ }
+ case PROP_OUTLINE_WIDTH:
+ text->outline_width = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_CAP_STYLE:
+ text->outline_cap_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_JOIN_STYLE:
+ text->outline_join_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_MITER_LIMIT:
+ text->outline_miter_limit = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_ANTIALIAS:
+ text->outline_antialias = g_value_get_boolean (value);
+ break;
+ case PROP_OUTLINE_DASH_UNIT:
+ /* unused */
+ break;
+ case PROP_OUTLINE_DASH_OFFSET:
+ text->outline_dash_offset = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_DASH_INFO:
+ {
+ GimpValueArray *value_array = g_value_get_boxed (value);
+ text->outline_dash_info = gimp_dash_pattern_from_value_array (value_array);
+ }
+ break;
case PROP_BORDER:
text->border = g_value_get_int (value);
break;
@@ -540,6 +727,9 @@ gimp_text_set_property (GObject *object,
GIMP_TEXT_HINT_STYLE_MEDIUM :
GIMP_TEXT_HINT_STYLE_NONE);
break;
+ case PROP_GIMP:
+ g_value_set_object (value, text->gimp);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -592,3 +782,82 @@ gimp_text_get_transformation (GimpText *text,
matrix->coeff[2][1] = 0.0;
matrix->coeff[2][2] = 1.0;
}
+
+static gboolean
+gimp_text_serialize_property (GimpConfig *config,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec,
+ GimpConfigWriter *writer)
+{
+ if (property_id == PROP_OUTLINE_PATTERN)
+ {
+ GimpObject *serialize_obj = g_value_get_object (value);
+
+ gimp_config_writer_open (writer, pspec->name);
+
+ if (serialize_obj)
+ gimp_config_writer_string (writer, gimp_object_get_name (serialize_obj));
+ else
+ gimp_config_writer_print (writer, "NULL", 4);
+
+ gimp_config_writer_close (writer);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_text_deserialize_property (GimpConfig *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected)
+{
+ if (property_id == PROP_OUTLINE_PATTERN)
+ {
+ gchar *object_name;
+
+ if (gimp_scanner_parse_identifier (scanner, "NULL"))
+ {
+ g_value_set_object (value, NULL);
+ }
+ else if (gimp_scanner_parse_string (scanner, &object_name))
+ {
+ GimpText *text = GIMP_TEXT (object);
+ GimpContainer *container;
+ GimpObject *deserialize_obj;
+
+ if (! object_name)
+ object_name = g_strdup ("");
+
+ container = gimp_data_factory_get_container (text->gimp->pattern_factory);
+
+ deserialize_obj = gimp_container_get_child_by_name (container,
+ object_name);
+
+ g_value_set_object (value, deserialize_obj);
+
+ g_free (object_name);
+ }
+ else
+ {
+ *expected = G_TOKEN_STRING;
+ }
+
+ return TRUE;
+ }
+ else if (property_id == PROP_OUTLINE_DASH_INFO)
+ {
+ if (gimp_scanner_parse_identifier (scanner, "NULL"))
+ {
+ g_value_take_boxed (value, NULL);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
diff --git a/app/text/gimptext.h b/app/text/gimptext.h
index 8a292be896..4ca3b333be 100644
--- a/app/text/gimptext.h
+++ b/app/text/gimptext.h
@@ -50,6 +50,16 @@ struct _GimpText
gchar *language;
GimpTextDirection base_dir;
GimpRGB color;
+ GimpFillStyle outline_style;
+ GimpPattern *outline_pattern;
+ GimpRGB 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;
@@ -64,6 +74,7 @@ struct _GimpText
gdouble offset_y;
gdouble border;
+ Gimp *gimp;
};
struct _GimpTextClass
diff --git a/app/text/gimptextlayer-xcf.c b/app/text/gimptextlayer-xcf.c
index d0961ee148..4c31924ce8 100644
--- a/app/text/gimptextlayer-xcf.c
+++ b/app/text/gimptextlayer-xcf.c
@@ -69,7 +69,9 @@ gimp_text_layer_xcf_load_hack (GimpLayer **layer)
{
GError *error = NULL;
- text = gimp_text_from_parasite (parasite, &error);
+ text = gimp_text_from_parasite (parasite,
+ gimp_item_get_image (GIMP_ITEM(*layer))->gimp,
+ &error);
if (error)
{
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index 002cec1904..581ef3bfd0 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -48,6 +48,8 @@
#include "core/gimpimage-undo-push.h"
#include "core/gimpitemtree.h"
#include "core/gimpparasitelist.h"
+#include "core/gimppattern.h"
+#include "core/gimptempbuf.h"
#include "gimptext.h"
#include "gimptextlayer.h"
@@ -799,6 +801,121 @@ gimp_text_layer_render (GimpTextLayer *layer)
return (width > 0 && height > 0);
}
+static void
+gimp_text_layer_set_dash_info (cairo_t *cr,
+ gdouble width,
+ gdouble dash_offset,
+ const GArray *dash_info)
+{
+ if (dash_info && dash_info->len >= 2)
+ {
+ gint n_dashes = dash_info->len;
+ gdouble *dashes = g_new (gdouble, dash_info->len);
+ gint i;
+
+ dash_offset = dash_offset * MAX (width, 1.0);
+
+ for (i = 0; i < n_dashes; i++)
+ dashes[i] = MAX (width, 1.0) * g_array_index (dash_info, gdouble, i);
+
+ /* correct 0.0 in the first element (starts with a gap) */
+
+ if (dashes[0] == 0.0)
+ {
+ gdouble first;
+
+ first = dashes[1];
+
+ /* shift the pattern to really starts with a dash and
+ * use the offset to skip into it.
+ */
+ for (i = 0; i < n_dashes - 2; i++)
+ {
+ dashes[i] = dashes[i+2];
+ dash_offset += dashes[i];
+ }
+
+ if (n_dashes % 2 == 1)
+ {
+ dashes[n_dashes - 2] = first;
+ n_dashes --;
+ }
+ else if (dash_info->len > 2)
+ {
+ dashes [n_dashes - 3] += first;
+ n_dashes -= 2;
+ }
+ }
+
+ /* correct odd number of dash specifiers */
+
+ if (n_dashes % 2 == 1)
+ {
+ gdouble last = dashes[n_dashes - 1];
+
+ dashes[0] += last;
+ dash_offset += last;
+ n_dashes --;
+ }
+
+ if (n_dashes >= 2)
+ cairo_set_dash (cr,
+ dashes,
+ n_dashes,
+ dash_offset);
+
+ g_free (dashes);
+ }
+}
+
+static cairo_surface_t *
+gimp_temp_buf_create_cairo_surface (GimpTempBuf *temp_buf)
+{
+ cairo_surface_t *surface;
+ gboolean has_alpha;
+ const Babl *format;
+ const Babl *fish = NULL;
+ const guchar *data;
+ gint width;
+ gint height;
+ gint bpp;
+ guchar *pixels;
+ gint rowstride;
+ gint i;
+
+ g_return_val_if_fail (temp_buf != NULL, NULL);
+
+ data = gimp_temp_buf_get_data (temp_buf);
+ format = gimp_temp_buf_get_format (temp_buf);
+ width = gimp_temp_buf_get_width (temp_buf);
+ height = gimp_temp_buf_get_height (temp_buf);
+ bpp = babl_format_get_bytes_per_pixel (format);
+ has_alpha = babl_format_has_alpha (format);
+
+ surface = cairo_image_surface_create (has_alpha ?
+ CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ width, height);
+
+ pixels = cairo_image_surface_get_data (surface);
+ rowstride = cairo_image_surface_get_stride (surface);
+
+ if (format != babl_format (has_alpha ? "cairo-ARGB32" : "cairo-RGB24"))
+ fish = babl_fish (format, babl_format (has_alpha ? "cairo-ARGB32" : "cairo-RGB24"));
+
+ for (i = 0; i < height; i++)
+ {
+ if (fish)
+ babl_process (fish, data, pixels, width);
+ else
+ memcpy (pixels, data, width * bpp);
+
+ data += width * bpp;
+ pixels += rowstride;
+ }
+
+ return surface;
+}
+
static void
gimp_text_layer_render_layout (GimpTextLayer *layer,
GimpTextLayout *layout)
@@ -834,7 +951,60 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
}
cr = cairo_create (surface);
- gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
+ if (layer->text->outline != GIMP_TEXT_OUTLINE_STROKE_ONLY)
+ {
+ cairo_save (cr);
+
+ gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
+
+ cairo_restore (cr);
+ }
+
+ if (layer->text->outline != GIMP_TEXT_OUTLINE_NONE)
+ {
+ GimpText *text = layer->text;
+ GimpRGB col = text->outline_foreground;
+
+ cairo_save (cr);
+
+ cairo_set_antialias (cr, text->outline_antialias ?
+ CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
+ cairo_set_line_cap (cr,
+ text->outline_cap_style == GIMP_CAP_BUTT ? CAIRO_LINE_CAP_BUTT :
+ text->outline_cap_style == GIMP_CAP_ROUND ? CAIRO_LINE_CAP_ROUND :
+ CAIRO_LINE_CAP_SQUARE);
+ cairo_set_line_join (cr, text->outline_join_style == GIMP_JOIN_MITER ? CAIRO_LINE_JOIN_MITER :
+ text->outline_join_style == GIMP_JOIN_ROUND ? CAIRO_LINE_JOIN_ROUND :
+ CAIRO_LINE_JOIN_BEVEL);
+ cairo_set_miter_limit (cr, text->outline_miter_limit);
+
+ if (text->outline_dash_info)
+ gimp_text_layer_set_dash_info (cr, text->outline_width, text->outline_dash_offset,
text->outline_dash_info);
+
+ if (text->outline_style == GIMP_FILL_STYLE_PATTERN && text->outline_pattern)
+ {
+ GimpTempBuf *tempbuf = gimp_pattern_get_mask (text->outline_pattern);
+ cairo_surface_t *surface = gimp_temp_buf_create_cairo_surface (tempbuf);
+
+ cairo_set_source_surface (cr, surface, 0.0, 0.0);
+ cairo_surface_destroy (surface);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ }
+ else
+ {
+ cairo_set_source_rgba (cr, col.r, col.g, col.b, col.a);
+ }
+
+ 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);
+
+ cairo_restore (cr);
+ }
+
cairo_destroy (cr);
cairo_surface_flush (surface);
diff --git a/app/text/text-enums.c b/app/text/text-enums.c
index ab9623838b..271b2065dd 100644
--- a/app/text/text-enums.c
+++ b/app/text/text-enums.c
@@ -51,9 +51,9 @@ gimp_text_outline_get_type (void)
static const GimpEnumDesc descs[] =
{
- { GIMP_TEXT_OUTLINE_NONE, "GIMP_TEXT_OUTLINE_NONE", NULL },
- { GIMP_TEXT_OUTLINE_STROKE_ONLY, "GIMP_TEXT_OUTLINE_STROKE_ONLY", NULL },
- { GIMP_TEXT_OUTLINE_STROKE_FILL, "GIMP_TEXT_OUTLINE_STROKE_FILL", NULL },
+ { GIMP_TEXT_OUTLINE_NONE, NC_("text-outline", "Filled"), NULL },
+ { GIMP_TEXT_OUTLINE_STROKE_ONLY, NC_("text-outline", "Outlined"), NULL },
+ { GIMP_TEXT_OUTLINE_STROKE_FILL, NC_("text-outline", "Outlined and filled"), NULL },
{ 0, NULL, NULL }
};
diff --git a/app/text/text-enums.h b/app/text/text-enums.h
index 20bd327d63..f032ce690b 100644
--- a/app/text/text-enums.h
+++ b/app/text/text-enums.h
@@ -36,9 +36,9 @@ GType gimp_text_outline_get_type (void) G_GNUC_CONST;
typedef enum
{
- GIMP_TEXT_OUTLINE_NONE,
- GIMP_TEXT_OUTLINE_STROKE_ONLY,
- GIMP_TEXT_OUTLINE_STROKE_FILL
+ GIMP_TEXT_OUTLINE_NONE, /*< desc="Filled" >*/
+ GIMP_TEXT_OUTLINE_STROKE_ONLY, /*< desc="Outlined" >*/
+ GIMP_TEXT_OUTLINE_STROKE_FILL /*< desc="Outlined and filled" >*/
} GimpTextOutline;
diff --git a/app/tools/gimptextoptions.c b/app/tools/gimptextoptions.c
index 48a75ee187..db1c8599cf 100644
--- a/app/tools/gimptextoptions.c
+++ b/app/tools/gimptextoptions.c
@@ -21,6 +21,7 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"
@@ -29,6 +30,11 @@
#include "config/gimpconfig-utils.h"
#include "core/gimp.h"
+#include "core/gimpcontainer.h"
+#include "core/gimpdashpattern.h"
+#include "core/gimpdatafactory.h"
+#include "core/gimppattern.h"
+#include "core/gimpstrokeoptions.h"
#include "core/gimpdatafactory.h"
#include "core/gimptoolinfo.h"
#include "core/gimpviewable.h"
@@ -38,6 +44,7 @@
#include "widgets/gimpcolorpanel.h"
#include "widgets/gimpmenufactory.h"
#include "widgets/gimppropwidgets.h"
+#include "widgets/gimpstrokeeditor.h"
#include "widgets/gimptextbuffer.h"
#include "widgets/gimptexteditor.h"
#include "widgets/gimpviewablebox.h"
@@ -64,6 +71,19 @@ enum
PROP_LETTER_SPACING,
PROP_BOX_MODE,
+ PROP_OUTLINE,
+ PROP_OUTLINE_STYLE, /* fill-options */
+ PROP_OUTLINE_FOREGROUND, /* context */
+ PROP_OUTLINE_PATTERN, /* context */
+ PROP_OUTLINE_WIDTH, /* stroke-options */
+ PROP_OUTLINE_UNIT,
+ PROP_OUTLINE_CAP_STYLE,
+ PROP_OUTLINE_JOIN_STYLE,
+ PROP_OUTLINE_MITER_LIMIT,
+ PROP_OUTLINE_ANTIALIAS, /* fill-options */
+ PROP_OUTLINE_DASH_UNIT, /* NOT USED */
+ PROP_OUTLINE_DASH_OFFSET,
+ PROP_OUTLINE_DASH_INFO,
PROP_USE_EDITOR,
PROP_FONT_VIEW_TYPE,
@@ -71,32 +91,46 @@ enum
};
-static void gimp_text_options_config_iface_init (GimpConfigInterface *config_iface);
-
-static void gimp_text_options_finalize (GObject *object);
-static void gimp_text_options_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_text_options_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gimp_text_options_reset (GimpConfig *config);
-
-static void gimp_text_options_notify_font (GimpContext *context,
- GParamSpec *pspec,
- GimpText *text);
-static void gimp_text_options_notify_text_font (GimpText *text,
- GParamSpec *pspec,
- GimpContext *context);
-static void gimp_text_options_notify_color (GimpContext *context,
- GParamSpec *pspec,
- GimpText *text);
-static void gimp_text_options_notify_text_color (GimpText *text,
- GParamSpec *pspec,
- GimpContext *context);
+static void
+ gimp_text_options_config_iface_init (GimpConfigInterface *config_iface);
+static gboolean
+ gimp_text_options_serialize_property (GimpConfig *config,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec,
+ GimpConfigWriter *writer);
+static gboolean
+ gimp_text_options_deserialize_property (GimpConfig *config,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected);
+
+static void gimp_text_options_finalize (GObject *object);
+static void gimp_text_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_text_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_text_options_reset (GimpConfig *config);
+
+static void gimp_text_options_notify_font (GimpContext *context,
+ GParamSpec *pspec,
+ GimpText *text);
+static void gimp_text_options_notify_text_font (GimpText *text,
+ GParamSpec *pspec,
+ GimpContext *context);
+static void gimp_text_options_notify_color (GimpContext *context,
+ GParamSpec *pspec,
+ GimpText *text);
+static void gimp_text_options_notify_text_color (GimpText *text,
+ GParamSpec *pspec,
+ GimpContext *context);
G_DEFINE_TYPE_WITH_CODE (GimpTextOptions, gimp_text_options,
@@ -113,7 +147,10 @@ static void
gimp_text_options_class_init (GimpTextOptionsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpRGB gray;
+ GParamSpec *array_spec;
+ gimp_rgba_set (&gray, 0.75, 0.75, 0.75, GIMP_OPACITY_OPAQUE);
object_class->finalize = gimp_text_options_finalize;
object_class->set_property = gimp_text_options_set_property;
object_class->get_property = gimp_text_options_get_property;
@@ -224,6 +261,82 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass)
GIMP_VIEWABLE_MAX_BUTTON_SIZE,
GIMP_VIEW_SIZE_SMALL,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE,
+ "outline",
+ NULL, NULL,
+ GIMP_TYPE_TEXT_OUTLINE,
+ GIMP_TEXT_OUTLINE_NONE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_DEFAULTS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_STYLE,
+ "outline-style",
+ NULL, NULL,
+ GIMP_TYPE_FILL_STYLE,
+ GIMP_FILL_STYLE_SOLID,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_OUTLINE_FOREGROUND,
+ "outline-foreground",
+ NULL, NULL,
+ FALSE, &gray,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_OUTLINE_PATTERN,
+ "outline-pattern",
+ NULL, NULL,
+ GIMP_TYPE_PATTERN,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_WIDTH,
+ "outline-width",
+ _("Outline width"),
+ _("Adjust outline width"),
+ 0, 8192.0, 2.0,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_DEFAULTS);
+ GIMP_CONFIG_PROP_UNIT (object_class, PROP_OUTLINE_UNIT,
+ "outline-unit",
+ _("Unit"),
+ _("Outline width unit"),
+ TRUE, FALSE, GIMP_UNIT_PIXEL,
+ 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,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE_JOIN_STYLE,
+ "outline-join-style",
+ NULL, NULL,
+ GIMP_TYPE_JOIN_STYLE, GIMP_JOIN_MITER,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_MITER_LIMIT,
+ "outline-miter-limit",
+ _("Outline miter limit"),
+ _("Convert a mitered join to a bevelled "
+ "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,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OUTLINE_ANTIALIAS,
+ "outline-antialias",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_DASH_OFFSET,
+ "outline-dash-offset",
+ NULL, NULL,
+ 0.0, 2000.0, 0.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ array_spec = g_param_spec_double ("outline-dash-length",
+ NULL, NULL,
+ 0.0, 2000.0, 1.0,
+ GIMP_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_OUTLINE_DASH_INFO,
+ gimp_param_spec_value_array ("outline-dash-info",
+ NULL, NULL,
+ array_spec,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_FLAGS));
}
static void
@@ -232,6 +345,9 @@ gimp_text_options_config_iface_init (GimpConfigInterface *config_iface)
parent_config_iface = g_type_interface_peek_parent (config_iface);
config_iface->reset = gimp_text_options_reset;
+
+ config_iface->serialize_property = gimp_text_options_serialize_property;
+ config_iface->deserialize_property = gimp_text_options_deserialize_property;
}
static void
@@ -294,6 +410,51 @@ gimp_text_options_get_property (GObject *object,
g_value_set_enum (value, options->box_mode);
break;
+ case PROP_OUTLINE:
+ g_value_set_enum (value, options->outline);
+ break;
+ case PROP_OUTLINE_STYLE:
+ g_value_set_enum (value, options->outline_style);
+ break;
+ case PROP_OUTLINE_FOREGROUND:
+ g_value_set_boxed (value, &options->outline_foreground);
+ break;
+ case PROP_OUTLINE_PATTERN:
+ g_value_set_object (value, options->outline_pattern);
+ break;
+ case PROP_OUTLINE_WIDTH:
+ g_value_set_double (value, options->outline_width);
+ break;
+ case PROP_OUTLINE_UNIT:
+ g_value_set_int (value, options->outline_unit);
+ break;
+ case PROP_OUTLINE_CAP_STYLE:
+ g_value_set_enum (value, options->outline_cap_style);
+ break;
+ case PROP_OUTLINE_JOIN_STYLE:
+ g_value_set_enum (value, options->outline_join_style);
+ break;
+ case PROP_OUTLINE_MITER_LIMIT:
+ g_value_set_double (value, options->outline_miter_limit);
+ break;
+ case PROP_OUTLINE_ANTIALIAS:
+ g_value_set_boolean (value, options->outline_antialias);
+ break;
+ case PROP_OUTLINE_DASH_UNIT:
+ /* NOT USED */
+ break;
+ case PROP_OUTLINE_DASH_OFFSET:
+ g_value_set_double (value, options->outline_dash_offset);
+ break;
+ case PROP_OUTLINE_DASH_INFO:
+ {
+ GimpValueArray *value_array;
+
+ value_array = gimp_dash_pattern_to_value_array (options->outline_dash_info);
+ g_value_take_boxed (value, value_array);
+ }
+ break;
+
case PROP_USE_EDITOR:
g_value_set_boolean (value, options->use_editor);
break;
@@ -318,6 +479,7 @@ gimp_text_options_set_property (GObject *object,
GParamSpec *pspec)
{
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
+ GimpRGB *color;
switch (property_id)
{
@@ -356,6 +518,60 @@ gimp_text_options_set_property (GObject *object,
options->box_mode = g_value_get_enum (value);
break;
+ case PROP_OUTLINE:
+ options->outline = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_STYLE:
+ options->outline_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_FOREGROUND:
+ color = g_value_get_boxed (value);
+ options->outline_foreground = *color;
+ break;
+ case PROP_OUTLINE_PATTERN:
+ {
+ GimpPattern *pattern = g_value_get_object (value);
+
+ if (options->outline_pattern != pattern)
+ {
+ if (options->outline_pattern)
+ g_object_unref (options->outline_pattern);
+
+ options->outline_pattern = pattern ? g_object_ref (pattern) : pattern;
+ }
+ break;
+ }
+ case PROP_OUTLINE_WIDTH:
+ options->outline_width = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_UNIT:
+ options->outline_unit = g_value_get_int (value);
+ break;
+ case PROP_OUTLINE_CAP_STYLE:
+ options->outline_cap_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_JOIN_STYLE:
+ options->outline_join_style = g_value_get_enum (value);
+ break;
+ case PROP_OUTLINE_MITER_LIMIT:
+ options->outline_miter_limit = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_ANTIALIAS:
+ options->outline_antialias = g_value_get_boolean (value);
+ break;
+ case PROP_OUTLINE_DASH_UNIT:
+ /* unused */
+ break;
+ case PROP_OUTLINE_DASH_OFFSET:
+ options->outline_dash_offset = g_value_get_double (value);
+ break;
+ case PROP_OUTLINE_DASH_INFO:
+ {
+ GimpValueArray *value_array = g_value_get_boxed (value);
+ options->outline_dash_info = gimp_dash_pattern_from_value_array (value_array);
+ }
+ break;
+
case PROP_USE_EDITOR:
options->use_editor = g_value_get_boolean (value);
break;
@@ -399,6 +615,21 @@ gimp_text_options_reset (GimpConfig *config)
gimp_config_reset_property (object, "line-spacing");
gimp_config_reset_property (object, "letter-spacing");
gimp_config_reset_property (object, "box-mode");
+
+ gimp_config_reset_property (object, "outline");
+ gimp_config_reset_property (object, "outline-style");
+ gimp_config_reset_property (object, "outline-foreground");
+ 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-cap-style");
+ gimp_config_reset_property (object, "outline-join-style");
+ gimp_config_reset_property (object, "outline-miter-limit");
+ gimp_config_reset_property (object, "outline-antialias");
+ //gimp_config_reset_property (object, "outline-dash-unit");
+ gimp_config_reset_property (object, "outline-dash-offset");
+ gimp_config_reset_property (object, "outline-dash-info");
+
gimp_config_reset_property (object, "use-editor");
}
@@ -510,21 +741,23 @@ gimp_text_options_connect_text (GimpTextOptions *options,
GtkWidget *
gimp_text_options_gui (GimpToolOptions *tool_options)
{
- GObject *config = G_OBJECT (tool_options);
- GimpTextOptions *options = GIMP_TEXT_OPTIONS (tool_options);
- GtkWidget *main_vbox = gimp_tool_options_gui (tool_options);
- GimpAsyncSet *async_set;
- GtkWidget *options_vbox;
- GtkWidget *grid;
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *button;
- GtkWidget *entry;
- GtkWidget *box;
- GtkWidget *spinbutton;
- GtkWidget *combo;
- GtkSizeGroup *size_group;
- gint row = 0;
+ GObject *config = G_OBJECT (tool_options);
+ GimpTextOptions *options = GIMP_TEXT_OPTIONS (tool_options);
+ GtkWidget *main_vbox = gimp_tool_options_gui (tool_options);
+ GimpAsyncSet *async_set;
+ GtkWidget *options_vbox;
+ GtkWidget *grid;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *button;
+ GtkWidget *entry;
+ GtkWidget *box;
+ GtkWidget *spinbutton;
+ GtkWidget *combo;
+ GtkWidget *editor;
+ GimpStrokeOptions *stroke_options;
+ GtkSizeGroup *size_group;
+ gint row = 0;
async_set =
gimp_data_factory_get_async_set (tool_options->tool_info->gimp->font_factory);
@@ -605,6 +838,12 @@ gimp_text_options_gui (GimpToolOptions *tool_options)
button, 1);
gtk_size_group_add_widget (size_group, button);
+ button = gimp_prop_enum_combo_box_new (config, "outline", -1, -1);
+ gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
+ _("Outline:"), 0.0, 0.5,
+ button, 1);
+ gtk_size_group_add_widget (size_group, button);
+
box = gimp_prop_enum_icon_box_new (config, "justify", "format-justify", 0, 0);
gtk_widget_set_halign (box, GTK_ALIGN_START);
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
@@ -640,6 +879,38 @@ gimp_text_options_gui (GimpToolOptions *tool_options)
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
_("Box:"), 0.0, 0.5,
combo, 1);
+ stroke_options = gimp_stroke_options_new (GIMP_CONTEXT (options)->gimp,
+ NULL,
+ FALSE);
+#define BIND(a) \
+ g_object_bind_property (options, "outline-" #a, \
+ stroke_options, #a, \
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE)
+ BIND (style);
+ BIND (foreground);
+ BIND (pattern);
+ BIND (width);
+ BIND (unit);
+ BIND (cap-style);
+ BIND (join-style);
+ BIND (miter-limit);
+ BIND (antialias);
+ // BIND (dash-unit);
+ BIND (dash-offset);
+ BIND (dash-info);
+ /*
+ {
+ GimpPattern *pattern = gimp_context_get_pattern (gimp_get_user_context (GIMP_CONTEXT (options)->gimp));
+ gimp_context_set_pattern (GIMP_CONTEXT (stroke_options), pattern);
+ }
+ */
+ editor = gimp_stroke_editor_new (stroke_options, 72.0, TRUE);
+ gtk_box_pack_start (GTK_BOX (main_vbox), editor, FALSE, FALSE, 0);
+ gtk_widget_show (editor);
+
+ g_object_unref (stroke_options);
+
+
/* Only add the language entry if the iso-codes package is available. */
@@ -745,3 +1016,75 @@ gimp_text_options_editor_new (GtkWindow *parent,
return editor;
}
+
+static gboolean
+gimp_text_options_serialize_property (GimpConfig *config,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec,
+ GimpConfigWriter *writer)
+{
+ if (property_id == PROP_OUTLINE_PATTERN)
+ {
+ GimpObject *serialize_obj = g_value_get_object (value);
+
+ gimp_config_writer_open (writer, pspec->name);
+
+ if (serialize_obj)
+ gimp_config_writer_string (writer, gimp_object_get_name (serialize_obj));
+ else
+ gimp_config_writer_print (writer, "NULL", 4);
+
+ gimp_config_writer_close (writer);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_text_options_deserialize_property (GimpConfig *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected)
+{
+ if (property_id == PROP_OUTLINE_PATTERN)
+ {
+ gchar *object_name;
+
+ if (gimp_scanner_parse_identifier (scanner, "NULL"))
+ {
+ g_value_set_object (value, NULL);
+ }
+ else if (gimp_scanner_parse_string (scanner, &object_name))
+ {
+ GimpContext *context = GIMP_CONTEXT (object);
+ GimpContainer *container;
+ GimpObject *deserialize_obj;
+
+ if (! object_name)
+ object_name = g_strdup ("");
+
+ container = gimp_data_factory_get_container (context->gimp->pattern_factory);
+
+ deserialize_obj = gimp_container_get_child_by_name (container,
+ object_name);
+
+ g_value_set_object (value, deserialize_obj);
+
+ g_free (object_name);
+ }
+ else
+ {
+ *expected = G_TOKEN_STRING;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/app/tools/gimptextoptions.h b/app/tools/gimptextoptions.h
index d80c21f5f8..b45d8625d8 100644
--- a/app/tools/gimptextoptions.h
+++ b/app/tools/gimptextoptions.h
@@ -49,6 +49,19 @@ struct _GimpTextOptions
gdouble letter_spacing;
GimpTextBoxMode box_mode;
+ GimpTextOutline outline;
+ GimpFillStyle outline_style;
+ GimpRGB 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;
+
GimpViewType font_view_type;
GimpViewSize font_view_size;
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index bc8309aa3e..0202d4cfa0 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -2117,7 +2117,8 @@ gimp_text_tool_apply (GimpTextTool *text_tool,
GIMP_DRAWABLE (layer), TRUE);
}
- gimp_image_undo_push_text_layer (image, NULL, layer, pspec);
+ if (pspec)
+ gimp_image_undo_push_text_layer (image, NULL, layer, pspec);
}
gimp_text_tool_apply_list (text_tool, list);
diff --git a/app/widgets/gimpfilleditor.c b/app/widgets/gimpfilleditor.c
index 50d110e150..0f16ccf4d4 100644
--- a/app/widgets/gimpfilleditor.c
+++ b/app/widgets/gimpfilleditor.c
@@ -121,7 +121,7 @@ gimp_fill_editor_constructed (GObject *object)
color_button = gimp_prop_color_button_new (G_OBJECT (editor->options),
"foreground",
_("Fill Color"),
- -1, 24,
+ 1, 24,
GIMP_COLOR_AREA_SMALL_CHECKS);
gimp_color_panel_set_context (GIMP_COLOR_PANEL (color_button),
GIMP_CONTEXT (editor->options));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]