printing works; font sizes are weird
[pspp] / src / output / cairo-pager.c
index 8a0f948cc86ab89a70495b2add3273cc64c2c211..2d287499a2b43858c2914186bea386aec1b001ae 100644 (file)
@@ -55,8 +55,6 @@ xr_page_style_unshare (struct xr_page_style *old)
   new->ref_cnt = 1;
   for (int i = 0; i < 2; i++)
     page_heading_copy (&new->headings[i], &old->headings[i]);
-  if (old->font)
-    new->font = pango_font_description_copy (old->font);
 
   return new;
 }
@@ -71,53 +69,37 @@ xr_page_style_unref (struct xr_page_style *ps)
         {
           for (int i = 0; i < 2; i++)
             page_heading_uninit (&ps->headings[i]);
-          if (ps->font)
-            pango_font_description_free (ps->font);
           free (ps);
         }
     }
 }
 
-static bool
-pfd_equals (const PangoFontDescription *a,
-            const PangoFontDescription *b)
-{
-  return a && b ? pango_font_description_equal (a, b) : !a && !b;
-}
-
 bool
 xr_page_style_equals (const struct xr_page_style *a,
                       const struct xr_page_style *b)
 {
   for (int i = 0; i < TABLE_N_AXES; i++)
-    {
-      if (a->size[i] != b->size[i])
+    for (int j = 0; j < 2; j++)
+      if (a->margins[i][j] != b->margins[i][j])
         return false;
 
-      for (int j = 0; j < 2; j++)
-        if (a->margins[i][j] != b->margins[i][j])
-          return false;
-    }
-
   for (int i = 0; i < 2; i++)
     if (!page_heading_equals (&a->headings[i], &b->headings[i]))
       return false;
 
-  return (pfd_equals (a->font, b->font)
-          && a->font_scale == b->font_scale
-          && a->initial_page_number == b->initial_page_number
+  return (a->initial_page_number == b->initial_page_number
           && a->object_spacing == b->object_spacing);
 }
 \f
 struct xr_pager
   {
     struct xr_page_style *page_style;
+    struct xr_fsm_style *fsm_style;
     int page_index;
     int heading_heights[2];
 
     /* Current output item. */
     struct xr_fsm *fsm;
-    struct xr_fsm_style *fsm_style;
     struct output_item *item;
 
     /* Current output page. */
@@ -200,7 +182,9 @@ xr_render_page_heading (cairo_t *cairo, const PangoFontDescription *font,
 }
 
 static void
-xr_measure_headings (const struct xr_page_style *ps, int heading_heights[2])
+xr_measure_headings (const struct xr_page_style *ps,
+                     const struct xr_fsm_style *fs,
+                     int heading_heights[2])
 {
   cairo_surface_t *surface = cairo_recording_surface_create (
     CAIRO_CONTENT_COLOR, NULL);
@@ -208,8 +192,9 @@ xr_measure_headings (const struct xr_page_style *ps, int heading_heights[2])
   for (int i = 0; i < 2; i++)
     {
       int *h = &heading_heights[i];
-      *h = xr_render_page_heading (cairo, ps->font, &ps->headings[i], -1,
-                                   ps->size[H], false, 0);
+      *h = xr_render_page_heading (cairo, fs->fonts[XR_FONT_PROPORTIONAL],
+                                   &ps->headings[i], -1, fs->size[H], false,
+                                   0);
       if (*h)
         *h += ps->object_spacing;
     }
@@ -218,24 +203,28 @@ xr_measure_headings (const struct xr_page_style *ps, int heading_heights[2])
 }
 
 struct xr_pager *
-xr_pager_create (const struct xr_page_style *ps_)
+xr_pager_create (const struct xr_page_style *ps_,
+                 const struct xr_fsm_style *fs_)
 {
+  printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
   struct xr_page_style *ps = xr_page_style_ref (ps_);
+  struct xr_fsm_style *fs = xr_fsm_style_ref (fs_);
 
   int heading_heights[2];
-  xr_measure_headings (ps, heading_heights);
+  xr_measure_headings (ps, fs, heading_heights);
   int total = heading_heights[0] + heading_heights[1];
-  if (total > 0 && total < ps->size[V])
+  if (total > 0 && total < fs->size[V])
     {
+      fs = xr_fsm_style_unshare (fs);
       ps = xr_page_style_unshare (ps);
 
       for (int i = 0; i < 2; i++)
         ps->margins[V][i] += heading_heights[i];
-      ps->size[V] -= total;
+      fs->size[V] -= total;
     }
 
   struct xr_pager *p = xmalloc (sizeof *p);
-  *p = (struct xr_pager) { .page_style = ps };
+  *p = (struct xr_pager) { .page_style = ps, .fsm_style = fs };
   return p;
 }
 
@@ -244,13 +233,18 @@ xr_pager_destroy (struct xr_pager *p)
 {
   if (p)
     {
-      xr_fsm_destroy (p->fsm);
+      printf (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+      xr_page_style_unref (p->page_style);
       xr_fsm_style_unref (p->fsm_style);
+
+      xr_fsm_destroy (p->fsm);
       output_item_unref (p->item);
 
-      xr_page_style_unref (p->page_style);
       if (p->cr)
-        cairo_destroy (p->cr);
+        {
+          cairo_restore (p->cr);
+          cairo_destroy (p->cr);
+        }
       free (p);
     }
 }
@@ -262,12 +256,11 @@ xr_pager_has_item (const struct xr_pager *p)
 }
 
 void
-xr_pager_add_item (struct xr_pager *p, const struct xr_fsm_style *fsm_style,
-                   const struct output_item *item)
+xr_pager_add_item (struct xr_pager *p, const struct output_item *item)
 {
+  printf ("add_item\n");
   assert (!p->item);
   p->item = output_item_ref (item);
-  p->fsm_style = xr_fsm_style_ref (fsm_style);
   xr_pager_run (p);
 }
 
@@ -280,10 +273,13 @@ xr_pager_has_page (const struct xr_pager *p)
 void
 xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
 {
+  printf ("add_page\n");
   assert (!p->cr);
+  cairo_save (cr);
   p->cr = cr;
   p->y = 0;
 
+  const struct xr_fsm_style *fs = p->fsm_style;
   const struct xr_page_style *ps = p->page_style;
   const struct cell_color *bg = &ps->bg;
   if (bg->alpha)
@@ -291,7 +287,7 @@ xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
       cairo_save (cr);
       cairo_set_source_rgba (cr, bg->r / 255.0, bg->g / 255.0,
                           bg->b / 255.0, bg->alpha / 255.0);
-      cairo_rectangle (cr, 0, 0, ps->size[H], ps->size[V]);
+      cairo_rectangle (cr, 0, 0, fs->size[H], fs->size[V]);
       cairo_fill (cr);
       cairo_restore (cr);
     }
@@ -299,15 +295,16 @@ xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
                    xr_to_pt (ps->margins[H][0]),
                    xr_to_pt (ps->margins[V][0]));
 
+  const PangoFontDescription *font = fs->fonts[XR_FONT_PROPORTIONAL];
   int page_number = p->page_index++ + ps->initial_page_number;
   if (p->heading_heights[0])
-    xr_render_page_heading (cr, ps->font, &ps->headings[0], page_number,
-                            ps->size[H], true, -p->heading_heights[0]);
+    xr_render_page_heading (cr, font, &ps->headings[0], page_number,
+                            fs->size[H], true, -p->heading_heights[0]);
 
   if (p->heading_heights[1])
-    xr_render_page_heading (cr, ps->font, &ps->headings[1], page_number,
-                            ps->size[H], true,
-                            ps->size[V] + ps->object_spacing);
+    xr_render_page_heading (cr, font, &ps->headings[1], page_number,
+                            fs->size[H], true,
+                            fs->size[V] + ps->object_spacing);
 
   xr_pager_run (p);
 }
@@ -315,10 +312,14 @@ xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
 bool
 xr_pager_needs_new_page (struct xr_pager *p)
 {
-  if (p->item && p->y >= p->page_style->size[V])
+  if (p->item && (!p->cr || p->y >= p->fsm_style->size[V]))
     {
-      cairo_destroy (p->cr);
-      p->cr = NULL;
+      if (p->cr)
+        {
+          cairo_restore (p->cr);
+          cairo_destroy (p->cr);
+          p->cr = NULL;
+        }
       return true;
     }
   else
@@ -328,16 +329,16 @@ xr_pager_needs_new_page (struct xr_pager *p)
 static void
 xr_pager_run (struct xr_pager *p)
 {
-  if (p->item && p->cr && p->y < p->page_style->size[V])
+  printf ("run:\n");
+  if (p->item && p->cr && p->y < p->fsm_style->size[V])
     {
       if (!p->fsm)
         {
-          /* XXX fsm_style needs to account for heading_heights */
+          printf ("\tcreate fsm\n");
           p->fsm = xr_fsm_create (p->item, p->fsm_style, p->cr);
           if (!p->fsm)
             {
-              xr_fsm_style_unref (p->fsm_style);
-              p->fsm_style = NULL;
+              printf ("\t(was null)\n");
               output_item_unref (p->item);
               p->item = NULL;
 
@@ -347,28 +348,34 @@ xr_pager_run (struct xr_pager *p)
 
       for (;;)
         {
+          printf ("\tdraw slice\n");
           int spacing = p->page_style->object_spacing;
           int chunk = xr_fsm_draw_slice (p->fsm, p->cr,
-                                         p->page_style->size[V] - p->y);
+                                         p->fsm_style->size[V] - p->y);
           p->y += chunk + spacing;
           cairo_translate (p->cr, 0, xr_to_pt (chunk + spacing));
 
           if (xr_fsm_is_empty (p->fsm))
             {
+              printf ("\tfinished object\n");
               xr_fsm_destroy (p->fsm);
               p->fsm = NULL;
-              xr_fsm_style_unref (p->fsm_style);
-              p->fsm_style = NULL;
               output_item_unref (p->item);
               p->item = NULL;
               return;
             }
           else if (!chunk)
             {
+              printf ("\tobject doesn't fit on page\n");
               assert (p->y > 0);
               p->y = INT_MAX;
               return;
             }
+          printf ("\tneed to draw another slice\n");
         }
     }
+  if (!p->item)
+    printf ("\tno item\n");
+  if (!p->cr)
+    printf ("\tno page\n");
 }