a->chart_cnt = 0;
a->object_cnt = 0;
- a->params.draw_line = ascii_draw_line;
- a->params.measure_cell_width = ascii_measure_cell_width;
- a->params.measure_cell_height = ascii_measure_cell_height;
- a->params.adjust_break = NULL;
- a->params.draw_cell = ascii_draw_cell;
+ static const struct render_ops ascii_render_ops = {
+ .draw_line = ascii_draw_line,
+ .measure_cell_width = ascii_measure_cell_width,
+ .measure_cell_height = ascii_measure_cell_height,
+ .adjust_break = NULL,
+ .draw_cell = ascii_draw_cell,
+ };
+ a->params.ops = &ascii_render_ops;
a->params.aux = a;
a->params.size[H] = a->width;
a->params.size[V] = INT_MAX;
a->params.font_size[H] = 1;
a->params.font_size[V] = 1;
- for (int i = 0; i < RENDER_N_LINES; i++)
- {
- int width = i == RENDER_LINE_NONE ? 0 : 1;
- a->params.line_widths[H][i] = width;
- a->params.line_widths[V][i] = width;
- }
+
+ static const int ascii_line_widths[RENDER_N_LINES] = {
+ [RENDER_LINE_NONE] = 0,
+ [RENDER_LINE_SINGLE] = 1,
+ [RENDER_LINE_DASHED] = 1,
+ [RENDER_LINE_THICK] = 1,
+ [RENDER_LINE_THIN] = 1,
+ [RENDER_LINE_DOUBLE] = 1,
+ };
+ a->params.line_widths = ascii_line_widths;
a->params.supports_margins = false;
a->params.rtl = render_direction_rtl ();
if (xr->params == NULL)
{
+ static const struct render_ops xr_render_ops = {
+ .draw_line = xr_draw_line,
+ .measure_cell_width = xr_measure_cell_width,
+ .measure_cell_height = xr_measure_cell_height,
+ .adjust_break = xr_adjust_break,
+ .draw_cell = xr_draw_cell,
+ };
+
xr->params = xmalloc (sizeof *xr->params);
- xr->params->draw_line = xr_draw_line;
- xr->params->measure_cell_width = xr_measure_cell_width;
- xr->params->measure_cell_height = xr_measure_cell_height;
- xr->params->adjust_break = xr_adjust_break;
- xr->params->draw_cell = xr_draw_cell;
+ xr->params->ops = &xr_render_ops;
xr->params->aux = xr;
xr->params->size[H] = xr->width;
xr->params->size[V] = xr->length;
xr->params->font_size[H] = xr->char_width;
xr->params->font_size[V] = xr->char_height;
- int lw = XR_LINE_WIDTH;
- int ls = XR_LINE_SPACE;
- for (int i = 0; i < TABLE_N_AXES; i++)
+ enum { LW = XR_LINE_WIDTH, LS = XR_LINE_SPACE };
+ static const int xr_line_widths[RENDER_N_LINES] =
{
- xr->params->line_widths[i][RENDER_LINE_NONE] = 0;
- xr->params->line_widths[i][RENDER_LINE_SINGLE] = lw;
- xr->params->line_widths[i][RENDER_LINE_DASHED] = lw;
- xr->params->line_widths[i][RENDER_LINE_THICK] = lw * 2;
- xr->params->line_widths[i][RENDER_LINE_THIN] = lw / 2;
- xr->params->line_widths[i][RENDER_LINE_DOUBLE] = 2 * lw + ls;
- }
+ [RENDER_LINE_NONE] = 0,
+ [RENDER_LINE_SINGLE] = LW,
+ [RENDER_LINE_DASHED] = LW,
+ [RENDER_LINE_THICK] = LW * 2,
+ [RENDER_LINE_THIN] = LW / 2,
+ [RENDER_LINE_DOUBLE] = 2 * LW + LS,
+ };
+ xr->params->line_widths = xr_line_widths;
for (int i = 0; i < TABLE_N_AXES; i++)
xr->params->min_break[i] = xr->min_break[i];
int width = 0;
for (size_t i = 0; i < TABLE_N_STROKES; i++)
if (rules & (1u << i))
- width = MAX (width, params->line_widths[a][rule_to_render_type (i)]);
+ width = MAX (width, params->line_widths[rule_to_render_type (i)]);
return width;
}
if (table_cell_colspan (&cell) == 1)
{
int w[2];
- params->measure_cell_width (params->aux, &cell,
- &w[MIN], &w[MAX]);
+ params->ops->measure_cell_width (params->aux, &cell,
+ &w[MIN], &w[MAX]);
for (int i = 0; i < 2; i++)
if (columns[i][x].unspanned < w[i])
columns[i][x].unspanned = w[i];
{
int w[2];
- params->measure_cell_width (params->aux, &cell, &w[MIN], &w[MAX]);
+ params->ops->measure_cell_width (params->aux, &cell,
+ &w[MIN], &w[MAX]);
for (int i = 0; i < 2; i++)
distribute_spanned_width (w[i], &columns[i][cell.d[H][0]],
rules[H], table_cell_colspan (&cell));
if (table_cell_rowspan (&cell) == 1)
{
int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
- int h = params->measure_cell_height (params->aux, &cell, w);
+ int h = params->ops->measure_cell_height (params->aux,
+ &cell, w);
if (h > r->unspanned)
r->unspanned = r->width = h;
}
if (y == cell.d[V][0] && table_cell_rowspan (&cell) > 1)
{
int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
- int h = params->measure_cell_height (params->aux, &cell, w);
+ int h = params->ops->measure_cell_height (params->aux, &cell, w);
distribute_spanned_width (h, &rows[cell.d[V][0]], rules[V],
table_cell_rowspan (&cell));
}
}
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, colors);
+ page->params->ops->draw_line (page->params->aux, bb, styles, colors);
}
}
int valign_offset = 0;
if (valign != TABLE_VALIGN_TOP)
{
- int height = page->params->measure_cell_height (
+ int height = page->params->ops->measure_cell_height (
page->params->aux, cell, bb[H][1] - bb[H][0]);
int extra = bb[V][1] - bb[V][0] - height;
if (extra > 0)
|| page->n[V] - (cell->d[V][0] + 1) < page->h[V][1]
? 0
: (cell->d[V][0] - page->h[V][0]) & 1);
- page->params->draw_cell (page->params->aux, cell, color_idx,
- bb, valign_offset, spill, clip);
+ page->params->ops->draw_cell (page->params->aux, cell, color_idx,
+ bb, valign_offset, spill, clip);
}
/* Draws the cells of PAGE indicated in BB. */
being broken have a better internal breakpoint than the exact
number of pixels available, which might look bad e.g. because
it breaks in the middle of a line of text. */
- if (axis == TABLE_VERT && page->params->adjust_break)
+ if (axis == TABLE_VERT && page->params->ops->adjust_break)
for (int x = 0; x < page->n[H];)
{
struct table_cell cell;
render_get_cell (page, x, z, &cell);
int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
- int better_pixel = page->params->adjust_break (
+ int better_pixel = page->params->ops->adjust_break (
page->params->aux, &cell, w, pixel);
x = cell.d[H][1];
corner at (0,0) in device coordinates. This is usually not the case from
the driver's perspective, so the driver should expect to apply its own
offset to coordinates passed to callback functions.
+*/
+struct render_params
+ {
+ /* Functional parameters and auxiliary data to pass to them. */
+ const struct render_ops *ops;
+ void *aux;
+ /* Page size to try to fit the rendering into. Some tables will, of
+ course, overflow this size. */
+ int size[TABLE_N_AXES];
- Callback functions
- ==================
+ /* Nominal size of a character in the most common font:
+ font_size[TABLE_HORZ]: Em width.
+ font_size[TABLE_VERT]: Line spacing. */
+ int font_size[TABLE_N_AXES];
- For each of the callback functions, AUX is passed as the 'aux' member of the
- render_params structure.
-*/
-struct render_params
+ /* Width of different kinds of lines. */
+ const int *line_widths; /* RENDER_N_LINES members. */
+
+ /* Minimum cell width or height before allowing the cell to be broken
+ across two pages. (Joined cells may always be broken at join
+ points.) */
+ int min_break[TABLE_N_AXES];
+
+ /* True if the driver supports cell margins. (If false, the rendering
+ engine will insert a small space betweeen adjacent cells that don't have
+ an intervening rule.) */
+ bool supports_margins;
+
+ /* True if the local language has a right-to-left direction, otherwise
+ false. (Use render_direction_rtl() to find out.) */
+ bool rtl;
+ };
+
+struct render_ops
{
/* Measures CELL's width. Stores in *MIN_WIDTH the minimum width required
to avoid splitting a single word across multiple lines (normally, this
int bb[TABLE_N_AXES][2], int valign_offset,
int spill[TABLE_N_AXES][2],
int clip[TABLE_N_AXES][2]);
-
- /* Auxiliary data passed to each of the above functions. */
- void *aux;
-
- /* Page size to try to fit the rendering into. Some tables will, of
- course, overflow this size. */
- int size[TABLE_N_AXES];
-
- /* Nominal size of a character in the most common font:
- font_size[TABLE_HORZ]: Em width.
- font_size[TABLE_VERT]: Line spacing. */
- int font_size[TABLE_N_AXES];
-
- /* Width of different kinds of lines. */
- int line_widths[TABLE_N_AXES][RENDER_N_LINES];
-
- /* Minimum cell width or height before allowing the cell to be broken
- across two pages. (Joined cells may always be broken at join
- points.) */
- int min_break[TABLE_N_AXES];
-
- /* True if the driver supports cell margins. (If false, the rendering
- engine will insert a small space betweeen adjacent cells that don't have
- an intervening rule.) */
- bool supports_margins;
-
- /* True if the local language has a right-to-left direction, otherwise
- false. (Use render_direction_rtl() to find out.) */
- bool rtl;
};
/* An iterator for breaking render_pages into smaller chunks. */