Until now, space between cells was implemented by adding some space on the
sides of rules. That worked fine before cells could have colored
backgrounds, but now it means that the backgrounds don't reach all the way
to the rules. Thus, this commit adds configurable margins to the cells
themselves.
int width);
static void ascii_draw_cell (void *, const struct table_cell *,
int bb[TABLE_N_AXES][2],
int width);
static void ascii_draw_cell (void *, const struct table_cell *,
int bb[TABLE_N_AXES][2],
+ int spill[TABLE_N_AXES][2],
int clip[TABLE_N_AXES][2]);
static struct ascii_driver *
int clip[TABLE_N_AXES][2]);
static struct ascii_driver *
static void
ascii_draw_cell (void *a_, const struct table_cell *cell,
static void
ascii_draw_cell (void *a_, const struct table_cell *cell,
- int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2])
+ int bb[TABLE_N_AXES][2],
+ int spill[TABLE_N_AXES][2] UNUSED,
+ int clip[TABLE_N_AXES][2])
{
struct ascii_driver *a = a_;
int w, h;
{
struct ascii_driver *a = a_;
int w, h;
return x / (double) XR_POINT;
}
return x / (double) XR_POINT;
}
+/* Conversion from 1/96" units ("pixels") to Cairo/Pango units. */
+static int
+px_to_xr (int x)
+{
+ return x * (PANGO_SCALE * 72 / 96);
+}
+
/* Output types. */
enum xr_output_type
{
/* Output types. */
enum xr_output_type
{
int top_margin; /* Top margin in inch/(72 * XR_POINT). */
int bottom_margin; /* Bottom margin in inch/(72 * XR_POINT). */
int top_margin; /* Top margin in inch/(72 * XR_POINT). */
int bottom_margin; /* Bottom margin in inch/(72 * XR_POINT). */
- int line_gutter; /* Space around lines. */
int line_space; /* Space between lines. */
int line_width; /* Width of lines. */
int line_space; /* Space between lines. */
int line_width; /* Width of lines. */
int min_break[TABLE_N_AXES]; /* Min cell size to break across pages. */
struct xr_color bg; /* Background color */
int min_break[TABLE_N_AXES]; /* Min cell size to break across pages. */
struct xr_color bg; /* Background color */
int width);
static void xr_draw_cell (void *, const struct table_cell *,
int bb[TABLE_N_AXES][2],
int width);
static void xr_draw_cell (void *, const struct table_cell *,
int bb[TABLE_N_AXES][2],
+ int spill[TABLE_N_AXES][2],
int clip[TABLE_N_AXES][2]);
static int xr_adjust_break (void *, const struct table_cell *,
int width, int height);
int clip[TABLE_N_AXES][2]);
static int xr_adjust_break (void *, const struct table_cell *,
int width, int height);
xr->fonts[XR_FONT_MARKER].desc = parse_font (d, o, "marker-font", "sans serif",
font_size * PANGO_SCALE_X_SMALL);
xr->fonts[XR_FONT_MARKER].desc = parse_font (d, o, "marker-font", "sans serif",
font_size * PANGO_SCALE_X_SMALL);
- xr->line_gutter = XR_POINT / 2;
xr->line_space = XR_POINT;
xr->line_width = XR_POINT / 2;
xr->page_number = 0;
xr->line_space = XR_POINT;
xr->line_width = XR_POINT / 2;
xr->page_number = 0;
xr->char_width = MAX (xr->char_width, pango_to_xr (char_width));
xr->char_height = MAX (xr->char_height, pango_to_xr (char_height));
}
xr->char_width = MAX (xr->char_width, pango_to_xr (char_width));
xr->char_height = MAX (xr->char_height, pango_to_xr (char_height));
}
- xr->cell_margin = xr->char_width / 2;
if (xr->params == NULL)
{
if (xr->params == NULL)
{
xr->params->font_size[H] = xr->char_width;
xr->params->font_size[V] = xr->char_height;
xr->params->font_size[H] = xr->char_width;
xr->params->font_size[V] = xr->char_height;
- int lg = xr->line_gutter;
int lw = xr->line_width;
int ls = xr->line_space;
for (i = 0; i < TABLE_N_AXES; i++)
{
xr->params->line_widths[i][RENDER_LINE_NONE] = 0;
int lw = xr->line_width;
int ls = xr->line_space;
for (i = 0; i < TABLE_N_AXES; i++)
{
xr->params->line_widths[i][RENDER_LINE_NONE] = 0;
- xr->params->line_widths[i][RENDER_LINE_SINGLE] = 2 * lg + lw;
- xr->params->line_widths[i][RENDER_LINE_DASHED] = 2 * lg + lw;
- xr->params->line_widths[i][RENDER_LINE_THICK] = 2 * lg + lw * 3;
- xr->params->line_widths[i][RENDER_LINE_THIN] = 2 * lg + lw / 2;
- xr->params->line_widths[i][RENDER_LINE_DOUBLE] = 2 * (lg + lw) + ls;
+ 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 * 3;
+ xr->params->line_widths[i][RENDER_LINE_THIN] = lw / 2;
+ xr->params->line_widths[i][RENDER_LINE_DOUBLE] = 2 * lw + ls;
}
for (i = 0; i < TABLE_N_AXES; i++)
}
for (i = 0; i < TABLE_N_AXES; i++)
xr_layout_cell (xr, cell, bb, clip, min_width, &h, NULL);
if (*min_width > 0)
xr_layout_cell (xr, cell, bb, clip, min_width, &h, NULL);
if (*min_width > 0)
- *min_width += xr->cell_margin * 2;
+ *min_width += px_to_xr (cell->style->margin[H][0]
+ + cell->style->margin[H][1]);
- *max_width += xr->cell_margin * 2;
+ *max_width += px_to_xr (cell->style->margin[H][0]
+ + cell->style->margin[H][1]);
- bb[H][1] = width - xr->cell_margin * 2;
+ bb[H][1] = width - px_to_xr (cell->style->margin[H][0]
+ + cell->style->margin[H][1]);
bb[V][0] = 0;
bb[V][1] = INT_MAX;
clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0;
xr_layout_cell (xr, cell, bb, clip, &w, &h, NULL);
bb[V][0] = 0;
bb[V][1] = INT_MAX;
clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0;
xr_layout_cell (xr, cell, bb, clip, &w, &h, NULL);
+ h += px_to_xr (cell->style->margin[V][0] + cell->style->margin[V][1]);
static void
xr_draw_cell (void *xr_, const struct table_cell *cell,
static void
xr_draw_cell (void *xr_, const struct table_cell *cell,
- int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2])
+ int bb[TABLE_N_AXES][2],
+ int spill[TABLE_N_AXES][2],
+ int clip[TABLE_N_AXES][2])
{
struct xr_driver *xr = xr_;
int w, h, brk;
cairo_save (xr->cairo);
{
struct xr_driver *xr = xr_;
int w, h, brk;
cairo_save (xr->cairo);
+ int bg_clip[TABLE_N_AXES][2];
+ for (int axis = 0; axis < TABLE_N_AXES; axis++)
+ {
+ bg_clip[axis][0] = clip[axis][0];
+ if (bb[axis][0] == clip[axis][0])
+ bg_clip[axis][0] -= spill[axis][0];
+
+ bg_clip[axis][1] = clip[axis][1];
+ if (bb[axis][1] == clip[axis][1])
+ bg_clip[axis][1] += spill[axis][1];
+ }
+ xr_clip (xr, bg_clip);
cairo_set_source_rgb (xr->cairo,
cell->style->bg.r / 255.,
cell->style->bg.g / 255.,
cell->style->bg.b / 255.);
cairo_set_source_rgb (xr->cairo,
cell->style->bg.r / 255.,
cell->style->bg.g / 255.,
cell->style->bg.b / 255.);
- fill_rectangle (xr, bb[H][0], bb[V][0], bb[H][1], bb[V][1]);
+ fill_rectangle (xr,
+ bb[H][0] - spill[H][0],
+ bb[V][0] - spill[V][0],
+ bb[H][1] + spill[H][1],
+ bb[V][1] + spill[V][1]);
cairo_restore (xr->cairo);
cairo_save (xr->cairo);
cairo_restore (xr->cairo);
cairo_save (xr->cairo);
cell->style->fg.g / 255.,
cell->style->fg.b / 255.);
cell->style->fg.g / 255.,
cell->style->fg.b / 255.);
- bb[H][0] += xr->cell_margin;
- bb[H][1] -= xr->cell_margin;
- if (bb[H][0] < bb[H][1])
+ for (int axis = 0; axis < TABLE_N_AXES; axis++)
+ {
+ bb[axis][0] += px_to_xr (cell->style->margin[axis][0]);
+ bb[axis][1] -= px_to_xr (cell->style->margin[axis][1]);
+ }
+ if (bb[H][0] < bb[H][1] && bb[V][0] < bb[V][1])
xr_layout_cell (xr, cell, bb, clip, &w, &h, &brk);
cairo_restore (xr->cairo);
}
xr_layout_cell (xr, cell, bb, clip, &w, &h, &brk);
cairo_restore (xr->cairo);
}
- bb[H][1] = width - 2 * xr->cell_margin;
+ bb[H][1] = width - px_to_xr (cell->style->margin[H][0]
+ + cell->style->margin[H][1]);
if (bb[H][1] <= 0)
return 0;
bb[V][0] = 0;
if (bb[H][1] <= 0)
return 0;
bb[V][0] = 0;
+ bb[V][1] = height - px_to_xr (cell->style->margin[V][0]
+ + cell->style->margin[V][1]);
clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0;
xr_layout_cell (xr, cell, bb, clip, &w, &h, &brk);
return brk;
clip[H][0] = clip[H][1] = clip[V][0] = clip[V][1] = 0;
xr_layout_cell (xr, cell, bb, clip, &w, &h, &brk);
return brk;
static int
xr_layout_cell_text (struct xr_driver *xr,
const struct cell_contents *contents,
static int
xr_layout_cell_text (struct xr_driver *xr,
const struct cell_contents *contents,
+ const struct cell_style *style,
int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2],
int *widthp, int *brk)
{
int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2],
int *widthp, int *brk)
{
pango_attr_list_unref (attrs);
pango_layout_get_size (font->layout, &w, &h);
pango_attr_list_unref (attrs);
pango_layout_get_size (font->layout, &w, &h);
- merge_footnotes = w > xr->cell_margin;
+ merge_footnotes = w > px_to_xr (style->margin[H][1]);
if (!merge_footnotes && clip[H][0] != clip[H][1])
{
cairo_save (xr->cairo);
if (!merge_footnotes && clip[H][0] != clip[H][1])
{
cairo_save (xr->cairo);
PangoAttrList *attrs;
struct string s;
PangoAttrList *attrs;
struct string s;
- bb[H][1] += xr->cell_margin;
+ bb[H][1] += px_to_xr (style->margin[H][1]);
ds_init_empty (&s);
ds_extend (&s, length + contents->n_footnotes * 10);
ds_init_empty (&s);
ds_extend (&s, length + contents->n_footnotes * 10);
- bb[V][0] = xr_layout_cell_text (xr, contents, bb, clip, width, brk);
+ bb[V][0] = xr_layout_cell_text (xr, contents, cell->style, bb, clip,
+ width, brk);
}
*height = bb[V][0] - bb_[V][0];
}
}
*height = bb[V][0] - bb_[V][0];
}
- page->params->draw_cell (page->params->aux, cell, bb, clip);
+ int spill[TABLE_N_AXES][2];
+ for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
+ {
+ spill[axis][0] = rule_width (page, axis, cell->d[axis][0]) / 2;
+ spill[axis][1] = rule_width (page, axis, cell->d[axis][1]) / 2;
+ }
+
+ page->params->draw_cell (page->params->aux, cell, bb, spill, clip);
}
/* Draws the cells of PAGE indicated in BB. */
}
/* Draws the cells of PAGE indicated in BB. */
render_page_draw_cells (const struct render_page *page,
int ofs[TABLE_N_AXES], int bb[TABLE_N_AXES][2])
{
render_page_draw_cells (const struct render_page *page,
int ofs[TABLE_N_AXES], int bb[TABLE_N_AXES][2])
{
- int x, y;
-
- for (y = bb[V][0]; y < bb[V][1]; y++)
- for (x = bb[H][0]; x < bb[H][1]; )
- if (is_rule (x) || is_rule (y))
- {
- int d[TABLE_N_AXES];
- d[H] = x;
- d[V] = y;
- render_rule (page, ofs, d);
- x++;
- }
- else
+ for (int y = bb[V][0]; y < bb[V][1]; y++)
+ for (int x = bb[H][0]; x < bb[H][1]; )
+ if (!is_rule (x) && !is_rule (y))
{
struct table_cell cell;
{
struct table_cell cell;
x = rule_ofs (cell.d[H][1]);
table_cell_free (&cell);
}
x = rule_ofs (cell.d[H][1]);
table_cell_free (&cell);
}
+ else
+ x++;
+
+ for (int y = bb[V][0]; y < bb[V][1]; y++)
+ for (int x = bb[H][0]; x < bb[H][1]; x++)
+ if (is_rule (x) || is_rule (y))
+ {
+ int d[TABLE_N_AXES];
+ d[H] = x;
+ d[V] = y;
+ render_rule (page, ofs, d);
+ }
}
/* Renders PAGE, by calling the 'draw_line' and 'draw_cell' functions from the
}
/* Renders PAGE, by calling the 'draw_line' and 'draw_cell' functions from the
of the cell that lies within CLIP should actually be drawn, although BB
should used to determine the layout of the cell. */
void (*draw_cell) (void *aux, const struct table_cell *cell,
of the cell that lies within CLIP should actually be drawn, although BB
should used to determine the layout of the cell. */
void (*draw_cell) (void *aux, const struct table_cell *cell,
- int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2]);
+ int bb[TABLE_N_AXES][2],
+ int spill[TABLE_N_AXES][2],
+ int clip[TABLE_N_AXES][2]);
/* Auxiliary data passed to each of the above functions. */
void *aux;
/* Auxiliary data passed to each of the above functions. */
void *aux;
struct cell_style
{
struct cell_color fg, bg;
struct cell_style
{
struct cell_color fg, bg;
+ int margin[TABLE_N_AXES][2];
};
/* A cell in a table. */
};
/* A cell in a table. */
{
.fg = { 0, 0, 0 },
.bg = { 255, 255, 255 },
{
.fg = { 0, 0, 0 },
.bg = { 255, 255, 255 },
+ .margin = { [TABLE_HORZ][0] = 8, [TABLE_HORZ][1] = 11,
+ [TABLE_VERT][0] = 1, [TABLE_VERT][1] = 1 },
};
cell->style = &default_style;
};
cell->style = &default_style;