size_t body[TABLE_N_AXES];
size_t *column_enumeration = pivot_table_enumerate_axis (
- pt, PIVOT_AXIS_COLUMN, layer_indexes, pt->look.omit_empty, &body[H]);
+ pt, PIVOT_AXIS_COLUMN, layer_indexes, pt->look->omit_empty, &body[H]);
size_t *row_enumeration = pivot_table_enumerate_axis (
- pt, PIVOT_AXIS_ROW, layer_indexes, pt->look.omit_empty, &body[V]);
+ pt, PIVOT_AXIS_ROW, layer_indexes, pt->look->omit_empty, &body[V]);
int stub[TABLE_N_AXES] = {
[H] = pt->axes[PIVOT_AXIS_ROW].label_depth,
for (size_t i = 0; i < PIVOT_N_AREAS; i++)
table->styles[i] = table_area_style_override (
- table->container, &pt->look.areas[i], NULL, NULL);
+ table->container, &pt->look->areas[i], NULL, NULL);
for (size_t i = 0; i < PIVOT_N_BORDERS; i++)
{
- const struct table_border_style *in = &pt->look.borders[i];
+ const struct table_border_style *in = &pt->look->borders[i];
table->rule_colors[i] = pool_alloc (table->container,
sizeof *table->rule_colors[i]);
struct cell_color *out = table->rule_colors[i];
footnotes[i] = table_create_footnote (
table, i, content, marker,
table_area_style_override (table->container,
- &pt->look.areas[PIVOT_AREA_FOOTER],
+ &pt->look->areas[PIVOT_AREA_FOOTER],
pf->content->cell_style,
pf->content->font_style));
free (marker);
compose_headings (table,
&pt->axes[PIVOT_AXIS_COLUMN], H, &pt->axes[PIVOT_AXIS_ROW],
- pt->look.borders,
+ pt->look->borders,
PIVOT_BORDER_DIM_COL_HORZ,
PIVOT_BORDER_DIM_COL_VERT,
PIVOT_BORDER_CAT_COL_HORZ,
PIVOT_BORDER_CAT_COL_VERT,
column_enumeration, body[H],
- &pt->look.areas[PIVOT_AREA_COLUMN_LABELS],
+ &pt->look->areas[PIVOT_AREA_COLUMN_LABELS],
PIVOT_AREA_COLUMN_LABELS,
- &pt->look.areas[PIVOT_AREA_CORNER], footnotes,
+ &pt->look->areas[PIVOT_AREA_CORNER], footnotes,
pt->show_values, pt->show_variables,
pt->rotate_inner_column_labels, false);
compose_headings (table,
&pt->axes[PIVOT_AXIS_ROW], V, &pt->axes[PIVOT_AXIS_COLUMN],
- pt->look.borders,
+ pt->look->borders,
PIVOT_BORDER_DIM_ROW_VERT,
PIVOT_BORDER_DIM_ROW_HORZ,
PIVOT_BORDER_CAT_ROW_VERT,
PIVOT_BORDER_CAT_ROW_HORZ,
row_enumeration, body[V],
- &pt->look.areas[PIVOT_AREA_ROW_LABELS],
+ &pt->look->areas[PIVOT_AREA_ROW_LABELS],
PIVOT_AREA_ROW_LABELS,
- &pt->look.areas[PIVOT_AREA_CORNER], footnotes,
+ &pt->look->areas[PIVOT_AREA_CORNER], footnotes,
pt->show_values, pt->show_variables,
false, pt->rotate_outer_row_labels);
fill_cell (table,
x + stub[H], y + stub[V],
x + stub[H], y + stub[V],
- &pt->look.areas[PIVOT_AREA_DATA], PIVOT_AREA_DATA,
+ &pt->look->areas[PIVOT_AREA_DATA], PIVOT_AREA_DATA,
value, footnotes,
pt->show_values, pt->show_variables, false);
if (pt->corner_text && stub[H] && stub[V])
fill_cell (table, 0, 0, stub[H] - 1, stub[V] - 1,
- &pt->look.areas[PIVOT_AREA_CORNER], PIVOT_AREA_CORNER,
+ &pt->look->areas[PIVOT_AREA_CORNER], PIVOT_AREA_CORNER,
pt->corner_text, footnotes,
pt->show_values, pt->show_variables, false);
if (table_nc (table) && table_nr (table))
{
table_hline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_INNER_TOP),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_TOP),
0, table_nc (table) - 1, 0);
table_hline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_INNER_BOTTOM),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_BOTTOM),
0, table_nc (table) - 1, table_nr (table));
table_vline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_INNER_LEFT),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_LEFT),
0, 0, table_nr (table) - 1);
table_vline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_INNER_RIGHT),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_INNER_RIGHT),
table_nc (table), 0, table_nr (table) - 1);
if (stub[V])
table_hline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_DATA_TOP),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_DATA_TOP),
0, table_nc (table) - 1, stub[V]);
if (stub[H])
table_vline (
- table, get_table_rule (pt->look.borders, PIVOT_BORDER_DATA_LEFT),
+ table, get_table_rule (pt->look->borders, PIVOT_BORDER_DATA_LEFT),
stub[H], 0, table_nr (table) - 1);
}
if (pt->title)
{
struct table_item_text *title = pivot_value_to_table_item_text (
- pt->title, &pt->look.areas[PIVOT_AREA_TITLE], footnotes,
+ pt->title, &pt->look->areas[PIVOT_AREA_TITLE], footnotes,
pt->show_values, pt->show_variables);
table_item_set_title (ti, title);
table_item_text_destroy (title);
{
layers = xzalloc (sizeof *layers);
layers->style = table_area_style_override (
- NULL, &pt->look.areas[PIVOT_AREA_LAYERS], NULL, NULL);
+ NULL, &pt->look->areas[PIVOT_AREA_LAYERS], NULL, NULL);
layers->layers = xnmalloc (layer_axis->n_dimensions,
sizeof *layers->layers);
}
if (pt->caption && pt->show_caption)
{
struct table_item_text *caption = pivot_value_to_table_item_text (
- pt->caption, &pt->look.areas[PIVOT_AREA_CAPTION], footnotes,
+ pt->caption, &pt->look->areas[PIVOT_AREA_CAPTION], footnotes,
pt->show_values, pt->show_variables);
table_item_set_caption (ti, caption);
table_item_text_destroy (caption);
if (pt->decimal == '.' || pt->decimal == ',')
settings_set_decimal_char (pt->decimal);
- if (pt->look.print_all_layers)
+ if (pt->look->print_all_layers)
{
size_t *layer_indexes;
PIVOT_AXIS_FOR_EACH (layer_indexes, &pt->axes[PIVOT_AXIS_LAYER])
{
- if (pt->look.paginate_layers)
+ if (pt->look->paginate_layers)
page_eject_item_submit (page_eject_item_create ());
pivot_table_submit_layer (pt, layer_indexes);
}
}
}
-const struct table_area_style *
-pivot_area_get_default_style (enum pivot_area area)
-{
-#define STYLE(BOLD, H, V, L, R, T, B) { \
- .cell_style = { \
- .halign = TABLE_HALIGN_##H, \
- .valign = TABLE_VALIGN_##V, \
- .margin = { [TABLE_HORZ][0] = L, [TABLE_HORZ][1] = R, \
- [TABLE_VERT][0] = T, [TABLE_VERT][1] = B }, \
- }, \
- .font_style = { \
- .bold = BOLD, \
- .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK}, \
- .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE}, \
- .size = 9, \
- .typeface = (char *) "Sans Serif", \
- }, \
- }
- static const struct table_area_style default_area_styles[PIVOT_N_AREAS] = {
- [PIVOT_AREA_TITLE] = STYLE(true, CENTER, CENTER, 8,11,1,8),
- [PIVOT_AREA_CAPTION] = STYLE(false, LEFT, TOP, 8,11,1,1),
- [PIVOT_AREA_FOOTER] = STYLE(false, LEFT, TOP, 11, 8,2,3),
- [PIVOT_AREA_CORNER] = STYLE(false, LEFT, BOTTOM, 8,11,1,1),
- [PIVOT_AREA_COLUMN_LABELS] = STYLE(false, CENTER, BOTTOM, 8,11,1,3),
- [PIVOT_AREA_ROW_LABELS] = STYLE(false, LEFT, TOP, 8,11,1,3),
- [PIVOT_AREA_DATA] = STYLE(false, MIXED, TOP, 8,11,1,1),
- [PIVOT_AREA_LAYERS] = STYLE(false, LEFT, BOTTOM, 8,11,1,3),
- };
-#undef STYLE
-
- return &default_area_styles[area];
-}
-
-void
-pivot_border_get_default_style (enum pivot_border border,
- struct table_border_style *style)
-{
- static const enum table_stroke default_strokes[PIVOT_N_BORDERS] = {
- [PIVOT_BORDER_TITLE] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_LEFT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_TOP] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_RIGHT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_BOTTOM] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_INNER_LEFT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_TOP] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_RIGHT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_BOTTOM] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DATA_LEFT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DATA_TOP] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DIM_ROW_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_DIM_ROW_VERT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_DIM_COL_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_DIM_COL_VERT] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_CAT_ROW_HORZ] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_CAT_ROW_VERT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_CAT_COL_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_CAT_COL_VERT] = TABLE_STROKE_SOLID,
- };
- *style = (struct table_border_style) {
- .stroke = default_strokes[border],
- .color = CELL_COLOR_BLACK,
- };
-}
-
/* Returns the name of BORDER. */
const char *
pivot_border_to_string (enum pivot_border border)
\f
/* Pivot table looks. */
-void
-pivot_table_look_init (struct pivot_table_look *look)
+const struct pivot_table_look *
+pivot_table_look_builtin_default (void)
{
- memset (look, 0, sizeof *look);
+ static struct pivot_table_look look = {
+ .ref_cnt = 1,
- look->omit_empty = true;
- look->row_labels_in_corner = true;
- look->width_ranges[TABLE_HORZ][0] = 36;
- look->width_ranges[TABLE_HORZ][1] = 72;
- look->width_ranges[TABLE_VERT][0] = 36;
- look->width_ranges[TABLE_VERT][1] = 120;
+ .omit_empty = true,
+ .row_labels_in_corner = true,
+ .width_ranges = {
+ [TABLE_HORZ] = { 36, 72 },
+ [TABLE_VERT] = { 36, 120 },
+ },
- for (size_t i = 0; i < PIVOT_N_AREAS; i++)
- table_area_style_copy (NULL, &look->areas[i],
- pivot_area_get_default_style (i));
-
- static const enum table_stroke default_strokes[PIVOT_N_BORDERS] = {
- [PIVOT_BORDER_TITLE] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_LEFT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_TOP] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_RIGHT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_OUTER_BOTTOM] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_INNER_LEFT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_TOP] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_RIGHT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_INNER_BOTTOM] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DATA_LEFT] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DATA_TOP] = TABLE_STROKE_THICK,
- [PIVOT_BORDER_DIM_ROW_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_DIM_ROW_VERT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_DIM_COL_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_DIM_COL_VERT] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_CAT_ROW_HORZ] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_CAT_ROW_VERT] = TABLE_STROKE_NONE,
- [PIVOT_BORDER_CAT_COL_HORZ] = TABLE_STROKE_SOLID,
- [PIVOT_BORDER_CAT_COL_VERT] = TABLE_STROKE_SOLID,
+ .areas = {
+#define AREA(BOLD, H, V, L, R, T, B) { \
+ .cell_style = { \
+ .halign = TABLE_HALIGN_##H, \
+ .valign = TABLE_VALIGN_##V, \
+ .margin = { [TABLE_HORZ][0] = L, [TABLE_HORZ][1] = R, \
+ [TABLE_VERT][0] = T, [TABLE_VERT][1] = B }, \
+ }, \
+ .font_style = { \
+ .bold = BOLD, \
+ .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK}, \
+ .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE}, \
+ .size = 9, \
+ .typeface = (char *) "Sans Serif", \
+ }, \
+ }
+ [PIVOT_AREA_TITLE] = AREA(true, CENTER, CENTER, 8,11,1,8),
+ [PIVOT_AREA_CAPTION] = AREA(false, LEFT, TOP, 8,11,1,1),
+ [PIVOT_AREA_FOOTER] = AREA(false, LEFT, TOP, 11, 8,2,3),
+ [PIVOT_AREA_CORNER] = AREA(false, LEFT, BOTTOM, 8,11,1,1),
+ [PIVOT_AREA_COLUMN_LABELS] = AREA(false, CENTER, BOTTOM, 8,11,1,3),
+ [PIVOT_AREA_ROW_LABELS] = AREA(false, LEFT, TOP, 8,11,1,3),
+ [PIVOT_AREA_DATA] = AREA(false, MIXED, TOP, 8,11,1,1),
+ [PIVOT_AREA_LAYERS] = AREA(false, LEFT, BOTTOM, 8,11,1,3),
+#undef AREA
+ },
+
+ .borders = {
+#define BORDER(STROKE) { .stroke = STROKE, .color = CELL_COLOR_BLACK }
+ [PIVOT_BORDER_TITLE] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_OUTER_LEFT] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_OUTER_TOP] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_OUTER_RIGHT] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_OUTER_BOTTOM] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_INNER_LEFT] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_INNER_TOP] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_INNER_RIGHT] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_INNER_BOTTOM] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_DATA_LEFT] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_DATA_TOP] = BORDER(TABLE_STROKE_THICK),
+ [PIVOT_BORDER_DIM_ROW_HORZ] = BORDER(TABLE_STROKE_SOLID),
+ [PIVOT_BORDER_DIM_ROW_VERT] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_DIM_COL_HORZ] = BORDER(TABLE_STROKE_SOLID),
+ [PIVOT_BORDER_DIM_COL_VERT] = BORDER(TABLE_STROKE_SOLID),
+ [PIVOT_BORDER_CAT_ROW_HORZ] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_CAT_ROW_VERT] = BORDER(TABLE_STROKE_NONE),
+ [PIVOT_BORDER_CAT_COL_HORZ] = BORDER(TABLE_STROKE_SOLID),
+ [PIVOT_BORDER_CAT_COL_VERT] = BORDER(TABLE_STROKE_SOLID),
+ },
};
- for (size_t i = 0; i < PIVOT_N_BORDERS; i++)
- look->borders[i] = (struct table_border_style) {
- .stroke = default_strokes[i],
- .color = CELL_COLOR_BLACK,
- };
+
+ return &look;
}
-void
-pivot_table_look_uninit (struct pivot_table_look *look)
+struct pivot_table_look *
+pivot_table_look_new_builtin_default (void)
{
- free (look->name);
+ return pivot_table_look_unshare (
+ pivot_table_look_ref (pivot_table_look_builtin_default ()));
+}
- for (size_t i = 0; i < PIVOT_N_AREAS; i++)
- table_area_style_uninit (&look->areas[i]);
+struct pivot_table_look *
+pivot_table_look_ref (const struct pivot_table_look *look_)
+{
+ assert (look_->ref_cnt > 0);
- free (look->continuation);
+ struct pivot_table_look *look = CONST_CAST (struct pivot_table_look *, look_);
+ look->ref_cnt++;
+ return look;
}
static char *
return s && s[0] ? xstrdup (s) : NULL;
}
-void
-pivot_table_look_copy (struct pivot_table_look *dst,
- const struct pivot_table_look *src)
+struct pivot_table_look *
+pivot_table_look_unshare (struct pivot_table_look *old)
{
- *dst = *src;
- dst->name = xstrdup_if_nonempty (src->name);
+ assert (old->ref_cnt > 0);
+ if (old->ref_cnt == 1)
+ return old;
+
+ pivot_table_look_unref (old);
+
+ struct pivot_table_look *new = xmemdup (old, sizeof *old);
+ new->ref_cnt = 1;
+ new->name = xstrdup_if_nonempty (old->name);
for (size_t i = 0; i < PIVOT_N_AREAS; i++)
- table_area_style_copy (NULL, &dst->areas[i], &src->areas[i]);
- dst->continuation = xstrdup_if_nonempty (src->continuation);
+ table_area_style_copy (NULL, &new->areas[i], &old->areas[i]);
+ new->continuation = xstrdup_if_nonempty (old->continuation);
+
+ return new;
+}
+
+void
+pivot_table_look_unref (struct pivot_table_look *look)
+{
+ if (look)
+ {
+ assert (look->ref_cnt > 0);
+ if (!--look->ref_cnt)
+ {
+ free (look->name);
+ for (size_t i = 0; i < PIVOT_N_AREAS; i++)
+ table_area_style_uninit (&look->areas[i]);
+ free (look->continuation);
+ free (look);
+ }
+ }
}
\f
/* Axes. */
table->title = title;
table->subtype = subtype ? pivot_value_new_text (subtype) : NULL;
table->command_c = output_get_command_name ();
-
- pivot_table_look_init (&table->look);
+ table->look = pivot_table_look_ref (pivot_table_look_builtin_default ());
hmap_init (&table->cells);
return;
free (table->current_layer);
- pivot_table_look_uninit (&table->look);
+ pivot_table_look_unref (table->look);
for (int i = 0; i < TABLE_N_AXES; i++)
pivot_table_sizing_uninit (&table->sizing[i]);
const struct pivot_table_look *
pivot_table_get_look (const struct pivot_table *table)
{
- return &table->look;
+ return table->look;
}
void
pivot_table_set_look (struct pivot_table *table,
const struct pivot_table_look *look)
{
- pivot_table_look_uninit (&table->look);
- pivot_table_look_copy (&table->look, look);
+ pivot_table_look_unref (table->look);
+ table->look = pivot_table_look_ref (look);
}
/* Sets the format used for PIVOT_RC_COUNT cells to the one used for variable
struct pivot_footnote *f = xmalloc (sizeof *f);
f->idx = table->n_footnotes;
f->marker = pivot_make_default_footnote_marker (
- f->idx, table->look.show_numeric_markers);
+ f->idx, table->look->show_numeric_markers);
f->content = NULL;
f->show = true;
{
pivot_axis_assign_label_depth (table, PIVOT_AXIS_COLUMN, false);
if (pivot_axis_assign_label_depth (
- table, PIVOT_AXIS_ROW, (table->look.row_labels_in_corner
+ table, PIVOT_AXIS_ROW, (table->look->row_labels_in_corner
&& !table->corner_text))
&& table->axes[PIVOT_AXIS_COLUMN].label_depth == 0)
table->axes[PIVOT_AXIS_COLUMN].label_depth = 1;
pivot_table_dump_string (table->dataset, "dataset", indentation);
pivot_table_dump_string (table->datafile, "datafile", indentation);
pivot_table_dump_string (table->notes, "notes", indentation);
- pivot_table_dump_string (table->look.name, "table-look", indentation);
+ pivot_table_dump_string (table->look->name, "table-look", indentation);
if (table->date)
{
indent (indentation);
indent (indentation);
printf ("sizing:\n");
- pivot_table_sizing_dump ("column", table->look.width_ranges[TABLE_HORZ],
+ pivot_table_sizing_dump ("column", table->look->width_ranges[TABLE_HORZ],
&table->sizing[TABLE_HORZ], indentation + 1);
- pivot_table_sizing_dump ("row", table->look.width_ranges[TABLE_VERT],
+ pivot_table_sizing_dump ("row", table->look->width_ranges[TABLE_VERT],
&table->sizing[TABLE_VERT], indentation + 1);
indent (indentation);
printf ("areas:\n");
for (enum pivot_area area = 0; area < PIVOT_N_AREAS; area++)
- table_area_style_dump (area, &table->look.areas[area], indentation + 1);
+ table_area_style_dump (area, &table->look->areas[area], indentation + 1);
indent (indentation);
printf ("borders:\n");
for (enum pivot_border border = 0; border < PIVOT_N_BORDERS; border++)
- table_border_style_dump (border, &table->look.borders[border],
+ table_border_style_dump (border, &table->look->borders[border],
indentation + 1);
for (size_t i = 0; i < table->n_dimensions; i++)
putchar ('\n');
size_t *column_enumeration = pivot_table_enumerate_axis (
- table, PIVOT_AXIS_COLUMN, layer_indexes, table->look.omit_empty, NULL);
+ table, PIVOT_AXIS_COLUMN, layer_indexes, table->look->omit_empty, NULL);
size_t *row_enumeration = pivot_table_enumerate_axis (
- table, PIVOT_AXIS_ROW, layer_indexes, table->look.omit_empty, NULL);
+ table, PIVOT_AXIS_ROW, layer_indexes, table->look->omit_empty, NULL);
char ***column_headings = compose_headings (
&table->axes[PIVOT_AXIS_COLUMN], column_enumeration,
};
const char *pivot_area_to_string (enum pivot_area);
-const struct table_area_style *pivot_area_get_default_style (enum pivot_area);
/* Table borders for styling purposes. */
enum pivot_border
};
const char *pivot_border_to_string (enum pivot_border);
-void pivot_border_get_default_style (enum pivot_border,
- struct table_border_style *);
/* Sizing for rows or columns of a rendered table. The comments below talk
about columns and their widths but they apply equally to rows and their
because that's how SPSS documentation and file formats do it. */
struct pivot_table_look
{
+ /* Reference count. A pivot_table_look may be shared between multiple
+ owners, indicated by a reference count greater than 1. When this is the
+ case, the pivot_table must not be modified. */
+ int ref_cnt;
+
char *name; /* May be null. */
/* General properties. */
size_t n_orphan_lines;
};
-void pivot_table_look_init (struct pivot_table_look *);
-void pivot_table_look_uninit (struct pivot_table_look *);
-void pivot_table_look_copy (struct pivot_table_look *,
- const struct pivot_table_look *);
+const struct pivot_table_look *pivot_table_look_builtin_default (void);
+struct pivot_table_look *pivot_table_look_new_builtin_default (void);
+struct pivot_table_look *pivot_table_look_ref (
+ const struct pivot_table_look *);
+void pivot_table_look_unref (struct pivot_table_look *);
+struct pivot_table_look *pivot_table_look_unshare (struct pivot_table_look *);
\f
/* A pivot table. See the top of this file for more information. */
struct pivot_table
int ref_cnt;
/* Styling. */
- struct pivot_table_look look;
+ struct pivot_table_look *look;
/* Display settings. */
bool rotate_inner_column_labels;
if (lf->label->purpose == SPVDX_PURPOSE_TITLE)
{
target = &table->title;
- area = &table->look.areas[PIVOT_AREA_TITLE];
+ area = &table->look->areas[PIVOT_AREA_TITLE];
}
else if (lf->label->purpose == SPVDX_PURPOSE_SUB_TITLE)
{
target = &table->caption;
- area = &table->look.areas[PIVOT_AREA_CAPTION];
+ area = &table->look->areas[PIVOT_AREA_CAPTION];
}
else if (lf->label->purpose == SPVDX_PURPOSE_FOOTNOTE)
{
&& lf->label->text[0]->uses_reference != INT_MIN)
{
target = NULL;
- area = &table->look.areas[PIVOT_AREA_FOOTER];
+ area = &table->look->areas[PIVOT_AREA_FOOTER];
}
else
return NULL;
else if (lf->label->purpose == SPVDX_PURPOSE_LAYER)
{
target = NULL;
- area = &table->look.areas[PIVOT_AREA_LAYERS];
+ area = &table->look->areas[PIVOT_AREA_LAYERS];
}
else
return NULL;
{
struct table_area_style *area
= (axis_type == PIVOT_AXIS_COLUMN
- ? &table->look.areas[PIVOT_AREA_COLUMN_LABELS]
+ ? &table->look->areas[PIVOT_AREA_COLUMN_LABELS]
: axis_type == PIVOT_AXIS_ROW
- ? &table->look.areas[PIVOT_AREA_ROW_LABELS]
+ ? &table->look->areas[PIVOT_AREA_ROW_LABELS]
: NULL);
if (area && fl->axis->label)
{
decode_spvdx_style_incremental (
fl2->axis->major_ticks->style,
fl2->axis->major_ticks->tick_frame_style,
- &table->look.areas[PIVOT_AREA_ROW_LABELS]);
+ &table->look->areas[PIVOT_AREA_ROW_LABELS]);
}
const struct spvdx_facet_level *fl3 = find_facet_level (v, base_facet_level);
/* Sets alt_fg_color and alt_bg_color. */
struct table_area_style area;
decode_spvdx_style (labeling, graph, &area);
- table->look.areas[PIVOT_AREA_DATA].font_style.fg[1]
+ table->look->areas[PIVOT_AREA_DATA].font_style.fg[1]
= area.font_style.fg[0];
- table->look.areas[PIVOT_AREA_DATA].font_style.bg[1]
+ table->look->areas[PIVOT_AREA_DATA].font_style.bg[1]
= area.font_style.bg[0];
table_area_style_uninit (&area);
}
{
const struct table_area_style *base_area_style
= (c->dimension->axis_type == PIVOT_AXIS_ROW
- ? &table->look.areas[PIVOT_AREA_ROW_LABELS]
- : &table->look.areas[PIVOT_AREA_COLUMN_LABELS]);
+ ? &table->look->areas[PIVOT_AREA_ROW_LABELS]
+ : &table->look->areas[PIVOT_AREA_COLUMN_LABELS]);
apply_styles_to_value (table, c->name, set_format,
base_area_style, major_ticks, frame);
}
goto skip;
}
apply_styles_to_value (table, cell->value, set_format,
- &table->look.areas[PIVOT_AREA_DATA],
+ &table->look->areas[PIVOT_AREA_DATA],
labeling, interval);
skip: ;
struct pivot_cell *cell;
HMAP_FOR_EACH (cell, struct pivot_cell, hmap_node, &table->cells)
apply_styles_to_value (table, cell->value, set_format,
- &table->look.areas[PIVOT_AREA_DATA],
+ &table->look->areas[PIVOT_AREA_DATA],
NULL, NULL);
}
}
struct spv_data *data, struct pivot_table **outp)
{
struct pivot_table *table = pivot_table_create__ (NULL, subtype);
+
pivot_table_set_look (table, look);
+ table->look = pivot_table_look_unshare (table->look);
struct hmap series_map = HMAP_INITIALIZER (series_map);
struct hmap format_map = HMAP_INITIALIZER (format_map);
&min_width, &max_width, &n)
&& v->graph->cell_style->width[n] == '\0')
{
- table->look.width_ranges[TABLE_HORZ][0] = min_width;
- table->look.width_ranges[TABLE_HORZ][1] = max_width;
+ table->look->width_ranges[TABLE_HORZ][0] = min_width;
+ table->look->width_ranges[TABLE_HORZ][1] = max_width;
}
}
}
if (v->graph->interval->labeling->style)
{
- table_area_style_uninit (&table->look.areas[PIVOT_AREA_DATA]);
+ table_area_style_uninit (&table->look->areas[PIVOT_AREA_DATA]);
decode_spvdx_style (v->graph->interval->labeling->style,
v->graph->cell_style,
- &table->look.areas[PIVOT_AREA_DATA]);
+ &table->look->areas[PIVOT_AREA_DATA]);
}
/* Decode all of the sourceVariable and derivedVariable */
if (in->border_type >= PIVOT_N_BORDERS)
return xasprintf ("bad border type %"PRIu32, in->border_type);
- struct table_border_style *out = &table->look.borders[in->border_type];
+ struct table_border_style *out = &table->look->borders[in->border_type];
out->color = decode_spvlb_color_u32 (in->color);
return decode_spvlb_stroke (in->stroke_type, &out->stroke);
}
struct pivot_table *out = xzalloc (sizeof *out);
out->ref_cnt = 1;
hmap_init (&out->cells);
+ out->look = pivot_table_look_new_builtin_default ();
const struct spvlb_y1 *y1 = (in->formats->x0 ? in->formats->x0->y1
: in->formats->x3 ? in->formats->x3->y1
}
/* Display settings. */
- out->look.show_numeric_markers = !in->ts->show_alphabetic_markers;
+ out->look->show_numeric_markers = !in->ts->show_alphabetic_markers;
out->rotate_inner_column_labels = in->header->rotate_inner_column_labels;
out->rotate_outer_row_labels = in->header->rotate_outer_row_labels;
- out->look.row_labels_in_corner = in->ts->show_row_labels_in_corner;
+ out->look->row_labels_in_corner = in->ts->show_row_labels_in_corner;
out->show_grid_lines = in->borders->show_grid_lines;
out->show_caption = true;
- out->look.footnote_marker_superscripts = in->ts->footnote_marker_superscripts;
- out->look.omit_empty = in->ts->omit_empty;
+ out->look->footnote_marker_superscripts = in->ts->footnote_marker_superscripts;
+ out->look->omit_empty = in->ts->omit_empty;
const struct spvlb_x1 *x1 = in->formats->x1;
if (x1)
}
/* Column and row display settings. */
- out->look.width_ranges[TABLE_VERT][0] = in->header->min_row_height;
- out->look.width_ranges[TABLE_VERT][1] = in->header->max_row_height;
- out->look.width_ranges[TABLE_HORZ][0] = in->header->min_col_width;
- out->look.width_ranges[TABLE_HORZ][1] = in->header->max_col_width;
+ out->look->width_ranges[TABLE_VERT][0] = in->header->min_row_height;
+ out->look->width_ranges[TABLE_VERT][1] = in->header->max_row_height;
+ out->look->width_ranges[TABLE_HORZ][0] = in->header->min_col_width;
+ out->look->width_ranges[TABLE_HORZ][1] = in->header->max_col_width;
convert_widths (in->formats->widths, in->formats->n_widths,
&out->sizing[TABLE_HORZ].widths,
&out->sizing[TABLE_HORZ].n_keeps);
out->notes = to_utf8_if_nonempty (in->ts->notes, encoding);
- out->look.name = to_utf8_if_nonempty (in->ts->table_look, encoding);
+ out->look->name = to_utf8_if_nonempty (in->ts->table_look, encoding);
/* Print settings. */
- out->look.print_all_layers = in->ps->all_layers;
- out->look.paginate_layers = in->ps->paginate_layers;
- out->look.shrink_to_fit[TABLE_HORZ] = in->ps->fit_width;
- out->look.shrink_to_fit[TABLE_VERT] = in->ps->fit_length;
- out->look.top_continuation = in->ps->top_continuation;
- out->look.bottom_continuation = in->ps->bottom_continuation;
- out->look.continuation = xstrdup (in->ps->continuation_string);
- out->look.n_orphan_lines = in->ps->n_orphan_lines;
+ out->look->print_all_layers = in->ps->all_layers;
+ out->look->paginate_layers = in->ps->paginate_layers;
+ out->look->shrink_to_fit[TABLE_HORZ] = in->ps->fit_width;
+ out->look->shrink_to_fit[TABLE_VERT] = in->ps->fit_length;
+ out->look->top_continuation = in->ps->top_continuation;
+ out->look->bottom_continuation = in->ps->bottom_continuation;
+ out->look->continuation = xstrdup (in->ps->continuation_string);
+ out->look->n_orphan_lines = in->ps->n_orphan_lines;
/* Format settings. */
out->epoch = in->formats->y0->epoch;
/* Styles. */
for (size_t i = 0; i < PIVOT_N_AREAS; i++)
{
- error = decode_spvlb_area (in->areas->areas[i], &out->look.areas[i],
+ error = decode_spvlb_area (in->areas->areas[i], &out->look->areas[i],
encoding);
if (error)
goto error;
spv_table_look_decode (const struct spvsx_table_properties *in,
struct pivot_table_look **outp)
{
- struct pivot_table_look *out = xzalloc (sizeof *out);
+ struct pivot_table_look *out = pivot_table_look_new_builtin_default ();
char *error = NULL;
out->name = in->name ? xstrdup (in->name) : NULL;
out->show_numeric_markers
= (f->number_format == SPVSX_NUMBER_FORMAT_NUMERIC);
- for (int i = 0; i < PIVOT_N_AREAS; i++)
- table_area_style_copy (NULL, &out->areas[i],
- pivot_area_get_default_style (i));
-
const struct spvsx_cell_format_properties *cfp = in->cell_format_properties;
for (size_t i = 0; i < cfp->n_cell_style; i++)
{
1);
}
- for (int i = 0; i < PIVOT_N_BORDERS; i++)
- pivot_border_get_default_style (i, &out->borders[i]);
-
const struct spvsx_border_properties *bp = in->border_properties;
for (size_t i = 0; i < bp->n_border_style; i++)
{
out->shrink_to_fit[TABLE_VERT] = pp->rescale_long_table_to_fit_page > 0;
out->top_continuation = pp->continuation_text_at_top > 0;
out->bottom_continuation = pp->continuation_text_at_bottom > 0;
+ free (out->continuation);
out->continuation = xstrdup (pp->continuation_text
? pp->continuation_text : "(cont.)");
out->n_orphan_lines = optional_int (pp->window_orphan_lines, 2);
return NULL;
error:
- pivot_table_look_uninit (out);
- free (out);
+ pivot_table_look_unref (out);
*outp = NULL;
return error;
}
static struct pivot_table_look *
tlo_decode (const struct tlo_table_look *in)
{
- struct pivot_table_look *out = xmalloc (sizeof *out);
- pivot_table_look_init (out);
+ struct pivot_table_look *out = pivot_table_look_new_builtin_default ();
const uint16_t flags = in->tl->flags;
out->shrink_to_fit[TABLE_VERT] = flags & 0x20;
out->top_continuation = flags & 0x80;
out->bottom_continuation = flags & 0x100;
+ if (in->v2_styles)
+ {
+ free (out->continuation);
+ out->continuation = xmemdup0 (in->v2_styles->continuation,
+ in->v2_styles->continuation_len);
+ }
/* n_orphan_lines isn't in .tlo files AFAICT. */
return out;
put_bool (buf, table->rotate_outer_row_labels);
put_bool (buf, true);
put_u32 (buf, 0x15);
- put_u32 (buf, table->look.width_ranges[H][0]);
- put_u32 (buf, table->look.width_ranges[H][1]);
- put_u32 (buf, table->look.width_ranges[V][0]);
- put_u32 (buf, table->look.width_ranges[V][1]);
+ put_u32 (buf, table->look->width_ranges[H][0]);
+ put_u32 (buf, table->look->width_ranges[H][1]);
+ put_u32 (buf, table->look->width_ranges[V][0]);
+ put_u32 (buf, table->look->width_ranges[V][1]);
put_u64 (buf, table_id);
/* Titles. */
/* Areas. */
for (size_t i = 0; i < PIVOT_N_AREAS; i++)
{
- const struct table_area_style *a = &table->look.areas[i];
+ const struct table_area_style *a = &table->look->areas[i];
put_byte (buf, i + 1);
put_byte (buf, 0x31);
put_string (buf, (a->font_style.typeface
put_be32 (buf, PIVOT_N_BORDERS);
for (size_t i = 0; i < PIVOT_N_BORDERS; i++)
{
- const struct table_border_style *b = &table->look.borders[i];
+ const struct table_border_style *b = &table->look->borders[i];
put_be32 (buf, i);
put_be32 (buf, (b->stroke == TABLE_STROKE_NONE ? 0
: b->stroke == TABLE_STROKE_SOLID ? 1
/* Print Settings. */
uint32_t ps_start = start_count (buf);
put_be32 (buf, 1);
- put_bool (buf, table->look.print_all_layers);
- put_bool (buf, table->look.paginate_layers);
- put_bool (buf, table->look.shrink_to_fit[H]);
- put_bool (buf, table->look.shrink_to_fit[V]);
- put_bool (buf, table->look.top_continuation);
- put_bool (buf, table->look.bottom_continuation);
- put_be32 (buf, table->look.n_orphan_lines);
- put_bestring (buf, table->look.continuation);
+ put_bool (buf, table->look->print_all_layers);
+ put_bool (buf, table->look->paginate_layers);
+ put_bool (buf, table->look->shrink_to_fit[H]);
+ put_bool (buf, table->look->shrink_to_fit[V]);
+ put_bool (buf, table->look->top_continuation);
+ put_bool (buf, table->look->bottom_continuation);
+ put_be32 (buf, table->look->n_orphan_lines);
+ put_bestring (buf, table->look->continuation);
end_count_u32 (buf, ps_start);
/* Table Settings. */
put_be32 (buf, 1);
put_be32 (buf, 4);
put_be32 (buf, 0); /* XXX current_layer */
- put_bool (buf, table->look.omit_empty);
- put_bool (buf, table->look.row_labels_in_corner);
- put_bool (buf, !table->look.show_numeric_markers);
- put_bool (buf, table->look.footnote_marker_superscripts);
+ put_bool (buf, table->look->omit_empty);
+ put_bool (buf, table->look->row_labels_in_corner);
+ put_bool (buf, !table->look->show_numeric_markers);
+ put_bool (buf, table->look->footnote_marker_superscripts);
put_byte (buf, 0);
uint32_t keep_start = start_count (buf);
put_be32 (buf, 0); /* n-row-breaks */
put_be32 (buf, 0); /* n-column-point-keeps */
end_count_be32 (buf, keep_start);
put_bestring (buf, table->notes);
- put_bestring (buf, table->look.name);
+ put_bestring (buf, table->look->name);
for (size_t i = 0; i < 82; i++)
put_byte (buf, 0);
end_count_u32 (buf, ts_start);
free (item->children);
pivot_table_unref (item->table);
- if (item->table_look)
- {
- pivot_table_look_uninit (item->table_look);
- free (item->table_look);
- }
+ pivot_table_look_unref (item->table_look);
free (item->bin_member);
free (item->xml_member);
free (item->subtype);
if (err)
error (1, 0, "%s", err);
- pivot_table_look_uninit (look);
+ pivot_table_look_unref (look);
free (look);
}
c->run (argc, argv);
- if (table_look)
- {
- pivot_table_look_uninit (table_look);
- free (table_look);
- }
+ pivot_table_look_unref (table_look);
i18n_done ();
return n_warnings ? EXIT_FAILURE : EXIT_SUCCESS;
static void
parse_table_look (const char *arg)
{
- if (table_look)
- {
- pivot_table_look_uninit (table_look);
- free (table_look);
- }
+ pivot_table_look_unref (table_look);
char *error_s = spv_table_look_read (arg, &table_look);
if (error_s)