1
2 /******************************************************************************
3 * MODULE : boxes.hpp
4 * DESCRIPTION: the low level box structure
5 * and formatting routines
6 * COPYRIGHT : (C) 1999 Joris van der Hoeven
7 *******************************************************************************
8 * This software falls under the GNU general public license version 3 or later.
9 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ******************************************************************************/
12
13 #ifndef BOXES_H
14 #define BOXES_H
15 #include "basic.hpp"
16 #include "rectangles.hpp"
17 #include "path.hpp"
18 #include "renderer.hpp"
19 #include "timer.hpp"
20 #include "font.hpp"
21 #include "language.hpp"
22 #include "hashmap.hpp"
23 #include "frame.hpp"
24 #include "grid.hpp"
25
26 #define STD_BOX 0
27 #define STACK_BOX 1
28 #define CONTROL_BOX 2
29 #define MOVE_BOX 3
30 #define SCROLL_BOX 4
31 #define TEXT_BOX 5
32 #define SHORTER_BOX 6
33 #define BIG_OP_BOX 7
34
35 /******************************************************************************
36 * The cursor class
37 ******************************************************************************/
38
39 struct cursor_rep: concrete_struct {
40 SI ox, oy; // main cursor position
41 SI delta; // infinitesimal shift to the right
42 SI y1; // under base line
43 SI y2; // upper base line
44 double slope; // slope of cursor
45 bool valid; // the cursor is valid
46 };
47
48 struct cursor {
49 CONCRETE(cursor);
50 cursor (SI x=0, SI y=0, SI delta=0, SI y1=0, SI y2=0,
51 double slope=0.0, bool valid=true);
52 };
53 CONCRETE_CODE(cursor);
54
55 cursor copy (cursor cu);
56 bool operator == (cursor cu1, cursor cu2);
57 bool operator != (cursor cu1, cursor cu2);
58 tm_ostream& operator << (tm_ostream& out, cursor cu);
59
60 /******************************************************************************
61 * The selection class
62 ******************************************************************************/
63
64 struct selection_rep: concrete_struct {
65 rectangles rs;
66 path start;
67 path end;
68 bool valid;
69 };
70
71 struct selection {
72 CONCRETE(selection);
73 selection (rectangles rs= rectangles(),
74 path start= path(), path end= path (),
75 bool valid= true);
76 };
77 CONCRETE_CODE(selection);
78
79 bool operator == (selection sel1, selection sel2);
80 bool operator != (selection sel1, selection sel2);
81 tm_ostream& operator << (tm_ostream& out, selection sel);
82
83 /******************************************************************************
84 * The graphical selection class
85 ******************************************************************************/
86
87 struct gr_selection_rep;
88 struct gr_selection {
89 CONCRETE(gr_selection);
90 gr_selection (array<path> cp= array<path> (), SI dist= 0);
91 };
92
93 tm_ostream& operator << (tm_ostream& out, gr_selection sel);
94
95 typedef array<gr_selection> gr_selections;
96 void sort (gr_selections& sels);
97 tree as_tree (gr_selections sels);
98
99 /******************************************************************************
100 * The box class
101 ******************************************************************************/
102
103 class box_rep;
104 struct lazy;
105 typedef array<double> point;
106
107 class box {
108 ABSTRACT_NULL(box);
109 inline box operator [] (int i);
110 box operator [] (path p);
111 operator tree ();
112 bool operator == (box b2);
113 bool operator != (box b2);
114 friend inline int N (box b);
115 };
116
117 class box_rep: public abstract_struct {
118 private:
119 SI x0, y0; // offset w.r.t. parent box
120
121 public:
122 SI x1, y1; // under left corner (logical)
123 SI x2, y2; // upper right corner (logical)
124 SI x3, y3; // under left corner (ink)
125 SI x4, y4; // upper right corner (ink)
126
127 path ip; // corresponding inverse path in source tree
128
129 /****************************** main routines ******************************/
130
131 inline box_rep (path ip);
132 inline virtual ~box_rep ();
133 void relocate (path p, bool force= false);
134 virtual box transform (frame fr);
135 virtual operator tree () = 0;
136 virtual void pre_display (renderer& ren);
137 virtual void post_display (renderer& ren);
138 virtual void display (renderer ren) = 0;
139 virtual void clear_incomplete (rectangles& rs, SI pixel,
140 int i, int i1, int i2);
141 virtual int subnr ();
142 virtual box subbox (int i);
143 virtual tree action (tree t, SI x, SI y, SI delta);
144 virtual void loci (SI x, SI y, SI d, list<string>& ids, rectangles& rs);
145 virtual void position_at (SI x, SI y, rectangles& change_log);
146 virtual void collect_page_numbers (hashmap<string,tree>& h, tree page);
147 virtual path find_tag (string name);
148
149 virtual int reindex (int i, int item, int n);
150 virtual void redraw (renderer ren, path p, rectangles& l);
151 void redraw (renderer ren, path p, rectangles& l, SI x, SI y);
152
153 /*************************** positioning routines **************************/
154
155 inline SI w ();
156 inline SI h ();
157 inline SI& sx (int i);
158 inline SI& sy (int i);
159 inline SI sx1 (int i);
160 inline SI sy1 (int i);
161 inline SI sx2 (int i);
162 inline SI sy2 (int i);
163 inline SI sx3 (int i);
164 inline SI sy3 (int i);
165 inline SI sx4 (int i);
166 inline SI sy4 (int i);
167 inline bool test_in (SI x, SI y);
168
169 inline bool accessible ();
170 inline bool decoration ();
171
172 SI distance (int i, SI x, SI y, SI delta);
173 bool in_rectangle (SI x1, SI y1, SI x2, SI y2);
174 bool contains_rectangle (SI x1, SI y1, SI x2, SI y2);
175
176 virtual box adjust_kerning (int mode, double factor);
177 virtual void get_cell_extents (SI& l, SI& r);
178 virtual box adjust_cell_geometry (SI dx, SI dl, SI dr);
179
180 /******************* path conversions and cursor routines ******************/
181
182 virtual path find_lip ();
183 virtual path find_rip ();
184 virtual path find_left_box_path ();
185 virtual path find_right_box_path ();
186 virtual path find_box_path (SI x, SI y, SI d, bool force, bool& found);
187 virtual cursor find_cursor (path bp);
188 virtual selection find_selection (path lbp, path rbp);
189 virtual path find_tree_path (path bp);
190 virtual path find_box_path (path p, bool& found);
191
192 path find_tree_path (SI x, SI y, SI delta);
193 cursor find_check_cursor (path p);
194 selection find_check_selection (path lp, path rp);
195
196 /************************ fine typesetting routines ************************/
197
198 virtual double left_slope ();
199 virtual double right_slope ();
200 virtual SI left_correction ();
201 virtual SI right_correction ();
202 virtual SI lsub_correction ();
203 virtual SI lsup_correction ();
204 virtual SI rsub_correction ();
205 virtual SI rsup_correction ();
206 virtual SI sub_lo_base (int level);
207 virtual SI sub_hi_lim (int level);
208 virtual SI sup_lo_lim (int level);
209 virtual SI sup_lo_base (int level);
210 virtual SI sup_hi_lim (int level);
211 virtual void get_bracket_extents (SI& lo, SI& hi);
212
213 /*************************** for graphical boxes ***************************/
214
215 virtual frame get_frame ();
216 virtual grid get_grid ();
217 virtual void get_limits (point& lim1, point& lim2);
218
219 frame find_frame (path bp, bool last= false);
220 grid find_grid (path bp);
221 void find_limits (path bp, point& lim1, point& lim2);
222
223 virtual SI graphical_distance (SI x, SI y);
224 virtual gr_selections graphical_select (SI x, SI y, SI dist);
225 virtual gr_selections graphical_select (SI x1, SI y1, SI x2, SI y2);
226
227 /************************** retrieving information *************************/
228
229 virtual int get_type ();
230 virtual tree get_info (tree in);
231 virtual int get_leaf_left_pos ();
232 virtual int get_leaf_right_pos ();
233 virtual string get_leaf_string ();
234 virtual font get_leaf_font ();
235 virtual pencil get_leaf_pencil ();
236 virtual language get_leaf_language ();
237 virtual tree get_leaf_tree ();
238 virtual box get_leaf_box ();
239 virtual lazy get_leaf_lazy ();
240 virtual SI get_leaf_offset (string search);
241
242 /******************************** animations *******************************/
243
244 virtual int anim_length ();
245 virtual bool anim_started ();
246 virtual bool anim_finished ();
247 virtual void anim_start_at (time_t at);
248 virtual void anim_finish_now ();
249 virtual time_t anim_next_update ();
250 void anim_check_invalid (bool& flag, time_t& at, rectangles& rs);
251 virtual void anim_get_invalid (bool& flag, time_t& at, rectangles& rs);
252
253 /********************************* obsolete ********************************/
254
255 friend struct page_box_rep; // temporary friends for accessing x0 and y0
256 friend struct lazy_paragraph_rep;
257 friend class phrase_box_rep;
258 friend class remember_box_rep;
259 friend class effect_box_rep;
260 friend void make_eps (url dest, box b, int dpi);
261 };
262 ABSTRACT_NULL_CODE(box);
263
264 extern int box_count;
box_rep(path ip2)265 inline box_rep::box_rep (path ip2):
266 x0(0), y0(0), x1(0), y1(0), x2(0), y2(0), x3(0), y3(0), x4(0), y4(0),
267 ip (ip2) { TM_DEBUG(box_count++); }
~box_rep()268 inline box_rep::~box_rep () { TM_DEBUG(box_count--); }
test_in(SI x,SI y)269 inline bool box_rep::test_in (SI x, SI y) {
270 return (x>=x1) && (x<x2) && (y>=y1) && (y<y2); }
w()271 inline SI box_rep::w () { return x2-x1; }
h()272 inline SI box_rep::h () { return y2-y1; }
sx(int i)273 inline SI& box_rep::sx (int i) { return subbox(i)->x0; }
sy(int i)274 inline SI& box_rep::sy (int i) { return subbox(i)->y0; }
sx1(int i)275 inline SI box_rep::sx1 (int i) { box b= subbox(i); return b->x0+ b->x1; }
sy1(int i)276 inline SI box_rep::sy1 (int i) { box b= subbox(i); return b->y0+ b->y1; }
sx2(int i)277 inline SI box_rep::sx2 (int i) { box b= subbox(i); return b->x0+ b->x2; }
sy2(int i)278 inline SI box_rep::sy2 (int i) { box b= subbox(i); return b->y0+ b->y2; }
sx3(int i)279 inline SI box_rep::sx3 (int i) { box b= subbox(i); return b->x0+ b->x3; }
sy3(int i)280 inline SI box_rep::sy3 (int i) { box b= subbox(i); return b->y0+ b->y3; }
sx4(int i)281 inline SI box_rep::sx4 (int i) { box b= subbox(i); return b->x0+ b->x4; }
sy4(int i)282 inline SI box_rep::sy4 (int i) { box b= subbox(i); return b->y0+ b->y4; }
283
operator [](int i)284 inline box box::operator [] (int i) { return rep->subbox(i); }
N(box b)285 inline int N (box b) { return b.rep->subnr(); }
286 tm_ostream& operator << (tm_ostream& out, box b);
287 SI get_delta (SI x, SI x1, SI x2);
288 bool outside (SI x, SI delta, SI x1, SI x2);
289 void make_eps (url dest, box b, int dpi);
290 path find_innermost_scroll (box b, path p);
291 path find_scrolled_tree_path (box b, path sp, SI x, SI y, SI delta);
292 void find_canvas_info (box b, path sp, SI& x, SI& y, SI& sx, SI& sy,
293 rectangle& outer, rectangle& inner);
294
295 extern bool refresh_needed;
296 extern time_t refresh_next;
297 void refresh_at (time_t t);
298
299 #define DECORATION (-1)
300 #define DECORATION_LEFT (-2)
301 #define DECORATION_MIDDLE (-3)
302 #define DECORATION_RIGHT (-4)
303 #define DETACHED (-5)
304 #define is_accessible(p) ((is_nil (p)) || ((p)->item >= 0))
305 #define is_decoration(p) ((!is_nil (p)) && ((p)->item < 0))
descend(path ip,int i)306 inline path descend (path ip, int i) {
307 return (is_nil (ip) || (ip->item >= 0))? path (i, ip): ip; }
decorate()308 inline path decorate () {
309 return path (DECORATION); }
decorate(path ip)310 inline path decorate (path ip) {
311 return (is_nil (ip) || (ip->item >= 0))? path (DECORATION, ip): ip; }
decorate_left(path ip)312 inline path decorate_left (path ip) {
313 return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_LEFT, ip): ip; }
decorate_middle(path ip)314 inline path decorate_middle (path ip) {
315 return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_MIDDLE, ip): ip; }
decorate_right(path ip)316 inline path decorate_right (path ip) {
317 return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_RIGHT, ip): ip; }
318 path descend_decode (path ip, int side);
319
accessible()320 inline bool box_rep::accessible () { return is_accessible (find_lip ()); }
decoration()321 inline bool box_rep::decoration () { return is_decoration (find_lip ()); }
322
323 tree attach_dip (tree ref, path ip);
324 #define attach_here(t,ip) attach_dip(t,ip),ip
325 #define attach_deco(t,ip) attach_dip(t,decorate(ip)),decorate(ip)
326 #define attach_left(t,ip) attach_dip(t,decorate_left(ip)),decorate_left(ip)
327 #define attach_middle(t,ip) \
328 attach_dip(t,decorate_middle(ip)),decorate_middle(ip)
329 #define attach_right(t,ip) attach_dip(t,decorate_right(ip)),decorate_right(ip)
330
331 /******************************************************************************
332 * The graphical selection class (continued)
333 ******************************************************************************/
334
335 struct gr_selection_rep: concrete_struct {
336 string type;
337 array<path> cp;
338 array<point> pts;
339 point p;
340 SI dist;
341 curve c;
342 };
343 CONCRETE_CODE(gr_selection);
344
345 #endif // defined BOXES_H
346