X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Ftable.h;h=07c88874c86a47eb925089c6b9606f3859f161f4;hb=22203a0e0daa6b6ab247b572b191d25bb48f61a3;hp=1748c24c855e71ec8c0212dac76d00662db76f67;hpb=b40baf410822471fbdeeec553693619d60d7c7b6;p=pspp diff --git a/src/output/table.h b/src/output/table.h index 1748c24c85..07c88874c8 100644 --- a/src/output/table.h +++ b/src/output/table.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2009, 2013, 2014 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,188 +14,274 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#if !tab_h -#define tab_h 1 +#ifndef OUTPUT_TABLE_H +#define OUTPUT_TABLE_H 1 -#include -#include +/* Tables. -/* Cell options. */ -enum - { - TAB_NONE = 0, +. A table is a rectangular grid of cells. Cells can be joined to form larger + cells. Rows and columns can be separated by rules of various types. Rows + at the top and bottom of a table and columns at the left and right edges of + a table can be designated as headers, which means that if the table must be + broken across more than one page, those rows or columns are repeated on each + page. + + A table is not itself an output_item, and thus a table cannot by itself be + used for output, but they can be embedded inside struct table_item (see + table-item.h) for that purpose. */ + +#include +#include +#include +#include "libpspp/compiler.h" + +struct casereader; +struct fmt_spec; +struct pool; +struct table_item; +struct variable; - TAB_ALIGN_MASK = 03, /* Alignment mask. */ - TAB_RIGHT = 00, /* Right justify. */ - TAB_LEFT = 01, /* Left justify. */ - TAB_CENTER = 02, /* Center. */ +/* A table axis. - /* Cell types. */ - TAB_JOIN = 004, /* Joined cell. */ - TAB_EMPTY = 010, /* Empty cell. */ + Many table-related declarations use 2-element arrays in place of "x" and "y" + variables. This reduces code duplication significantly, because much table + code treats rows and columns the same way. - /* Flags. */ - TAB_EMPH = 020, /* Emphasize cell contents. */ - TAB_FIX = 040, /* Use fixed font. */ + A lot of code that uses these enumerations assumes that the two values are 0 + and 1, so don't change them to other values. */ +enum table_axis + { + TABLE_HORZ, + TABLE_VERT +#define TABLE_N_AXES 2 }; -/* Line styles. */ -enum +struct cell_color { - TAL_0 = 0, /* No line. */ - TAL_1 = 1, /* Single line. */ - TAL_2 = 2, /* Double line. */ - TAL_GAP = 3, /* Spacing but no line. */ - TAL_COUNT, /* Number of line styles. */ + uint8_t alpha, r, g, b; }; -/* Column styles. Must correspond to SOM_COL_*. */ -enum +#define CELL_COLOR(r, g, b) { 255, r, g, b } +#define CELL_COLOR_BLACK CELL_COLOR (0, 0, 0) +#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) +{ + 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 *); + +enum table_stroke { - TAB_COL_NONE, /* No columns. */ - TAB_COL_DOWN /* Columns down first. */ + TABLE_STROKE_NONE, + TABLE_STROKE_SOLID, + TABLE_STROKE_DASHED, + TABLE_STROKE_THICK, + TABLE_STROKE_THIN, + TABLE_STROKE_DOUBLE, + TABLE_N_STROKES, }; -/* Joined cell. */ -struct tab_joined_cell +const char *table_stroke_to_string (enum table_stroke); + +/* Given strokes A and B, returns a stroke that "combines" them, that is, that + gives a reasonable stroke choice for a rule for different reasons should + have both styles A and B. */ +static inline int +table_stroke_combine (enum table_stroke a, enum table_stroke b) +{ + return a > b ? a : b; +} + +struct table_border_style { - int x1, y1; - int x2, y2; - int hit; - struct substring contents; + enum table_stroke stroke; + struct cell_color color; }; -struct outp_driver; -struct tab_table; -typedef void tab_dim_func (struct tab_table *, struct outp_driver *, - void *aux); +#define TABLE_BORDER_STYLE_INITIALIZER { TABLE_STROKE_SOLID, CELL_COLOR_BLACK } -/* A table. */ -struct tab_table +enum table_halign { - struct pool *container; + TABLE_HALIGN_RIGHT, + TABLE_HALIGN_LEFT, + TABLE_HALIGN_CENTER, + TABLE_HALIGN_MIXED, + TABLE_HALIGN_DECIMAL + }; - /* Contents. */ - int col_style; /* Columns: One of TAB_COL_*. */ - int col_group; /* Number of rows per column group. */ - char *title; /* Table title. */ - unsigned flags; /* SOMF_*. */ - int nc, nr; /* Number of columns, rows. */ - int cf; /* Column factor for indexing purposes. */ - int l, r, t, b; /* Number of header rows on each side. */ - struct substring *cc; /* Cell contents; substring *[nr][nc]. */ - unsigned char *ct; /* Cell types; unsigned char[nr][nc]. */ - unsigned char *rh; /* Horiz rules; unsigned char[nr+1][nc]. */ - unsigned char *rv; /* Vert rules; unsigned char[nr][nc+1]. */ - tab_dim_func *dim; /* Calculates cell widths and heights. */ - void *dim_aux; /* Auxiliary data for dim function. */ - - /* Calculated during output. */ - int *w; /* Column widths; [nc]. */ - int *h; /* Row heights; [nr]. */ - int *hrh; /* Heights of horizontal rules; [nr+1]. */ - int *wrv; /* Widths of vertical rules; [nc+1]. */ - int wl, wr, ht, hb; /* Width/height of header rows/columns. */ - - /* Editing info. */ - int col_ofs, row_ofs; /* X and Y offsets. */ +const char *table_halign_to_string (enum table_halign); + +enum table_valign + { + TABLE_VALIGN_TOP, + TABLE_VALIGN_CENTER, + TABLE_VALIGN_BOTTOM, }; -/* Number of rows in TABLE. */ -#define tab_nr(TABLE) ((TABLE)->nr) +const char *table_valign_to_string (enum table_valign); -/* Number of columns in TABLE. */ -#define tab_nc(TABLE) ((TABLE)->nc) +struct cell_style + { + enum table_halign halign; + enum table_valign valign; + double decimal_offset; /* In 1/96" units. */ + char decimal_char; /* Either '.' or ','. */ + int margin[TABLE_N_AXES][2]; /* In 1/96" units. */ + }; -/* Number of left header columns in TABLE. */ -#define tab_l(TABLE) ((TABLE)->l) +#define CELL_STYLE_INITIALIZER { CELL_STYLE_INITIALIZER__ } +#define CELL_STYLE_INITIALIZER__ \ + .margin = { [TABLE_HORZ][0] = 8, [TABLE_HORZ][1] = 11, \ + [TABLE_VERT][0] = 1, [TABLE_VERT][1] = 1 } -/* Number of right header columns in TABLE. */ -#define tab_r(TABLE) ((TABLE)->r) +void cell_style_dump (const struct cell_style *); -/* Number of top header rows in TABLE. */ -#define tab_t(TABLE) ((TABLE)->t) +struct font_style + { + bool bold, italic, underline, markup; + struct cell_color fg[2], bg[2]; + char *typeface; + int size; /* In 1/72" units. */ + }; -/* Number of bottom header rows in TABLE. */ -#define tab_b(TABLE) ((TABLE)->b) +#define FONT_STYLE_INITIALIZER { FONT_STYLE_INITIALIZER__ } +#define FONT_STYLE_INITIALIZER__ \ + .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK}, \ + .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE}, -/* Tables. */ -struct tab_table *tab_create (int nc, int nr, int reallocable); -void tab_destroy (struct tab_table *); -void tab_resize (struct tab_table *, int nc, int nr); -void tab_realloc (struct tab_table *, int nc, int nr); -void tab_headers (struct tab_table *, int l, int r, int t, int b); -void tab_columns (struct tab_table *, int style, int group); -void tab_title (struct tab_table *, const char *, ...) - PRINTF_FORMAT (2, 3); -void tab_flags (struct tab_table *, unsigned); -void tab_submit (struct tab_table *); - -/* Dimensioning. */ -tab_dim_func tab_natural_dimensions; -int tab_natural_width (struct tab_table *t, struct outp_driver *d, int c); -int tab_natural_height (struct tab_table *t, struct outp_driver *d, int r); -void tab_dim (struct tab_table *, tab_dim_func *, void *aux); +void font_style_copy (struct pool *, + struct font_style *, const struct font_style *); +void font_style_uninit (struct font_style *); +void font_style_dump (const struct font_style *); -/* Rules. */ -void tab_hline (struct tab_table *, int style, int x1, int x2, int y); -void tab_vline (struct tab_table *, int style, int x, int y1, int y2); -void tab_box (struct tab_table *, int f_h, int f_v, int i_h, int i_v, - int x1, int y1, int x2, int y2); +struct table_area_style + { + struct cell_style cell_style; + struct font_style font_style; + }; + +#define TABLE_AREA_STYLE_INITIALIZER { TABLE_AREA_STYLE_INITIALIZER__ } +#define TABLE_AREA_STYLE_INITIALIZER__ \ + .cell_style = CELL_STYLE_INITIALIZER, \ + .font_style = FONT_STYLE_INITIALIZER -/* Text options, passed in the `opt' argument. */ +struct table_area_style *table_area_style_clone ( + struct pool *, const struct table_area_style *); +void table_area_style_copy (struct pool *, struct table_area_style *, + const struct table_area_style *); +void table_area_style_uninit (struct table_area_style *); +void table_area_style_free (struct table_area_style *); + +/* Properties of a table cell. */ enum { - TAT_NONE = 0, /* No options. */ - TAT_TITLE = 0x0200 | TAB_EMPH, /* Title attributes. */ - TAT_NOWRAP = 0x0800 /* No text wrap (tab_output_text() only). */ + TAB_NONE = 0, + TAB_FIX = 1 << 1, /* Use fixed font. */ + TAB_MARKUP = 1 << 2, /* Text contains Pango markup. */ + TAB_NUMERIC = 1 << 3, /* Cell contents are numeric. */ + TAB_ROTATE = 1 << 4, /* Rotate cell contents 90 degrees. */ + + TAB_STYLE_SHIFT = 5, + TAB_STYLE_MASK = 7 << TAB_STYLE_SHIFT, + + /* Internal use by tab.c only. */ + TAB_JOIN = 1 << 14, }; -/* Cells. */ -struct fmt_spec; -struct dictionary; -union value; -void tab_value (struct tab_table *, int c, int r, unsigned char opt, - const union value *, const struct dictionary *dict, - const struct fmt_spec *); +/* A table. */ +struct table + { + struct pool *container; + + /* Table size. + + n[TABLE_HORZ]: Number of columns. + n[TABLE_VERT]: Number of rows. */ + int n[TABLE_N_AXES]; + + /* Table headers. -void tab_fixed (struct tab_table *, int c, int r, unsigned char opt, - double v, int w, int d); + Rows at the top and bottom of a table and columns at the left and right + edges of a table can be designated as headers. If the table must be + broken across more than one page for output, headers rows and columns + are repeated on each page. -void tab_double (struct tab_table *, int c, int r, unsigned char opt, - double v, const struct fmt_spec *); + h[TABLE_HORZ][0]: Left header columns. + h[TABLE_HORZ][1]: Right header columns. + h[TABLE_VERT][0]: Top header rows. + h[TABLE_VERT][1]: Bottom header rows. */ + int h[TABLE_N_AXES][2]; -void tab_text (struct tab_table *, int c, int r, unsigned opt, const char *); -void tab_text_format (struct tab_table *, int c, int r, unsigned opt, - const char *, ...) - PRINTF_FORMAT (5, 6); + /* Reference count. A table may be shared between multiple owners, + indicated by a reference count greater than 1. When this is the case, + the table must not be modified. */ + int ref_cnt; -void tab_joint_text (struct tab_table *, int x1, int y1, int x2, int y2, - unsigned opt, const char *); -void tab_joint_text_format (struct tab_table *, int x1, int y1, int x2, int y2, - unsigned opt, const char *, ...) - PRINTF_FORMAT (7, 8); + /* Table contents. -/* Cell low-level access. */ -#define tab_alloc(TABLE, AMT) pool_alloc ((TABLE)->container, (AMT)) -void tab_raw (struct tab_table *, int c, int r, unsigned opt, - struct substring *); + Each array element in cc[] is ordinarily a "char *" pointer to a string. + If TAB_JOIN (defined in table.c) is set in ct[] for the element, + however, it is a joined cell and the corresponding element of cc[] + points to a struct table_cell. */ + void **cc; /* Cell contents; void *[nr][nc]. */ + unsigned short *ct; /* Cell types; unsigned short[nr][nc]. */ + struct table_area_style *styles[8]; -/* Editing. */ -void tab_offset (struct tab_table *, int col, int row); -void tab_next_row (struct tab_table *); + /* 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]; + }; -/* Current row/column offset. */ -#define tab_row(TABLE) ((TABLE)->row_ofs) -#define tab_col(TABLE) ((TABLE)->col_ofs) +/* Reference counting. */ +struct table *table_ref (const struct table *); +void table_unref (struct table *); +bool table_is_shared (const struct table *); -/* Simple output. */ -void tab_output_text (int options, const char *string); -void tab_output_text_format (int options, const char *, ...) - PRINTF_FORMAT (2, 3); +/* 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 -/* Embedding the command name in the output. */ -void tab_set_command_name (const char *); +/* Tables. */ +struct table *table_create (int nc, int nr, int hl, int hr, int ht, int hb); -#endif /* tab_h */ +/* Rules. */ +void table_hline (struct table *, int style, int x1, int x2, int y); +void table_vline (struct table *, int style, int x, int y1, int y2); +void table_box (struct table *, int f_h, int f_v, int i_h, int i_v, + int x1, int y1, int x2, int y2); +/* Cells. */ +void table_text (struct table *, int c, int r, unsigned opt, const char *); +void table_text_format (struct table *, int c, int r, unsigned opt, + const char *, ...) + PRINTF_FORMAT (5, 6); +void table_joint_text (struct table *, int x1, int y1, int x2, int y2, + unsigned opt, const char *); + +void table_add_subscripts (struct table *, int x, int y, + char **subscripts, size_t n_subscripts); + +/* Footnotes. + + Use table_create_footnote() to create the footnotes themselves, then use + table_add_footnote() to create a reference from a table cell to a footnote. + There are two steps because a footnote may have multiple references. */ +struct footnote *table_create_footnote (struct table *, size_t idx, + const char *content, + const char *marker, + struct table_area_style *); +void table_add_footnote (struct table *, int x, int y, + const struct footnote *); + +void table_add_style (struct table *, int x, int y, + const struct table_area_style *); + +bool table_cell_is_empty (const struct table *, int c, int r); + +#endif /* output/table.h */