+/* Renders the vertical rule at the given column and row
+ at (X,Y) on the page. */
+static void
+render_vert_rule (int x, int y, int c, int r)
+{
+ enum outp_line_style style = rule_to_draw_type (get_vrule (c, r));
+ if (style != OUTP_L_NONE)
+ d->class->line (d, x, y, x + t->wrv[c], y + t->h[r],
+ style, OUTP_L_NONE, style, OUTP_L_NONE);
+}
+
+/* Renders the rule intersection at the given column and row
+ at (X,Y) on the page. */
+static void
+render_rule_intersection (int x, int y, int c, int r)
+{
+ /* Bounds of intersection. */
+ int x0 = x;
+ int y0 = y;
+ int x1 = x + t->wrv[c];
+ int y1 = y + t->hrh[r];
+
+ /* Lines on each side of intersection. */
+ int top = r > 0 ? get_vrule (c, r - 1) : TAL_0;
+ int left = c > 0 ? get_hrule (c - 1, r) : TAL_0;
+ int bottom = r < t->nr ? get_vrule (c, r) : TAL_0;
+ int right = c < t->nc ? get_hrule (c, r) : TAL_0;
+
+ /* Output style for each line. */
+ enum outp_line_style o_top = rule_to_draw_type (top);
+ enum outp_line_style o_left = rule_to_draw_type (left);
+ enum outp_line_style o_bottom = rule_to_draw_type (bottom);
+ enum outp_line_style o_right = rule_to_draw_type (right);
+
+ if (o_top != OUTP_L_NONE || o_left != OUTP_L_NONE
+ || o_bottom != OUTP_L_NONE || o_right != OUTP_L_NONE)
+ d->class->line (d, x0, y0, x1, y1, o_top, o_left, o_bottom, o_right);
+}
+
+/* Returns the width of columns C1...C2 exclusive,
+ including interior but not exterior rules. */
+static int
+strip_width (int c1, int c2)
+{
+ int width = 0;
+ int c;
+
+ for (c = c1; c < c2; c++)
+ width += t->w[c] + t->wrv[c + 1];
+ if (c1 < c2)
+ width -= t->wrv[c2];
+ return width;
+}
+
+/* Returns the height of rows R1...R2 exclusive,
+ including interior but not exterior rules. */
+static int
+strip_height (int r1, int r2)
+{
+ int height = 0;
+ int r;
+
+ for (r = r1; r < r2; r++)
+ height += t->h[r] + t->hrh[r + 1];
+ if (r1 < r2)
+ height -= t->hrh[r2];
+ return height;
+}
+
+/* Renders the cell at the given column and row at (X,Y) on the
+ page. Also renders joined cells that extend as far to the
+ right as C1 and as far down as R1. */
+static void
+render_cell (int x, int y, int c, int r, int c1, int r1)
+{
+ const int index = c + (r * t->cf);
+ unsigned char type = t->ct[index];
+ struct substring *content = &t->cc[index];
+
+ if (!(type & TAB_JOIN))
+ {
+ if (!(type & TAB_EMPTY))
+ {
+ struct outp_text text;
+ text.font = options_to_font (type);
+ text.justification = translate_justification (type);
+ text.string = *content;
+ text.h = t->w[c];
+ text.v = t->h[r];
+ text.x = x;
+ text.y = y;
+ d->class->text_draw (d, &text);
+ }
+ }
+ else