mirror of https://github.com/GNOME/gimp.git
text: Add outline options to text editor
This ports Massimo’s code to work in the latest version of GIMP. It adds new outline-related properties to GimpText and GimpTextOptions. These are controlled via the Text Tool Editor. Cairo is currently used to draw the outline around the text.
This commit is contained in:
parent
2080abf0a3
commit
ca6b58e970
|
@ -243,6 +243,20 @@ gimp_g_value_get_memsize (GValue *value)
|
||||||
memsize += gimp_string_get_memsize (array[i]);
|
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
|
else
|
||||||
{
|
{
|
||||||
g_printerr ("%s: unhandled boxed value type: %s\n",
|
g_printerr ("%s: unhandled boxed value type: %s\n",
|
||||||
|
@ -251,6 +265,9 @@ gimp_g_value_get_memsize (GValue *value)
|
||||||
}
|
}
|
||||||
else if (G_VALUE_HOLDS_OBJECT (value))
|
else if (G_VALUE_HOLDS_OBJECT (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_printerr ("%s: unhandled object value type: %s\n",
|
||||||
G_STRFUNC, G_VALUE_TYPE_NAME (value));
|
G_STRFUNC, G_VALUE_TYPE_NAME (value));
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ gimp_text_to_parasite (GimpText *text)
|
||||||
|
|
||||||
GimpText *
|
GimpText *
|
||||||
gimp_text_from_parasite (const GimpParasite *parasite,
|
gimp_text_from_parasite (const GimpParasite *parasite,
|
||||||
|
Gimp *gimp,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GimpText *text;
|
GimpText *text;
|
||||||
|
@ -76,7 +77,7 @@ gimp_text_from_parasite (const GimpParasite *parasite,
|
||||||
gimp_text_parasite_name ()) == 0, NULL);
|
gimp_text_parasite_name ()) == 0, NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, 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);
|
parasite_data = (gchar *) gimp_parasite_get_data (parasite, ¶site_data_size);
|
||||||
if (parasite_data)
|
if (parasite_data)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
const gchar * gimp_text_parasite_name (void) G_GNUC_CONST;
|
const gchar * gimp_text_parasite_name (void) G_GNUC_CONST;
|
||||||
GimpParasite * gimp_text_to_parasite (GimpText *text);
|
GimpParasite * gimp_text_to_parasite (GimpText *text);
|
||||||
GimpText * gimp_text_from_parasite (const GimpParasite *parasite,
|
GimpText * gimp_text_from_parasite (const GimpParasite *parasite,
|
||||||
|
Gimp *gimp,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
const gchar * gimp_text_gdyntext_parasite_name (void) G_GNUC_CONST;
|
const gchar * gimp_text_gdyntext_parasite_name (void) G_GNUC_CONST;
|
||||||
|
|
|
@ -34,9 +34,14 @@
|
||||||
|
|
||||||
#include "text-types.h"
|
#include "text-types.h"
|
||||||
|
|
||||||
|
#include "core/gimp.h"
|
||||||
#include "core/gimp-memsize.h"
|
#include "core/gimp-memsize.h"
|
||||||
#include "core/gimp-utils.h"
|
#include "core/gimp-utils.h"
|
||||||
|
#include "core/gimpcontainer.h"
|
||||||
|
#include "core/gimpdashpattern.h"
|
||||||
|
#include "core/gimpdatafactory.h"
|
||||||
#include "core/gimpstrokeoptions.h"
|
#include "core/gimpstrokeoptions.h"
|
||||||
|
#include "core/gimppattern.h"
|
||||||
|
|
||||||
#include "gimptext.h"
|
#include "gimptext.h"
|
||||||
|
|
||||||
|
@ -68,8 +73,22 @@ enum
|
||||||
PROP_OFFSET_X,
|
PROP_OFFSET_X,
|
||||||
PROP_OFFSET_Y,
|
PROP_OFFSET_Y,
|
||||||
PROP_BORDER,
|
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_OFFSET,
|
||||||
|
PROP_OUTLINE_DASH_INFO,
|
||||||
/* for backward compatibility */
|
/* for backward compatibility */
|
||||||
PROP_HINTING
|
PROP_HINTING,
|
||||||
|
|
||||||
|
PROP_GIMP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -78,6 +97,18 @@ enum
|
||||||
LAST_SIGNAL
|
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_finalize (GObject *object);
|
||||||
static void gimp_text_get_property (GObject *object,
|
static void gimp_text_get_property (GObject *object,
|
||||||
|
@ -96,7 +127,8 @@ static gint64 gimp_text_get_memsize (GimpObject *object,
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GimpText, gimp_text, GIMP_TYPE_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
|
#define parent_class gimp_text_parent_class
|
||||||
|
|
||||||
|
@ -109,8 +141,10 @@ gimp_text_class_init (GimpTextClass *klass)
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||||
GimpRGB black;
|
GimpRGB black;
|
||||||
|
GimpRGB gray;
|
||||||
GimpMatrix2 identity;
|
GimpMatrix2 identity;
|
||||||
gchar *language;
|
gchar *language;
|
||||||
|
GParamSpec *array_spec;
|
||||||
|
|
||||||
text_signals[CHANGED] =
|
text_signals[CHANGED] =
|
||||||
g_signal_new ("changed",
|
g_signal_new ("changed",
|
||||||
|
@ -128,6 +162,7 @@ gimp_text_class_init (GimpTextClass *klass)
|
||||||
gimp_object_class->get_memsize = gimp_text_get_memsize;
|
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 (&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_matrix2_identity (&identity);
|
||||||
|
|
||||||
GIMP_CONFIG_PROP_STRING (object_class, PROP_TEXT,
|
GIMP_CONFIG_PROP_STRING (object_class, PROP_TEXT,
|
||||||
|
@ -298,12 +333,68 @@ gimp_text_class_init (GimpTextClass *klass)
|
||||||
G_PARAM_CONSTRUCT |
|
G_PARAM_CONSTRUCT |
|
||||||
GIMP_PARAM_WRITABLE));
|
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' */
|
/* the old hinting options have been replaced by 'hint-style' */
|
||||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_HINTING,
|
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_HINTING,
|
||||||
"hinting",
|
"hinting",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
TRUE,
|
TRUE,
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
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
|
static void
|
||||||
|
@ -311,6 +402,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
|
static void
|
||||||
gimp_text_finalize (GObject *object)
|
gimp_text_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
|
@ -403,10 +501,48 @@ gimp_text_get_property (GObject *object,
|
||||||
case PROP_OFFSET_Y:
|
case PROP_OFFSET_Y:
|
||||||
g_value_set_double (value, text->offset_y);
|
g_value_set_double (value, text->offset_y);
|
||||||
break;
|
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_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:
|
case PROP_HINTING:
|
||||||
g_value_set_boolean (value,
|
g_value_set_boolean (value,
|
||||||
text->hint_style != GIMP_TEXT_HINT_STYLE_NONE);
|
text->hint_style != GIMP_TEXT_HINT_STYLE_NONE);
|
||||||
break;
|
break;
|
||||||
|
case PROP_GIMP:
|
||||||
|
g_value_set_object (value, text->gimp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -527,6 +663,50 @@ gimp_text_set_property (GObject *object,
|
||||||
case PROP_OFFSET_Y:
|
case PROP_OFFSET_Y:
|
||||||
text->offset_y = g_value_get_double (value);
|
text->offset_y = g_value_get_double (value);
|
||||||
break;
|
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_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:
|
case PROP_BORDER:
|
||||||
text->border = g_value_get_int (value);
|
text->border = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
@ -540,6 +720,8 @@ gimp_text_set_property (GObject *object,
|
||||||
GIMP_TEXT_HINT_STYLE_MEDIUM :
|
GIMP_TEXT_HINT_STYLE_MEDIUM :
|
||||||
GIMP_TEXT_HINT_STYLE_NONE);
|
GIMP_TEXT_HINT_STYLE_NONE);
|
||||||
break;
|
break;
|
||||||
|
case PROP_GIMP:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -592,3 +774,82 @@ gimp_text_get_transformation (GimpText *text,
|
||||||
matrix->coeff[2][1] = 0.0;
|
matrix->coeff[2][1] = 0.0;
|
||||||
matrix->coeff[2][2] = 1.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;
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,16 @@ struct _GimpText
|
||||||
gchar *language;
|
gchar *language;
|
||||||
GimpTextDirection base_dir;
|
GimpTextDirection base_dir;
|
||||||
GimpRGB color;
|
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;
|
GimpTextOutline outline;
|
||||||
GimpTextJustification justify;
|
GimpTextJustification justify;
|
||||||
gdouble indent;
|
gdouble indent;
|
||||||
|
@ -64,6 +74,7 @@ struct _GimpText
|
||||||
gdouble offset_y;
|
gdouble offset_y;
|
||||||
|
|
||||||
gdouble border;
|
gdouble border;
|
||||||
|
Gimp *gimp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GimpTextClass
|
struct _GimpTextClass
|
||||||
|
|
|
@ -69,7 +69,9 @@ gimp_text_layer_xcf_load_hack (GimpLayer **layer)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
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)
|
if (error)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
|
|
||||||
#include "core/gimp.h"
|
#include "core/gimp.h"
|
||||||
#include "core/gimp-utils.h"
|
#include "core/gimp-utils.h"
|
||||||
#include "core/gimpcontext.h"
|
|
||||||
#include "core/gimpcontainer.h"
|
#include "core/gimpcontainer.h"
|
||||||
|
#include "core/gimpcontext.h"
|
||||||
#include "core/gimpdatafactory.h"
|
#include "core/gimpdatafactory.h"
|
||||||
#include "core/gimpimage.h"
|
#include "core/gimpimage.h"
|
||||||
#include "core/gimpimage-color-profile.h"
|
#include "core/gimpimage-color-profile.h"
|
||||||
|
@ -48,6 +48,8 @@
|
||||||
#include "core/gimpimage-undo-push.h"
|
#include "core/gimpimage-undo-push.h"
|
||||||
#include "core/gimpitemtree.h"
|
#include "core/gimpitemtree.h"
|
||||||
#include "core/gimpparasitelist.h"
|
#include "core/gimpparasitelist.h"
|
||||||
|
#include "core/gimppattern.h"
|
||||||
|
#include "core/gimptempbuf.h"
|
||||||
|
|
||||||
#include "gimptext.h"
|
#include "gimptext.h"
|
||||||
#include "gimptextlayer.h"
|
#include "gimptextlayer.h"
|
||||||
|
@ -799,6 +801,121 @@ gimp_text_layer_render (GimpTextLayer *layer)
|
||||||
return (width > 0 && height > 0);
|
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
|
static void
|
||||||
gimp_text_layer_render_layout (GimpTextLayer *layer,
|
gimp_text_layer_render_layout (GimpTextLayer *layer,
|
||||||
GimpTextLayout *layout)
|
GimpTextLayout *layout)
|
||||||
|
@ -834,7 +951,60 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
|
||||||
}
|
}
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
|
if (layer->text->outline != GIMP_TEXT_OUTLINE_STROKE_ONLY)
|
||||||
|
{
|
||||||
|
cairo_save (cr);
|
||||||
|
|
||||||
gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
|
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_destroy (cr);
|
||||||
|
|
||||||
cairo_surface_flush (surface);
|
cairo_surface_flush (surface);
|
||||||
|
|
|
@ -51,9 +51,9 @@ gimp_text_outline_get_type (void)
|
||||||
|
|
||||||
static const GimpEnumDesc descs[] =
|
static const GimpEnumDesc descs[] =
|
||||||
{
|
{
|
||||||
{ GIMP_TEXT_OUTLINE_NONE, "GIMP_TEXT_OUTLINE_NONE", NULL },
|
{ GIMP_TEXT_OUTLINE_NONE, NC_("text-outline", "Filled"), NULL },
|
||||||
{ GIMP_TEXT_OUTLINE_STROKE_ONLY, "GIMP_TEXT_OUTLINE_STROKE_ONLY", NULL },
|
{ GIMP_TEXT_OUTLINE_STROKE_ONLY, NC_("text-outline", "Outlined"), NULL },
|
||||||
{ GIMP_TEXT_OUTLINE_STROKE_FILL, "GIMP_TEXT_OUTLINE_STROKE_FILL", NULL },
|
{ GIMP_TEXT_OUTLINE_STROKE_FILL, NC_("text-outline", "Outlined and filled"), NULL },
|
||||||
{ 0, NULL, NULL }
|
{ 0, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ GType gimp_text_outline_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GIMP_TEXT_OUTLINE_NONE,
|
GIMP_TEXT_OUTLINE_NONE, /*< desc="Filled" >*/
|
||||||
GIMP_TEXT_OUTLINE_STROKE_ONLY,
|
GIMP_TEXT_OUTLINE_STROKE_ONLY, /*< desc="Outlined" >*/
|
||||||
GIMP_TEXT_OUTLINE_STROKE_FILL
|
GIMP_TEXT_OUTLINE_STROKE_FILL /*< desc="Outlined and filled" >*/
|
||||||
} GimpTextOutline;
|
} GimpTextOutline;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "libgimpbase/gimpbase.h"
|
#include "libgimpbase/gimpbase.h"
|
||||||
|
#include "libgimpcolor/gimpcolor.h"
|
||||||
#include "libgimpconfig/gimpconfig.h"
|
#include "libgimpconfig/gimpconfig.h"
|
||||||
#include "libgimpwidgets/gimpwidgets.h"
|
#include "libgimpwidgets/gimpwidgets.h"
|
||||||
|
|
||||||
|
@ -29,7 +30,11 @@
|
||||||
#include "config/gimpconfig-utils.h"
|
#include "config/gimpconfig-utils.h"
|
||||||
|
|
||||||
#include "core/gimp.h"
|
#include "core/gimp.h"
|
||||||
|
#include "core/gimpcontainer.h"
|
||||||
|
#include "core/gimpdashpattern.h"
|
||||||
#include "core/gimpdatafactory.h"
|
#include "core/gimpdatafactory.h"
|
||||||
|
#include "core/gimppattern.h"
|
||||||
|
#include "core/gimpstrokeoptions.h"
|
||||||
#include "core/gimptoolinfo.h"
|
#include "core/gimptoolinfo.h"
|
||||||
#include "core/gimpviewable.h"
|
#include "core/gimpviewable.h"
|
||||||
|
|
||||||
|
@ -38,6 +43,7 @@
|
||||||
#include "widgets/gimpcolorpanel.h"
|
#include "widgets/gimpcolorpanel.h"
|
||||||
#include "widgets/gimpmenufactory.h"
|
#include "widgets/gimpmenufactory.h"
|
||||||
#include "widgets/gimppropwidgets.h"
|
#include "widgets/gimppropwidgets.h"
|
||||||
|
#include "widgets/gimpstrokeeditor.h"
|
||||||
#include "widgets/gimptextbuffer.h"
|
#include "widgets/gimptextbuffer.h"
|
||||||
#include "widgets/gimptexteditor.h"
|
#include "widgets/gimptexteditor.h"
|
||||||
#include "widgets/gimpviewablebox.h"
|
#include "widgets/gimpviewablebox.h"
|
||||||
|
@ -64,6 +70,18 @@ enum
|
||||||
PROP_LETTER_SPACING,
|
PROP_LETTER_SPACING,
|
||||||
PROP_BOX_MODE,
|
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_OFFSET,
|
||||||
|
PROP_OUTLINE_DASH_INFO,
|
||||||
PROP_USE_EDITOR,
|
PROP_USE_EDITOR,
|
||||||
|
|
||||||
PROP_FONT_VIEW_TYPE,
|
PROP_FONT_VIEW_TYPE,
|
||||||
|
@ -71,7 +89,21 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void gimp_text_options_config_iface_init (GimpConfigInterface *config_iface);
|
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_finalize (GObject *object);
|
||||||
static void gimp_text_options_set_property (GObject *object,
|
static void gimp_text_options_set_property (GObject *object,
|
||||||
|
@ -97,6 +129,9 @@ static void gimp_text_options_notify_color (GimpContext *context,
|
||||||
static void gimp_text_options_notify_text_color (GimpText *text,
|
static void gimp_text_options_notify_text_color (GimpText *text,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GimpContext *context);
|
GimpContext *context);
|
||||||
|
static void gimp_text_options_outline_changed (GtkWidget *combo,
|
||||||
|
GtkWidget *vbox);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GimpTextOptions, gimp_text_options,
|
G_DEFINE_TYPE_WITH_CODE (GimpTextOptions, gimp_text_options,
|
||||||
|
@ -113,7 +148,10 @@ static void
|
||||||
gimp_text_options_class_init (GimpTextOptionsClass *klass)
|
gimp_text_options_class_init (GimpTextOptionsClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (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->finalize = gimp_text_options_finalize;
|
||||||
object_class->set_property = gimp_text_options_set_property;
|
object_class->set_property = gimp_text_options_set_property;
|
||||||
object_class->get_property = gimp_text_options_get_property;
|
object_class->get_property = gimp_text_options_get_property;
|
||||||
|
@ -224,6 +262,82 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass)
|
||||||
GIMP_VIEWABLE_MAX_BUTTON_SIZE,
|
GIMP_VIEWABLE_MAX_BUTTON_SIZE,
|
||||||
GIMP_VIEW_SIZE_SMALL,
|
GIMP_VIEW_SIZE_SMALL,
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
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
|
static void
|
||||||
|
@ -232,6 +346,9 @@ gimp_text_options_config_iface_init (GimpConfigInterface *config_iface)
|
||||||
parent_config_iface = g_type_interface_peek_parent (config_iface);
|
parent_config_iface = g_type_interface_peek_parent (config_iface);
|
||||||
|
|
||||||
config_iface->reset = gimp_text_options_reset;
|
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
|
static void
|
||||||
|
@ -294,6 +411,48 @@ gimp_text_options_get_property (GObject *object,
|
||||||
g_value_set_enum (value, options->box_mode);
|
g_value_set_enum (value, options->box_mode);
|
||||||
break;
|
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_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:
|
case PROP_USE_EDITOR:
|
||||||
g_value_set_boolean (value, options->use_editor);
|
g_value_set_boolean (value, options->use_editor);
|
||||||
break;
|
break;
|
||||||
|
@ -318,6 +477,7 @@ gimp_text_options_set_property (GObject *object,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
|
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
|
||||||
|
GimpRGB *color;
|
||||||
|
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
|
@ -356,6 +516,57 @@ gimp_text_options_set_property (GObject *object,
|
||||||
options->box_mode = g_value_get_enum (value);
|
options->box_mode = g_value_get_enum (value);
|
||||||
break;
|
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_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:
|
case PROP_USE_EDITOR:
|
||||||
options->use_editor = g_value_get_boolean (value);
|
options->use_editor = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
@ -399,6 +610,20 @@ gimp_text_options_reset (GimpConfig *config)
|
||||||
gimp_config_reset_property (object, "line-spacing");
|
gimp_config_reset_property (object, "line-spacing");
|
||||||
gimp_config_reset_property (object, "letter-spacing");
|
gimp_config_reset_property (object, "letter-spacing");
|
||||||
gimp_config_reset_property (object, "box-mode");
|
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-offset");
|
||||||
|
gimp_config_reset_property (object, "outline-dash-info");
|
||||||
|
|
||||||
gimp_config_reset_property (object, "use-editor");
|
gimp_config_reset_property (object, "use-editor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +748,9 @@ gimp_text_options_gui (GimpToolOptions *tool_options)
|
||||||
GtkWidget *box;
|
GtkWidget *box;
|
||||||
GtkWidget *spinbutton;
|
GtkWidget *spinbutton;
|
||||||
GtkWidget *combo;
|
GtkWidget *combo;
|
||||||
|
GtkWidget *editor;
|
||||||
|
GimpStrokeOptions *stroke_options;
|
||||||
|
GtkWidget *outline_frame;
|
||||||
GtkSizeGroup *size_group;
|
GtkSizeGroup *size_group;
|
||||||
gint row = 0;
|
gint row = 0;
|
||||||
|
|
||||||
|
@ -605,6 +833,29 @@ gimp_text_options_gui (GimpToolOptions *tool_options)
|
||||||
button, 1);
|
button, 1);
|
||||||
gtk_size_group_add_widget (size_group, button);
|
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++,
|
||||||
|
_("Style:"), 0.0, 0.5,
|
||||||
|
button, 1);
|
||||||
|
gtk_size_group_add_widget (size_group, button);
|
||||||
|
|
||||||
|
outline_frame = gimp_frame_new (_("Outline Options"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (options_vbox), outline_frame, FALSE, FALSE, 0);
|
||||||
|
gtk_widget_show (outline_frame);
|
||||||
|
|
||||||
|
g_signal_connect (button, "changed",
|
||||||
|
G_CALLBACK (gimp_text_options_outline_changed),
|
||||||
|
outline_frame);
|
||||||
|
gimp_text_options_outline_changed (button, outline_frame);
|
||||||
|
|
||||||
|
grid = gtk_grid_new ();
|
||||||
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
|
||||||
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
|
||||||
|
gtk_box_pack_start (GTK_BOX (options_vbox), grid, FALSE, FALSE, 0);
|
||||||
|
gtk_widget_show (grid);
|
||||||
|
|
||||||
|
row = 0;
|
||||||
|
|
||||||
box = gimp_prop_enum_icon_box_new (config, "justify", "format-justify", 0, 0);
|
box = gimp_prop_enum_icon_box_new (config, "justify", "format-justify", 0, 0);
|
||||||
gtk_widget_set_halign (box, GTK_ALIGN_START);
|
gtk_widget_set_halign (box, GTK_ALIGN_START);
|
||||||
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
||||||
|
@ -640,6 +891,29 @@ gimp_text_options_gui (GimpToolOptions *tool_options)
|
||||||
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++,
|
||||||
_("Box:"), 0.0, 0.5,
|
_("Box:"), 0.0, 0.5,
|
||||||
combo, 1);
|
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-offset);
|
||||||
|
BIND (dash-info);
|
||||||
|
|
||||||
|
editor = gimp_stroke_editor_new (stroke_options, 72.0, TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (outline_frame), editor);
|
||||||
|
gtk_widget_show (editor);
|
||||||
|
|
||||||
|
g_object_unref (stroke_options);
|
||||||
|
|
||||||
/* Only add the language entry if the iso-codes package is available. */
|
/* Only add the language entry if the iso-codes package is available. */
|
||||||
|
|
||||||
|
@ -702,6 +976,20 @@ gimp_text_options_editor_notify_font (GimpTextOptions *options,
|
||||||
gimp_text_editor_set_font_name (editor, font_name);
|
gimp_text_editor_set_font_name (editor, font_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_text_options_outline_changed (GtkWidget *combo,
|
||||||
|
GtkWidget *vbox)
|
||||||
|
{
|
||||||
|
GimpTextOutline active;
|
||||||
|
|
||||||
|
active = (GimpTextOutline) gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
|
||||||
|
|
||||||
|
if (active == GIMP_TEXT_OUTLINE_NONE)
|
||||||
|
gtk_widget_hide (vbox);
|
||||||
|
else
|
||||||
|
gtk_widget_show (vbox);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gimp_text_options_editor_new (GtkWindow *parent,
|
gimp_text_options_editor_new (GtkWindow *parent,
|
||||||
Gimp *gimp,
|
Gimp *gimp,
|
||||||
|
@ -745,3 +1033,74 @@ gimp_text_options_editor_new (GtkWindow *parent,
|
||||||
|
|
||||||
return editor;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,19 @@ struct _GimpTextOptions
|
||||||
gdouble letter_spacing;
|
gdouble letter_spacing;
|
||||||
GimpTextBoxMode box_mode;
|
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;
|
GimpViewType font_view_type;
|
||||||
GimpViewSize font_view_size;
|
GimpViewSize font_view_size;
|
||||||
|
|
||||||
|
|
|
@ -2117,6 +2117,7 @@ gimp_text_tool_apply (GimpTextTool *text_tool,
|
||||||
GIMP_DRAWABLE (layer), TRUE);
|
GIMP_DRAWABLE (layer), TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pspec)
|
||||||
gimp_image_undo_push_text_layer (image, NULL, layer, pspec);
|
gimp_image_undo_push_text_layer (image, NULL, layer, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ gimp_fill_editor_constructed (GObject *object)
|
||||||
color_button = gimp_prop_color_button_new (G_OBJECT (editor->options),
|
color_button = gimp_prop_color_button_new (G_OBJECT (editor->options),
|
||||||
"foreground",
|
"foreground",
|
||||||
_("Fill Color"),
|
_("Fill Color"),
|
||||||
-1, 24,
|
1, 24,
|
||||||
GIMP_COLOR_AREA_SMALL_CHECKS);
|
GIMP_COLOR_AREA_SMALL_CHECKS);
|
||||||
gimp_color_panel_set_context (GIMP_COLOR_PANEL (color_button),
|
gimp_color_panel_set_context (GIMP_COLOR_PANEL (color_button),
|
||||||
GIMP_CONTEXT (editor->options));
|
GIMP_CONTEXT (editor->options));
|
||||||
|
|
Loading…
Reference in New Issue