static int parse_page_size (struct driver_option *);
static void ascii_draw_line (void *, int bb[TABLE_N_AXES][2],
- enum table_stroke styles[TABLE_N_AXES][2],
- struct cell_color colors[TABLE_N_AXES][2]);
+ const struct table_border_style[TABLE_N_AXES][2]);
static void ascii_measure_cell_width (void *, const struct table_cell *,
int *min, int *max);
static int ascii_measure_cell_height (void *, const struct table_cell *,
static void
ascii_draw_line (void *a_, int bb[TABLE_N_AXES][2],
- enum table_stroke styles[TABLE_N_AXES][2],
- struct cell_color colors[TABLE_N_AXES][2] UNUSED)
+ const struct table_border_style styles[TABLE_N_AXES][2])
{
struct ascii_driver *a = a_;
char mbchar[6];
return;
/* Draw. */
- uc = box_get (a->box, styles[V][0], styles[V][1], styles[H][0], styles[H][1]);
+ enum table_stroke v0 = styles[V][0].stroke;
+ enum table_stroke v1 = styles[V][1].stroke;
+ enum table_stroke h0 = styles[H][0].stroke;
+ enum table_stroke h1 = styles[H][1].stroke;
+ uc = box_get (a->box, v0, v1, h0, h1);
mblen = u8_uctomb (CHAR_CAST (uint8_t *, mbchar), uc, 6);
for (y = y0; y < y1; y++)
{
int *width, int *height, int *brk);
static void
-xr_set_source_rgba (cairo_t *cairo, const struct cell_color *color)
+xr_set_source_rgba (cairo_t *cairo, const struct cell_color color)
{
cairo_set_source_rgba (cairo,
- color->r / 255., color->g / 255., color->b / 255.,
- color->alpha / 255.);
+ color.r / 255., color.g / 255., color.b / 255.,
+ color.alpha / 255.);
}
static void
xr_draw_line (struct xr_fsm *xr, int x0, int y0, int x1, int y1, int style,
- const struct cell_color *color)
+ const struct cell_color color)
{
cairo_new_path (xr->cairo);
cairo_set_line_width (
static void
xr_draw_horz_line (struct xr_fsm *xr, int x0, int x1, int x2, int x3, int y,
enum table_stroke left, enum table_stroke right,
- const struct cell_color *left_color,
- const struct cell_color *right_color,
+ const struct cell_color left_color,
+ const struct cell_color right_color,
bool shorten)
{
if (left != TABLE_STROKE_NONE && right != TABLE_STROKE_NONE && !shorten
static void
xr_draw_vert_line (struct xr_fsm *xr, int y0, int y1, int y2, int y3, int x,
enum table_stroke top, enum table_stroke bottom,
- const struct cell_color *top_color,
- const struct cell_color *bottom_color,
+ const struct cell_color top_color,
+ const struct cell_color bottom_color,
bool shorten)
{
if (top != TABLE_STROKE_NONE && bottom != TABLE_STROKE_NONE && !shorten
static void
xrr_draw_line (void *xr_, int bb[TABLE_N_AXES][2],
- enum table_stroke styles[TABLE_N_AXES][2],
- struct cell_color colors[TABLE_N_AXES][2])
+ const struct table_border_style styles[TABLE_N_AXES][2])
{
const int x0 = bb[H][0];
const int y0 = bb[V][0];
const int x3 = bb[H][1];
const int y3 = bb[V][1];
- const int top = styles[H][0];
- const int bottom = styles[H][1];
+ const enum table_stroke top = styles[H][0].stroke;
+ const enum table_stroke bottom = styles[H][1].stroke;
int start_side = render_direction_rtl();
int end_side = !start_side;
- const int start_of_line = styles[V][start_side];
- const int end_of_line = styles[V][end_side];
- const struct cell_color *top_color = &colors[H][0];
- const struct cell_color *bottom_color = &colors[H][1];
- const struct cell_color *start_color = &colors[V][start_side];
- const struct cell_color *end_color = &colors[V][end_side];
+ const int start_of_line = styles[V][start_side].stroke;
+ const int end_of_line = styles[V][end_side].stroke;
+ const struct cell_color top_color = styles[H][0].color;
+ const struct cell_color bottom_color = styles[H][1].color;
+ const struct cell_color start_color = styles[V][start_side].color;
+ const struct cell_color end_color = styles[V][end_side].color;
/* The algorithm here is somewhat subtle, to allow it to handle
all the kinds of intersections that we need.
struct xr_fsm *xr = xr_;
int w, h, brk;
- const struct cell_color *bg = &cell->font_style->bg[color_idx];
- if ((bg->r != 255 || bg->g != 255 || bg->b != 255) && bg->alpha)
+ const struct cell_color bg = cell->font_style->bg[color_idx];
+ if ((bg.r != 255 || bg.g != 255 || bg.b != 255) && bg.alpha)
{
cairo_save (xr->cairo);
int bg_clip[TABLE_N_AXES][2];
}
cairo_save (xr->cairo);
if (!xr->style->use_system_colors)
- xr_set_source_rgba (xr->cairo, &cell->font_style->fg[color_idx]);
+ xr_set_source_rgba (xr->cairo, cell->font_style->fg[color_idx]);
bb[V][0] += valign_offset;
xr_draw_line (xr, 0, best,
xr->style->size[H], best,
TABLE_STROKE_SOLID,
- &(struct cell_color) CELL_COLOR (0, 255, 0));
+ (struct cell_color) CELL_COLOR (0, 255, 0));
}
}
const struct cell_color default_color,
char *buf, size_t bufsize)
{
- bool retval = !cell_color_equal (&color, &default_color);
+ bool retval = !cell_color_equal (color, default_color);
if (retval)
{
if (color.alpha == 255)
enum table_axis axis, int h, int v,
const char *border_name)
{
- struct cell_color color;
- const char *css = border_to_css (
- table_get_rule (table, axis, cell->d[H][h], cell->d[V][v], &color));
+ struct table_border_style border
+ = table_get_rule (table, axis, cell->d[H][h], cell->d[V][v]);
+ const char *css = border_to_css (border.stroke);
if (css)
{
next_style (style);
fprintf (style->file, "border-%s: %s", border_name, css);
char buf[32];
- if (format_color (color, (struct cell_color) CELL_COLOR_BLACK,
+ if (format_color (border.color, (struct cell_color) CELL_COLOR_BLACK,
buf, sizeof buf))
fprintf (style->file, " %s", buf);
}
pivot_value_new_user_text_nocopy (ds_steal_cstr (s)));
}
-static int
-get_table_rule (const struct table_border_style *styles,
- enum pivot_border style_idx)
-{
- return styles[style_idx].stroke | (style_idx << TAB_RULE_STYLE_SHIFT);
-}
-
static void
-draw_line (struct table *t, const struct table_border_style *styles,
- enum pivot_border style_idx,
+draw_line (struct table *t, enum pivot_border border_idx,
enum table_axis axis, int a, int b0, int b1)
{
- int rule = get_table_rule (styles, style_idx);
if (axis == H)
- table_hline (t, rule, b0, b1, a);
+ table_hline (t, border_idx, b0, b1, a);
else
- table_vline (t, rule, a, b0, b1);
+ table_vline (t, border_idx, a, b0, b1);
}
/* Fills row or column headings into T.
compose_headings (struct table *t,
const struct pivot_axis *h_axis, enum table_axis h,
const struct pivot_axis *v_axis,
- const struct table_border_style *borders,
enum pivot_border dim_col_horz,
enum pivot_border dim_col_vert,
enum pivot_border cat_col_horz,
= (y1 == v_size - 1 ? cat_col_vert : dim_col_vert);
if (!vrules[x2])
{
- draw_line (t, borders, style, v, x2 + h_ofs, y1,
- t->n[v] - 1);
+ draw_line (t, style, v, x2 + h_ofs, y1, t->n[v] - 1);
vrules[x2] = true;
}
if (!vrules[x1])
{
- draw_line (t, borders, style, v, x1 + h_ofs, y1,
- t->n[v] - 1);
+ draw_line (t, style, v, x1 + h_ofs, y1, t->n[v] - 1);
vrules[x1] = true;
}
}
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
*/
if (c->parent && c->parent->show_label)
- draw_line (t, borders, cat_col_horz, h, y1,
- x1 + h_ofs, x2 + h_ofs - 1);
+ draw_line (t, cat_col_horz, h, y1, x1 + h_ofs, x2 + h_ofs - 1);
x1 = x2;
}
}
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
*/
if (dim_index != h_axis->n_dimensions - 1)
- draw_line (t, borders, dim_col_horz, h, top_row, h_ofs,
- t->n[h] - 1);
+ draw_line (t, dim_col_horz, h, top_row, h_ofs, t->n[h] - 1);
top_row += d->label_depth;
}
free (vrules);
body->styles[i] = table_area_style_override (
body->container, &pt->look->areas[i], NULL, NULL, false);
- struct table_border_style borders[PIVOT_N_BORDERS];
- memcpy (borders, pt->look->borders, sizeof borders);
- if (!printing && pt->show_grid_lines)
- for (int b = 0; b < PIVOT_N_BORDERS; b++)
- if (borders[b].stroke == TABLE_STROKE_NONE)
- borders[b].stroke = TABLE_STROKE_DASHED;
-
+ body->n_borders = PIVOT_N_BORDERS;
+ body->borders = pool_nmalloc (body->container, PIVOT_N_BORDERS,
+ sizeof *body->borders);
for (size_t i = 0; i < PIVOT_N_BORDERS; i++)
{
- const struct table_border_style *in = &pt->look->borders[i];
- body->rule_colors[i] = pool_alloc (body->container,
- sizeof *body->rule_colors[i]);
- *body->rule_colors[i] = in->color;
+ const struct table_border_style *src = &pt->look->borders[i];
+ struct table_border_style *dst = &body->borders[i];
+ *dst = (!printing && pt->show_grid_lines && src->stroke == TABLE_STROKE_NONE
+ ? (struct table_border_style) { .stroke = TABLE_STROKE_DASHED,
+ .color = CELL_COLOR_BLACK }
+ : *src);
}
compose_headings (body,
&pt->axes[PIVOT_AXIS_COLUMN], H, &pt->axes[PIVOT_AXIS_ROW],
- borders,
PIVOT_BORDER_DIM_COL_HORZ,
PIVOT_BORDER_DIM_COL_VERT,
PIVOT_BORDER_CAT_COL_HORZ,
compose_headings (body,
&pt->axes[PIVOT_AXIS_ROW], V, &pt->axes[PIVOT_AXIS_COLUMN],
- borders,
PIVOT_BORDER_DIM_ROW_VERT,
PIVOT_BORDER_DIM_ROW_HORZ,
PIVOT_BORDER_CAT_ROW_VERT,
if (body->n[H] && body->n[V])
{
- table_hline (
- body, get_table_rule (borders, PIVOT_BORDER_INNER_TOP),
- 0, body->n[H] - 1, 0);
- table_hline (
- body, get_table_rule (borders, PIVOT_BORDER_INNER_BOTTOM),
- 0, body->n[H] - 1, body->n[V]);
- table_vline (
- body, get_table_rule (borders, PIVOT_BORDER_INNER_LEFT),
- 0, 0, body->n[V] - 1);
- table_vline (
- body, get_table_rule (borders, PIVOT_BORDER_INNER_RIGHT),
- body->n[H], 0, body->n[V] - 1);
+ table_hline (body, PIVOT_BORDER_INNER_TOP, 0, body->n[H] - 1, 0);
+ table_hline (body, PIVOT_BORDER_INNER_BOTTOM, 0, body->n[H] - 1,
+ body->n[V]);
+ table_vline (body, PIVOT_BORDER_INNER_LEFT, 0, 0, body->n[V] - 1);
+ table_vline (body, PIVOT_BORDER_INNER_RIGHT, body->n[H], 0,
+ body->n[V] - 1);
if (stub[V])
- table_hline (
- body, get_table_rule (borders, PIVOT_BORDER_DATA_TOP),
- 0, body->n[H] - 1, stub[V]);
+ table_hline (body, PIVOT_BORDER_DATA_TOP, 0, body->n[H] - 1, stub[V]);
if (stub[H])
- table_vline (
- body, get_table_rule (borders, PIVOT_BORDER_DATA_LEFT),
- stub[H], 0, body->n[V] - 1);
+ table_vline (body, PIVOT_BORDER_DATA_LEFT, stub[H], 0, body->n[V] - 1);
}
free (column_enumeration);
/* Determine all types of rules that are present, as a bitmap in 'rules'
where rule type 't' is present if bit 2**t is set. */
- struct cell_color color;
unsigned int rules = 0;
int d[TABLE_N_AXES];
d[a] = z;
for (d[b] = 0; d[b] < table->n[b]; d[b]++)
- rules |= 1u << table_get_rule (table, a, d[H], d[V], &color);
+ rules |= 1u << table_get_rule (table, a, d[H], d[V]).stroke;
/* Turn off TABLE_STROKE_NONE because it has width 0 and we needn't bother.
However, if the device doesn't support margins, make sure that there is at
\f
/* Drawing render_pages. */
-/* This is like table_get_rule() except:
-
- - D is in terms of the page's rows and column rather than the underlying
- table's.
-
- - The result is in the form of a table_stroke. */
-static enum table_stroke
+/* This is like table_get_rule() except that D is in terms of the page's rows
+ and column rather than the underlying table's. */
+static struct table_border_style
get_rule (const struct render_page *page, enum table_axis axis,
- const int d_[TABLE_N_AXES], struct cell_color *color)
+ const int d_[TABLE_N_AXES])
{
int d[TABLE_N_AXES] = { d_[0] / 2, d_[1] / 2 };
int d2 = -1;
get_map (page, b, d[b], &m);
d[b] += m.t0 - m.p0;
- int r = table_get_rule (page->table, axis, d[H], d[V], color);
+ struct table_border_style border
+ = table_get_rule (page->table, axis, d[H], d[V]);
if (d2 >= 0)
{
d[a] = d2;
- int r2 = table_get_rule (page->table, axis, d[H], d[V], color);
- r = table_stroke_combine (r, r2);
+ struct table_border_style border2 = table_get_rule (page->table, axis,
+ d[H], d[V]);
+ border.stroke = table_stroke_combine (border.stroke, border2.stroke);
}
- return r;
+ return border;
}
static bool
render_rule (const struct render_page *page, const int ofs[TABLE_N_AXES],
const int d[TABLE_N_AXES])
{
- enum table_stroke styles[TABLE_N_AXES][2];
- struct cell_color colors[TABLE_N_AXES][2];
+ const struct table_border_style none = { .stroke = TABLE_STROKE_NONE };
+ struct table_border_style styles[TABLE_N_AXES][2];
for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
{
enum table_axis b = !a;
- styles[a][0] = styles[a][1] = TABLE_STROKE_NONE;
-
if (!is_rule (d[a])
|| (page->is_edge_cutoff[a][0] && d[a] == 0)
|| (page->is_edge_cutoff[a][1] && d[a] == page->n[a] * 2))
- continue;
-
- if (is_rule (d[b]))
+ styles[a][0] = styles[a][1] = none;
+ else if (is_rule (d[b]))
{
if (d[b] > 0)
{
e[H] = d[H];
e[V] = d[V];
e[b]--;
- styles[a][0] = get_rule (page, a, e, &colors[a][0]);
+ styles[a][0] = get_rule (page, a, e);
}
+ else
+ styles[a][0] = none;
if (d[b] / 2 < page->n[b])
- styles[a][1] = get_rule (page, a, d, &colors[a][1]);
+ styles[a][1] = get_rule (page, a, d);
+ else
+ styles[a][1] = none;
}
else
- {
- styles[a][0] = styles[a][1] = get_rule (page, a, d, &colors[a][0]);
- colors[a][1] = colors[a][0];
- }
+ styles[a][0] = styles[a][1] = get_rule (page, a, d);
}
- if (styles[H][0] != TABLE_STROKE_NONE || styles[H][1] != TABLE_STROKE_NONE
- || styles[V][0] != TABLE_STROKE_NONE || styles[V][1] != TABLE_STROKE_NONE)
+ if (styles[H][0].stroke != TABLE_STROKE_NONE
+ || styles[H][1].stroke != TABLE_STROKE_NONE
+ || styles[V][0].stroke != TABLE_STROKE_NONE
+ || styles[V][1].stroke != TABLE_STROKE_NONE)
{
int bb[TABLE_N_AXES][2];
}
bb[V][0] = ofs[V] + page->cp[V][d[V]];
bb[V][1] = ofs[V] + page->cp[V][d[V] + 1];
- page->params->ops->draw_line (page->params->aux, bb, styles, colors);
+ page->params->ops->draw_line (page->params->aux, bb, styles);
}
}
STYLES[TABLE_VERT][0]: style of line from left of BB to its center.
STYLES[TABLE_VERT][1]: style of line from right of BB to its center. */
void (*draw_line) (void *aux, int bb[TABLE_N_AXES][2],
- enum table_stroke styles[TABLE_N_AXES][2],
- struct cell_color colors[TABLE_N_AXES][2]);
+ const struct table_border_style styles[TABLE_N_AXES][2]);
/* 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
start_elem (xml, pivot_area_names[a]);
if (a == PIVOT_AREA_DATA
- && (!cell_color_equal (&font->fg[0], &font->fg[1])
- || !cell_color_equal (&font->bg[0], &font->bg[1])))
+ && (!cell_color_equal (font->fg[0], font->fg[1])
+ || !cell_color_equal (font->bg[0], font->bg[1])))
{
write_attr_color (xml, "alternatingColor", &font->bg[1]);
write_attr_color (xml, "alternatingTextColor", &font->fg[1]);
put_color (buf, &a->font_style.bg[0]);
bool alt
- = (!cell_color_equal (&a->font_style.fg[0], &a->font_style.fg[1])
- || !cell_color_equal (&a->font_style.bg[0], &a->font_style.bg[1]));
+ = (!cell_color_equal (a->font_style.fg[0], a->font_style.fg[1])
+ || !cell_color_equal (a->font_style.bg[0], a->font_style.bg[1]));
put_bool (buf, alt);
if (alt)
{
/* For use primarily by output drivers. */
void table_get_cell (const struct table *, int x, int y, struct table_cell *);
-int table_get_rule (const struct table *, enum table_axis, int x, int y,
- struct cell_color *);
+struct table_border_style table_get_rule (const struct table *,
+ enum table_axis, int x, int y);
#endif /* output/table-provider.h */
cell_color_dump (&f->fg[0]);
putchar ('/');
cell_color_dump (&f->bg[0]);
- if (!cell_color_equal (&f->fg[0], &f->fg[1])
- || !cell_color_equal (&f->bg[0], &f->bg[1]))
+ if (!cell_color_equal (f->fg[0], f->fg[1])
+ || !cell_color_equal (f->bg[0], f->bg[1]))
{
printf (" alt=");
cell_color_dump (&f->fg[1]);
&& a->italic == b->italic
&& a->underline == b->underline
&& a->markup == b->markup
- && cell_color_equal (&a->fg[0], &b->fg[0])
- && cell_color_equal (&a->fg[1], &b->fg[1])
- && cell_color_equal (&a->bg[0], &b->bg[0])
- && cell_color_equal (&a->bg[1], &b->bg[1])
+ && cell_color_equal (a->fg[0], b->fg[0])
+ && cell_color_equal (a->fg[1], b->fg[1])
+ && cell_color_equal (a->bg[0], b->bg[0])
+ && cell_color_equal (a->bg[1], b->bg[1])
&& !strcmp (a->typeface ? a->typeface : "",
b->typeface ? b->typeface : "")
&& a->size == b->size);
struct table *
table_create (int nc, int nr, int hl, int hr, int ht, int hb)
{
- struct table *t;
-
- t = pool_create_container (struct table, container);
- t->n[TABLE_HORZ] = nc;
- t->n[TABLE_VERT] = nr;
- t->h[TABLE_HORZ][0] = hl;
- t->h[TABLE_HORZ][1] = hr;
- t->h[TABLE_VERT][0] = ht;
- t->h[TABLE_VERT][1] = hb;
- t->ref_cnt = 1;
-
- t->cc = pool_calloc (t->container, nr * nc, sizeof *t->cc);
- t->cp = pool_calloc (t->container, nr * nc, sizeof *t->cp);
-
- t->rh = pool_nmalloc (t->container, nc, nr + 1);
- memset (t->rh, TABLE_STROKE_NONE, nc * (nr + 1));
-
- t->rv = pool_nmalloc (t->container, nr, nc + 1);
- memset (t->rv, TABLE_STROKE_NONE, nr * (nc + 1));
-
- memset (t->styles, 0, sizeof t->styles);
- memset (t->rule_colors, 0, sizeof t->rule_colors);
-
+ struct pool *pool = pool_create ();
+ struct table *t = pool_alloc (pool, sizeof *t);
+ *t = (struct table) {
+ .container = pool,
+ .n = { [H] = nc, [V] = nr },
+ .h = { [H] = { hl, hr }, [V] = { ht, hb } },
+ .ref_cnt = 1,
+ .cc = pool_calloc (pool, nr * nc, sizeof *t->cc),
+ .cp = pool_calloc (pool, nr * nc, sizeof *t->cp),
+ .rh = pool_calloc (pool, nc, nr + 1),
+ .rv = pool_nmalloc (pool, nr, nc + 1),
+ };
return t;
}
\f
assert (cell->cell_style);
}
-/* Returns one of the TAL_* enumeration constants (declared in output/table.h)
- representing a rule running alongside one of the cells in TABLE.
+/* Returns one of the TABLE_STROKE_* enumeration constants (declared in
+ output/table.h) representing a rule running alongside one of the cells in
+ TABLE.
Suppose NC is the number of columns in TABLE and NR is the number of rows.
Then, if AXIS is TABLE_HORZ, then 0 <= X <= NC and 0 <= Y < NR. If (X,Y) =
the top of cell (0,0); if (X,Y) = (0,1), it is the horizontal rule
between that cell and cell (0,1); and so on, up to (0,NR), which runs
horizontally below cell (0,NR-1). */
-int
-table_get_rule (const struct table *table, enum table_axis axis, int x, int y,
- struct cell_color *color)
+struct table_border_style
+table_get_rule (const struct table *table, enum table_axis axis, int x, int y)
{
assert (x >= 0 && x < table->n[TABLE_HORZ] + (axis == TABLE_HORZ));
assert (y >= 0 && y < table->n[TABLE_VERT] + (axis == TABLE_VERT));
- uint8_t raw = (axis == TABLE_VERT
- ? table->rh[x + table->n[H] * y]
- : table->rv[x + (table->n[H] + 1) * y]);
- struct cell_color *p = table->rule_colors[(raw & TAB_RULE_STYLE_MASK)
- >> TAB_RULE_STYLE_SHIFT];
- *color = p ? *p : (struct cell_color) CELL_COLOR_BLACK;
- return (raw & TAB_RULE_TYPE_MASK) >> TAB_RULE_TYPE_SHIFT;
+ size_t border_idx = (axis == TABLE_VERT
+ ? table->rh[x + table->n[H] * y]
+ : table->rv[x + (table->n[H] + 1) * y]);
+ return (border_idx < table->n_borders
+ ? table->borders[border_idx]
+ : (struct table_border_style) { TABLE_STROKE_NONE,
+ CELL_COLOR_BLACK });
}
#define CELL_COLOR_WHITE CELL_COLOR (255, 255, 255)
static inline bool
-cell_color_equal (const struct cell_color *a, const struct cell_color *b)
+cell_color_equal (const struct cell_color a, const struct cell_color b)
{
- return a->alpha == b->alpha && a->r == b->r && a->g == b->g && a->b == b->b;
+ return a.alpha == b.alpha && a.r == b.r && a.g == b.g && a.b == b.b;
}
void cell_color_dump (const struct cell_color *);
/* Rules. */
unsigned char *rh; /* Horiz rules; unsigned char[nr+1][nc]. */
unsigned char *rv; /* Vert rules; unsigned char[nr][nc+1]. */
- struct cell_color *rule_colors[32];
+ struct table_border_style *borders;
+ size_t n_borders;
};
/* Reference counting. */
void table_unref (struct table *);
bool table_is_shared (const struct table *);
-/* Rule masks. */
-#define TAB_RULE_TYPE_MASK 7
-#define TAB_RULE_TYPE_SHIFT 0
-#define TAB_RULE_STYLE_MASK (31 << TAB_RULE_STYLE_SHIFT)
-#define TAB_RULE_STYLE_SHIFT 3
-
/* Tables. */
struct table *table_create (int nc, int nr, int hl, int hr, int ht, int hb);