#include "gl/xalloc.h"
+/* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */
+#define H TABLE_HORZ
+#define V TABLE_VERT
+
/* Increases TABLE's reference count, indicating that it has an additional
owner. An table that is shared among multiple owners must not be
modified. */
return table->ref_cnt > 1;
}
\f
-struct area_style *
-area_style_clone (struct pool *pool, const struct area_style *old)
+struct table_area_style *
+table_area_style_clone (struct pool *pool, const struct table_area_style *old)
{
- struct area_style *new = pool_malloc (pool, sizeof *new);
+ struct table_area_style *new = pool_malloc (pool, sizeof *new);
*new = *old;
if (new->font_style.typeface)
new->font_style.typeface = pool_strdup (pool, new->font_style.typeface);
}
void
-area_style_free (struct area_style *style)
+table_area_style_free (struct table_area_style *style)
{
if (style)
{
size_t n = 0;
struct table *t = item->table;
- for (int y = 0; y < table_nr (t); y++)
+ for (int y = 0; y < t->n[V]; y++)
{
struct table_cell cell;
- for (int x = 0; x < table_nc (t); x = cell.d[TABLE_HORZ][1])
+ for (int x = 0; x < t->n[H]; x = cell.d[TABLE_HORZ][1])
{
table_get_cell (t, x, y, &cell);
return n_nonnull;
}
\f
-/* Returns a table that contains a single cell, whose contents are the
- left-aligned TEXT. */
-struct table *
-table_from_string (const char *text)
-{
- struct table *t = table_create (1, 1, 0, 0, 0, 0);
- t->styles[0] = xmalloc (sizeof *t->styles[0]);
- *t->styles[0] = (struct area_style) {
- AREA_STYLE_INITIALIZER__,
- .cell_style.halign = TABLE_HALIGN_LEFT,
- .cell_style.valign = TABLE_VALIGN_TOP
- };
- table_text (t, 0, 0, 0 << TAB_STYLE_SHIFT, text);
- return t;
-}
-\f
const char *
table_halign_to_string (enum table_halign halign)
{
}
void
-area_style_copy (struct pool *container,
- struct area_style *dst, const struct area_style *src)
+table_area_style_copy (struct pool *container, struct table_area_style *dst,
+ const struct table_area_style *src)
{
font_style_copy (container, &dst->font_style, &src->font_style);
dst->cell_style = src->cell_style;
}
void
-area_style_uninit (struct area_style *area)
+table_area_style_uninit (struct table_area_style *area)
{
if (area)
font_style_uninit (&area->font_style);
{
if (debugging)
{
- if (x < 0 || x > table_nc (t)
- || y1 < 0 || y1 >= table_nr (t)
- || y2 < 0 || y2 >= table_nr (t))
+ if (x < 0 || x > t->n[H]
+ || y1 < 0 || y1 >= t->n[V]
+ || y2 < 0 || y2 >= t->n[V])
{
printf ("bad vline: x=%d y=(%d,%d) in table size (%d,%d)\n",
- x, y1, y2, table_nc (t), table_nr (t));
+ x, y1, y2, t->n[H], t->n[V]);
return;
}
}
assert (x >= 0);
- assert (x <= table_nc (t));
+ assert (x <= t->n[H]);
assert (y1 >= 0);
assert (y2 >= y1);
- assert (y2 <= table_nr (t));
+ assert (y2 <= t->n[V]);
if (style != -1)
{
int y;
for (y = y1; y <= y2; y++)
- t->rv[x + (table_nc (t) + 1) * y] = style;
+ t->rv[x + (t->n[H] + 1) * y] = style;
}
}
{
if (debugging)
{
- if (y < 0 || y > table_nr (t)
- || x1 < 0 || x1 >= table_nc (t)
- || x2 < 0 || x2 >= table_nc (t))
+ if (y < 0 || y > t->n[V]
+ || x1 < 0 || x1 >= t->n[H]
+ || x2 < 0 || x2 >= t->n[H])
{
printf ("bad hline: x=(%d,%d) y=%d in table size (%d,%d)\n",
- x1, x2, y, table_nc (t), table_nr (t));
+ x1, x2, y, t->n[H], t->n[V]);
return;
}
}
assert (y >= 0);
- assert (y <= table_nr (t));
+ assert (y <= t->n[V]);
assert (x2 >= x1);
assert (x1 >= 0);
- assert (x2 < table_nc (t));
+ assert (x2 < t->n[H]);
if (style != -1)
{
int x;
for (x = x1; x <= x2; x++)
- t->rh[x + table_nc (t) * y] = style;
+ t->rh[x + t->n[H] * y] = style;
}
}
{
if (debugging)
{
- if (x1 < 0 || x1 >= table_nc (t)
- || x2 < 0 || x2 >= table_nc (t)
- || y1 < 0 || y1 >= table_nr (t)
- || y2 < 0 || y2 >= table_nr (t))
+ if (x1 < 0 || x1 >= t->n[H]
+ || x2 < 0 || x2 >= t->n[H]
+ || y1 < 0 || y1 >= t->n[V]
+ || y2 < 0 || y2 >= t->n[V])
{
printf ("bad box: (%d,%d)-(%d,%d) in table size (%d,%d)\n",
- x1, y1, x2, y2, table_nc (t), table_nr (t));
+ x1, y1, x2, y2, t->n[H], t->n[V]);
NOT_REACHED ();
}
}
assert (y2 >= y1);
assert (x1 >= 0);
assert (y1 >= 0);
- assert (x2 < table_nc (t));
- assert (y2 < table_nr (t));
+ assert (x2 < t->n[H]);
+ assert (y2 < t->n[V]);
if (f_h != -1)
{
int x;
for (x = x1; x <= x2; x++)
{
- t->rh[x + table_nc (t) * y1] = f_h;
- t->rh[x + table_nc (t) * (y2 + 1)] = f_h;
+ t->rh[x + t->n[H] * y1] = f_h;
+ t->rh[x + t->n[H] * (y2 + 1)] = f_h;
}
}
if (f_v != -1)
int y;
for (y = y1; y <= y2; y++)
{
- t->rv[x1 + (table_nc (t) + 1) * y] = f_v;
- t->rv[(x2 + 1) + (table_nc (t) + 1) * y] = f_v;
+ t->rv[x1 + (t->n[H] + 1) * y] = f_v;
+ t->rv[(x2 + 1) + (t->n[H] + 1) * y] = f_v;
}
}
int x;
for (x = x1; x <= x2; x++)
- t->rh[x + table_nc (t) * y] = i_h;
+ t->rh[x + t->n[H] * y] = i_h;
}
}
if (i_v != -1)
int y;
for (y = y1; y <= y2; y++)
- t->rv[x + (table_nc (t) + 1) * y] = i_v;
+ t->rv[x + (t->n[H] + 1) * y] = i_v;
}
}
}
{
assert (c >= 0);
assert (r >= 0);
- assert (c < table_nc (table));
- assert (r < table_nr (table));
+ assert (c < table->n[H]);
+ assert (r < table->n[V]);
if (debugging)
{
- if (c < 0 || r < 0 || c >= table_nc (table) || r >= table_nr (table))
+ if (c < 0 || r < 0 || c >= table->n[H] || r >= table->n[V])
{
printf ("table_text(): bad cell (%d,%d) in table size (%d,%d)\n",
- c, r, table_nc (table), table_nr (table));
+ c, r, table->n[H], table->n[V]);
return;
}
}
- table->cc[c + r * table_nc (table)] = text;
- table->ct[c + r * table_nc (table)] = opt;
+ table->cc[c + r * table->n[H]] = text;
+ table->ct[c + r * table->n[H]] = opt;
}
/* Sets cell (C,R) in TABLE, with options OPT, to have text value
assert (y1 >= 0);
assert (y2 >= y1);
assert (x2 >= x1);
- assert (y2 < table_nr (table));
- assert (x2 < table_nc (table));
+ assert (y2 < table->n[V]);
+ assert (x2 < table->n[H]);
if (debugging)
{
- if (x1 < 0 || x1 >= table_nc (table)
- || y1 < 0 || y1 >= table_nr (table)
- || x2 < x1 || x2 >= table_nc (table)
- || y2 < y1 || y2 >= table_nr (table))
+ if (x1 < 0 || x1 >= table->n[H]
+ || y1 < 0 || y1 >= table->n[V]
+ || x2 < x1 || x2 >= table->n[H]
+ || y2 < y1 || y2 >= table->n[V])
{
printf ("table_joint_text(): bad cell "
"(%d,%d)-(%d,%d) in table size (%d,%d)\n",
- x1, y1, x2, y2, table_nc (table), table_nr (table));
+ x1, y1, x2, y2, table->n[H], table->n[V]);
return NULL;
}
}
x1, y1, x2, y2);
struct table_cell *cell = pool_alloc (table->container, sizeof *cell);
- cell->d[TABLE_HORZ][0] = x1;
- cell->d[TABLE_VERT][0] = y1;
- cell->d[TABLE_HORZ][1] = ++x2;
- cell->d[TABLE_VERT][1] = ++y2;
- cell->options = opt;
- cell->footnotes = NULL;
- cell->n_footnotes = 0;
- cell->style = NULL;
-
- void **cc = &table->cc[x1 + y1 * table_nc (table)];
- unsigned short *ct = &table->ct[x1 + y1 * table_nc (table)];
- const int ofs = table_nc (table) - (x2 - x1);
+ *cell = (struct table_cell) {
+ .d = { [TABLE_HORZ] = { x1, ++x2 },
+ [TABLE_VERT] = { y1, ++y2 } },
+ .options = opt,
+ };
+
+ void **cc = &table->cc[x1 + y1 * table->n[H]];
+ unsigned short *ct = &table->ct[x1 + y1 * table->n[H]];
+ const int ofs = table->n[H] - (x2 - x1);
for (int y = y1; y < y2; y++)
{
for (int x = x1; x < x2; x++)
static struct table_cell *
get_joined_cell (struct table *table, int x, int y)
{
- int index = x + y * table_nc (table);
+ int index = x + y * table->n[H];
unsigned short opt = table->ct[index];
struct table_cell *cell;
return cell;
}
+/* Sets the subscripts for column X, row Y in TABLE. */
+void
+table_add_subscripts (struct table *table, int x, int y,
+ char **subscripts, size_t n_subscripts)
+{
+ struct table_cell *cell = get_joined_cell (table, x, y);
+
+ cell->n_subscripts = n_subscripts;
+ cell->subscripts = pool_nalloc (table->container, n_subscripts,
+ sizeof *cell->subscripts);
+ for (size_t i = 0; i < n_subscripts; i++)
+ cell->subscripts[i] = pool_strdup (table->container, subscripts[i]);
+}
+
/* Create a footnote in TABLE with MARKER (e.g. "a") as its marker and CONTENT
as its content. The footnote will be styled as STYLE, which is mandatory.
IDX must uniquely identify the footnote within TABLE.
footnote later, so it is important for the caller to remember it. */
struct footnote *
table_create_footnote (struct table *table, size_t idx, const char *content,
- const char *marker, struct area_style *style)
+ const char *marker, struct table_area_style *style)
{
assert (style);
TABLE->container or have a lifetime that will outlive TABLE. */
void
table_add_style (struct table *table, int x, int y,
- const struct area_style *style)
+ const struct table_area_style *style)
{
get_joined_cell (table, x, y)->style = style;
}
bool
table_cell_is_empty (const struct table *table, int c, int r)
{
- return table->cc[c + r * table_nc (table)] == NULL;
-}
-\f
-/* Editing. */
-
-/* Writes STRING to the output. OPTIONS may be any valid combination of TAB_*
- bits.
-
- This function is obsolete. Please do not add new uses of it. Instead, use
- a text_item (see output/text-item.h). */
-void
-table_output_text (int options UNUSED, const char *string)
-{
- text_item_submit (text_item_create (TEXT_ITEM_LOG, string));
-}
-
-/* Same as table_output_text(), but FORMAT is passed through printf-like
- formatting before output. */
-void
-table_output_text_format (int options, const char *format, ...)
-{
- va_list args;
- char *text;
-
- va_start (args, format);
- text = xvasprintf (format, args);
- va_end (args);
-
- table_output_text (options, text);
-
- free (text);
+ return table->cc[c + r * table->n[H]] == NULL;
}
\f
/* Initializes CELL with the contents of the table cell at column X and row Y
- within TABLE. When CELL is no longer needed, the caller is responsible for
- freeing it by calling table_cell_free(CELL).
-
- The caller must ensure that CELL is destroyed before TABLE is unref'ed. */
+ within TABLE. */
void
table_get_cell (const struct table *t, int x, int y, struct table_cell *cell)
{
assert (x >= 0 && x < t->n[TABLE_HORZ]);
assert (y >= 0 && y < t->n[TABLE_VERT]);
- int index = x + y * table_nc (t);
+ int index = x + y * t->n[H];
unsigned short opt = t->ct[index];
const void *cc = t->cc[index];
- const struct area_style *style
+ const struct table_area_style *style
= t->styles[(opt & TAB_STYLE_MASK) >> TAB_STYLE_SHIFT];
if (opt & TAB_JOIN)
{
assert (y >= 0 && y < table->n[TABLE_VERT] + (axis == TABLE_VERT));
uint8_t raw = (axis == TABLE_VERT
- ? table->rh[x + table_nc (table) * y]
- : table->rv[x + (table_nc (table) + 1) * y]);
+ ? 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;