- for (c = c1; c < c2; c++)
- {
- if (c & 1)
- {
- const int index = (c / 2) + (r / 2 * t->cf);
-
- if (!(t->ct[index] & TAB_JOIN))
- {
- struct outp_text text;
-
- text.options = ((t->ct[index] & OUTP_T_JUST_MASK)
- | OUTP_T_HORZ | OUTP_T_VERT);
- if ((t->ct[index] & TAB_EMPTY) == 0)
- {
- text.s = t->cc[index];
- assert (!ls_null_p (&text.s));
- text.h = t->w[c / 2];
- text.v = t->h[r / 2];
- text.x = x;
- text.y = y;
- d->class->text_draw (d, &text);
- }
- } else {
- struct tab_joined_cell *j =
- (struct tab_joined_cell *) ls_c_str (&t->cc[index]);
-
- if (j->hit != tab_hit)
- {
- j->hit = tab_hit;
-
- if (j->x1 == c / 2 && j->y1 == r / 2)
- {
- struct outp_text text;
-
- text.options = ((t->ct[index] & OUTP_T_JUST_MASK)
- | OUTP_T_HORZ | OUTP_T_VERT);
- text.s = j->contents;
- text.x = x;
- text.y = y;
-
- {
- int c;
-
- for (c = j->x1, text.h = -t->wrv[j->x2];
- c < j->x2 && c < c2 / 2; c++)
- text.h += t->w[c] + t->wrv[c + 1];
- }
-
- {
- int r;
-
- for (r = j->y1, text.v = -t->hrh[j->y2];
- r < j->y2 && r < r2 / 2; r++)
- text.v += t->h[r] + t->hrh[r + 1];
- }
- d->class->text_draw (d, &text);
- }
- }
- }
- x += t->w[c / 2];
- } else {
- int style = t->rv[(c / 2) + (r / 2 * (t->cf + 1))];
-
- if (style != TAL_0)
- {
- const struct color clr = {0, 0, 0, 0};
- struct rect rct;
-
- rct.x1 = x;
- rct.y1 = y;
- rct.x2 = x + t->wrv[c / 2];
- rct.y2 = y + t->h[r / 2];
- d->class->line_vert (d, &rct, &clr, style);
- }
- x += t->wrv[c / 2];
- }
- }
+/* Renders the rule intersection at the given column and row
+ at (X,Y) on the page. */
+static void
+render_rule_intersection (const struct tab_rendering *r,
+ int x, int y, int col, int row)
+{
+ const struct tab_table *t = r->table;
+
+ /* Bounds of intersection. */
+ int x0 = x;
+ int y0 = y;
+ int x1 = x + r->wrv[col];
+ int y1 = y + r->hrh[row];
+
+ /* Lines on each side of intersection. */
+ int top = row > 0 ? get_vrule (t, col, row - 1) : TAL_0;
+ int left = col > 0 ? get_hrule (t, col - 1, row) : TAL_0;
+ int bottom = row < t->nr ? get_vrule (t, col, row) : TAL_0;
+ int right = col < t->nc ? get_hrule (t, col, row) : 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)
+ r->driver->class->line (r->driver, 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 (const struct tab_rendering *r, int c1, int c2)
+{
+ int width = 0;
+ int c;
+
+ for (c = c1; c < c2; c++)
+ width += r->w[c] + r->wrv[c + 1];
+ if (c1 < c2)
+ width -= r->wrv[c2];
+ return width;
+}
+
+/* Returns the height of rows R1...R2 exclusive,
+ including interior but not exterior rules. */
+static int
+strip_height (const struct tab_rendering *r, int r1, int r2)
+{
+ int height = 0;
+ int row;
+
+ for (row = r1; row < r2; row++)
+ height += r->h[row] + r->hrh[row + 1];
+ if (r1 < r2)
+ height -= r->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 (const struct tab_rendering *r,
+ int x, int y, int col, int row, int c1, int r1)
+{
+ const struct tab_table *t = r->table;
+ const int index = col + (row * 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 = r->w[col];
+ text.v = r->h[row];
+ text.x = x;
+ text.y = y;
+ r->driver->class->text_draw (r->driver, &text);
+ }