static int ascii_measure_cell_height (void *, const struct table_cell *,
                                       int width);
 static void ascii_draw_cell (void *, const struct table_cell *, int color_idx,
-                             int bb[TABLE_N_AXES][2],
+                             int bb[TABLE_N_AXES][2], int valign_offset,
                              int spill[TABLE_N_AXES][2],
                              int clip[TABLE_N_AXES][2]);
 
 
 static void
 ascii_draw_cell (void *a_, const struct table_cell *cell, int color_idx UNUSED,
-                 int bb[TABLE_N_AXES][2],
+                 int bb[TABLE_N_AXES][2], int valign_offset,
                  int spill[TABLE_N_AXES][2] UNUSED,
                  int clip[TABLE_N_AXES][2])
 {
   struct ascii_driver *a = a_;
   int w, h;
 
+  bb[V][0] += valign_offset;
   ascii_layout_cell (a, cell, bb, clip, &w, &h);
 }
 
 
 static int xr_measure_cell_height (void *, const struct table_cell *,
                                    int width);
 static void xr_draw_cell (void *, const struct table_cell *, int color_idx,
-                          int bb[TABLE_N_AXES][2],
+                          int bb[TABLE_N_AXES][2], int valign_offset,
                           int spill[TABLE_N_AXES][2],
                           int clip[TABLE_N_AXES][2]);
 static int xr_adjust_break (void *, const struct table_cell *,
 
 static void
 xr_draw_cell (void *xr_, const struct table_cell *cell, int color_idx,
-              int bb[TABLE_N_AXES][2],
+              int bb[TABLE_N_AXES][2], int valign_offset,
               int spill[TABLE_N_AXES][2],
               int clip[TABLE_N_AXES][2])
 {
   if (!xr->systemcolors)
     set_source_rgba (xr->cairo, &cell->style->font_style.fg[color_idx]);
 
+  bb[V][0] += valign_offset;
+
   for (int axis = 0; axis < TABLE_N_AXES; axis++)
     {
       bb[axis][0] += px_to_xr (cell->style->cell_style.margin[axis][0]);
 
   bb[V][1] = clip[V][1] = ofs[V] + page->cp[V][cell->d[V][1] * 2];
 
   enum table_valign valign = cell->style->cell_style.valign;
+  int valign_offset = 0;
   if (valign != TABLE_VALIGN_TOP)
     {
       int height = page->params->measure_cell_height (
         {
           if (valign == TABLE_VALIGN_CENTER)
             extra /= 2;
-          bb[V][0] += extra;
+          valign_offset += extra;
         }
     }
 
                    ? 0
                    : (cell->d[V][0] - page->h[V][0]) & 1);
   page->params->draw_cell (page->params->aux, cell, color_idx,
-                           bb, spill, clip);
+                           bb, valign_offset, spill, clip);
 }
 
 /* Draws the cells of PAGE indicated in BB. */
 
     /* 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
        of the cell that lies within CLIP should actually be drawn, although BB
-       should used to determine the layout of the cell. */
+       should used to determine the layout of the cell.
+
+       The text in the cell needs to be vertically offset VALIGN_OFFSET units
+       from the top of the bounding box.  This handles vertical alignment with
+       the cell.  (The caller doesn't just reduce the bounding box size because
+       that would prevent the implementation from filling the entire cell with
+       the background color.)  The implementation must handle horizontal
+       alignment itself. */
     void (*draw_cell) (void *aux, const struct table_cell *cell, int color_idx,
-                       int bb[TABLE_N_AXES][2],
+                       int bb[TABLE_N_AXES][2], int valign_offset,
                        int spill[TABLE_N_AXES][2],
                        int clip[TABLE_N_AXES][2]);