2917051a13039c3f0d015bf4891bb6971b7eb5cf
[pspp] / src / output / table-provider.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997, 1998, 1999, 2000, 2009, 2011, 2013, 2014, 2018 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifndef OUTPUT_TABLE_PROVIDER
18 #define OUTPUT_TABLE_PROVIDER 1
19
20 #include <stdint.h>
21 #include "output/table.h"
22
23 struct pool;
24 struct string;
25
26 struct footnote
27   {
28     size_t idx;
29     char *content;
30     char *marker;
31     struct cell_style *style;
32   };
33
34 /* An item of contents within a table cell. */
35 struct cell_contents
36   {
37     unsigned int options;       /* TAB_*. */
38     char *text;                 /* A paragraph of text. */
39
40     /* Optional footnote(s). */
41     const struct footnote **footnotes;
42     size_t n_footnotes;
43   };
44
45 void cell_contents_format_footnote_markers (const struct cell_contents *,
46                                             struct string *);
47
48 struct cell_color
49   {
50     uint8_t r, g, b;
51   };
52
53 #define CELL_COLOR(r, g, b) (struct cell_color) { r, g, b }
54 #define CELL_COLOR_BLACK CELL_COLOR (0, 0, 0)
55 #define CELL_COLOR_WHITE CELL_COLOR (255, 255, 255)
56
57 static inline bool
58 cell_color_equal (const struct cell_color *a, const struct cell_color *b)
59 {
60   return a->r == b->r && a->g == b->g && a->b == b->b;
61 }
62
63 struct cell_style
64   {
65     struct cell_color fg, bg;
66     int margin[TABLE_N_AXES][2];
67     char *font;
68     int font_size;
69     bool bold, italic, underline;
70   };
71
72 #define CELL_STYLE_INITIALIZER                                  \
73     {                                                           \
74       .fg = CELL_COLOR_BLACK,                                   \
75       .bg = CELL_COLOR_WHITE,                                   \
76       .margin = { [TABLE_HORZ][0] = 8, [TABLE_HORZ][1] = 11,    \
77                   [TABLE_VERT][0] = 1, [TABLE_VERT][1] = 1 },   \
78       .font = NULL,                                             \
79       .font_size = 0,                                           \
80       .bold = false,                                            \
81       .italic = false,                                          \
82       .underline = false,                                       \
83     }
84
85 struct cell_style *cell_style_clone (struct pool *, const struct cell_style *);
86 void cell_style_free (struct cell_style *);
87
88 /* A cell in a table. */
89 struct table_cell
90   {
91     /* Occupied table region.
92
93        d[TABLE_HORZ][0] is the leftmost column.
94        d[TABLE_HORZ][1] is the rightmost column, plus 1.
95        d[TABLE_VERT][0] is the top row.
96        d[TABLE_VERT][1] is the bottom row, plus 1.
97
98        For an ordinary cell:
99            d[TABLE_HORZ][1] == d[TABLE_HORZ][0] + 1
100        and d[TABLE_VERT][1] == d[TABLE_VERT][0] + 1
101
102        For a joined cell:
103           d[TABLE_HORZ][1] > d[TABLE_HORZ][0] + 1
104        or d[TABLE_VERT][1] > d[TABLE_VERT][0] + 1
105        or both. */
106     int d[TABLE_N_AXES][2];
107
108     /* The cell's contents.
109
110        Most table cells contain only one item (a paragraph of text), but cells
111        are allowed to be empty (n_contents == 0) or contain a nested table, or
112        multiple items.
113
114        'inline_contents' provides a place to store a single item to handle the
115        common case.
116     */
117     const struct cell_contents *contents;
118     size_t n_contents;
119     struct cell_contents inline_contents;
120
121     const struct cell_style *style;
122
123     /* Called to free the cell's data, if nonnull. */
124     void (*destructor) (void *destructor_aux);
125     void *destructor_aux;
126   };
127
128 void table_cell_free (struct table_cell *);
129
130 /* Returns the number of columns that CELL spans.  This is 1 for an ordinary
131    cell and greater than one for a cell that joins multiple columns. */
132 static inline int
133 table_cell_colspan (const struct table_cell *cell)
134 {
135   return cell->d[TABLE_HORZ][1] - cell->d[TABLE_HORZ][0];
136 }
137
138 /* Returns the number of rows that CELL spans.  This is 1 for an ordinary cell
139    and greater than one for a cell that joins multiple rows. */
140 static inline int
141 table_cell_rowspan (const struct table_cell *cell)
142 {
143   return cell->d[TABLE_VERT][1] - cell->d[TABLE_VERT][0];
144 }
145
146 /* Returns true if CELL is a joined cell, that is, if it spans multiple rows
147    or columns.  Otherwise, returns false. */
148 static inline bool
149 table_cell_is_joined (const struct table_cell *cell)
150 {
151   return table_cell_colspan (cell) > 1 || table_cell_rowspan (cell) > 1;
152 }
153 \f
154 /* Declarations to allow defining table classes. */
155
156 struct table_class
157   {
158     /* Frees TABLE.
159
160        The table class may assume that any cells that were retrieved by calling
161        the 'get_cell' function have been freed (by calling their destructors)
162        before this function is called. */
163     void (*destroy) (struct table *table);
164
165     /* Initializes CELL with the contents of the table cell at column X and row
166        Y within TABLE.  All members of CELL must be initialized, except that if
167        'destructor' is set to a null pointer, then 'destructor_aux' need not be
168        initialized.  The 'contents' member of CELL must be set to a nonnull
169        value.
170
171        The table class must allow any number of cells in the table to be
172        retrieved simultaneously; that is, TABLE must not assume that a given
173        cell will be freed before another one is retrieved using 'get_cell'.
174
175        The table class must allow joined cells to be retrieved, with identical
176        contents, using any (X,Y) location inside the cell.
177
178        The table class must not allow cells to overlap.
179
180        The table class should not allow a joined cell to cross the border
181        between header rows/columns and the interior of the table.  That is, a
182        joined cell should be entirely within headers rows and columns or
183        entirely outside them.
184
185        The table class may assume that CELL will be freed before TABLE is
186        destroyed. */
187     void (*get_cell) (const struct table *table, int x, int y,
188                       struct table_cell *cell);
189
190     /* Returns one of the TAL_* enumeration constants (declared in
191        output/table.h) representing a rule running alongside one of the cells
192        in TABLE.
193
194        See table_get_rule() in table.c for a detailed explanation of the
195        meaning of AXIS and X and Y, including a diagram. */
196     int (*get_rule) (const struct table *table,
197                      enum table_axis axis, int x, int y,
198                      struct cell_color *color);
199
200     /* This function is optional and most table classes will not implement it.
201
202        If provided, this function must take ownership of A and B and return a
203        table that consists of tables A and B "pasted together", that is, a
204        table whose size is the sum of the sizes of A and B along the axis
205        specified by ORIENTATION.  A and B will ordinarily have the same size
206        along the axis opposite ORIENTATION; no particular handling of tables
207        that have different sizes along that axis is required.
208
209        The handling of rules at the seam between A and B is not specified, but
210        table_rule_combine() is one reasonable way to do it.
211
212        Called only if neither A and B is shared (as returned by
213        table_is_shared()).
214
215        Called if A or B or both is of the class defined by this table class.
216        That is, the implementation must be prepared to deal with the case where
217        A or B is not the ordinarily expected table class.
218
219        This function may return a null pointer if it cannot implement the paste
220        operation, in which case the caller will use a fallback
221        implementation.
222
223        This function is used to implement table_paste(). */
224     struct table *(*paste) (struct table *a, struct table *b,
225                             enum table_axis orientation);
226
227     /* This function is optional and most table classes will not implement it.
228
229        If provided, this function must take ownership of TABLE and return a new
230        table whose contents are the TABLE's rows RECT[TABLE_VERT][0] through
231        RECT[TABLE_VERT][1], exclusive, and the TABLE's columns
232        RECT[TABLE_HORZ][0] through RECT[TABLE_HORZ][1].
233
234        Called only if TABLE is not shared (as returned by table_is_shared()).
235
236        This function may return a null pointer if it cannot implement the
237        select operation, in which case the caller will use a fallback
238        implementation.
239
240        This function is used to implement table_select(). */
241     struct table *(*select) (struct table *table, int rect[TABLE_N_AXES][2]);
242   };
243
244 void table_init (struct table *, const struct table_class *);
245
246 /* Table class implementations can call these functions or just set the
247    table's n[] and h[][] members directly. */
248 void table_set_nc (struct table *, int nc);
249 void table_set_nr (struct table *, int nr);
250 \f
251 /* For use primarily by output drivers. */
252
253 void table_get_cell (const struct table *, int x, int y, struct table_cell *);
254 int table_get_rule (const struct table *, enum table_axis, int x, int y,
255                     struct cell_color *);
256 size_t table_collect_footnotes (const struct table_item *,
257                                 const struct footnote ***);
258
259 #endif /* output/table-provider.h */