output: Drop TAB_FIX and the idea of a configurable fixed-width font.
[pspp] / src / output / pivot-output.c
index 1a4ac9db7ce7e4faf48b05049a95cef25207fb6b..8cde929c500b6f16e03be9f934768b80157784fb 100644 (file)
@@ -93,6 +93,27 @@ table_area_style_override (struct pool *pool,
   return out;
 }
 
+static int
+format_cell (const struct pivot_value *value, int style_idx,
+             enum settings_value_show show_values,
+             enum settings_value_show show_variables,
+             bool rotate_label, struct string *s)
+{
+  int options = style_idx << TAB_STYLE_SHIFT;
+  if (value)
+    {
+      bool numeric = pivot_value_format_body (value, show_values,
+                                              show_variables, s);
+      if (numeric)
+        options |= TAB_NUMERIC;
+      if (value->font_style && value->font_style->markup)
+        options |= TAB_MARKUP;
+      if (rotate_label)
+        options |= TAB_ROTATE;
+    }
+  return options;
+}
+
 static void
 fill_cell (struct table *t, int x1, int y1, int x2, int y2,
            const struct table_area_style *style, int style_idx,
@@ -101,21 +122,10 @@ fill_cell (struct table *t, int x1, int y1, int x2, int y2,
            enum settings_value_show show_variables,
            bool rotate_label)
 {
-
   struct string s = DS_EMPTY_INITIALIZER;
-  int opts = style_idx << TAB_STYLE_SHIFT;
-  if (value)
-    {
-      bool numeric = pivot_value_format_body (value, show_values,
-                                              show_variables, &s);
-      if (numeric)
-        opts |= TAB_NUMERIC;
-      if (value->font_style && value->font_style->markup)
-        opts |= TAB_MARKUP;
-      if (rotate_label)
-        opts |= TAB_ROTATE;
-    }
-  table_joint_text (t, x1, y1, x2, y2, opts, ds_cstr (&s));
+  int options = format_cell (value, style_idx,
+                             show_values, show_variables, rotate_label, &s);
+  table_joint_text (t, x1, y1, x2, y2, options, ds_cstr (&s));
   ds_destroy (&s);
 
   if (value)
@@ -140,35 +150,49 @@ fill_cell (struct table *t, int x1, int y1, int x2, int y2,
     }
 }
 
-static struct table_item_text *
-pivot_value_to_table_item_text (const struct pivot_value *value,
-                                const struct table_area_style *area,
-                                struct footnote **footnotes,
-                                enum settings_value_show show_values,
-                                enum settings_value_show show_variables)
+static struct table_cell *
+pivot_value_to_table_cell (const struct pivot_value *value,
+                           const struct table_area_style *style, int style_idx,
+                           struct footnote **footnotes,
+                           enum settings_value_show show_values,
+                           enum settings_value_show show_variables)
 {
   if (!value)
     return NULL;
 
   struct string s = DS_EMPTY_INITIALIZER;
-  pivot_value_format_body (value, show_values, show_variables, &s);
+  int options = format_cell (value, style_idx,
+                             show_values, show_variables, false, &s);
 
-  struct table_item_text *text = xmalloc (sizeof *text);
-  *text = (struct table_item_text) {
-    .content = ds_steal_cstr (&s),
-    .footnotes = xnmalloc (value->n_footnotes, sizeof *text->footnotes),
+  struct table_cell *cell = xmalloc (sizeof *cell);
+  *cell = (struct table_cell) {
+    .options = options,
+    .text = ds_steal_cstr (&s),
     .style = table_area_style_override (
-      NULL, area, value->cell_style, value->font_style, false),
+      NULL, style, value->cell_style, value->font_style, false),
   };
 
-  for (size_t i = 0; i < value->n_footnotes; i++)
+  if (value->n_subscripts)
     {
-      struct footnote *f = footnotes[value->footnotes[i]->idx];
-      if (f)
-        text->footnotes[text->n_footnotes++] = f;
+      cell->subscripts = xnmalloc (value->n_subscripts,
+                                   sizeof *cell->subscripts);
+      cell->n_subscripts = value->n_subscripts;
+      for (size_t i = 0; i < value->n_subscripts; i++)
+        cell->subscripts[i] = xstrdup (value->subscripts[i]);
     }
 
-  return text;
+  if (value->n_footnotes)
+    {
+      cell->footnotes = xnmalloc (value->n_footnotes, sizeof *cell->footnotes);
+      for (size_t i = 0; i < value->n_footnotes; i++)
+        {
+          struct footnote *f = footnotes[value->footnotes[i]->idx];
+          if (f)
+            cell->footnotes[cell->n_footnotes++] = f;
+        }
+    }
+
+  return cell;
 }
 
 static int
@@ -190,6 +214,13 @@ draw_line (struct table *t, const struct table_border_style *styles,
     table_vline (t, rule, a, b0, b1);
 }
 
+/* Fills row or column headings into T.
+
+   This function uses terminology and variable names for column headings, but
+   it also applies to row headings because it uses variables for the
+   differences, e.g. when for column headings it would use the H axis, it
+   instead uses 'h', which is set to H for column headings and V for row
+   headings.  */
 static void
 compose_headings (struct table *t,
                   const struct pivot_axis *a_axis, enum table_axis a,
@@ -348,6 +379,23 @@ compose_headings (struct table *t,
                       vrules[x1] = true;
                     }
                 }
+
+              /* Draws the horizontal lines within a dimension, that is, those
+                 that separate a separating a category (or group) from its
+                 parent group or dimension's label.  Our running example
+                 doesn't have groups but the ==== lines below show the
+                 separators between categories and their dimension label:
+
+                 +-----------------------------------------------------+
+                 |                         bbbb                        |
+                 +=================+=================+=================+
+                 |      bbbb1      |      bbbb2      |      bbbb3      |
+                 +-----------------+-----------------+-----------------+
+                 |       aaaa      |       aaaa      |       aaaa      |
+                 +=====+=====+=====+=====+=====+=====+=====+=====+=====+
+                 |aaaa1|aaaa2|aaaa3|aaaa1|aaaa2|aaaa3|aaaa1|aaaa2|aaaa3|
+                 +-----+-----+-----+-----+-----+-----+-----+-----+-----+
+              */
               if (c->parent && c->parent->show_label)
                 draw_line (t, borders, cat_col_horz, a, y1,
                            x1 + a_ofs, x2 + a_ofs - 1);
@@ -536,15 +584,18 @@ pivot_table_submit_layer (const struct pivot_table *pt,
   free (column_enumeration);
   free (row_enumeration);
 
-  struct table_item *ti = table_item_create (table, NULL, NULL, pt->notes);
+  struct table_item *ti = table_item_create (table);
+
+  if (pt->notes)
+    table_item_set_notes (ti, pt->notes);
 
   if (pt->title && pt->show_title)
     {
-      struct table_item_text *title = pivot_value_to_table_item_text (
-        pt->title, &pt->look->areas[PIVOT_AREA_TITLE], footnotes,
-        pt->show_values, pt->show_variables);
+      struct table_cell *title = pivot_value_to_table_cell (
+        pt->title, &pt->look->areas[PIVOT_AREA_TITLE], PIVOT_AREA_TITLE,
+        footnotes, pt->show_values, pt->show_variables);
       table_item_set_title (ti, title);
-      table_item_text_destroy (title);
+      table_cell_destroy (title);
     }
 
   const struct pivot_axis *layer_axis = &pt->axes[PIVOT_AXIS_LAYER];
@@ -589,11 +640,11 @@ pivot_table_submit_layer (const struct pivot_table *pt,
 
   if (pt->caption && pt->show_caption)
     {
-      struct table_item_text *caption = pivot_value_to_table_item_text (
-        pt->caption, &pt->look->areas[PIVOT_AREA_CAPTION], footnotes,
-        pt->show_values, pt->show_variables);
+      struct table_cell *caption = pivot_value_to_table_cell (
+        pt->caption, &pt->look->areas[PIVOT_AREA_CAPTION], PIVOT_AREA_CAPTION,
+        footnotes, pt->show_values, pt->show_variables);
       table_item_set_caption (ti, caption);
-      table_item_text_destroy (caption);
+      table_cell_destroy (caption);
     }
 
   free (footnotes);