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