Here's a patch for review then.

J'


On Sun, Dec 18, 2011 at 05:04:31PM -0800, Ben Pfaff wrote:
     Yes, that's one way to implement the approach I have in mind.
     
     John Darrington <j...@darrington.wattle.id.au> writes:
     
     > I think I understand what you're saying now.
     > You're suggesting that we add the string_map as a member of the output
     > viewer object?   Yes I think that will work.
     >
     > J'
     >
     > On Sun, Dec 18, 2011 at 11:22:36AM -0800, Ben Pfaff wrote:
     >      [adding pspp-dev back, assuming it was just dropped accidentally]
     >      
     >      John Darrington <j...@darrington.wattle.id.au> writes:
     >      
     >      > On Sat, Dec 17, 2011 at 10:13:30AM -0800, Ben Pfaff wrote:
     >      >
     >      >      I don't understand the problem yet.  If we pass a particular 
set
     >      >      of options to a driver, then we'll get a particular
     >      >      configuration.  If we need to change one option, then we can 
do
     >      >      that by updating the set of options slightly (just changing 
the
     >      >      one value) and then handing the driver the updated set of
     >      >      options.  
     >      >
     >      > This sounds perfectly reasonable.
     >      >
     >      >   The default values should default the same way they did
     >      >      on the first try, right?  
     >      >
     >      > This doesn't sound so good.  I don't want them to default.  I 
want them
     >      > to remain in their current state.
     >      >
     >      >
     >      > For the current problem, I need a function, to be called in
     >      > psppire-output-window.c (expose_event_callback) which sets the
     >      > font and the foreground colour (perhaps a few other things too)
     >      > but leaves the rest of the options in their current state.
     >      > This doesn't seem possible at the moment without changing code
     >      > in quote a lot of places or by circumventing the interface to
     >      > the cairo xr driver.
     >      
     >      So let's use an example, because I still don't see the problem
     >      yet.  Suppose the cairo driver is initially configured as:
     >      
     >              foreground-color: black
     >              font: Sans
     >              font-size: 12pt
     >      
     >      No background color is specified, so suppose it defaults to
     >      white.  Now something comes along and wants to set the font size
     >      to 10pt.  So we take the original set of options, change the
     >      font-size to 10pt, and hand the updated set of options back to
     >      the driver (using some new "set_options" function I guess).  The
     >      new option set looks like this:
     >      
     >              foreground-color: black
     >              font: Sans
     >              font-size: 10pt
     >      
     >      No background color is specified now either, so it still defaults
     >      to white.
     >      
     >      What's the problem with defaults in this scenario?
     >      
     >      Thanks,
     >      
     >      Ben.
     >      -- 
     >      Ben Pfaff 
     >      http://benpfaff.org
     
     -- 
     Ben Pfaff 
     http://benpfaff.org

-- 
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://keys.gnupg.net or any PGP keyserver for public key.

diff --git a/src/output/cairo.c b/src/output/cairo.c
index 72cf51c..1de46b2 100644
--- a/src/output/cairo.c
+++ b/src/output/cairo.c
@@ -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)
diff --git a/src/output/cairo.h b/src/output/cairo.h
index af317d9..974acb4 100644
--- a/src/output/cairo.h
+++ b/src/output/cairo.h
@@ -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);
diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c
index 25a16b5..99a11ed 100644
--- a/src/ui/gui/psppire-output-window.c
+++ b/src/ui/gui/psppire-output-window.c
@@ -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");
diff --git a/src/ui/gui/psppire-output-window.h b/src/ui/gui/psppire-output-window.h
index 54447b1..4fc0199 100644
--- a/src/ui/gui/psppire-output-window.h
+++ b/src/ui/gui/psppire-output-window.h
@@ -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;

Attachment: signature.asc
Description: Digital signature

_______________________________________________
pspp-dev mailing list
pspp-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/pspp-dev

Reply via email to