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