[gimp] app: support baseline changing via Alt+Up and Alt+Down
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: support baseline changing via Alt+Up and Alt+Down
- Date: Sat, 27 Feb 2010 17:00:50 +0000 (UTC)
commit 1e26bb13483b5b76f40ccae445e6e0289898f88f
Author: Michael Natterer <mitch gimp org>
Date: Sat Feb 27 17:54:36 2010 +0100
app: support baseline changing via Alt+Up and Alt+Down
Add a list of available baseline tags to GimpTextBuffer and
automatically create baseline tags as needed. They get serialized as
<span rise="value">, so add attribute and value parameters to the
buffer's tag_to_name() and name_to_tag() functions. Properly managing
the rise's amount is a TODO, currently each keystroke changes the
baseline by 1024 pango units, which might be whatever depending on the
output grid.
app/tools/gimptexttool-editor.c | 37 ++++++-
app/widgets/gimptextbuffer-serialize.c | 38 +++++-
app/widgets/gimptextbuffer.c | 191 +++++++++++++++++++++++++++++++-
app/widgets/gimptextbuffer.h | 74 ++++++++-----
4 files changed, 299 insertions(+), 41 deletions(-)
---
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
index 9e5c1b5..e200365 100644
--- a/app/tools/gimptexttool-editor.c
+++ b/app/tools/gimptexttool-editor.c
@@ -1034,14 +1034,47 @@ static void
gimp_text_tool_change_baseline (GimpTextTool *text_tool,
gint count)
{
- g_printerr ("%s: count = %d\n", G_STRFUNC, count);
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
+ GtkTextIter start;
+ GtkTextIter end;
+
+ if (! gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &start,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ }
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ gtk_text_iter_order (&start, &end);
+ gimp_text_buffer_change_baseline (text_tool->buffer, &start, &end,
+ count * PANGO_SCALE);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
}
static void
gimp_text_tool_change_spacing (GimpTextTool *text_tool,
gint count)
{
- g_printerr ("%s: count = %d\n", G_STRFUNC, count);
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
+ GtkTextIter start;
+ GtkTextIter end;
+
+ if (! gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &start,
+ gtk_text_buffer_get_insert (buffer));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ }
+
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ gtk_text_iter_order (&start, &end);
+ gimp_text_buffer_change_spacing (text_tool->buffer, &start, &end, count);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
}
static void
diff --git a/app/widgets/gimptextbuffer-serialize.c b/app/widgets/gimptextbuffer-serialize.c
index d377ff5..ed57042 100644
--- a/app/widgets/gimptextbuffer-serialize.c
+++ b/app/widgets/gimptextbuffer-serialize.c
@@ -73,11 +73,26 @@ open_tag (GimpTextBuffer *buffer,
GString *string,
GtkTextTag *tag)
{
- const gchar *name = gimp_text_buffer_tag_to_name (buffer, tag);
+ const gchar *name;
+ const gchar *attribute;
+ gchar *attribute_value;
- if (tag)
+ name = gimp_text_buffer_tag_to_name (buffer, tag,
+ &attribute,
+ &attribute_value);
+
+ if (name)
{
- g_string_append_printf (string, "<%s>", name);
+ if (attribute && attribute_value)
+ {
+ g_string_append_printf (string, "<%s %s=\"%s\">",
+ name, attribute, attribute_value);
+ g_free (attribute_value);
+ }
+ else
+ {
+ g_string_append_printf (string, "<%s>", name);
+ }
return TRUE;
}
@@ -90,9 +105,9 @@ close_tag (GimpTextBuffer *buffer,
GString *string,
GtkTextTag *tag)
{
- const gchar *name = gimp_text_buffer_tag_to_name (buffer, tag);
+ const gchar *name = gimp_text_buffer_tag_to_name (buffer, tag, NULL, NULL);
- if (tag)
+ if (name)
{
g_string_append_printf (string, "</%s>", name);
@@ -335,14 +350,23 @@ parse_tag_element (GMarkupParseContext *context,
ParseInfo *info,
GError **error)
{
- GtkTextTag *tag;
+ GtkTextTag *tag;
+ const gchar *attribute_name = NULL;
+ const gchar *attribute_value = NULL;
g_assert (peek_state (info) == STATE_MARKUP ||
peek_state (info) == STATE_TAG ||
peek_state (info) == STATE_UNKNOWN);
+ if (attribute_names)
+ attribute_name = attribute_names[0];
+
+ if (attribute_values)
+ attribute_value = attribute_values[0];
+
tag = gimp_text_buffer_name_to_tag (GIMP_TEXT_BUFFER (info->buffer),
- element_name);
+ element_name,
+ attribute_name, attribute_value);
if (tag)
{
diff --git a/app/widgets/gimptextbuffer.c b/app/widgets/gimptextbuffer.c
index 4f07da5..66fecc4 100644
--- a/app/widgets/gimptextbuffer.c
+++ b/app/widgets/gimptextbuffer.c
@@ -20,6 +20,7 @@
#include "config.h"
+#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@@ -146,6 +147,18 @@ gimp_text_buffer_finalize (GObject *object)
{
GimpTextBuffer *buffer = GIMP_TEXT_BUFFER (object);
+ if (buffer->baseline_tags)
+ {
+ g_list_free (buffer->baseline_tags);
+ buffer->baseline_tags = NULL;
+ }
+
+ if (buffer->spacing_tags)
+ {
+ g_list_free (buffer->spacing_tags);
+ buffer->spacing_tags = NULL;
+ }
+
gimp_text_buffer_clear_insert_tags (buffer);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -244,13 +257,155 @@ gimp_text_buffer_get_markup (GimpTextBuffer *buffer)
&length);
}
+static gint
+get_baseline_at_iter (GimpTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextTag **baseline_tag)
+{
+ GList *list;
+
+ for (list = buffer->baseline_tags; list; list = g_list_next (list))
+ {
+ GtkTextTag *tag = list->data;
+
+ if (gtk_text_iter_has_tag (iter, tag))
+ {
+ gint baseline;
+
+ *baseline_tag = tag;
+
+ g_object_get (tag,
+ "rise", &baseline,
+ NULL);
+
+ return baseline;
+ }
+ }
+
+ *baseline_tag = NULL;
+
+ return 0;
+}
+
+static GtkTextTag *
+get_baseline_tag (GimpTextBuffer *buffer,
+ gint baseline)
+{
+ GList *list;
+ GtkTextTag *tag;
+ gchar name[32];
+
+ for (list = buffer->baseline_tags; list; list = g_list_next (list))
+ {
+ gint tag_baseline;
+
+ tag = list->data;
+
+ g_object_get (tag,
+ "rise", &tag_baseline,
+ NULL);
+
+ if (tag_baseline == baseline)
+ return tag;
+ }
+
+ g_snprintf (name, sizeof (name), "baseline-%d", baseline);
+
+ tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (buffer),
+ name,
+ "rise", baseline,
+ NULL);
+
+ buffer->baseline_tags = g_list_prepend (buffer->baseline_tags, tag);
+
+ return tag;
+}
+
+void
+gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ gint count)
+{
+ GtkTextIter iter;
+ GtkTextIter span_start;
+ GtkTextIter span_end;
+ gint span_baseline;
+ GtkTextTag *span_tag;
+
+ 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 (&iter, end))
+ return;
+
+ iter = *start;
+ span_start = *start;
+ span_baseline = get_baseline_at_iter (buffer, &iter, &span_tag);
+
+ do
+ {
+ gint iter_baseline;
+ GtkTextTag *iter_tag;
+
+ gtk_text_iter_forward_char (&iter);
+
+ iter_baseline = get_baseline_at_iter (buffer, &iter, &iter_tag);
+
+ span_end = iter;
+
+ if (iter_baseline != span_baseline ||
+ gtk_text_iter_equal (&iter, end))
+ {
+ if (span_baseline != 0)
+ {
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (buffer), span_tag,
+ &span_start, &span_end);
+ }
+
+ if (span_baseline + count != 0)
+ {
+ span_tag = get_baseline_tag (buffer, span_baseline + count);
+
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (buffer), span_tag,
+ &span_start, &span_end);
+ }
+
+ span_start = iter;
+ span_baseline = iter_baseline;
+ span_tag = iter_tag;
+ }
+ }
+ while (! gtk_text_iter_equal (&iter, end));
+}
+
+void
+gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ gint count)
+{
+ g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
+ g_return_if_fail (start != NULL);
+ g_return_if_fail (end != NULL);
+}
+
const gchar *
-gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
- GtkTextTag *tag)
+gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
+ GtkTextTag *tag,
+ const gchar **attribute,
+ gchar **value)
{
g_return_val_if_fail (GIMP_IS_TEXT_BUFFER (buffer), NULL);
g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), NULL);
+ if (attribute)
+ *attribute = NULL;
+
+ if (value)
+ *value = NULL;
+
if (tag == buffer->bold_tag)
{
return "b";
@@ -267,13 +422,33 @@ gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
{
return "s";
}
+ else if (g_list_find (buffer->baseline_tags, tag))
+ {
+ if (attribute)
+ *attribute = "rise";
+
+ if (value)
+ {
+ gint baseline;
+
+ g_object_get (tag,
+ "rise", &baseline,
+ NULL);
+
+ *value = g_strdup_printf ("%d", baseline);
+ }
+
+ return "span";
+ }
return NULL;
}
GtkTextTag *
gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
- const gchar *name)
+ const gchar *name,
+ const gchar *attribute,
+ const gchar *value)
{
g_return_val_if_fail (GIMP_IS_TEXT_BUFFER (buffer), NULL);
g_return_val_if_fail (name != NULL, NULL);
@@ -294,6 +469,16 @@ gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
{
return buffer->strikethrough_tag;
}
+ else if (! strcmp (name, "span"))
+ {
+ if (! attribute || ! value)
+ return NULL;
+
+ if (! strcmp (attribute, "rise"))
+ {
+ return get_baseline_tag (buffer, atoi (value));
+ }
+ }
return NULL;
}
diff --git a/app/widgets/gimptextbuffer.h b/app/widgets/gimptextbuffer.h
index da69623..a21838f 100644
--- a/app/widgets/gimptextbuffer.h
+++ b/app/widgets/gimptextbuffer.h
@@ -40,6 +40,9 @@ struct _GimpTextBuffer
GtkTextTag *underline_tag;
GtkTextTag *strikethrough_tag;
+ GList *baseline_tags;
+ GList *spacing_tags;
+
GList *insert_tags;
gboolean insert_tags_set;
@@ -56,35 +59,48 @@ GType gimp_text_buffer_get_type (void) G_GNUC_CONST;
GimpTextBuffer * gimp_text_buffer_new (void);
-void gimp_text_buffer_set_text (GimpTextBuffer *buffer,
- const gchar *text);
-gchar * gimp_text_buffer_get_text (GimpTextBuffer *buffer);
-
-void gimp_text_buffer_set_markup (GimpTextBuffer *buffer,
- const gchar *markup);
-gchar * gimp_text_buffer_get_markup (GimpTextBuffer *buffer);
-
-const gchar * gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
- GtkTextTag *tag);
-GtkTextTag * gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
- const gchar *name);
-
-void gimp_text_buffer_set_insert_tags (GimpTextBuffer *buffer,
- GList *style);
-void gimp_text_buffer_clear_insert_tags (GimpTextBuffer *buffer);
-void gimp_text_buffer_insert (GimpTextBuffer *buffer,
- const gchar *text);
-
-gint gimp_text_buffer_get_iter_index (GimpTextBuffer *buffer,
- GtkTextIter *iter);
-
-gboolean gimp_text_buffer_load (GimpTextBuffer *buffer,
- const gchar *filename,
- GError **error);
-gboolean gimp_text_buffer_save (GimpTextBuffer *buffer,
- const gchar *filename,
- gboolean selection_only,
- GError **error);
+void gimp_text_buffer_set_text (GimpTextBuffer *buffer,
+ const gchar *text);
+gchar * gimp_text_buffer_get_text (GimpTextBuffer *buffer);
+
+void gimp_text_buffer_set_markup (GimpTextBuffer *buffer,
+ const gchar *markup);
+gchar * gimp_text_buffer_get_markup (GimpTextBuffer *buffer);
+
+void gimp_text_buffer_change_baseline (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ gint count);
+void gimp_text_buffer_change_spacing (GimpTextBuffer *buffer,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ gint count);
+
+const gchar * gimp_text_buffer_tag_to_name (GimpTextBuffer *buffer,
+ GtkTextTag *tag,
+ const gchar **attribute,
+ gchar **value);
+GtkTextTag * gimp_text_buffer_name_to_tag (GimpTextBuffer *buffer,
+ const gchar *name,
+ const gchar *attribute,
+ const gchar *value);
+
+void gimp_text_buffer_set_insert_tags (GimpTextBuffer *buffer,
+ GList *style);
+void gimp_text_buffer_clear_insert_tags (GimpTextBuffer *buffer);
+void gimp_text_buffer_insert (GimpTextBuffer *buffer,
+ const gchar *text);
+
+gint gimp_text_buffer_get_iter_index (GimpTextBuffer *buffer,
+ GtkTextIter *iter);
+
+gboolean gimp_text_buffer_load (GimpTextBuffer *buffer,
+ const gchar *filename,
+ GError **error);
+gboolean gimp_text_buffer_save (GimpTextBuffer *buffer,
+ const gchar *filename,
+ gboolean selection_only,
+ GError **error);
#endif /* __GIMP_TEXT_BUFFER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]