render: Fix rendering of backgrounds in middle- or bottom-justified cells.
[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
52    Callback functions
53    ==================
54
55    For each of the callback functions, AUX is passed as the 'aux' member of the
56    render_params structure.
57 */
58 struct render_params
59   {
60     /* Measures CELL's width.  Stores in *MIN_WIDTH the minimum width required
61        to avoid splitting a single word across multiple lines (normally, this
62        is the width of the longest word in the cell) and in *MAX_WIDTH the
63        minimum width required to avoid line breaks other than at new-lines.
64        */
65     void (*measure_cell_width) (void *aux, const struct table_cell *cell,
66                                 int *min_width, int *max_width);
67
68     /* Returns the height required to render CELL given a width of WIDTH. */
69     int (*measure_cell_height) (void *aux, const struct table_cell *cell,
70                                 int width);
71
72     /* Given that there is space measuring WIDTH by HEIGHT to render CELL,
73        where HEIGHT is insufficient to render the entire height of the cell,
74        returns the largest height less than HEIGHT at which it is appropriate
75        to break the cell.  For example, if breaking at the specified HEIGHT
76        would break in the middle of a line of text, the return value would be
77        just sufficiently less that the breakpoint would be between lines of
78        text.
79
80        Optional.  If NULL, the rendering engine assumes that all breakpoints
81        are acceptable. */
82     int (*adjust_break) (void *aux, const struct table_cell *cell,
83                          int width, int height);
84
85     /* Draws a generalized intersection of lines in the rectangle whose
86        top-left corner is (BB[TABLE_HORZ][0], BB[TABLE_VERT][0]) and whose
87        bottom-right corner is (BB[TABLE_HORZ][1], BB[TABLE_VERT][1]).
88
89        STYLES is interpreted this way:
90
91        STYLES[TABLE_HORZ][0]: style of line from top of BB to its center.
92        STYLES[TABLE_HORZ][1]: style of line from bottom of BB to its center.
93        STYLES[TABLE_VERT][0]: style of line from left of BB to its center.
94        STYLES[TABLE_VERT][1]: style of line from right of BB to its center. */
95     void (*draw_line) (void *aux, int bb[TABLE_N_AXES][2],
96                        enum render_line_style styles[TABLE_N_AXES][2],
97                        struct cell_color colors[TABLE_N_AXES][2]);
98
99     /* Draws CELL within bounding box BB.  CLIP is the same as BB (the common
100        case) or a subregion enclosed by BB.  In the latter case only the part
101        of the cell that lies within CLIP should actually be drawn, although BB
102        should used to determine the layout of the cell.
103
104        The text in the cell needs to be vertically offset VALIGN_OFFSET units
105        from the top of the bounding box.  This handles vertical alignment with
106        the cell.  (The caller doesn't just reduce the bounding box size because
107        that would prevent the implementation from filling the entire cell with
108        the background color.)  The implementation must handle horizontal
109        alignment itself. */
110     void (*draw_cell) (void *aux, const struct table_cell *cell, int color_idx,
111                        int bb[TABLE_N_AXES][2], int valign_offset,
112                        int spill[TABLE_N_AXES][2],
113                        int clip[TABLE_N_AXES][2]);
114
115     /* Auxiliary data passed to each of the above functions. */
116     void *aux;
117
118     /* Page size to try to fit the rendering into.  Some tables will, of
119        course, overflow this size. */
120     int size[TABLE_N_AXES];
121
122     /* Nominal size of a character in the most common font:
123        font_size[TABLE_HORZ]: Em width.
124        font_size[TABLE_VERT]: Line spacing. */
125     int font_size[TABLE_N_AXES];
126
127     /* Width of different kinds of lines. */
128     int line_widths[TABLE_N_AXES][RENDER_N_LINES];
129
130     /* Minimum cell width or height before allowing the cell to be broken
131        across two pages.  (Joined cells may always be broken at join
132        points.) */
133     int min_break[TABLE_N_AXES];
134
135     /* True if the driver supports cell margins.  (If false, the rendering
136        engine will insert a small space betweeen adjacent cells that don't have
137        an intervening rule.)  */
138     bool supports_margins;
139
140     /* True if the local language has a right-to-left direction, otherwise
141        false.  (Use render_direction_rtl() to find out.) */
142     bool rtl;
143   };
144
145 /* An iterator for breaking render_pages into smaller chunks. */
146 struct render_pager *render_pager_create (const struct render_params *,
147                                           const struct table_item *);
148 void render_pager_destroy (struct render_pager *);
149
150 bool render_pager_has_next (const struct render_pager *);
151 int render_pager_draw_next (struct render_pager *, int space);
152
153 void render_pager_draw (const struct render_pager *);
154 void render_pager_draw_region (const struct render_pager *,
155                                int x, int y, int w, int h);
156
157 int render_pager_get_size (const struct render_pager *, enum table_axis);
158 int render_pager_get_best_breakpoint (const struct render_pager *, int height);
159
160 bool render_direction_rtl (void);
161
162
163 #endif /* output/render.h */