output: Support decimal and mixed alignment,
[pspp] / src / output / tab.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997, 1998, 1999, 2000, 2009, 2011, 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_TAB_H
18 #define OUTPUT_TAB_H
19
20 /* Simple table class.
21
22    This is a type of table (see output/table.h) whose content is composed
23    manually by the code that generates it, by filling in cells one by one.
24
25    Some of the features of this type of table are obsolete but have not yet
26    been removed, because some code still uses them.  These features are:
27
28        - The title and caption.  These are properties of the table_item (see
29          output/table-item.h) in which a table is embedded, not properties of
30          the table itself.
31
32        - Row and columns offsets (via tab_offset(), tab_next_row()).  This
33          feature simply isn't used enough to justify keeping it.
34
35        - Table resizing.  The code that does use this feature is just as well
36          served by creating multiple tables and pasting them together with
37          table_paste().  Eliminating this feature would also slightly simplify
38          the table code here.
39 */
40
41 #include "libpspp/compiler.h"
42 #include "output/table.h"
43 #include "data/format.h"
44
45 enum result_class
46   {
47     RC_INTEGER,
48     RC_WEIGHT,
49     RC_PVALUE,
50     RC_OTHER,
51     n_RC
52   };
53
54 #define TAB_STYLE_MASK (7u << (TAB_FIRST_AVAILABLE + 1))
55 #define TAB_STYLE_SHIFT (TAB_FIRST_AVAILABLE + 1)
56
57 enum
58   {
59     /* Horizontal alignment of cell contents. */
60     TAB_RIGHT      = 0 << (TAB_FIRST_AVAILABLE + 2),
61     TAB_LEFT       = 1 << (TAB_FIRST_AVAILABLE + 2),
62     TAB_CENTER     = 2 << (TAB_FIRST_AVAILABLE + 2),
63     TAB_HALIGN     = 3 << (TAB_FIRST_AVAILABLE + 2), /* Alignment mask. */
64
65     /* Vertical alignment of cell contents. */
66     TAB_TOP        = 0 << (TAB_FIRST_AVAILABLE + 4),
67     TAB_MIDDLE     = 1 << (TAB_FIRST_AVAILABLE + 4),
68     TAB_BOTTOM     = 2 << (TAB_FIRST_AVAILABLE + 4),
69     TAB_VALIGN     = 3 << (TAB_FIRST_AVAILABLE + 4), /* Alignment mask. */
70   };
71
72 /* Rule masks. */
73 #define TAB_RULE_TYPE_MASK   7
74 #define TAB_RULE_TYPE_SHIFT  0
75 #define TAB_RULE_STYLE_MASK  (31 << TAB_RULE_STYLE_SHIFT)
76 #define TAB_RULE_STYLE_SHIFT 3
77
78 /* A table. */
79 struct tab_table
80   {
81     struct table table;
82     struct pool *container;
83
84     /* Table title and caption, or null. */
85     char *title, *caption;
86     int cf;                     /* Column factor for indexing purposes. */
87
88     /* Table contents.
89
90        Each array element in cc[] is ordinarily a "char *" pointer to a
91        string.  If TAB_JOIN (defined in tab.c) is set in ct[] for the element,
92        however, it is a joined cell and the corresponding element of cc[]
93        points to a struct tab_joined_cell. */
94     void **cc;                  /* Cell contents; void *[nr][nc]. */
95     unsigned short *ct;         /* Cell types; unsigned short[nr][nc]. */
96     struct area_style *styles[8];
97
98     /* Rules. */
99     unsigned char *rh;          /* Horiz rules; unsigned char[nr+1][nc]. */
100     unsigned char *rv;          /* Vert rules; unsigned char[nr][nc+1]. */
101     struct cell_color *rule_colors[32];
102
103     /* X and Y offsets. */
104     int col_ofs, row_ofs;
105
106     struct fmt_spec fmtmap [n_RC];
107   };
108
109 struct tab_table *tab_cast (const struct table *);
110
111 /* Number of rows or columns in TABLE. */
112 static inline int tab_nr (const struct tab_table *table)
113         { return table_nr (&table->table); }
114 static inline int tab_nc (const struct tab_table *table)
115         { return table_nc (&table->table); }
116
117 /* Number of left/right/top/bottom header columns/rows in TABLE. */
118 static inline int tab_l (const struct tab_table *table)
119         { return table_hl (&table->table); }
120 static inline int tab_r (const struct tab_table *table)
121         { return table_hr (&table->table); }
122 static inline int tab_t (const struct tab_table *table)
123         { return table_ht (&table->table); }
124 static inline int tab_b (const struct tab_table *table)
125         { return table_hb (&table->table); }
126
127 /* Tables. */
128 struct tab_table *tab_create (int nc, int nr);
129 void tab_resize (struct tab_table *, int nc, int nr);
130 void tab_realloc (struct tab_table *, int nc, int nr);
131 void tab_headers (struct tab_table *, int l, int r, int t, int b);
132 void tab_title (struct tab_table *, const char *, ...)
133      PRINTF_FORMAT (2, 3);
134 void tab_caption (struct tab_table *, const char *, ...)
135      PRINTF_FORMAT (2, 3);
136 void tab_submit (struct tab_table *);
137
138 /* Rules. */
139 void tab_hline (struct tab_table *, int style, int x1, int x2, int y);
140 void tab_vline (struct tab_table *, int style, int x, int y1, int y2);
141 void tab_box (struct tab_table *, int f_h, int f_v, int i_h, int i_v,
142               int x1, int y1, int x2, int y2);
143
144 /* Obsolete cell options. */
145 #define TAT_TITLE TAB_EMPH      /* Title attributes. */
146
147 void tab_set_format (struct tab_table *, enum result_class, const struct fmt_spec *);
148
149
150 /* Cells. */
151 struct fmt_spec;
152 struct dictionary;
153 union value;
154 void tab_value (struct tab_table *, int c, int r, unsigned short opt,
155                 const union value *, const struct variable *,
156                 const struct fmt_spec *);
157
158 void tab_double (struct tab_table *, int c, int r, unsigned short opt,
159                  double v, const struct fmt_spec *, enum result_class );
160
161 void tab_text (struct tab_table *, int c, int r, unsigned opt, const char *);
162 void tab_text_format (struct tab_table *, int c, int r, unsigned opt,
163                       const char *, ...)
164      PRINTF_FORMAT (5, 6);
165
166 void tab_joint_text (struct tab_table *, int x1, int y1, int x2, int y2,
167                      unsigned opt, const char *);
168 void tab_joint_text_format (struct tab_table *, int x1, int y1, int x2, int y2,
169                             unsigned opt, const char *, ...)
170      PRINTF_FORMAT (7, 8);
171
172 struct footnote *tab_create_footnote (struct tab_table *, size_t idx,
173                                       const char *content, const char *marker,
174                                       struct area_style *);
175 void tab_add_footnote (struct tab_table *, int x, int y,
176                        const struct footnote *);
177
178 void tab_add_style (struct tab_table *, int x, int y,
179                     const struct area_style *);
180
181 bool tab_cell_is_empty (const struct tab_table *, int c, int r);
182
183 /* Editing. */
184 void tab_offset (struct tab_table *, int col, int row);
185 void tab_next_row (struct tab_table *);
186
187 /* Current row/column offset. */
188 #define tab_row(TABLE) ((TABLE)->row_ofs)
189 #define tab_col(TABLE) ((TABLE)->col_ofs)
190
191 /* Simple output. */
192 void tab_output_text (int options, const char *string);
193 void tab_output_text_format (int options, const char *, ...)
194      PRINTF_FORMAT (2, 3);
195
196 #endif /* output/tab.h */
197