output: Add support for colors for rules.
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 21 Nov 2018 17:32:23 +0000 (09:32 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 25 Dec 2018 20:36:08 +0000 (12:36 -0800)
14 files changed:
src/output/ascii.c
src/output/cairo.c
src/output/html.c
src/output/render.c
src/output/render.h
src/output/tab.c
src/output/tab.h
src/output/table-casereader.c
src/output/table-paste.c
src/output/table-provider.h
src/output/table-select.c
src/output/table-stomp.c
src/output/table-transpose.c
src/output/table.c

index 72c628871c2317950cb3a9ac0a21bad69afd04d3..c2c5dd54fd55863dd6580e7bfabb07ff8442c3b8 100644 (file)
@@ -214,7 +214,8 @@ static int parse_page_size (struct driver_option *);
 static bool ascii_open_page (struct ascii_driver *);
 
 static void ascii_draw_line (void *, int bb[TABLE_N_AXES][2],
-                             enum render_line_style styles[TABLE_N_AXES][2]);
+                             enum render_line_style styles[TABLE_N_AXES][2],
+                             struct cell_color colors[TABLE_N_AXES][2]);
 static void ascii_measure_cell_width (void *, const struct table_cell *,
                                       int *min, int *max);
 static int ascii_measure_cell_height (void *, const struct table_cell *,
@@ -533,7 +534,8 @@ static void ascii_layout_cell (struct ascii_driver *,
 
 static void
 ascii_draw_line (void *a_, int bb[TABLE_N_AXES][2],
-                 enum render_line_style styles[TABLE_N_AXES][2])
+                 enum render_line_style styles[TABLE_N_AXES][2],
+                 struct cell_color colors[TABLE_N_AXES][2] UNUSED)
 {
   struct ascii_driver *a = a_;
   char mbchar[6];
index b3ab780ba68e4a53cc68d7d03cb6e6ca32e73ff2..49d8f0bc885a684d426e15236cb3794d94f1d1f1 100644 (file)
@@ -166,7 +166,8 @@ static void xr_driver_destroy_fsm (struct xr_driver *);
 static void xr_driver_run_fsm (struct xr_driver *);
 
 static void xr_draw_line (void *, int bb[TABLE_N_AXES][2],
-                          enum render_line_style styles[TABLE_N_AXES][2]);
+                          enum render_line_style styles[TABLE_N_AXES][2],
+                          struct cell_color colors[TABLE_N_AXES][2]);
 static void xr_measure_cell_width (void *, const struct table_cell *,
                                    int *min, int *max);
 static int xr_measure_cell_height (void *, const struct table_cell *,
@@ -658,9 +659,12 @@ xr_layout_cell (struct xr_driver *, const struct table_cell *,
                 int *width, int *height, int *brk);
 
 static void
-dump_line (struct xr_driver *xr, int x0, int y0, int x1, int y1, int style)
+dump_line (struct xr_driver *xr, int x0, int y0, int x1, int y1, int style,
+           const struct cell_color *color)
 {
   cairo_new_path (xr->cairo);
+  cairo_set_source_rgb (xr->cairo,
+                        color->r / 255.0, color->g / 255.0, color->b / 255.0);
   cairo_set_line_width (
     xr->cairo,
     xr_to_pt (style == RENDER_LINE_THICK ? xr->line_width * 2
@@ -702,16 +706,19 @@ fill_rectangle (struct xr_driver *xr, int x0, int y0, int x1, int y1)
 static void
 horz_line (struct xr_driver *xr, int x0, int x1, int x2, int x3, int y,
            enum render_line_style left, enum render_line_style right,
+           const struct cell_color *left_color,
+           const struct cell_color *right_color,
            bool shorten)
 {
-  if (left != RENDER_LINE_NONE && right != RENDER_LINE_NONE && !shorten)
-    dump_line (xr, x0, y, x3, y, left);
+  if (left != RENDER_LINE_NONE && right != RENDER_LINE_NONE && !shorten
+      && cell_color_equal (left_color, right_color))
+    dump_line (xr, x0, y, x3, y, left, left_color);
   else
     {
       if (left != RENDER_LINE_NONE)
-        dump_line (xr, x0, y, shorten ? x1 : x2, y, left);
+        dump_line (xr, x0, y, shorten ? x1 : x2, y, left, left_color);
       if (right != RENDER_LINE_NONE)
-        dump_line (xr, shorten ? x2 : x1, y, x3, y, right);
+        dump_line (xr, shorten ? x2 : x1, y, x3, y, right, right_color);
     }
 }
 
@@ -722,22 +729,26 @@ horz_line (struct xr_driver *xr, int x0, int x1, int x2, int x3, int y,
 static void
 vert_line (struct xr_driver *xr, int y0, int y1, int y2, int y3, int x,
            enum render_line_style top, enum render_line_style bottom,
+           const struct cell_color *top_color,
+           const struct cell_color *bottom_color,
            bool shorten)
 {
-  if (top != RENDER_LINE_NONE && bottom != RENDER_LINE_NONE && !shorten)
-    dump_line (xr, x, y0, x, y3, top);
+  if (top != RENDER_LINE_NONE && bottom != RENDER_LINE_NONE && !shorten
+      && cell_color_equal (top_color, bottom_color))
+    dump_line (xr, x, y0, x, y3, top, top_color);
   else
     {
       if (top != RENDER_LINE_NONE)
-        dump_line (xr, x, y0, x, shorten ? y1 : y2, top);
+        dump_line (xr, x, y0, x, shorten ? y1 : y2, top, top_color);
       if (bottom != RENDER_LINE_NONE)
-        dump_line (xr, x, shorten ? y2 : y1, x, y3, bottom);
+        dump_line (xr, x, shorten ? y2 : y1, x, y3, bottom, bottom_color);
     }
 }
 
 static void
 xr_draw_line (void *xr_, int bb[TABLE_N_AXES][2],
-              enum render_line_style styles[TABLE_N_AXES][2])
+              enum render_line_style styles[TABLE_N_AXES][2],
+              struct cell_color colors[TABLE_N_AXES][2])
 {
   const int x0 = bb[H][0];
   const int y0 = bb[V][0];
@@ -745,8 +756,15 @@ xr_draw_line (void *xr_, int bb[TABLE_N_AXES][2],
   const int y3 = bb[V][1];
   const int top = styles[H][0];
   const int bottom = styles[H][1];
-  const int start_of_line = render_direction_rtl() ? styles[V][1]: styles[V][0];
-  const int end_of_line   = render_direction_rtl() ? styles[V][0]: styles[V][1];
+
+  int start_side = render_direction_rtl();
+  int end_side = !start_side;
+  const int start_of_line = styles[V][start_side];
+  const int end_of_line   = styles[V][end_side];
+  const struct cell_color *top_color = &colors[H][0];
+  const struct cell_color *bottom_color = &colors[H][1];
+  const struct cell_color *start_color = &colors[V][start_side];
+  const struct cell_color *end_color = &colors[V][end_side];
 
   /* The algorithm here is somewhat subtle, to allow it to handle
      all the kinds of intersections that we need.
@@ -830,19 +848,25 @@ xr_draw_line (void *xr_, int bb[TABLE_N_AXES][2],
   int y2 = yc + vert_line_ofs;
 
   if (!double_horz)
-    horz_line (xr, x0, x1, x2, x3, yc, start_of_line, end_of_line, shorten_yc_line);
+    horz_line (xr, x0, x1, x2, x3, yc, start_of_line, end_of_line,
+               start_color, end_color, shorten_yc_line);
   else
     {
-      horz_line (xr, x0, x1, x2, x3, y1, start_of_line, end_of_line, shorten_y1_lines);
-      horz_line (xr, x0, x1, x2, x3, y2, start_of_line, end_of_line, shorten_y2_lines);
+      horz_line (xr, x0, x1, x2, x3, y1, start_of_line, end_of_line,
+                 start_color, end_color, shorten_y1_lines);
+      horz_line (xr, x0, x1, x2, x3, y2, start_of_line, end_of_line,
+                 start_color, end_color, shorten_y2_lines);
     }
 
   if (!double_vert)
-    vert_line (xr, y0, y1, y2, y3, xc, top, bottom, shorten_xc_line);
+    vert_line (xr, y0, y1, y2, y3, xc, top, bottom, top_color, bottom_color,
+               shorten_xc_line);
   else
     {
-      vert_line (xr, y0, y1, y2, y3, x1, top, bottom, shorten_x1_lines);
-      vert_line (xr, y0, y1, y2, y3, x2, top, bottom, shorten_x2_lines);
+      vert_line (xr, y0, y1, y2, y3, x1, top, bottom, top_color, bottom_color,
+                 shorten_x1_lines);
+      vert_line (xr, y0, y1, y2, y3, x2, top, bottom, top_color, bottom_color,
+                 shorten_x2_lines);
     }
 }
 
@@ -1172,14 +1196,9 @@ xr_layout_cell_text (struct xr_driver *xr,
       if (0)
         {
           if (best && !xr->nest)
-            {
-              cairo_save (xr->cairo);
-              cairo_set_source_rgb (xr->cairo, 0, 1, 0);
-              dump_line (xr, -xr->left_margin, best,
-                         xr->width + xr->right_margin, best,
-                         RENDER_LINE_SINGLE);
-              cairo_restore (xr->cairo);
-            }
+            dump_line (xr, -xr->left_margin, best,
+                       xr->width + xr->right_margin, best,
+                       RENDER_LINE_SINGLE, &CELL_COLOR (0, 255, 0));
         }
     }
 
index f9d45736ef0fe866537e97a9a068b5664acd68aa..7cc2fecab7d2704b3acfed8d00cf20ac939aadb0 100644 (file)
@@ -540,21 +540,24 @@ html_output_table (struct html_driver *html, const struct table_item *item)
              /* Cell borders. */
              int n_borders = 0;
 
-             top = table_get_rule (t, TABLE_VERT, x, y);
+              struct cell_color color;
+             top = table_get_rule (t, TABLE_VERT, x, y, &color);
               put_border (html->file, &n_borders, top, "top");
 
              if (y + rowspan == table_nr (t))
                {
-                 bottom = table_get_rule (t, TABLE_VERT, x, y + rowspan);
+                 bottom = table_get_rule (t, TABLE_VERT, x, y + rowspan,
+                                           &color);
                   put_border (html->file, &n_borders, bottom, "bottom");
                }
 
-             left = table_get_rule (t, TABLE_HORZ, x, y);
+             left = table_get_rule (t, TABLE_HORZ, x, y, &color);
               put_border (html->file, &n_borders, left, "left");
 
              if (x + colspan == table_nc (t))
                {
-                 right = table_get_rule (t, TABLE_HORZ, x + colspan, y);
+                 right = table_get_rule (t, TABLE_HORZ, x + colspan, y,
+                                          &color);
                   put_border (html->file, &n_borders, right, "right");
                }
 
index 418193b87ef9bc8446318ffe898267c3eccc3f55..c3a59a6c429c01aa97ec7489a48cb543c7d5d0ce 100644 (file)
@@ -488,10 +488,11 @@ measure_rule (const struct render_params *params, const struct table *table,
 
   /* 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. */
+  struct cell_color color;
   rules = 0;
   d[a] = z;
   for (d[b] = 0; d[b] < table->n[b]; d[b]++)
-    rules |= 1u << table_get_rule (table, a, d[H], d[V]);
+    rules |= 1u << table_get_rule (table, a, d[H], d[V], &color);
 
   /* Turn off TAL_NONE because it has width 0 and we needn't bother.  However,
      if the device doesn't support margins, make sure that there is at least a
@@ -870,10 +871,11 @@ render_page_get_best_breakpoint (const struct render_page *page, int height)
 
 static inline enum render_line_style
 get_rule (const struct render_page *page, enum table_axis axis,
-          const int d[TABLE_N_AXES])
+          const int d[TABLE_N_AXES], struct cell_color *color)
 {
   return rule_to_render_type (table_get_rule (page->table,
-                                              axis, d[H] / 2, d[V] / 2));
+                                              axis, d[H] / 2, d[V] / 2,
+                                              color));
 }
 
 static bool
@@ -904,6 +906,7 @@ render_rule (const struct render_page *page, const int ofs[TABLE_N_AXES],
              const int d[TABLE_N_AXES])
 {
   enum render_line_style styles[TABLE_N_AXES][2];
+  struct cell_color colors[TABLE_N_AXES][2];
   enum table_axis a;
 
   for (a = 0; a < TABLE_N_AXES; a++)
@@ -925,14 +928,17 @@ render_rule (const struct render_page *page, const int ofs[TABLE_N_AXES],
               e[H] = d[H];
               e[V] = d[V];
               e[b]--;
-              styles[a][0] = get_rule (page, a, e);
+              styles[a][0] = get_rule (page, a, e, &colors[a][0]);
             }
 
           if (d[b] / 2 < page->table->n[b])
-            styles[a][1] = get_rule (page, a, d);
+            styles[a][1] = get_rule (page, a, d, &colors[a][1]);
         }
       else
-        styles[a][0] = styles[a][1] = get_rule (page, a, d);
+        {
+          styles[a][0] = styles[a][1] = get_rule (page, a, d, &colors[a][0]);
+          colors[a][1] = colors[a][0];
+        }
     }
 
   if (styles[H][0] != RENDER_LINE_NONE || styles[H][1] != RENDER_LINE_NONE
@@ -950,7 +956,7 @@ render_rule (const struct render_page *page, const int ofs[TABLE_N_AXES],
        }
       bb[V][0] = ofs[V] + page->cp[V][d[V]];
       bb[V][1] = ofs[V] + page->cp[V][d[V] + 1];
-      page->params->draw_line (page->params->aux, bb, styles);
+      page->params->draw_line (page->params->aux, bb, styles, colors);
     }
 }
 
index f04eb79005df1b8a5ffc0a66d6b5d2b2b2b95f7d..cceea9e72323a95edbef1083ecf2da07740cc844 100644 (file)
@@ -93,7 +93,8 @@ struct render_params
        STYLES[TABLE_VERT][0]: style of line from left of BB to its center.
        STYLES[TABLE_VERT][1]: style of line from right of BB to its center. */
     void (*draw_line) (void *aux, int bb[TABLE_N_AXES][2],
-                       enum render_line_style styles[TABLE_N_AXES][2]);
+                       enum render_line_style styles[TABLE_N_AXES][2],
+                       struct cell_color colors[TABLE_N_AXES][2]);
 
     /* Draws CELL within bounding box BB.  CLIP is the same as BB (the common
        case) or a subregion enclosed by BB.  In the latter case only the part
index a158b22979e1cb79b9ec3f2dc2bd57e325ef42e9..23fccd6f9c035d9f29d755f3024c6e412df80eb4 100644 (file)
@@ -106,6 +106,7 @@ tab_create (int nc, int nr)
   t->fmtmap[RC_OTHER] = *settings_get_format ();
 
   memset (t->styles, 0, sizeof t->styles);
+  memset (t->rule_colors, 0, sizeof t->rule_colors);
 
   t->col_ofs = t->row_ofs = 0;
 
@@ -833,11 +834,17 @@ tab_get_cell (const struct table *table, int x, int y,
 }
 
 static int
-tab_get_rule (const struct table *table, enum table_axis axis, int x, int y)
+tab_get_rule (const struct table *table, enum table_axis axis, int x, int y,
+              struct cell_color *color)
 {
   const struct tab_table *t = tab_cast (table);
-  return (axis == TABLE_VERT
-          ? t->rh[x + t->cf * y] : t->rv[x + (t->cf + 1) * y]);
+  uint8_t raw = (axis == TABLE_VERT
+                 ? t->rh[x + t->cf * y] : t->rv[x + (t->cf + 1) * y]);
+  struct cell_color *p = t->rule_colors[(raw & TAB_RULE_STYLE_MASK)
+                                        >> TAB_RULE_STYLE_SHIFT];
+  if (p)
+    *color = *p;
+  return (raw & TAB_RULE_TYPE_MASK) >> TAB_RULE_TYPE_SHIFT;
 }
 
 static const struct table_class tab_table_class = {
index 43f0278964fb90e3d6767850e700c31e2f2565ec..178607aa2bf1652d6f7c5c99c7a8d4ac8b525ad4 100644 (file)
@@ -54,6 +54,12 @@ enum result_class
 #define TAB_STYLE_MASK (7u << (TAB_FIRST_AVAILABLE + 3))
 #define TAB_STYLE_SHIFT (TAB_FIRST_AVAILABLE + 3)
 
+/* Rule masks. */
+#define TAB_RULE_TYPE_MASK   7
+#define TAB_RULE_TYPE_SHIFT  0
+#define TAB_RULE_STYLE_MASK  (31 << TAB_RULE_STYLE_SHIFT)
+#define TAB_RULE_STYLE_SHIFT 3
+
 /* A table. */
 struct tab_table
   {
@@ -72,13 +78,12 @@ struct tab_table
        points to a struct tab_joined_cell. */
     void **cc;                  /* Cell contents; void *[nr][nc]. */
     unsigned short *ct;                /* Cell types; unsigned short[nr][nc]. */
+    struct cell_style *styles[8];
 
     /* Rules. */
     unsigned char *rh;         /* Horiz rules; unsigned char[nr+1][nc]. */
     unsigned char *rv;         /* Vert rules; unsigned char[nr][nc+1]. */
-
-    /* Cell styles. */
-    struct cell_style *styles[8];
+    struct cell_color *rule_colors[32];
 
     /* X and Y offsets. */
     int col_ofs, row_ofs;
index 5acb1a928d98aa72e3ffb1ea8bfb1f17a1485d85..ecd85a1df469e21bb3033bc746e760742b811807 100644 (file)
@@ -142,7 +142,8 @@ table_casereader_get_cell (const struct table *t, int x, int y,
 
 static int
 table_casereader_get_rule (const struct table *t, enum table_axis axis,
-                           int x UNUSED, int y)
+                           int x UNUSED, int y,
+                           struct cell_color *color UNUSED)
 {
   struct table_casereader *tc = table_casereader_cast (t);
   if (axis == TABLE_VERT)
index c1054d1369baf1e5c05915edd8221004206c8ec9..05c8987ce6f891a0a888d582339bb2ff49aa9137 100644 (file)
@@ -227,7 +227,8 @@ table_paste_get_cell (const struct table *t, int x, int y,
 
 static int
 table_paste_get_rule (const struct table *t,
-                      enum table_axis axis, int x, int y)
+                      enum table_axis axis, int x, int y,
+                      struct cell_color *color)
 {
   struct table_paste *tp = table_paste_cast (t);
   int h = tp->orientation == TABLE_HORZ ? x : y;
@@ -241,9 +242,9 @@ table_paste_get_rule (const struct table *t,
 
       ps = paste_subtable_lookup (tp, h == 0 ? 0 : h - 1, &start);
       if (tp->orientation == TABLE_HORZ) /* XXX */
-        r = table_get_rule (ps->table, axis, h - start, k);
+        r = table_get_rule (ps->table, axis, h - start, k, color);
       else
-        r = table_get_rule (ps->table, axis, k, h - start);
+        r = table_get_rule (ps->table, axis, k, h - start, color);
       if (h == start + tower_node_get_size (&ps->node))
         {
           struct tower_node *ps2_ = tower_next (&tp->subtables, &ps->node);
@@ -253,9 +254,9 @@ table_paste_get_rule (const struct table *t,
               int r2;
 
               if (tp->orientation == TABLE_HORZ) /* XXX */
-                r2 = table_get_rule (ps2->table, axis, 0, k);
+                r2 = table_get_rule (ps2->table, axis, 0, k, color);
               else
-                r2 = table_get_rule (ps2->table, axis, k, 0);
+                r2 = table_get_rule (ps2->table, axis, k, 0, color);
               return table_rule_combine (r, r2);
             }
         }
@@ -265,9 +266,9 @@ table_paste_get_rule (const struct table *t,
     {
       ps = paste_subtable_lookup (tp, h, &start);
       if (tp->orientation == TABLE_HORZ) /* XXX */
-        return table_get_rule (ps->table, axis, h - start, k);
+        return table_get_rule (ps->table, axis, h - start, k, color);
       else
-        return table_get_rule (ps->table, axis, k, h - start);
+        return table_get_rule (ps->table, axis, k, h - start, color);
     }
 }
 
index ae7f77d420b40cf7fa364cf2c87431f0c119c7cd..d875462c9c237b7c00f3f8f3e88b32666da55a17 100644 (file)
@@ -192,7 +192,8 @@ struct table_class
        See table_get_rule() in table.c for a detailed explanation of the
        meaning of AXIS and X and Y, including a diagram. */
     int (*get_rule) (const struct table *table,
-                     enum table_axis axis, int x, int y);
+                     enum table_axis axis, int x, int y,
+                     struct cell_color *color);
 
     /* This function is optional and most table classes will not implement it.
 
@@ -248,7 +249,8 @@ void table_set_nr (struct table *, int nr);
 /* For use primarily by output drivers. */
 
 void table_get_cell (const struct table *, int x, int y, struct table_cell *);
-int table_get_rule (const struct table *, enum table_axis, int x, int y);
+int table_get_rule (const struct table *, enum table_axis, int x, int y,
+                    struct cell_color *);
 size_t table_collect_footnotes (const struct table_item *,
                                 const struct footnote ***);
 
index 5bbc8caa1eb948bec775c2d27ff652696356487f..b7e431a28feaec9f00eb942bcd71eec0d8e57a4a 100644 (file)
@@ -194,12 +194,12 @@ table_select_get_cell (const struct table *ti, int x, int y,
 static int
 table_select_get_rule (const struct table *ti,
                        enum table_axis axis,
-                       int x, int y)
+                       int x, int y, struct cell_color *color)
 {
   struct table_select *ts = table_select_cast (ti);
   return table_get_rule (ts->subtable, axis,
                          x + ts->ofs[TABLE_HORZ],
-                         y + ts->ofs[TABLE_VERT]);
+                         y + ts->ofs[TABLE_VERT], color);
 }
 
 static struct table *
index e9df26a95f6bfcf28593a2df30d1d7c9e97b9493..075a2d2ba21de07d634ae8043e34805645a26a7a 100644 (file)
@@ -146,12 +146,14 @@ table_stomp_get_cell (const struct table *t, int x, int y UNUSED,
 
 static int
 table_stomp_get_rule (const struct table *t,
-                      enum table_axis axis, int x, int y)
+                      enum table_axis axis, int x, int y,
+                      struct cell_color *color)
 {
   struct table_stomp *ts = table_stomp_cast (t);
 
   return table_get_rule (ts->subtable, axis, x,
-                         axis == H || y == 0 ? y : ts->subtable->n[V]);
+                         axis == H || y == 0 ? y : ts->subtable->n[V],
+                         color);
 }
 
 static const struct table_class table_stomp_class =
index f2db939f5a012246ec9424ec71417e0a462aeebf..aa617b3aaa94ea221f1f21f262992a210fb819fd 100644 (file)
@@ -103,10 +103,10 @@ table_transpose_get_cell (const struct table *ti, int x, int y,
 static int
 table_transpose_get_rule (const struct table *ti,
                           enum table_axis axis,
-                          int x, int y)
+                          int x, int y, struct cell_color *color)
 {
   struct table_transpose *tt = table_transpose_cast (ti);
-  return table_get_rule (tt->subtable, !axis, y, x);
+  return table_get_rule (tt->subtable, !axis, y, x, color);
 }
 
 static const struct table_class table_transpose_class =
index 3fccde9c9833e5542974b5d1c8dec609167e8120..44efa3abc34f1fc379356598742212dca7ed6b10 100644 (file)
@@ -214,11 +214,13 @@ table_cell_free (struct table_cell *cell)
    between that cell and cell (0,1); and so on, up to (0,NR), which runs
    horizontally below cell (0,NR-1). */
 int
-table_get_rule (const struct table *table, enum table_axis axis, int x, int y)
+table_get_rule (const struct table *table, enum table_axis axis, int x, int y,
+                struct cell_color *color)
 {
   assert (x >= 0 && x < table->n[TABLE_HORZ] + (axis == TABLE_HORZ));
   assert (y >= 0 && y < table->n[TABLE_VERT] + (axis == TABLE_VERT));
-  return table->klass->get_rule (table, axis, x, y);
+  *color = CELL_COLOR_BLACK;
+  return table->klass->get_rule (table, axis, x, y, color);
 }
 
 void
@@ -355,10 +357,11 @@ table_unshared_get_cell (const struct table *tiu_, int x, int y,
 
 static int
 table_unshared_get_rule (const struct table *tiu_,
-                              enum table_axis axis, int x, int y)
+                         enum table_axis axis, int x, int y,
+                         struct cell_color *color)
 {
   struct table_unshared *tiu = table_unshared_cast (tiu_);
-  return table_get_rule (tiu->subtable, axis, x, y);
+  return table_get_rule (tiu->subtable, axis, x, y, color);
 }
 
 static const struct table_class table_unshared_class =
@@ -427,7 +430,8 @@ table_string_get_cell (const struct table *ts_, int x UNUSED, int y UNUSED,
 
 static int
 table_string_get_rule (const struct table *ts UNUSED,
-                       enum table_axis axis UNUSED, int x UNUSED, int y UNUSED)
+                       enum table_axis axis UNUSED, int x UNUSED, int y UNUSED,
+                       struct cell_color *color UNUSED)
 {
   return TAL_0;
 }