output: Add support for cell margins.
[pspp] / src / output / render.c
index 60cda45b16bb4c44a2442671f06a3f301e738127..d30818a355bd8fe77150b6fc72d90d74d33aa7e8 100644 (file)
@@ -458,11 +458,17 @@ rule_to_render_type (unsigned char type)
 {
   switch (type)
     {
-    case TAL_0:
+    case TAL_NONE:
       return RENDER_LINE_NONE;
-    case TAL_1:
+    case TAL_SOLID:
       return RENDER_LINE_SINGLE;
-    case TAL_2:
+    case TAL_DASHED:
+      return RENDER_LINE_DASHED;
+    case TAL_THICK:
+      return RENDER_LINE_THICK;
+    case TAL_THIN:
+      return RENDER_LINE_THIN;
+    case TAL_DOUBLE:
       return RENDER_LINE_DOUBLE;
     default:
       NOT_REACHED ();
@@ -478,7 +484,6 @@ measure_rule (const struct render_params *params, const struct table *table,
   enum table_axis b = !a;
   unsigned int rules;
   int d[TABLE_N_AXES];
-  int width;
 
   /* Determine all types of rules that are present, as a bitmap in 'rules'
      where rule type 't' is present if bit 2**t is set. */
@@ -491,20 +496,18 @@ measure_rule (const struct render_params *params, const struct table *table,
      if the device doesn't support margins, make sure that there is at least a
      small gap between cells (but we don't need any at the left or right edge
      of the table). */
-  if (rules & (1u << TAL_0))
+  if (rules & (1u << TAL_NONE))
     {
-      rules &= ~(1u << TAL_0);
+      rules &= ~(1u << TAL_NONE);
       if (z > 0 && z < table->n[a] && !params->supports_margins && a == H)
-        rules |= 1u << TAL_1;
+        rules |= 1u << TAL_SOLID;
     }
 
   /* Calculate maximum width of the rules that are present. */
-  width = 0;
-  if (rules & (1u << TAL_1)
-      || (z > 0 && z < table->n[a] && rules & (1u << TAL_0)))
-    width = params->line_widths[a][RENDER_LINE_SINGLE];
-  if (rules & (1u << TAL_2))
-    width = MAX (width, params->line_widths[a][RENDER_LINE_DOUBLE]);
+  int width = 0;
+  for (size_t i = 0; i < N_LINES; i++)
+    if (rules & (1u << i))
+      width = MAX (width, params->line_widths[a][rule_to_render_type (i)]);
   return width;
 }
 
@@ -1007,7 +1010,14 @@ render_cell (const struct render_page *page, const int ofs[TABLE_N_AXES],
         }
     }
 
-  page->params->draw_cell (page->params->aux, cell, bb, clip);
+  int spill[TABLE_N_AXES][2];
+  for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
+    {
+      spill[axis][0] = rule_width (page, axis, cell->d[axis][0]) / 2;
+      spill[axis][1] = rule_width (page, axis, cell->d[axis][1]) / 2;
+    }
+
+  page->params->draw_cell (page->params->aux, cell, bb, spill, clip);
 }
 
 /* Draws the cells of PAGE indicated in BB. */
@@ -1015,19 +1025,9 @@ static void
 render_page_draw_cells (const struct render_page *page,
                         int ofs[TABLE_N_AXES], int bb[TABLE_N_AXES][2])
 {
-  int x, y;
-
-  for (y = bb[V][0]; y < bb[V][1]; y++)
-    for (x = bb[H][0]; x < bb[H][1]; )
-      if (is_rule (x) || is_rule (y))
-        {
-          int d[TABLE_N_AXES];
-          d[H] = x;
-          d[V] = y;
-          render_rule (page, ofs, d);
-          x++;
-        }
-      else
+  for (int y = bb[V][0]; y < bb[V][1]; y++)
+    for (int x = bb[H][0]; x < bb[H][1]; )
+      if (!is_rule (x) && !is_rule (y))
         {
           struct table_cell cell;
 
@@ -1037,6 +1037,18 @@ render_page_draw_cells (const struct render_page *page,
           x = rule_ofs (cell.d[H][1]);
           table_cell_free (&cell);
         }
+      else
+        x++;
+
+  for (int y = bb[V][0]; y < bb[V][1]; y++)
+    for (int x = bb[H][0]; x < bb[H][1]; x++)
+      if (is_rule (x) || is_rule (y))
+        {
+          int d[TABLE_N_AXES];
+          d[H] = x;
+          d[V] = y;
+          render_rule (page, ofs, d);
+        }
 }
 
 /* Renders PAGE, by calling the 'draw_line' and 'draw_cell' functions from the