[gimp] Bug 620674 - Adding support for multi-colored text layer
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 620674 - Adding support for multi-colored text layer
- Date: Wed, 1 Sep 2010 22:21:00 +0000 (UTC)
commit ad819263af66224d6c60e37a0adbbb695a06575b
Author: Michael Natterer <mitch gimp org>
Date: Thu Sep 2 00:20:04 2010 +0200
Bug 620674 - Adding support for multi-colored text layer
Apply slightly modified patch from Barak Itkin that adds colors for
text spans plus GUI to edit these colors.
app/widgets/gimptextbuffer.c | 137 +++++++++++++++++++++++++++++++++++++
app/widgets/gimptextbuffer.h | 9 +++
app/widgets/gimptextstyleeditor.c | 93 +++++++++++++++++++++++++
app/widgets/gimptextstyleeditor.h | 2 +
app/widgets/gimptexttag.c | 20 ++++++
app/widgets/gimptexttag.h | 3 +
6 files changed, 264 insertions(+), 0 deletions(-)
---
diff --git a/app/widgets/gimptextbuffer.c b/app/widgets/gimptextbuffer.c
index 99b7fe8..76e17cc 100644
--- a/app/widgets/gimptextbuffer.c
+++ b/app/widgets/gimptextbuffer.c
@@ -42,12 +42,14 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "widgets-types.h"
#include "gimptextbuffer.h"
#include "gimptextbuffer-serialize.h"
#include "gimptexttag.h"
+#include "gimpwidgets-utils.h"
#include "gimp-intl.h"
@@ -172,6 +174,12 @@ gimp_text_buffer_finalize (GObject *object)
buffer->font_tags = NULL;
}
+ if (buffer->color_tags)
+ {
+ g_list_free (buffer->color_tags);
+ buffer->color_tags = NULL;
+ }
+
gimp_text_buffer_clear_insert_tags (buffer);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -908,12 +916,112 @@ gimp_text_buffer_set_font (GimpTextBuffer *buffer,
gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
+GtkTextTag *
+gimp_text_buffer_get_iter_color (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GimpRGB *color)
+{
+ GList *list;
+
+ for (list = buffer->color_tags; list; list = g_list_next (list))
+ {
+ GtkTextTag *tag = list->data;
+
+ if (gtk_text_iter_has_tag (iter, tag))
+ {
+ if (color)
+ gimp_text_tag_get_color (tag, color);
+
+ return tag;
+ }
+ }
+
+ return NULL;
+}
+
+static GtkTextTag *
+gimp_text_buffer_get_color_tag (GimpTextBuffer *buffer,
+ const GimpRGB *color)
+{
+ GList *list;
+ GtkTextTag *tag;
+ gchar name[256];
+ GdkColor gdk_color;
+
+ for (list = buffer->color_tags; list; list = g_list_next (list))
+ {
+ GimpRGB tag_color;
+
+ tag = list->data;
+
+ gimp_text_tag_get_color (tag, &tag_color);
+
+ /* Do not compare the alpha channel, since it's unused */
+ if (tag_color.r == color->r &&
+ tag_color.g == color->g &&
+ tag_color.b == color->b)
+ {
+ return tag;
+ }
+ }
+
+ g_snprintf (name, sizeof (name), "color-(%0.f,%0.f,%0.f)",
+ color->r, color->g, color->b);
+
+ gimp_rgb_get_gdk_color (color, &gdk_color);
+
+ tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (buffer),
+ name,
+ "foreground-gdk", &gdk_color,
+ "foreground-set", TRUE,
+ NULL);
+
+ buffer->color_tags = g_list_prepend (buffer->color_tags, tag);
+
+ return tag;
+}
+
+void
+gimp_text_buffer_set_color (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ const GimpRGB *color)
+{
+ GList *list;
+
+ g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
+ g_return_if_fail (start != NULL);
+ g_return_if_fail (end != NULL);
+
+ if (gtk_text_iter_equal (start, end))
+ return;
+
+ gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+
+ for (list = buffer->color_tags; list; list = g_list_next (list))
+ {
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), list->data,
+ start, end);
+ }
+
+ if (color)
+ {
+ GtkTextTag *tag = gimp_text_buffer_get_color_tag (buffer, color);
+
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag,
+ start, end);
+ }
+
+ gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+}
+
/* Pango markup attribute names */
#define GIMP_TEXT_ATTR_NAME_SIZE "size"
#define GIMP_TEXT_ATTR_NAME_BASELINE "rise"
#define GIMP_TEXT_ATTR_NAME_KERNING "letter_spacing"
#define GIMP_TEXT_ATTR_NAME_FONT "font"
+#define GIMP_TEXT_ATTR_NAME_COLOR "foreground"
const gchar *
gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
@@ -986,6 +1094,24 @@ gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
return "span";
}
+ else if (g_list_find (buffer->color_tags, tag))
+ {
+ if (attribute)
+ *attribute = GIMP_TEXT_ATTR_NAME_COLOR;
+
+ if (value)
+ {
+ GimpRGB color;
+ guchar r, g, b;
+
+ gimp_text_tag_get_color (tag, &color);
+ gimp_rgb_get_uchar (&color, &r, &g, &b);
+
+ *value = g_strdup_printf ("#%02x%02x%02x", r, g, b);
+ }
+
+ return "span";
+ }
return NULL;
}
@@ -1035,6 +1161,17 @@ gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
{
return gimp_text_buffer_get_font_tag (buffer, value);
}
+ else if (! strcmp (attribute, GIMP_TEXT_ATTR_NAME_COLOR))
+ {
+ GimpRGB color;
+ guint r, g, b;
+
+ sscanf (value, "#%02x%02x%02x", &r, &g, &b);
+
+ gimp_rgb_set_uchar (&color, r, g, b);
+
+ return gimp_text_buffer_get_color_tag (buffer, &color);
+ }
}
return NULL;
diff --git a/app/widgets/gimptextbuffer.h b/app/widgets/gimptextbuffer.h
index 1e46598..11ae4f5 100644
--- a/app/widgets/gimptextbuffer.h
+++ b/app/widgets/gimptextbuffer.h
@@ -44,6 +44,7 @@ struct _GimpTextBuffer
GList *baseline_tags;
GList *kerning_tags;
GList *font_tags;
+ GList *color_tags;
gboolean insert_tags_set;
GList *insert_tags;
@@ -116,6 +117,14 @@ void gimp_text_buffer_set_font (GimpTextBuffer *buffer,
const GtkTextIter *end,
const gchar *font);
+GtkTextTag * gimp_text_buffer_get_iter_color (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GimpRGB *color);
+void gimp_text_buffer_set_color (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ const GimpRGB *color);
+
const gchar * gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
GtkTextTag *tag,
const gchar **attribute,
diff --git a/app/widgets/gimptextstyleeditor.c b/app/widgets/gimptextstyleeditor.c
index f0f6da4..4f23406 100644
--- a/app/widgets/gimptextstyleeditor.c
+++ b/app/widgets/gimptextstyleeditor.c
@@ -24,6 +24,7 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
@@ -80,6 +81,11 @@ static void gimp_text_style_editor_font_changed (GimpContext *c
static void gimp_text_style_editor_set_font (GimpTextStyleEditor *editor,
GtkTextTag *font_tag);
+static void gimp_text_style_editor_color_changed (GimpColorButton *button,
+ GimpTextStyleEditor *editor);
+static void gimp_text_style_editor_set_color (GimpTextStyleEditor *editor,
+ GtkTextTag *color_tag);
+
static void gimp_text_style_editor_tag_toggled (GtkToggleButton *toggle,
GimpTextStyleEditor *editor);
static void gimp_text_style_editor_set_toggle (GimpTextStyleEditor *editor,
@@ -166,6 +172,7 @@ static void
gimp_text_style_editor_init (GimpTextStyleEditor *editor)
{
GtkWidget *image;
+ GimpRGB color;
/* upper row */
@@ -195,6 +202,19 @@ gimp_text_style_editor_init (GimpTextStyleEditor *editor)
G_CALLBACK (gimp_text_style_editor_size_changed),
editor);
+ gimp_rgb_set (&color, 0.0, 0.0, 0.0);
+ editor->color_button = gimp_color_button_new (_("Change color of selected text"),
+ 20, 20, &color,
+ GIMP_COLOR_AREA_FLAT);
+
+ gtk_box_pack_start (GTK_BOX (editor->upper_hbox), editor->color_button,
+ FALSE, FALSE, 0);
+ gtk_widget_show (editor->color_button);
+
+ g_signal_connect (editor->color_button, "color-changed",
+ G_CALLBACK (gimp_text_style_editor_color_changed),
+ editor);
+
/* lower row */
editor->lower_hbox = gtk_hbox_new (FALSE, 0);
@@ -568,6 +588,46 @@ gimp_text_style_editor_set_font (GimpTextStyleEditor *editor,
}
static void
+gimp_text_style_editor_color_changed (GimpColorButton *button,
+ GimpTextStyleEditor *editor)
+{
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer);
+ GtkTextIter start, end;
+ GimpRGB color;
+
+ if (! gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+ {
+ return;
+ }
+
+ gimp_color_button_get_color (button, &color);
+ gimp_text_buffer_set_color (editor->buffer, &start, &end, &color);
+}
+
+static void
+gimp_text_style_editor_set_color (GimpTextStyleEditor *editor,
+ GtkTextTag *color_tag)
+{
+ GimpRGB color;
+
+ if (color_tag)
+ gimp_text_tag_get_color (color_tag, &color);
+ else
+ gimp_rgb_set (&color, 0.0, 0.0, 0.0);
+
+ g_signal_handlers_block_by_func (editor->color_button,
+ gimp_text_style_editor_color_changed,
+ editor);
+
+ gimp_color_button_set_color (GIMP_COLOR_BUTTON (editor->color_button),
+ &color);
+
+ g_signal_handlers_unblock_by_func (editor->color_button,
+ gimp_text_style_editor_color_changed,
+ editor);
+}
+
+static void
gimp_text_style_editor_tag_toggled (GtkToggleButton *toggle,
GimpTextStyleEditor *editor)
{
@@ -774,10 +834,12 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
GList *list;
gboolean any_toggle_active = TRUE;
gboolean font_differs = FALSE;
+ gboolean color_differs = FALSE;
gboolean size_differs = FALSE;
gboolean baseline_differs = FALSE;
gboolean kerning_differs = FALSE;
GtkTextTag *font_tag = NULL;
+ GtkTextTag *color_tag = NULL;
GtkTextTag *size_tag = NULL;
GtkTextTag *baseline_tag = NULL;
GtkTextTag *kerning_tag = NULL;
@@ -796,6 +858,8 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
/* and get some initial values */
font_tag = gimp_text_buffer_get_iter_font (editor->buffer,
&start, NULL);
+ color_tag = gimp_text_buffer_get_iter_color (editor->buffer,
+ &start, NULL);
size_tag = gimp_text_buffer_get_iter_size (editor->buffer,
&start, NULL);
baseline_tag = gimp_text_buffer_get_iter_baseline (editor->buffer,
@@ -839,6 +903,17 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
font_differs = TRUE;
}
+ if (! color_differs)
+ {
+ GtkTextTag *tag;
+
+ tag = gimp_text_buffer_get_iter_color (editor->buffer, &iter,
+ NULL);
+
+ if (tag != color_tag)
+ color_differs = TRUE;
+ }
+
if (! size_differs)
{
GtkTextTag *tag;
@@ -881,6 +956,8 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
}
gimp_text_style_editor_set_font (editor, font_differs ? NULL : font_tag);
+ gimp_text_style_editor_set_color (editor,
+ color_differs ? NULL : color_tag);
gimp_text_style_editor_set_size (editor, size_differs ? NULL : size_tag);
if (baseline_differs)
@@ -924,6 +1001,22 @@ gimp_text_style_editor_update_idle (GimpTextStyleEditor *editor)
if (! list)
gimp_text_style_editor_set_font (editor, NULL);
+ for (list = editor->buffer->color_tags; list; list = g_list_next (list))
+ {
+ GtkTextTag *tag = list->data;
+
+ if ((g_slist_find (tags, tag) &&
+ ! g_slist_find (tags_on, tag)) ||
+ g_slist_find (tags_off, tag))
+ {
+ gimp_text_style_editor_set_color (editor, tag);
+ break;
+ }
+ }
+
+ if (! list)
+ gimp_text_style_editor_set_color (editor, NULL);
+
for (list = editor->buffer->size_tags; list; list = g_list_next (list))
{
GtkTextTag *tag = list->data;
diff --git a/app/widgets/gimptextstyleeditor.h b/app/widgets/gimptextstyleeditor.h
index 7ce3fd8..46227b6 100644
--- a/app/widgets/gimptextstyleeditor.h
+++ b/app/widgets/gimptextstyleeditor.h
@@ -50,6 +50,8 @@ struct _GimpTextStyleEditor
GtkWidget *font_entry;
+ GtkWidget *color_button;
+
GtkWidget *clear_button;
GtkWidget *size_spinbutton;
diff --git a/app/widgets/gimptexttag.c b/app/widgets/gimptexttag.c
index 81941c2..5b706af 100644
--- a/app/widgets/gimptexttag.c
+++ b/app/widgets/gimptexttag.c
@@ -22,7 +22,12 @@
#include <gtk/gtk.h>
+#include "libgimpcolor/gimpcolor.h"
+
+#include "widgets-types.h"
+
#include "gimptexttag.h"
+#include "gimpwidgets-utils.h"
gint
@@ -74,3 +79,18 @@ gimp_text_tag_get_font (GtkTextTag *tag)
return font;
}
+
+void
+gimp_text_tag_get_color (GtkTextTag *tag,
+ GimpRGB *color)
+{
+ GdkColor *gdk_color;
+
+ g_object_get (tag,
+ GIMP_TEXT_PROP_NAME_COLOR, &gdk_color,
+ NULL);
+
+ gimp_rgb_set_gdk_color (color, gdk_color);
+
+ gdk_color_free (gdk_color);
+}
diff --git a/app/widgets/gimptexttag.h b/app/widgets/gimptexttag.h
index af0c93a..e0c967a 100644
--- a/app/widgets/gimptexttag.h
+++ b/app/widgets/gimptexttag.h
@@ -28,12 +28,15 @@
#define GIMP_TEXT_PROP_NAME_BASELINE "rise"
#define GIMP_TEXT_PROP_NAME_KERNING "rise" /* FIXME */
#define GIMP_TEXT_PROP_NAME_FONT "font"
+#define GIMP_TEXT_PROP_NAME_COLOR "foreground-gdk"
gint gimp_text_tag_get_size (GtkTextTag *tag);
gint gimp_text_tag_get_baseline (GtkTextTag *tag);
gint gimp_text_tag_get_kerning (GtkTextTag *tag);
gchar * gimp_text_tag_get_font (GtkTextTag *tag);
+void gimp_text_tag_get_color (GtkTextTag *tag,
+ GimpRGB *color);
#endif /* __GIMP_TEXT_TAG_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]