[gimp] app: allow to select fonts on text spans
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: allow to select fonts on text spans
- Date: Tue, 2 Mar 2010 17:43:33 +0000 (UTC)
commit bea0c7f3d440619697e537e0cd34015a1c02af8d
Author: Michael Natterer <mitch gimp org>
Date: Tue Mar 2 11:11:06 2010 +0100
app: allow to select fonts on text spans
A bit hackish, will cleanup...
app/widgets/gimptextbuffer.c | 169 ++++++++++++++++++++++++++++++++-----
app/widgets/gimptextbuffer.h | 16 ++++
app/widgets/gimptextstyleeditor.c | 135 +++++++++++++++++++++++++++---
3 files changed, 289 insertions(+), 31 deletions(-)
---
diff --git a/app/widgets/gimptextbuffer.c b/app/widgets/gimptextbuffer.c
index 4bf1a15..ae40126 100644
--- a/app/widgets/gimptextbuffer.c
+++ b/app/widgets/gimptextbuffer.c
@@ -162,6 +162,12 @@ gimp_text_buffer_finalize (GObject *object)
buffer->spacing_tags = NULL;
}
+ if (buffer->font_tags)
+ {
+ g_list_free (buffer->font_tags);
+ buffer->font_tags = NULL;
+ }
+
gimp_text_buffer_clear_insert_tags (buffer);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -297,10 +303,10 @@ gimp_text_buffer_get_markup (GimpTextBuffer *buffer)
return markup;
}
-static gint
-get_baseline_at_iter (GimpTextBuffer *buffer,
- const GtkTextIter *iter,
- GtkTextTag **baseline_tag)
+gint
+gimp_text_buffer_get_baseline (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **baseline_tag)
{
GList *list;
@@ -328,8 +334,8 @@ get_baseline_at_iter (GimpTextBuffer *buffer,
}
static GtkTextTag *
-get_baseline_tag (GimpTextBuffer *buffer,
- gint baseline)
+gimp_text_buffer_get_baseline_tag (GimpTextBuffer *buffer,
+ gint baseline)
{
GList *list;
GtkTextTag *tag;
@@ -382,7 +388,7 @@ gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
iter = *start;
span_start = *start;
- span_baseline = get_baseline_at_iter (buffer, &iter, &span_tag);
+ span_baseline = gimp_text_buffer_get_baseline (buffer, &iter, &span_tag);
gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
@@ -393,7 +399,7 @@ gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
gtk_text_iter_forward_char (&iter);
- iter_baseline = get_baseline_at_iter (buffer, &iter, &iter_tag);
+ iter_baseline = gimp_text_buffer_get_baseline (buffer, &iter, &iter_tag);
span_end = iter;
@@ -408,7 +414,8 @@ gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
if (span_baseline + count != 0)
{
- span_tag = get_baseline_tag (buffer, span_baseline + count);
+ span_tag = gimp_text_buffer_get_baseline_tag (buffer,
+ span_baseline + count);
gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), span_tag,
&span_start, &span_end);
@@ -428,10 +435,10 @@ gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
-static gint
-get_spacing_at_iter (GimpTextBuffer *buffer,
- const GtkTextIter *iter,
- GtkTextTag **spacing_tag)
+gint
+gimp_text_buffer_get_spacing (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **spacing_tag)
{
GList *list;
@@ -459,8 +466,8 @@ get_spacing_at_iter (GimpTextBuffer *buffer,
}
static GtkTextTag *
-get_spacing_tag (GimpTextBuffer *buffer,
- gint spacing)
+gimp_text_buffer_get_spacing_tag (GimpTextBuffer *buffer,
+ gint spacing)
{
GList *list;
GtkTextTag *tag;
@@ -513,7 +520,7 @@ gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
iter = *start;
span_start = *start;
- span_spacing = get_spacing_at_iter (buffer, &iter, &span_tag);
+ span_spacing = gimp_text_buffer_get_spacing (buffer, &iter, &span_tag);
gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
@@ -524,7 +531,7 @@ gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
gtk_text_iter_forward_char (&iter);
- iter_spacing = get_spacing_at_iter (buffer, &iter, &iter_tag);
+ iter_spacing = gimp_text_buffer_get_spacing (buffer, &iter, &iter_tag);
span_end = iter;
@@ -539,7 +546,8 @@ gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
if (span_spacing + count != 0)
{
- span_tag = get_spacing_tag (buffer, span_spacing + count);
+ span_tag = gimp_text_buffer_get_spacing_tag (buffer,
+ span_spacing + count);
gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), span_tag,
&span_start, &span_end);
@@ -559,6 +567,109 @@ gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
}
+gchar *
+gimp_text_buffer_get_font (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **font_tag)
+{
+ GList *list;
+
+ for (list = buffer->font_tags; list; list = g_list_next (list))
+ {
+ GtkTextTag *tag = list->data;
+
+ if (gtk_text_iter_has_tag (iter, tag))
+ {
+ gchar *font;
+
+ *font_tag = tag;
+
+ g_object_get (tag,
+ "font", &font,
+ NULL);
+
+ return font;
+ }
+ }
+
+ *font_tag = NULL;
+
+ return NULL;
+}
+
+static GtkTextTag *
+gimp_text_buffer_get_font_tag (GimpTextBuffer *buffer,
+ const gchar *font)
+{
+ GList *list;
+ GtkTextTag *tag;
+ gchar name[256];
+
+ for (list = buffer->font_tags; list; list = g_list_next (list))
+ {
+ gchar *tag_font;
+
+ tag = list->data;
+
+ g_object_get (tag,
+ "font", &tag_font,
+ NULL);
+
+ if (! strcmp (font, tag_font))
+ {
+ g_free (tag_font);
+ return tag;
+ }
+
+ g_free (tag_font);
+ }
+
+ g_snprintf (name, sizeof (name), "font-%s", font);
+
+ tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (buffer),
+ name,
+ "font", font,
+ NULL);
+
+ buffer->font_tags = g_list_prepend (buffer->font_tags, tag);
+
+ return tag;
+}
+
+void
+gimp_text_buffer_set_font (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ const gchar *font)
+{
+ 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->font_tags; list; list = g_list_next (list))
+ {
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), list->data,
+ start, end);
+ }
+
+ if (font)
+ {
+ GtkTextTag *tag = gimp_text_buffer_get_font_tag (buffer, font);
+
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), tag,
+ start, end);
+ }
+
+ gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+}
+
const gchar *
gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
GtkTextTag *tag,
@@ -626,6 +737,20 @@ gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
return "span";
}
+ else if (g_list_find (buffer->font_tags, tag))
+ {
+ if (attribute)
+ *attribute = "font";
+
+ if (value)
+ {
+ g_object_get (tag,
+ "font", value,
+ NULL);
+ }
+
+ return "span";
+ }
return NULL;
}
@@ -661,11 +786,15 @@ gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
{
if (! strcmp (attribute, "rise"))
{
- return get_baseline_tag (buffer, atoi (value));
+ return gimp_text_buffer_get_baseline_tag (buffer, atoi (value));
}
else if (! strcmp (attribute, "letter_spacing"))
{
- return get_spacing_tag (buffer, atoi (value));
+ return gimp_text_buffer_get_spacing_tag (buffer, atoi (value));
+ }
+ else if (! strcmp (attribute, "font"))
+ {
+ return gimp_text_buffer_get_font_tag (buffer, value);
}
}
diff --git a/app/widgets/gimptextbuffer.h b/app/widgets/gimptextbuffer.h
index ab695ff..cb982c0 100644
--- a/app/widgets/gimptextbuffer.h
+++ b/app/widgets/gimptextbuffer.h
@@ -42,6 +42,7 @@ struct _GimpTextBuffer
GList *baseline_tags;
GList *spacing_tags;
+ GList *font_tags;
gboolean insert_tags_set;
GList *insert_tags;
@@ -68,15 +69,30 @@ void gimp_text_buffer_set_markup (GimpTextBuffer *buffer,
const gchar *markup);
gchar * gimp_text_buffer_get_markup (GimpTextBuffer *buffer);
+gint gimp_text_buffer_get_baseline (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **baseline_tag);
void gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
const GtkTextIter *start,
const GtkTextIter *end,
gint count);
+
+gint gimp_text_buffer_get_spacing (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **spacing_tag);
void gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
const GtkTextIter *start,
const GtkTextIter *end,
gint count);
+gchar * gimp_text_buffer_get_font (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **font_tag);
+void gimp_text_buffer_set_font (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ const gchar *font);
+
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 27c046c..cccd42c 100644
--- a/app/widgets/gimptextstyleeditor.c
+++ b/app/widgets/gimptextstyleeditor.c
@@ -73,6 +73,9 @@ static GtkWidget *
static void gimp_text_style_editor_clear_tags (GtkButton *button,
GimpTextStyleEditor *editor);
+static void gimp_text_style_editor_font_changed (GimpContext *context,
+ GimpFont *font,
+ GimpTextStyleEditor *editor);
static void gimp_text_style_editor_tag_toggled (GtkToggleButton *toggle,
GimpTextStyleEditor *editor);
@@ -194,6 +197,10 @@ gimp_text_style_editor_constructor (GType type,
editor->context = gimp_context_new (editor->gimp, "text style editor", NULL);
+ g_signal_connect (editor->context, "font-changed",
+ G_CALLBACK (gimp_text_style_editor_font_changed),
+ editor);
+
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (editor->font_entry),
editor->fonts);
gimp_container_view_set_context (GIMP_CONTAINER_VIEW (editor->font_entry),
@@ -439,6 +446,28 @@ gimp_text_style_editor_clear_tags (GtkButton *button,
}
static void
+gimp_text_style_editor_font_changed (GimpContext *context,
+ GimpFont *font,
+ GimpTextStyleEditor *editor)
+{
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer);
+ const gchar *name = gimp_context_get_font_name (context);
+
+ if (gtk_text_buffer_get_has_selection (buffer))
+ {
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+
+ gtk_text_buffer_begin_user_action (buffer);
+
+ gimp_text_buffer_set_font (editor->buffer, &start, &end, name);
+
+ gtk_text_buffer_end_user_action (buffer);
+ }
+}
+
+static void
gimp_text_style_editor_tag_toggled (GtkToggleButton *toggle,
GimpTextStyleEditor *editor)
{
@@ -488,6 +517,30 @@ gimp_text_style_editor_set_toggle (GimpTextStyleEditor *editor,
}
static void
+gimp_text_style_editor_set_font (GimpTextStyleEditor *editor,
+ GtkTextTag *font_tag)
+{
+ gchar *font = NULL;
+
+ if (font_tag)
+ g_object_get (font_tag,
+ "font", &font,
+ NULL);
+
+ g_signal_handlers_block_by_func (editor->context,
+ gimp_text_style_editor_font_changed,
+ editor);
+
+ gimp_context_set_font_name (editor->context, font);
+
+ g_signal_handlers_unblock_by_func (editor->context,
+ gimp_text_style_editor_font_changed,
+ editor);
+
+ g_free (font);
+}
+
+static void
gimp_text_style_editor_update (GimpTextStyleEditor *editor)
{
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (editor->buffer);
@@ -497,6 +550,9 @@ gimp_text_style_editor_update (GimpTextStyleEditor *editor)
GtkTextIter start, end;
GtkTextIter iter;
GList *list;
+ gboolean any_toggle_active = TRUE;
+ gboolean font_differs = FALSE;
+ GtkTextTag *font_tag = NULL;
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
gtk_text_iter_order (&start, &end);
@@ -509,32 +565,73 @@ gimp_text_style_editor_update (GimpTextStyleEditor *editor)
gimp_text_style_editor_set_toggle (editor, toggle, TRUE);
}
+ /* and get the initial font tag */
+ for (list = editor->buffer->font_tags; list; list = g_list_next (list))
+ {
+ GtkTextTag *tag = list->data;
+
+ if (gtk_text_iter_has_tag (&start, tag))
+ {
+ font_tag = tag;
+ break;
+ }
+ }
+
for (iter = start;
gtk_text_iter_in_range (&iter, &start, &end);
gtk_text_iter_forward_cursor_position (&iter))
{
- gboolean any_active = FALSE;
-
- for (list = editor->toggles; list; list = g_list_next (list))
+ if (any_toggle_active)
{
- GtkToggleButton *toggle = list->data;
- GtkTextTag *tag = g_object_get_data (G_OBJECT (toggle),
- "tag");
+ any_toggle_active = FALSE;
- if (! gtk_text_iter_has_tag (&iter, tag))
+ for (list = editor->toggles; list; list = g_list_next (list))
{
- gimp_text_style_editor_set_toggle (editor, toggle, FALSE);
+ GtkToggleButton *toggle = list->data;
+ GtkTextTag *tag = g_object_get_data (G_OBJECT (toggle),
+ "tag");
+
+ if (! gtk_text_iter_has_tag (&iter, tag))
+ {
+ gimp_text_style_editor_set_toggle (editor, toggle, FALSE);
+ }
+ else
+ {
+ any_toggle_active = TRUE;
+ }
}
- else
+ }
+
+ if (! font_differs)
+ {
+ for (list = editor->buffer->font_tags;
+ list;
+ list = g_list_next (list))
{
- any_active = TRUE;
+ GtkTextTag *tag = list->data;
+
+ if (gtk_text_iter_has_tag (&iter, tag))
+ {
+ if (tag != font_tag)
+ font_differs = TRUE;
+
+ break;
+ }
}
+
+ if (! list && font_tag)
+ font_differs = TRUE;
}
- if (! any_active)
+ if (! any_toggle_active || font_differs)
break;
}
+ if (font_differs)
+ font_tag = NULL;
+
+ gimp_text_style_editor_set_font (editor, font_tag);
+
gtk_label_set_text (GTK_LABEL (editor->size_label), "---");
}
else
@@ -553,6 +650,22 @@ gimp_text_style_editor_update (GimpTextStyleEditor *editor)
tags_on = gtk_text_iter_get_toggled_tags (&cursor, TRUE);
tags_off = gtk_text_iter_get_toggled_tags (&cursor, FALSE);
+ for (list = editor->buffer->font_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_font (editor, tag);
+ break;
+ }
+ }
+
+ if (! list)
+ gimp_text_style_editor_set_font (editor, NULL);
+
for (list = editor->toggles; list; list = g_list_next (list))
{
GtkToggleButton *toggle = list->data;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]