text-item: Use struct font_style instead of individual fields.
[pspp] / src / output / table.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997, 1998, 1999, 2000, 2009, 2013, 2014 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_H
18 #define OUTPUT_TABLE_H 1
19
20 /* Tables.
21
22    A table is a rectangular grid of cells.  Cells can be joined to form larger
23    cells.  Rows and columns can be separated by rules of various types.  Rows
24    at the top and bottom of a table and columns at the left and right edges of
25    a table can be designated as headers, which means that if the table must be
26    broken across more than one page, those rows or columns are repeated on each
27    page.
28
29    A table is not itself an output_item, and thus a table cannot by itself be
30    used for output, but they can be embedded inside struct table_item (see
31    table-item.h) for that purpose. */
32
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stddef.h>
36 #include "libpspp/compiler.h"
37
38 struct casereader;
39 struct fmt_spec;
40 struct pool;
41 struct table_item;
42 struct variable;
43
44 /* A table axis.
45
46    Many table-related declarations use 2-element arrays in place of "x" and "y"
47    variables.  This reduces code duplication significantly, because much table
48    code treats rows and columns the same way.
49
50    A lot of code that uses these enumerations assumes that the two values are 0
51    and 1, so don't change them to other values. */
52 enum table_axis
53   {
54     TABLE_HORZ,
55     TABLE_VERT
56 #define TABLE_N_AXES 2
57   };
58
59 struct cell_color
60   {
61     uint8_t alpha, r, g, b;
62   };
63
64 #define CELL_COLOR(r, g, b) { 255, r, g, b }
65 #define CELL_COLOR_BLACK CELL_COLOR (0, 0, 0)
66 #define CELL_COLOR_WHITE CELL_COLOR (255, 255, 255)
67
68 static inline bool
69 cell_color_equal (const struct cell_color *a, const struct cell_color *b)
70 {
71   return a->alpha == b->alpha && a->r == b->r && a->g == b->g && a->b == b->b;
72 }
73
74 void cell_color_dump (const struct cell_color *);
75
76 enum table_stroke
77   {
78     TABLE_STROKE_NONE,
79     TABLE_STROKE_SOLID,
80     TABLE_STROKE_DASHED,
81     TABLE_STROKE_THICK,
82     TABLE_STROKE_THIN,
83     TABLE_STROKE_DOUBLE,
84     TABLE_N_STROKES,
85   };
86
87 const char *table_stroke_to_string (enum table_stroke);
88
89 /* Given strokes A and B, returns a stroke that "combines" them, that is, that
90    gives a reasonable stroke choice for a rule for different reasons should
91    have both styles A and B. */
92 static inline int
93 table_stroke_combine (enum table_stroke a, enum table_stroke b)
94 {
95   return a > b ? a : b;
96 }
97
98 struct table_border_style
99   {
100     enum table_stroke stroke;
101     struct cell_color color;
102   };
103
104 #define TABLE_BORDER_STYLE_INITIALIZER { TABLE_STROKE_SOLID, CELL_COLOR_BLACK }
105
106 enum table_halign
107   {
108     TABLE_HALIGN_RIGHT,
109     TABLE_HALIGN_LEFT,
110     TABLE_HALIGN_CENTER,
111     TABLE_HALIGN_MIXED,
112     TABLE_HALIGN_DECIMAL
113   };
114
115 const char *table_halign_to_string (enum table_halign);
116
117 enum table_valign
118   {
119     TABLE_VALIGN_TOP,
120     TABLE_VALIGN_CENTER,
121     TABLE_VALIGN_BOTTOM,
122   };
123
124 const char *table_valign_to_string (enum table_valign);
125
126 struct cell_style
127   {
128     enum table_halign halign;
129     enum table_valign valign;
130     double decimal_offset;       /* In 1/96" units. */
131     char decimal_char;           /* Either '.' or ','. */
132     int margin[TABLE_N_AXES][2]; /* In 1/96" units. */
133   };
134
135 #define CELL_STYLE_INITIALIZER { CELL_STYLE_INITIALIZER__ }
136 #define CELL_STYLE_INITIALIZER__                                \
137         .margin = { [TABLE_HORZ][0] = 8, [TABLE_HORZ][1] = 11,  \
138                     [TABLE_VERT][0] = 1, [TABLE_VERT][1] = 1 }
139
140 void cell_style_dump (const struct cell_style *);
141
142 struct font_style
143   {
144     bool bold, italic, underline, markup;
145     struct cell_color fg[2], bg[2];
146     char *typeface;
147     int size;                   /* In 1/72" units. */
148   };
149
150 #define FONT_STYLE_INITIALIZER { FONT_STYLE_INITIALIZER__ }
151 #define FONT_STYLE_INITIALIZER__                                        \
152         .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK},        \
153         .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE},
154
155 void font_style_copy (struct pool *,
156                       struct font_style *, const struct font_style *);
157 void font_style_uninit (struct font_style *);
158 void font_style_dump (const struct font_style *);
159 bool font_style_equal (const struct font_style *, const struct font_style *);
160
161 struct table_area_style
162   {
163     struct cell_style cell_style;
164     struct font_style font_style;
165   };
166
167 #define TABLE_AREA_STYLE_INITIALIZER { TABLE_AREA_STYLE_INITIALIZER__ }
168 #define TABLE_AREA_STYLE_INITIALIZER__          \
169        .cell_style = CELL_STYLE_INITIALIZER,    \
170        .font_style = FONT_STYLE_INITIALIZER
171
172 struct table_area_style *table_area_style_clone (
173   struct pool *, const struct table_area_style *);
174 void table_area_style_copy (struct pool *, struct table_area_style *,
175                             const struct table_area_style *);
176 void table_area_style_uninit (struct table_area_style *);
177 void table_area_style_free (struct table_area_style *);
178
179 /* Properties of a table cell. */
180 enum
181   {
182     TAB_NONE = 0,
183     TAB_FIX        = 1 << 1,    /* Use fixed font. */
184     TAB_MARKUP     = 1 << 2,    /* Text contains Pango markup. */
185     TAB_NUMERIC    = 1 << 3,    /* Cell contents are numeric. */
186     TAB_ROTATE     = 1 << 4,    /* Rotate cell contents 90 degrees. */
187
188     TAB_STYLE_SHIFT = 5,
189     TAB_STYLE_MASK = 7 << TAB_STYLE_SHIFT,
190
191     /* Internal use by tab.c only. */
192     TAB_JOIN = 1 << 14,
193   };
194
195 /* A table. */
196 struct table
197   {
198     struct pool *container;
199
200     /* Table size.
201
202        n[TABLE_HORZ]: Number of columns.
203        n[TABLE_VERT]: Number of rows. */
204     int n[TABLE_N_AXES];
205
206     /* Table headers.
207
208        Rows at the top and bottom of a table and columns at the left and right
209        edges of a table can be designated as headers.  If the table must be
210        broken across more than one page for output, headers rows and columns
211        are repeated on each page.
212
213        h[TABLE_HORZ][0]: Left header columns.
214        h[TABLE_HORZ][1]: Right header columns.
215        h[TABLE_VERT][0]: Top header rows.
216        h[TABLE_VERT][1]: Bottom header rows. */
217     int h[TABLE_N_AXES][2];
218
219     /* Reference count.  A table may be shared between multiple owners,
220        indicated by a reference count greater than 1.  When this is the case,
221        the table must not be modified. */
222     int ref_cnt;
223
224     /* Table contents.
225
226        Each array element in cc[] is ordinarily a "char *" pointer to a string.
227        If TAB_JOIN (defined in table.c) is set in ct[] for the element,
228        however, it is a joined cell and the corresponding element of cc[]
229        points to a struct table_cell. */
230     void **cc;                  /* Cell contents; void *[nr][nc]. */
231     unsigned short *ct;         /* Cell types; unsigned short[nr][nc]. */
232     struct table_area_style *styles[8];
233
234     /* Rules. */
235     unsigned char *rh;          /* Horiz rules; unsigned char[nr+1][nc]. */
236     unsigned char *rv;          /* Vert rules; unsigned char[nr][nc+1]. */
237     struct cell_color *rule_colors[32];
238   };
239
240 /* Reference counting. */
241 struct table *table_ref (const struct table *);
242 void table_unref (struct table *);
243 bool table_is_shared (const struct table *);
244
245 /* Rule masks. */
246 #define TAB_RULE_TYPE_MASK   7
247 #define TAB_RULE_TYPE_SHIFT  0
248 #define TAB_RULE_STYLE_MASK  (31 << TAB_RULE_STYLE_SHIFT)
249 #define TAB_RULE_STYLE_SHIFT 3
250
251 /* Tables. */
252 struct table *table_create (int nc, int nr, int hl, int hr, int ht, int hb);
253
254 /* Rules. */
255 void table_hline (struct table *, int style, int x1, int x2, int y);
256 void table_vline (struct table *, int style, int x, int y1, int y2);
257 void table_box (struct table *, int f_h, int f_v, int i_h, int i_v,
258                 int x1, int y1, int x2, int y2);
259
260 /* Cells. */
261 void table_text (struct table *, int c, int r, unsigned opt, const char *);
262 void table_text_format (struct table *, int c, int r, unsigned opt,
263                         const char *, ...)
264   PRINTF_FORMAT (5, 6);
265 void table_joint_text (struct table *, int x1, int y1, int x2, int y2,
266                        unsigned opt, const char *);
267
268 void table_add_subscripts (struct table *, int x, int y,
269                            char **subscripts, size_t n_subscripts);
270
271 /* Footnotes.
272
273    Use table_create_footnote() to create the footnotes themselves, then use
274    table_add_footnote() to create a reference from a table cell to a footnote.
275    There are two steps because a footnote may have multiple references. */
276 struct footnote *table_create_footnote (struct table *, size_t idx,
277                                         const char *content,
278                                         const char *marker,
279                                         struct table_area_style *);
280 void table_add_footnote (struct table *, int x, int y, struct footnote *);
281
282 void table_add_style (struct table *, int x, int y, struct table_area_style *);
283
284 bool table_cell_is_empty (const struct table *, int c, int r);
285
286 #endif /* output/table.h */