bc8db241f88ce91b88db1808367c742e2686df8c
[pspp] / src / output / render.h
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2009, 2010, 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_RENDER_H
18 #define OUTPUT_RENDER_H 1
19
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include "output/table-provider.h"
23
24 struct table_item;
25
26 enum render_line_style
27   {
28     RENDER_LINE_NONE,
29     RENDER_LINE_SINGLE,
30     RENDER_LINE_DASHED,
31     RENDER_LINE_THICK,
32     RENDER_LINE_THIN,
33     RENDER_LINE_DOUBLE,
34     RENDER_N_LINES
35   };
36
37 /* Parameters for rendering a table_item to a device.
38
39
40    Coordinate system
41    =================
42
43    The rendering code assumes that larger 'x' is to the right and larger 'y'
44    toward the bottom of the page.
45
46    The rendering code assumes that the table being rendered has its upper left
47    corner at (0,0) in device coordinates.  This is usually not the case from
48    the driver's perspective, so the driver should expect to apply its own
49    offset to coordinates passed to callback functions.
50 */
51 struct render_params
52   {
53     /* Functional parameters and auxiliary data to pass to them. */
54     const struct render_ops *ops;
55     void *aux;
56
57     /* Page size to try to fit the rendering into.  Some tables will, of
58        course, overflow this size. */
59     int size[TABLE_N_AXES];
60
61     /* Nominal size of a character in the most common font:
62        font_size[TABLE_HORZ]: Em width.
63        font_size[TABLE_VERT]: Line spacing. */
64     int font_size[TABLE_N_AXES];
65
66     /* Width of different kinds of lines. */
67     const int *line_widths;           /* RENDER_N_LINES members. */
68
69     /* Minimum cell width or height before allowing the cell to be broken
70        across two pages.  (Joined cells may always be broken at join
71        points.) */
72     int min_break[TABLE_N_AXES];
73
74     /* True if the driver supports cell margins.  (If false, the rendering
75        engine will insert a small space betweeen adjacent cells that don't have
76        an intervening rule.)  */
77     bool supports_margins;
78
79     /* True if the local language has a right-to-left direction, otherwise
80        false.  (Use render_direction_rtl() to find out.) */
81     bool rtl;
82
83     /* True if the table is being rendered for printing (as opposed to
84        on-screen display). */
85     bool printing;
86   };
87
88 struct render_ops
89   {
90     /* Measures CELL's width.  Stores in *MIN_WIDTH the minimum width required
91        to avoid splitting a single word across multiple lines (normally, this
92        is the width of the longest word in the cell) and in *MAX_WIDTH the
93        minimum width required to avoid line breaks other than at new-lines.
94        */
95     void (*measure_cell_width) (void *aux, const struct table_cell *cell,
96                                 int *min_width, int *max_width);
97
98     /* Returns the height required to render CELL given a width of WIDTH. */
99     int (*measure_cell_height) (void *aux, const struct table_cell *cell,
100                                 int width);
101
102     /* Given that there is space measuring WIDTH by HEIGHT to render CELL,
103        where HEIGHT is insufficient to render the entire height of the cell,
104        returns the largest height less than HEIGHT at which it is appropriate
105        to break the cell.  For example, if breaking at the specified HEIGHT
106        would break in the middle of a line of text, the return value would be
107        just sufficiently less that the breakpoint would be between lines of
108        text.
109
110        Optional.  If NULL, the rendering engine assumes that all breakpoints
111        are acceptable. */
112     int (*adjust_break) (void *aux, const struct table_cell *cell,
113                          int width, int height);
114
115     /* Draws a generalized intersection of lines in the rectangle whose
116        top-left corner is (BB[TABLE_HORZ][0], BB[TABLE_VERT][0]) and whose
117        bottom-right corner is (BB[TABLE_HORZ][1], BB[TABLE_VERT][1]).
118
119        STYLES is interpreted this way:
120
121        STYLES[TABLE_HORZ][0]: style of line from top of BB to its center.
122        STYLES[TABLE_HORZ][1]: style of line from bottom of BB to its center.
123        STYLES[TABLE_VERT][0]: style of line from left of BB to its center.
124        STYLES[TABLE_VERT][1]: style of line from right of BB to its center. */
125     void (*draw_line) (void *aux, int bb[TABLE_N_AXES][2],
126                        enum render_line_style styles[TABLE_N_AXES][2],
127                        struct cell_color colors[TABLE_N_AXES][2]);
128
129     /* Draws CELL within bounding box BB.  CLIP is the same as BB (the common
130        case) or a subregion enclosed by BB.  In the latter case only the part
131        of the cell that lies within CLIP should actually be drawn, although BB
132        should used to determine the layout of the cell.
133
134        The text in the cell needs to be vertically offset VALIGN_OFFSET units
135        from the top of the bounding box.  This handles vertical alignment with
136        the cell.  (The caller doesn't just reduce the bounding box size because
137        that would prevent the implementation from filling the entire cell with
138        the background color.)  The implementation must handle horizontal
139        alignment itself. */
140     void (*draw_cell) (void *aux, const struct table_cell *cell, int color_idx,
141                        int bb[TABLE_N_AXES][2], int valign_offset,
142                        int spill[TABLE_N_AXES][2],
143                        int clip[TABLE_N_AXES][2]);
144
145     /* Scales all output by FACTOR, e.g. a FACTOR of 0.5 would cause everything
146        subsequent to be drawn half-size.  FACTOR will be greater than 0 and
147        less than or equal to 1.
148
149        Optional.  If NULL, the rendering engine won't try to scale output. */
150     void (*scale) (void *aux, double factor);
151   };
152
153 /* An iterator for breaking render_pages into smaller chunks. */
154 struct render_pager *render_pager_create (const struct render_params *,
155                                           const struct table_item *,
156                                           const size_t *layer_indexes);
157 void render_pager_destroy (struct render_pager *);
158
159 bool render_pager_has_next (const struct render_pager *);
160 int render_pager_draw_next (struct render_pager *, int space);
161
162 void render_pager_draw (const struct render_pager *);
163 void render_pager_draw_region (const struct render_pager *,
164                                int x, int y, int w, int h);
165
166 int render_pager_get_size (const struct render_pager *, enum table_axis);
167 int render_pager_get_best_breakpoint (const struct render_pager *, int height);
168
169 bool render_direction_rtl (void);
170
171
172 #endif /* output/render.h */