-
-/* Draws a box around cells (X1,Y1)-(X2,Y2) inclusive with horizontal
- lines of style F_H and vertical lines of style F_V. Fills the
- interior of the box with horizontal lines of style I_H and vertical
- lines of style I_V. Any of the line styles may be -1 to avoid
- drawing those lines. This is distinct from 0, which draws a null
- line. */
-void
-tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
- int x1, int y1, int x2, int y2)
-{
- assert (t != NULL);
-
-#if DEBUGGING
- if (x1 + t->col_ofs < 0 || x1 + t->col_ofs >= t->nc
- || x2 + t->col_ofs < 0 || x2 + t->col_ofs >= t->nc
- || y1 + t->row_ofs < 0 || y1 + t->row_ofs >= t->nr
- || y2 + t->row_ofs < 0 || y2 + t->row_ofs >= t->nr)
- {
- printf (_("bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) "
- "in table size (%d,%d)\n"),
- x1, t->col_ofs, x1 + t->col_ofs,
- y1, t->row_ofs, y1 + t->row_ofs,
- x2, t->col_ofs, x2 + t->col_ofs,
- y2, t->row_ofs, y2 + t->row_ofs,
- t->nc, t->nr);
- abort ();
- }
-#endif
-
- x1 += t->col_ofs;
- x2 += t->col_ofs;
- y1 += t->row_ofs;
- y2 += t->row_ofs;
-
- assert (x2 >= x1);
- assert (y2 >= y1);
- assert (x1 >= 0);
- assert (y1 >= 0);
- assert (x2 < t->nc);
- assert (y2 < t->nr);
-
- if (f_h != -1)
- {
- int x;
- for (x = x1; x <= x2; x++)
- {
- t->rh[x + t->cf * y1] = f_h;
- t->rh[x + t->cf * (y2 + 1)] = f_h;
- }
- }
- if (f_v != -1)
- {
- int y;
- for (y = y1; y <= y2; y++)
- {
- t->rv[x1 + (t->cf + 1) * y] = f_v;
- t->rv[(x2 + 1) + (t->cf + 1) * y] = f_v;
- }
- }
-
- if (i_h != -1)
- {
- int y;
-
- for (y = y1 + 1; y <= y2; y++)
- {
- int x;
-
- for (x = x1; x <= x2; x++)
- t->rh[x + t->cf * y] = i_h;
- }
- }
- if (i_v != -1)
- {
- int x;
-
- for (x = x1 + 1; x <= x2; x++)
- {
- int y;
-
- for (y = y1; y <= y2; y++)
- t->rv[x + (t->cf + 1) * y] = i_v;
- }
- }
-}
-
-/* Formats text TEXT and arguments ARGS as indicated in OPT and sets
- the resultant string into S in TABLE's pool. */
-static void
-text_format (struct tab_table *table, int opt, const char *text, va_list args,
- struct fixed_string *s)
-{
- char *tmp = NULL;
-
- assert (table != NULL && text != NULL && s != NULL);
-
- if (opt & TAT_PRINTF)
- text = tmp = xvasprintf (text, args);
-
- ls_create_buffer (s, text, strlen (text));
- pool_register (table->container, free, s->string);
-
- free (tmp);
-}
-
-/* Set the title of table T to TITLE, which is formatted as if
- passed to printf(). */
-void
-tab_title (struct tab_table *t, const char *title, ...)
-{
- va_list args;
-
- assert (t != NULL && title != NULL);
- va_start (args, title);
- text_format (t, TAT_PRINTF, title, args, &t->title);
- va_end (args);
-}
-
-/* Set DIM_FUNC as the dimension function for table T. */
-void
-tab_dim (struct tab_table *t, tab_dim_func *dim_func)
-{
- assert (t != NULL && t->dim == NULL);
- t->dim = dim_func;
-}
-
-/* Returns the natural width of column C in table T for driver D, that
- is, the smallest width necessary to display all its cells without
- wrapping. The width will be no larger than the page width minus
- left and right rule widths. */
-int
-tab_natural_width (struct tab_table *t, struct outp_driver *d, int c)
-{
- int width;
-
- assert (t != NULL && c >= 0 && c < t->nc);
- {
- int r;
-
- for (width = r = 0; r < t->nr; r++)
- {
- struct outp_text text;
- unsigned char opt = t->ct[c + r * t->cf];
- int w;
-
- if (opt & (TAB_JOIN | TAB_EMPTY))
- continue;
-
- text.string = t->cc[c + r * t->cf];
- assert (!ls_null_p (&text.string));
- text.justification = OUTP_LEFT;
- text.font = options_to_font (opt);
- text.h = text.v = INT_MAX;
-
- d->class->text_metrics (d, &text, &w, NULL);
- if (w > width)
- width = w;
- }
- }
-
- if (width == 0)
- {
- width = d->prop_em_width * 8;
-#if DEBUGGING
- printf ("warning: table column %d contains no data.\n", c);
-#endif
- }
-
- {
- const int clamp = d->width - t->wrv[0] - t->wrv[t->nc];
-
- if (width > clamp)
- width = clamp;
- }
-
- return width;
-}
-
-/* Returns the natural height of row R in table T for driver D, that
- is, the minimum height necessary to display the information in the
- cell at the widths set for each column. */
-int
-tab_natural_height (struct tab_table *t, struct outp_driver *d, int r)
-{
- int height;
-
- assert (t != NULL && r >= 0 && r < t->nr);
-
- {
- int c;
-
- for (height = d->font_height, c = 0; c < t->nc; c++)
- {
- struct outp_text text;
- unsigned char opt = t->ct[c + r * t->cf];
- int h;
-
- assert (t->w[c] != NOT_INT);
- if (opt & (TAB_JOIN | TAB_EMPTY))
- continue;
-
- text.string = t->cc[c + r * t->cf];
- assert (!ls_null_p (&text.string));
- text.justification = OUTP_LEFT;
- text.font = options_to_font (opt);
- text.h = t->w[c];
- text.v = INT_MAX;
- d->class->text_metrics (d, &text, NULL, &h);
-
- if (h > height)
- height = h;
- }
- }
-
- return height;
-}
-
-/* Callback function to set all columns and rows to their natural
- dimensions. Not really meant to be called directly. */
-void
-tab_natural_dimensions (struct tab_table *t, struct outp_driver *d)
-{
- int i;
-
- assert (t != NULL);
-
- for (i = 0; i < t->nc; i++)
- t->w[i] = tab_natural_width (t, d, i);
-
- for (i = 0; i < t->nr; i++)
- t->h[i] = tab_natural_height (t, d, i);
-}
-