bool[rotate-outer-row-labels]
bool[x2]
int32[x3]
- int32[min-col-width] int32[max-col-width]
- int32[min-row-width] int32[max-row-width]
+ int32[min-col-heading-width] int32[max-col-heading-width]
+ int32[min-row-heading-width] int32[max-row-heading-width]
int64[table-id]
@end example
the data are rotated 90° counterclockwise; otherwise, they are shown
in the normal way.
-@code{min-col-width} is the minimum width that a column will be
-assigned automatically. @code{max-col-width} is the maximum width
-that a column will be assigned to accommodate a long column label.
-@code{min-row-width} and @code{max-row-width} are a similar range for
-the width of row labels. All of these measurements are in 1/96 inch
-units (called a ``device independent pixel'' unit in Windows).
+@code{min-col-heading-width}, @code{max-col-heading-width}, @code{min-row-heading-width}, and
+@code{max-row-heading-width} are measurements in 1/96 inch units (called
+``device independent pixel'' units in Windows) whose values influence
+column widths. For the purpose of interpreting these values, a table
+is divided into the three regions shown below:
+
+@example
++------------------+-------------------------------------------------+
+| | column headings |
+| +-------------------------------------------------+
+| corner | |
+| and | |
+| row headings | data |
+| | |
+| | |
++------------------+-------------------------------------------------+
+@end example
+
+@code{min-col-heading-width} and @code{max-col-heading-width} apply to the columns in
+the column headings region. @code{min-col-heading-width} is the minimum width
+that any of these columns will be given automatically. In addition,
+@code{max-col-heading-width} is the maximum width that a column will be
+assigned to accommodate a long label in the column headings cells.
+These columns will still be made wider to accommodate wide data values
+in the data region.
+
+@code{min-row-heading-width} is the minimum width that a column in the corner
+and row headings region will be given automatically.
+@code{max-col-heading-width} is the maximum width that a column in this region
+will be assigned to accomodate a long label. This region doesn't
+include data, so data values don't affect column widths.
@code{table-id} is a binary version of the @code{tableId} attribute in
the structure member that refers to the detail member. For example,
for (size_t i = 0; i < 2; i++)
if (widths[i] != SYSMIS)
{
- int *wr = ct->look->width_ranges[TABLE_HORZ];
+ int *wr = ct->look->col_heading_width_range;
wr[i] = widths[i] / units_per_inch * 96.0;
if (wr[0] > wr[1])
wr[!i] = wr[i];
.size = { [H] = style->size[H], [V] = style->size[V] },
.line_widths = xr_line_widths,
.min_break = { [H] = style->min_break[H], [V] = style->min_break[V] },
+ .px_size = px_to_xr (1),
.supports_margins = true,
.rtl = render_direction_rtl (),
.printing = print,
.omit_empty = true,
.row_labels_in_corner = true,
- .width_ranges = {
- [TABLE_HORZ] = { 36, 72 },
- [TABLE_VERT] = { 36, 120 },
- },
+ .col_heading_width_range = { 36, 72 },
+ .row_heading_width_range = { 36, 120 },
.areas = {
#define AREA(BOLD, H, V, L, R, T, B) { \
indent (indentation);
printf ("sizing:\n");
- pivot_table_sizing_dump ("column", table->look->width_ranges[TABLE_HORZ],
+ pivot_table_sizing_dump ("column", table->look->col_heading_width_range,
&table->sizing[TABLE_HORZ], indentation + 1);
- pivot_table_sizing_dump ("row", table->look->width_ranges[TABLE_VERT],
+ pivot_table_sizing_dump ("row", table->look->row_heading_width_range,
&table->sizing[TABLE_VERT], indentation + 1);
indent (indentation);
char *name; /* May be null. */
- /* General properties. */
+ /* General properties.
+
+ col_heading_width_range and row_heading_width_range is minimum and
+ maximum width of columns based on their column heading labels, in 1/96"
+ units. row_heading_width_range is for columns in the row headings and
+ corner, and col_heading_width_range is for columns in the column
+ headings.
+ */
bool omit_empty;
bool row_labels_in_corner;
- int width_ranges[TABLE_N_AXES][2]; /* In 1/96" units. */
+ int row_heading_width_range[2];
+ int col_heading_width_range[2];
/* Footnote display settings. */
bool show_numeric_markers;
so no part of the cell's content is lost (and in fact it is duplicated
across both pages). */
int *join_crossing[TABLE_N_AXES];
+
+ /* Minimum and maximum widths of columns based on headings.
+
+ For this purpose, a table has the following three regions:
+
+ +------------------+-------------------------------------------------+
+ | | column headings |
+ | +-------------------------------------------------+
+ | corner | |
+ | and | |
+ | row headings | data |
+ | | |
+ | | |
+ +------------------+-------------------------------------------------+
+
+ - width_ranges[TABLE_HORZ] controls the minimum and maximum width that
+ columns in the column headings will be based on the column headings
+ themselves. That is, these columns will have width at least
+ width_ranges[TABLE_HORZ][0] wide, and no more than
+ width_ranges[TABLE_HORZ][1] unless the data requires it.
+
+ - width_ranges[TABLE_VERT] controls the minimum and maximum width that
+ columns in the corner and row headings will be based on the corner and
+ row headings themselves. That is, these columns will have width at
+ least width_ranges[TABLE_VERT][0] wide, and no more than
+ width_ranges[TABLE_VERT][1]. (The corner and row headings don't have
+ data in their columns so data can't affect their widths.)
+ */
+ int width_ranges[TABLE_N_AXES][2];
};
static struct render_page *render_page_create (const struct render_params *,
- struct table *, int min_width);
+ struct table *, int min_width,
+ const struct pivot_table_look *);
struct render_page *render_page_ref (const struct render_page *page_);
static void render_page_unref (struct render_page *);
}
}
-/* Creates and returns a new render_page for rendering TABLE on a device
- described by PARAMS.
+/* Creates and returns a new render_page for rendering TABLE with the given
+ LOOK on a device described by PARAMS.
The new render_page will be suitable for rendering on a device whose page
size is PARAMS->size, but the caller is responsible for actually breaking it
up to fit on such a device, using the render_break abstraction. */
static struct render_page *
render_page_create (const struct render_params *params, struct table *table,
- int min_width)
+ int min_width, const struct pivot_table_look *look)
{
enum { MIN, MAX };
rules[axis][z] = measure_rule (params, table, axis, z);
}
+ int col_heading_width_range[2];
+ int row_heading_width_range[2];
+ for (int i = 0; i < 2; i++)
+ col_heading_width_range[i] = look->col_heading_width_range[i] * params->px_size;
+ for (int i = 0; i < 2; i++)
+ row_heading_width_range[i] = look->row_heading_width_range[i] * params->px_size;
+
/* Calculate minimum and maximum widths of cells that do not
span multiple columns. */
struct render_row *columns[2];
int w[2];
params->ops->measure_cell_width (params->aux, &cell,
&w[MIN], &w[MAX]);
+
+ if (params->px_size)
+ {
+ const int *wr = (x < table->h[H][0] ? row_heading_width_range
+ : y < table->h[V][0] ? col_heading_width_range
+ : NULL);
+ if (wr)
+ {
+ if (w[0] < wr[0])
+ {
+ w[0] = wr[0];
+ if (w[0] > w[1])
+ w[1] = w[0];
+ }
+ else if (w[1] > wr[1])
+ {
+ w[1] = wr[1];
+ if (w[1] < w[0])
+ w[0] = w[1];
+ }
+ }
+ }
+
for (int i = 0; i < 2; i++)
if (columns[i][x].unspanned < w[i])
columns[i][x].unspanned = w[i];
static void
render_pager_add_table (struct render_pager *p, struct table *table,
- int min_width)
+ int min_width, const struct pivot_table_look *look)
{
if (table)
- p->pages[p->n_pages++] = render_page_create (p->params, table, min_width);
+ p->pages[p->n_pages++] = render_page_create (p->params, table, min_width,
+ look);
}
static void
/* Figure out the width of the body of the table. Use this to determine the
base scale. */
- struct render_page *body_page = render_page_create (params, body, 0);
+ struct render_page *body_page = render_page_create (params, body, 0, pt->look);
int body_width = table_width (body_page, H);
double scale = 1.0;
if (body_width > params->size[H])
/* Create the pager. */
struct render_pager *p = xmalloc (sizeof *p);
*p = (struct render_pager) { .params = params, .scale = scale };
- render_pager_add_table (p, title, body_width);
- render_pager_add_table (p, layers, body_width);
+ render_pager_add_table (p, title, body_width, pt->look);
+ render_pager_add_table (p, layers, body_width, pt->look);
p->pages[p->n_pages++] = body_page;
- render_pager_add_table (p, caption, 0);
- render_pager_add_table (p, footnotes, 0);
+ render_pager_add_table (p, caption, 0, pt->look);
+ render_pager_add_table (p, footnotes, 0, pt->look);
assert (p->n_pages <= sizeof p->pages / sizeof *p->pages);
/* If we're shrinking tables to fit the page length, then adjust the scale
/* Width of different kinds of lines. */
const int *line_widths; /* RENDER_N_LINES members. */
+ /* 1/96" of an inch (1px) in the rendering unit. Currently used only for
+ column width ranges (as specified in width_ranges in struct
+ pivot_table_look). Set to 0 to disable this feature. */
+ int px_size;
+
/* Minimum cell width or height before allowing the cell to be broken
across two pages. (Joined cells may always be broken at join
points.) */
bool[rotate-outer-row-labels]
bool[x2]
int32[x3]
- int32[min-col-width] int32[max-col-width]
- int32[min-row-height] int32[max-row-height]
+ int32[min-col-heading-width] int32[max-col-heading-width]
+ int32[min-row-heading-width] int32[max-row-heading-width]
int64[table-id]
Titles =>
&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->col_heading_width_range[0] = min_width;
+ table->look->col_heading_width_range[1] = max_width;
}
}
}
/* 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->row_heading_width_range[0] = in->header->min_row_heading_width;
+ out->look->row_heading_width_range[1] = in->header->max_row_heading_width;
+ out->look->col_heading_width_range[0] = in->header->min_col_heading_width;
+ out->look->col_heading_width_range[1] = in->header->max_col_heading_width;
convert_widths (in->formats->widths, in->formats->n_widths,
&out->sizing[TABLE_HORZ].widths,
const struct spvsx_general_properties *g = in->general_properties;
out->omit_empty = g->hide_empty_rows != 0;
- out->width_ranges[TABLE_HORZ][0] = optional_pt (g->minimum_column_width, -1);
- out->width_ranges[TABLE_HORZ][1] = optional_pt (g->maximum_column_width, -1);
- out->width_ranges[TABLE_VERT][0] = optional_pt (g->minimum_row_width, -1);
- out->width_ranges[TABLE_VERT][1] = optional_pt (g->maximum_row_width, -1);
+ out->col_heading_width_range[0] = optional_pt (g->minimum_column_width, -1);
+ out->col_heading_width_range[1] = optional_pt (g->maximum_column_width, -1);
+ out->row_heading_width_range[0] = optional_pt (g->minimum_row_width, -1);
+ out->row_heading_width_range[1] = optional_pt (g->maximum_row_width, -1);
out->row_labels_in_corner
= g->row_dimension_labels != SPVSX_ROW_DIMENSION_LABELS_NESTED;
out->row_labels_in_corner = !in->tl->nested_row_labels;
if (in->v2_styles)
{
- out->width_ranges[TABLE_HORZ][0] = in->v2_styles->min_col_width;
- out->width_ranges[TABLE_HORZ][1] = in->v2_styles->max_col_width;
- out->width_ranges[TABLE_VERT][0] = in->v2_styles->min_row_height;
- out->width_ranges[TABLE_VERT][1] = in->v2_styles->max_row_height;
+ out->col_heading_width_range[0] = in->v2_styles->min_col_heading_width;
+ out->col_heading_width_range[1] = in->v2_styles->max_col_heading_width;
+ out->row_heading_width_range[0] = in->v2_styles->min_row_heading_width;
+ out->row_heading_width_range[1] = in->v2_styles->max_row_heading_width;
}
else
{
- out->width_ranges[TABLE_HORZ][0] = 36;
- out->width_ranges[TABLE_HORZ][1] = 72;
- out->width_ranges[TABLE_VERT][0] = 36;
- out->width_ranges[TABLE_VERT][1] = 120;
+ out->col_heading_width_range[0] = 36;
+ out->col_heading_width_range[1] = 72;
+ out->row_heading_width_range[0] = 36;
+ out->row_heading_width_range[1] = 120;
}
out->show_numeric_markers = flags & 0x04;
start_elem (xml, "generalProperties");
write_attr_bool (xml, "hideEmptyRows", look->omit_empty);
- const int (*wr)[2] = look->width_ranges;
- write_attr_format (xml, "maximumColumnWidth", "%d", wr[TABLE_HORZ][1]);
- write_attr_format (xml, "maximumRowWidth", "%d", wr[TABLE_VERT][1]);
- write_attr_format (xml, "minimumColumnWidth", "%d", wr[TABLE_HORZ][0]);
- write_attr_format (xml, "minimumRowWidth", "%d", wr[TABLE_VERT][0]);
+ const int *chwr = look->col_heading_width_range;
+ const int *rhwr = look->row_heading_width_range;
+ write_attr_format (xml, "maximumColumnWidth", "%d", chwr[1]);
+ write_attr_format (xml, "maximumRowWidth", "%d", rhwr[1]);
+ write_attr_format (xml, "minimumColumnWidth", "%d", chwr[0]);
+ write_attr_format (xml, "minimumRowWidth", "%d", rhwr[0]);
write_attr (xml, "rowDimensionLabels",
look->row_labels_in_corner ? "inCorner" : "nested");
end_elem (xml);
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->col_heading_width_range[0]);
+ put_u32 (buf, table->look->col_heading_width_range[1]);
+ put_u32 (buf, table->look->row_heading_width_range[0]);
+ put_u32 (buf, table->look->row_heading_width_range[1]);
put_u64 (buf, table_id);
/* Titles. */
V2Styles =>
Separator*11[sep3]
byte[continuation-len] byte*[continuation-len][continuation]
- int32[min-col-width] int32[max-col-width]
- int32[min-row-height] int32[max-row-height]
+ int32[min-col-heading-width] int32[max-col-heading-width]
+ int32[min-row-heading-width] int32[max-row-heading-width]