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