Set the output driver parameters dynamically from the output window style.
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 22 Dec 2011 19:57:23 +0000 (20:57 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 22 Dec 2011 20:00:55 +0000 (21:00 +0100)
This change allows the output driver options to be changed after the driver
has been created.  This is necessary in the GUI to follow the style changes
(eg from theme engines etc)

src/output/cairo.c
src/output/cairo.h
src/ui/gui/psppire-output-window.c
src/ui/gui/psppire-output-window.h

index 72cf51c3660eaaf006d2298c0d6636db355dc20c..1de46b25bbe9ce7f7fbe3ee92ea3aae6563bb8ee 100644 (file)
@@ -184,7 +184,7 @@ opt (struct output_driver *d, struct string_map *options, const char *key,
    Currently, the input string must be of the form "#RRRRGGGGBBBB"
    Future implementations might allow things like "yellow" and
    "sky-blue-ultra-brown"
- */
+*/
 static void
 parse_color (struct output_driver *d, struct string_map *options,
              const char *key, const char *default_value,
@@ -240,20 +240,15 @@ parse_font (struct output_driver *d, struct string_map *options,
   return desc;
 }
 
-static struct xr_driver *
-xr_allocate (const char *name, int device_type, struct string_map *o)
+
+static void
+apply_options (struct xr_driver *xr, struct string_map *o)
 {
-  int paper_width, paper_length;
-  struct output_driver *d;
-  struct xr_driver *xr;
-  int font_points;
+  struct output_driver *d = &xr->driver;
 
-  xr = xzalloc (sizeof *xr);
-  d = &xr->driver;
-  output_driver_init (d, &cairo_driver_class, name, device_type);
+  int paper_width, paper_length;
 
-  font_points = parse_int (opt (d, o, "font-size", "10000"),
-                           1000, 1000000);
+  int font_points = parse_int (opt (d, o, "font-size", "10000"), 1000, 1000000);
   xr->fonts[XR_FONT_FIXED].desc = parse_font (d, o, "fixed-font", "monospace",
                                               font_points);
   xr->fonts[XR_FONT_PROPORTIONAL].desc = parse_font (d, o, "prop-font",
@@ -277,6 +272,17 @@ xr_allocate (const char *name, int device_type, struct string_map *o)
 
   xr->width = paper_width - xr->left_margin - xr->right_margin;
   xr->length = paper_length - xr->top_margin - xr->bottom_margin;
+}
+
+static struct xr_driver *
+xr_allocate (const char *name, int device_type, struct string_map *o)
+{
+  struct xr_driver *xr = xzalloc (sizeof *xr);
+  struct output_driver *d = &xr->driver;
+
+  output_driver_init (d, &cairo_driver_class, name, device_type);
+
+  apply_options (xr, o);
 
   return xr;
 }
@@ -934,6 +940,8 @@ struct xr_rendering
 #define CHART_WIDTH 500
 #define CHART_HEIGHT 375
 
+
+
 struct xr_driver *
 xr_driver_create (cairo_t *cairo, struct string_map *options)
 {
@@ -971,6 +979,12 @@ xr_rendering_create_text (struct xr_driver *xr, const char *text, cairo_t *cr)
   return r;
 }
 
+void 
+xr_rendering_apply_options (struct xr_rendering *xr, struct string_map *o)
+{
+  apply_options (xr->xr, o);
+}
+
 struct xr_rendering *
 xr_rendering_create (struct xr_driver *xr, const struct output_item *item,
                      cairo_t *cr)
index af317d9c6b95548db207eac02a5a7c9b87e55aa2..974acb444e5f6e191896fad3036891dfc159bb94 100644 (file)
@@ -31,12 +31,15 @@ struct string_map;
 struct xr_driver *xr_driver_create (cairo_t *, struct string_map *options);
 void xr_driver_destroy (struct xr_driver *);
 
+
 /* Functions for rendering a single output item to a Cairo context.
    Output items are never broken across multiple pages.
    Used by PSPPIRE to render in the GUI. */
 struct xr_rendering *xr_rendering_create (struct xr_driver *,
                                           const struct output_item *,
                                           cairo_t *);
+
+void xr_rendering_apply_options (struct xr_rendering *, struct string_map *o);
 void xr_rendering_measure (struct xr_rendering *, int *w, int *h);
 void xr_rendering_draw (struct xr_rendering *, cairo_t *,
                         int x, int y, int w, int h);
index 25a16b515727277986f7fd045c44f2c36889afbd..99a11ed52d9fe84e8c84e27e43183f25535c7f8e 100644 (file)
@@ -95,6 +95,9 @@ static GObjectClass *parent_class;
 static void
 psppire_output_window_finalize (GObject *object)
 {
+  string_map_destroy (&PSPPIRE_OUTPUT_WINDOW(object)->render_opts);
+
+
   if (G_OBJECT_CLASS (parent_class)->finalize)
     (*G_OBJECT_CLASS (parent_class)->finalize) (object);
 }
@@ -171,9 +174,39 @@ static void on_dwgarea_realize (GtkWidget *widget, gpointer data);
 static gboolean
 expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
+  PsppireOutputWindow *viewer = PSPPIRE_OUTPUT_WINDOW (data);
   struct xr_rendering *r = g_object_get_data (G_OBJECT (widget), "rendering");
   cairo_t *cr = gdk_cairo_create (widget->window);
 
+  const GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (viewer));
+
+  struct text_item *text_item;
+  PangoFontDescription *font_desc;
+  char *font_name;
+  int font_width;
+  
+  gchar *fgc =
+    gdk_color_to_string (&style->text[gtk_widget_get_state (GTK_WIDGET (widget))]);
+
+  string_map_replace (&viewer->render_opts, "foreground-color", fgc);
+
+  free (fgc);
+
+  /* Use GTK+ default font as proportional font. */
+  font_name = pango_font_description_to_string (style->font_desc);
+  string_map_replace (&viewer->render_opts, "prop-font", font_name);
+  g_free (font_name);
+
+  /* Derived emphasized font from proportional font. */
+  font_desc = pango_font_description_copy (style->font_desc);
+  pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
+  font_name = pango_font_description_to_string (font_desc);
+  string_map_replace (&viewer->render_opts, "emph-font", font_name);
+  g_free (font_name);
+  pango_font_description_free (font_desc);
+
+  xr_rendering_apply_options (r, &viewer->render_opts);
+
   xr_rendering_draw (r, cr, event->area.x, event->area.y,
                      event->area.width, event->area.height);
   cairo_destroy (cr);
@@ -228,7 +261,6 @@ psppire_output_submit (struct output_driver *this,
   if (pod->xr == NULL)
     {
       const GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (viewer));
-      struct string_map options = STRING_MAP_INITIALIZER (options);
       struct text_item *text_item;
       PangoFontDescription *font_desc;
       char *font_name;
@@ -236,19 +268,20 @@ psppire_output_submit (struct output_driver *this,
       
       /* Set the widget's text color as the foreground color for the output driver */
       gchar *fgc = gdk_color_to_string (&style->text[gtk_widget_get_state (GTK_WIDGET (viewer))]);
-      string_map_insert (&options, "foreground-color", fgc);
+
+      string_map_insert (&pod->viewer->render_opts, "foreground-color", fgc);
       g_free (fgc);
 
       /* Use GTK+ default font as proportional font. */
       font_name = pango_font_description_to_string (style->font_desc);
-      string_map_insert (&options, "prop-font", font_name);
+      string_map_insert (&pod->viewer->render_opts, "prop-font", font_name);
       g_free (font_name);
 
       /* Derived emphasized font from proportional font. */
       font_desc = pango_font_description_copy (style->font_desc);
       pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
       font_name = pango_font_description_to_string (font_desc);
-      string_map_insert (&options, "emph-font", font_name);
+      string_map_insert (&pod->viewer->render_opts, "emph-font", font_name);
       g_free (font_name);
       pango_font_description_free (font_desc);
 
@@ -257,15 +290,14 @@ psppire_output_submit (struct output_driver *this,
          scrolling only.  (The length should not be increased very much because
          it is already close enough to INT_MAX when expressed as thousands of a
          point.) */
-      string_map_insert (&options, "paper-size", "300x200000mm");
-      string_map_insert (&options, "left-margin", "0");
-      string_map_insert (&options, "right-margin", "0");
-      string_map_insert (&options, "top-margin", "0");
-      string_map_insert (&options, "bottom-margin", "0");
+      string_map_insert (&pod->viewer->render_opts, "paper-size", "300x200000mm");
+      string_map_insert (&pod->viewer->render_opts, "left-margin", "0");
+      string_map_insert (&pod->viewer->render_opts, "right-margin", "0");
+      string_map_insert (&pod->viewer->render_opts, "top-margin", "0");
+      string_map_insert (&pod->viewer->render_opts, "bottom-margin", "0");
 
-      pod->xr = xr_driver_create (cr, &options);
+      pod->xr = xr_driver_create (cr, &pod->viewer->render_opts);
 
-      string_map_destroy (&options);
 
       text_item = text_item_create (TEXT_ITEM_PARAGRAPH, "X");
       r = xr_rendering_create (pod->xr, text_item_super (text_item), cr);
@@ -289,7 +321,7 @@ psppire_output_submit (struct output_driver *this,
                      G_CALLBACK (on_dwgarea_realize), pod->viewer);
 
   g_signal_connect (drawing_area, "expose_event",
-                     G_CALLBACK (expose_event_callback), NULL);
+                     G_CALLBACK (expose_event_callback), pod->viewer);
 
   gtk_widget_set_size_request (drawing_area, tw, th);
   gtk_layout_put (pod->viewer->output, drawing_area, 0, pod->viewer->y);
@@ -918,6 +950,8 @@ psppire_output_window_init (PsppireOutputWindow *window)
   GtkAction *select_all_action;
   GtkTreeSelection *sel;
 
+  string_map_init (&window->render_opts);
+
   xml = builder_new ("output-viewer.ui");
 
   copy_action = get_action_assert (xml, "edit_copy");
index 54447b1d5b417f22397632988435ae37f1e714bc..4fc019991c8cdb264b764620f20918d1aa060e74 100644 (file)
@@ -24,9 +24,7 @@
 #include <gtk/gtk.h>
 #include "psppire-window.h"
 #include "psppire.h"
-
-extern int viewer_length;
-extern int viewer_width ;
+#include "libpspp/string-map.h"
 
 
 G_BEGIN_DECLS
@@ -55,6 +53,7 @@ struct _PsppireOutputWindow
   int max_width;
   int y;
 
+  struct string_map render_opts;
   GtkTreeView *overview;
   GtkTreeIter cur_command;
   bool in_command;