Commit ad819263 authored by Michael Natterer's avatar Michael Natterer 😴
Browse files

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.
parent 3759b3f0
......@@ -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;
......
......@@ -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,
......
......@@ -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);
......@@ -567,6 +587,46 @@ gimp_text_style_editor_set_font (GimpTextStyleEditor *editor,
g_free (font);
}
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;
......
......@@ -50,6 +50,8 @@ struct _GimpTextStyleEditor
GtkWidget *font_entry;
GtkWidget *color_button;
GtkWidget *clear_button;
GtkWidget *size_spinbutton;
......
......@@ -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);
}
......@@ -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__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment