output: Implement styling for titles and captions.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 22 Nov 2018 06:04:12 +0000 (22:04 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 25 Dec 2018 20:48:08 +0000 (12:48 -0800)
src/output/render.c
src/output/table-item.c
src/output/table-item.h
src/output/table-provider.h
src/output/table.c

index f73137f0e35eafe8ab11b8981de11998f01c73cf..bb4b4ad996304449d557fdf5a58886eb84853845 100644 (file)
@@ -134,7 +134,7 @@ struct render_page
   };
 
 static struct render_page *render_page_create (const struct render_params *,
-                                               struct table *);
+                                               struct table *, int min_width);
 
 struct render_page *render_page_ref (const struct render_page *page_);
 static void render_page_unref (struct render_page *);
@@ -622,7 +622,8 @@ set_join_crossings (struct render_page *page, enum table_axis axis,
    size is PARAMS->size, but the caller is responsible for actually breaking it
    up to fit on such a device, using the render_break abstraction.  */
 static struct render_page *
-render_page_create (const struct render_params *params, struct table *table)
+render_page_create (const struct render_params *params, struct table *table,
+                    int min_width)
 {
   struct render_page *page;
   enum { MIN, MAX };
@@ -699,6 +700,9 @@ render_page_create (const struct render_params *params, struct table *table)
         x = cell.d[H][1];
         table_cell_free (&cell);
       }
+  if (min_width > 0)
+    for (i = 0; i < 2; i++)
+      distribute_spanned_width (min_width, &columns[i][0], rules[H], nc);
 
   /* In pathological cases, spans can cause the minimum width of a column to
      exceed the maximum width.  This bollixes our interpolation algorithm
@@ -1392,13 +1396,15 @@ struct render_pager
   };
 
 static const struct render_page *
-render_pager_add_table (struct render_pager *p, struct table *table)
+render_pager_add_table (struct render_pager *p, struct table *table,
+                        int min_width)
 {
   struct render_page *page;
 
   if (p->n_pages >= p->allocated_pages)
     p->pages = x2nrealloc (p->pages, &p->allocated_pages, sizeof *p->pages);
-  page = p->pages[p->n_pages++] = render_page_create (p->params, table);
+  page = p->pages[p->n_pages++] = render_page_create (p->params, table,
+                                                      min_width);
   return page;
 }
 
@@ -1431,28 +1437,25 @@ add_footnote_page (struct render_pager *p, const struct table_item *item)
             tab_add_style (t, 1, i, f[i]->style);
           }
       }
-  render_pager_add_table (p, &t->table);
+  render_pager_add_table (p, &t->table, 0);
 
   free (f);
 }
 
 static void
-add_text_page (struct render_pager *p, const struct table_item_text *t)
+add_text_page (struct render_pager *p, const struct table_item_text *t,
+               int min_width)
 {
   if (!t)
     return;
 
   struct tab_table *tab = tab_create (1, 1);
-  tab_text (tab, 0, 0, TAB_LEFT, t->content);
+  tab_text (tab, 0, 0, t->halign, t->content);
   for (size_t i = 0; i < t->n_footnotes; i++)
     tab_add_footnote (tab, 0, 0, t->footnotes[i]);
   if (t->style)
-    {
-      tab->styles[0] = pool_clone (tab->container, t->style, sizeof *t->style);
-      if (t->style->font)
-        tab->styles[0]->font = pool_strdup (tab->container, t->style->font);
-    }
-  render_pager_add_table (p, &tab->table);
+    tab->styles[0] = cell_style_clone (tab->container, t->style);
+  render_pager_add_table (p, &tab->table, min_width);
 }
 
 /* Creates and returns a new render_pager for rendering TABLE_ITEM on the
@@ -1461,19 +1464,28 @@ struct render_pager *
 render_pager_create (const struct render_params *params,
                      const struct table_item *table_item)
 {
+  const struct table *table = table_item_get_table (table_item);
   struct render_pager *p;
 
   p = xzalloc (sizeof *p);
   p->params = params;
 
+  struct render_page *page = render_page_create (params, table_ref (table), 0);
+  struct render_break b;
+  render_break_init (&b, page, H);
+  struct render_page *subpage = render_break_next (&b, p->params->size[H]);
+  int title_width = subpage ? subpage->cp[H][2 * subpage->n[H] + 1] : 0;
+  render_page_unref (subpage);
+  render_break_destroy (&b);
+
   /* Title. */
-  add_text_page (p, table_item_get_title (table_item));
+  add_text_page (p, table_item_get_title (table_item), title_width);
 
   /* Body. */
-  render_pager_add_table (p, table_ref (table_item_get_table (table_item)));
+  render_pager_add_table (p, table_ref (table_item_get_table (table_item)), 0);
 
   /* Caption. */
-  add_text_page (p, table_item_get_caption (table_item));
+  add_text_page (p, table_item_get_caption (table_item), 0);
 
   /* Footnotes. */
   add_footnote_page (p, table_item);
index d2d3ea54abc79bfe287ad72c8e2fe691c27241d3..6d4927326c3e6ea7f89e13de81c0d730b9b56fce 100644 (file)
@@ -35,7 +35,8 @@ table_item_text_create (const char *content)
     return NULL;
 
   struct table_item_text *text = xmalloc (sizeof *text);
-  *text = (struct table_item_text) { .content = xstrdup (content) };
+  *text = (struct table_item_text) { .content = xstrdup (content),
+                                     .halign = TAB_LEFT };
   return text;
 }
 
@@ -51,7 +52,8 @@ table_item_text_clone (const struct table_item_text *old)
     .footnotes = xmemdup (old->footnotes,
                           old->n_footnotes * sizeof *old->footnotes),
     .n_footnotes = old->n_footnotes,
-    .style = cell_style_clone (old->style),
+    .style = cell_style_clone (NULL, old->style),
+    .halign = old->halign,
   };
   return new;
 }
index 1cc92eaf5dc27c2f7e4587cc4a3bf8160f194f7c..3b8c09d75909fb51a2efa1ef0f5a5d556e42a883 100644 (file)
@@ -34,6 +34,7 @@ struct table_item_text
     char *content;
     const struct footnote **footnotes;
     size_t n_footnotes;
+    int halign;                 /* TAB_*. */
     struct cell_style *style;
   };
 
index 2a3a17c9daeec45e4c8461ce6bcd2255b2cc8b68..2917051a13039c3f0d015bf4891bb6971b7eb5cf 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include "output/table.h"
 
+struct pool;
 struct string;
 
 struct footnote
@@ -81,7 +82,7 @@ struct cell_style
       .underline = false,                                       \
     }
 
-struct cell_style *cell_style_clone (const struct cell_style *);
+struct cell_style *cell_style_clone (struct pool *, const struct cell_style *);
 void cell_style_free (struct cell_style *);
 
 /* A cell in a table. */
index 44efa3abc34f1fc379356598742212dca7ed6b10..c8dfcbb0f83910802a379d59ba29b341ce824bf0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "libpspp/cast.h"
 #include "libpspp/compiler.h"
+#include "libpspp/pool.h"
 #include "libpspp/str.h"
 #include "output/table-item.h"
 
@@ -130,12 +131,12 @@ table_set_nr (struct table *table, int nr)
 }
 \f
 struct cell_style *
-cell_style_clone (const struct cell_style *old)
+cell_style_clone (struct pool *pool, const struct cell_style *old)
 {
-  struct cell_style *new = xmalloc (sizeof *new);
+  struct cell_style *new = pool_malloc (pool, sizeof *new);
   *new = *old;
   if (new->font)
-    new->font = strdup (new->font);
+    new->font = pool_strdup (pool, new->font);
   return new;
 }