[gnome-initial-setup/wip/pango] eulas: Support pango markup



commit e5896e6d5d956b9423f9012dcfceac4abb20e54d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Jul 2 22:56:06 2012 -0400

    eulas: Support pango markup
    
    Harder than it looks
    
    Requires patches from https://bugzilla.gnome.org/show_bug.cgi?id=679299

 gnome-initial-setup/gis-eula-pages.c |   56 ++++++++++++++++
 gnome-initial-setup/gis-utils.c      |  118 ++++++++++++++++++++++++++++++++++
 gnome-initial-setup/gis-utils.h      |    4 +
 3 files changed, 178 insertions(+), 0 deletions(-)
---
diff --git a/gnome-initial-setup/gis-eula-pages.c b/gnome-initial-setup/gis-eula-pages.c
index e118383..309b56c 100644
--- a/gnome-initial-setup/gis-eula-pages.c
+++ b/gnome-initial-setup/gis-eula-pages.c
@@ -4,6 +4,7 @@
 
 #include "config.h"
 #include "gis-eula-pages.h"
+#include "gis-utils.h"
 
 #include <glib/gi18n.h>
 #include <gio/gio.h>
@@ -39,6 +40,59 @@ splice_into (GInputStream  *stream,
 }
 
 static gboolean
+splice_into_gmarkup_parser (GMarkupParseContext *context,
+                            char                *contents,
+                            gssize               n_read,
+                            GError             **error)
+{
+  return g_markup_parse_context_parse (context, contents, n_read, error);
+}
+
+static GtkTextBuffer *
+build_eula_text_buffer_pango_markup (GInputStream *input_stream,
+                                     GError      **error_out)
+{
+  GtkTextBuffer *buffer = NULL;
+  GMarkupParseContext *context;
+  GError *error = NULL;
+  PangoAttrList *attrlist;
+  gchar *text;
+  GtkTextIter iter;
+
+  context = pango_markup_parser_new (0, &error);
+  if (context == NULL)
+    {
+      g_propagate_error (error_out, error);
+      goto error_out;
+    }
+
+  splice_into (input_stream, (SpliceFunc) splice_into_gmarkup_parser, context, &error);
+  if (error != NULL)
+    {
+      g_propagate_error (error_out, error);
+      goto error_out;
+    }
+
+  pango_markup_parser_finish (context, &attrlist, &text, NULL, &error);
+  if (error != NULL)
+    {
+      g_propagate_error (error_out, error);
+      goto error_out;
+    }
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  gis_gtk_text_buffer_insert_pango_text (buffer, &iter, attrlist, text);
+
+  return buffer;
+
+ error_out:
+  pango_markup_parser_finish (context, NULL, NULL, NULL, NULL);
+  return NULL;
+}
+
+static gboolean
 splice_into_buffer (GtkTextBuffer *buffer,
                     char          *contents,
                     gssize         n_read,
@@ -94,6 +148,8 @@ build_eula_text_view (GFile *eula)
 
   if (last_dot == NULL || strcmp(last_dot, ".txt") == 0)
     buffer = build_eula_text_buffer_plain_text (input_stream, &error);
+  else if (strcmp (last_dot, ".xml") == 0)
+    buffer = build_eula_text_buffer_pango_markup (input_stream, &error);
   else
     goto out;
 
diff --git a/gnome-initial-setup/gis-utils.c b/gnome-initial-setup/gis-utils.c
index c36ffd6..01c29ea 100644
--- a/gnome-initial-setup/gis-utils.c
+++ b/gnome-initial-setup/gis-utils.c
@@ -104,3 +104,121 @@ gis_builder (gchar *resource)
 
     return builder;
 }
+
+
+/* remove when this is landed in GTK+ itself */
+
+#include <gtk/gtk.h>
+#include <pango/pango.h>
+
+static GtkTextTag *
+gis_gtk_text_buffer_get_text_tag_from_pango (PangoAttrIterator *paiter)
+{
+  PangoAttribute *attr;
+  GtkTextTag *tag = gtk_text_tag_new (NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_LANGUAGE)))
+    g_object_set (tag, "language", pango_language_to_string ( ( (PangoAttrLanguage*)attr)->value), NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FAMILY)))
+    g_object_set (tag, "family", ( (PangoAttrString*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STYLE)))
+    g_object_set (tag, "style", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_WEIGHT)))
+    g_object_set (tag, "weight", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_VARIANT)))
+    g_object_set (tag, "variant", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STRETCH)))
+    g_object_set (tag, "stretch", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_SIZE)))
+    g_object_set (tag, "size", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FONT_DESC)))
+    g_object_set (tag, "font-desc", ( (PangoAttrFontDesc*)attr)->desc, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_FOREGROUND))) {
+    GdkColor col = { 0,
+                     ( (PangoAttrColor*)attr)->color.red,
+                     ( (PangoAttrColor*)attr)->color.green,
+                     ( (PangoAttrColor*)attr)->color.blue
+    };
+
+    g_object_set (tag, "foreground-gdk", &col, NULL);
+  }
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_BACKGROUND))) {
+    GdkColor col = { 0,
+                     ( (PangoAttrColor*)attr)->color.red,
+                     ( (PangoAttrColor*)attr)->color.green,
+                     ( (PangoAttrColor*)attr)->color.blue
+    };
+
+    g_object_set (tag, "background-gdk", &col, NULL);
+  }
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_UNDERLINE)))
+    g_object_set (tag, "underline", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_STRIKETHROUGH)))
+    g_object_set (tag, "strikethrough", (gboolean) ( ( (PangoAttrInt*)attr)->value != 0), NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_RISE)))
+    g_object_set (tag, "rise", ( (PangoAttrInt*)attr)->value, NULL);
+
+  if ( (attr = pango_attr_iterator_get (paiter, PANGO_ATTR_SCALE)))
+    g_object_set (tag, "scale", ( (PangoAttrFloat*)attr)->value, NULL);
+
+  return tag;
+}
+
+void
+gis_gtk_text_buffer_insert_pango_text (GtkTextBuffer *buffer,
+                                       GtkTextIter *iter,
+                                       PangoAttrList *attrlist,
+                                       gchar *text)
+{
+  GtkTextMark *mark;
+  PangoAttrIterator *paiter;
+
+  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+
+  /* trivial, no markup */
+  if (attrlist == NULL) {
+    gtk_text_buffer_insert (buffer, iter, text, -1);
+    return;
+  }
+
+  /* create mark with right gravity */
+  mark = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
+  paiter = pango_attr_list_get_iterator (attrlist);
+
+  do {
+    GtkTextTag *tag;
+    GtkTextTag *tag_para;
+    gint start, end;
+
+    pango_attr_iterator_range (paiter, &start, &end);
+
+    if (end == G_MAXINT)	/* last chunk */
+      end = start-1; /* resulting in -1 to be passed to _insert */
+
+    tag = gis_gtk_text_buffer_get_text_tag_from_pango (paiter);
+
+    gtk_text_tag_table_add (gtk_text_buffer_get_tag_table (buffer), tag);
+
+    tag_para = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer), "para");
+    gtk_text_buffer_insert_with_tags (buffer, iter, text+start, end - start, tag, tag_para, NULL);
+
+    /* mark had right gravity, so it should be
+     *	at the end of the inserted text now */
+    gtk_text_buffer_get_iter_at_mark (buffer, iter, mark);
+  } while (pango_attr_iterator_next (paiter));
+
+  gtk_text_buffer_delete_mark (buffer, mark);
+  pango_attr_iterator_destroy (paiter);
+}
diff --git a/gnome-initial-setup/gis-utils.h b/gnome-initial-setup/gis-utils.h
index 6cfb1ce..5b9d7e2 100644
--- a/gnome-initial-setup/gis-utils.h
+++ b/gnome-initial-setup/gis-utils.h
@@ -12,6 +12,10 @@ G_BEGIN_DECLS
 void gis_copy_account_file (ActUser     *act_user,
                             const gchar *relative_path);
 GtkBuilder * gis_builder (gchar *resource);
+void gis_gtk_text_buffer_insert_pango_text (GtkTextBuffer *buffer,
+                                            GtkTextIter *iter,
+                                            PangoAttrList *attrlist,
+                                            gchar *text);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]