~registry/texmacs/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/******************************************************************************
* MODULE     : boxes.hpp
* DESCRIPTION: the low level box structure
*              and formatting routines
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/

#ifndef BOXES_H
#define BOXES_H
#include "basic.hpp"
#include "rectangles.hpp"
#include "path.hpp"
#include "renderer.hpp"
#include "font.hpp"
#include "language.hpp"
#include "hashmap.hpp"
#include "Graphics/frame.hpp"
#include "Graphics/grid.hpp"

#define MAX_SI 0x7fffffff
#define MIN_SI 0x80000000

#define STD_BOX       0
#define STACK_BOX     1
#define CONTROL_BOX   2
#define MOVE_BOX      3
#define SCROLL_BOX    4

/******************************************************************************
* The cursor class
******************************************************************************/

struct cursor_rep: concrete_struct {
  SI ox, oy;    // main cursor position
  SI delta;     // infinitesimal shift to the right
  SI y1;        // under base line
  SI y2;        // upper base line
  double slope; // slope of cursor
  bool valid;   // the cursor is valid
};

struct cursor {
  CONCRETE(cursor);
  cursor (SI x=0, SI y=0, SI delta=0, SI y1=0, SI y2=0,
	  double slope=0.0, bool valid=true);
};
CONCRETE_CODE(cursor);

cursor copy (cursor cu);
bool operator == (cursor cu1, cursor cu2);
bool operator != (cursor cu1, cursor cu2);
ostream& operator << (ostream& out, cursor cu);

/******************************************************************************
* The selection class
******************************************************************************/

struct selection_rep: concrete_struct {
  rectangles rs;
  path start;
  path end;
  bool valid;
};

struct selection {
  CONCRETE(selection);
  selection (rectangles rs= rectangles(),
	     path start= path(), path end= path (),
	     bool valid= true);
};
CONCRETE_CODE(selection);

bool operator == (selection sel1, selection sel2);
bool operator != (selection sel1, selection sel2);
ostream& operator << (ostream& out, selection sel);

/******************************************************************************
* The graphical selection class
******************************************************************************/

struct gr_selection_rep;
struct gr_selection {
  CONCRETE(gr_selection);
  gr_selection (array<path> cp= array<path> (), SI dist= 0);
};

ostream& operator << (ostream& out, gr_selection sel);

typedef array<gr_selection> gr_selections;
tree as_tree (gr_selections sels);

/******************************************************************************
* The box class
******************************************************************************/

class box_rep;
struct lazy;
typedef array<double> point;

class box {
  ABSTRACT_NULL(box);
  inline box operator [] (int i);
  box operator [] (path p);
  operator tree ();
  bool operator == (box b2);
  bool operator != (box b2);
  friend inline int N (box b);
};

class box_rep: public abstract_struct {
private:
  SI x0, y0;    // offset w.r.t. parent box

public:
  SI x1, y1;    // under left corner (logical)
  SI x2, y2;    // upper right corner (logical)
  SI x3, y3;    // under left corner (ink)
  SI x4, y4;    // upper right corner (ink)

  path ip;      // corresponding inverse path in source tree

  /****************************** main routines ******************************/

  inline            box_rep (path ip);
  inline            virtual ~box_rep ();
  void              relocate (path p, bool force= false);
  virtual box	    transform (frame fr);
  virtual operator  tree () = 0;
  virtual void      pre_display (renderer& ren);
  virtual void      post_display (renderer& ren);
  virtual void      display (renderer ren) = 0;
  virtual void      clear_incomplete (rectangles& rs, SI pixel,
				      int i, int i1, int i2);
  virtual int       subnr ();
  virtual box       subbox (int i);
  virtual tree      action (tree t, SI x, SI y, SI delta);
  virtual void      loci (SI x, SI y, SI d, list<string>& ids, rectangles& rs);
  virtual void      position_at (SI x, SI y, rectangles& change_log);
  virtual void      collect_page_numbers (hashmap<string,tree>& h, tree page);
  virtual path      find_tag (string name);

  virtual int  reindex (int i, int item, int n);
  void redraw (renderer ren, path p, rectangles& l);
  void redraw (renderer ren, path p, rectangles& l, SI x, SI y);

  /*************************** positioning routines **************************/

  inline SI   w ();
  inline SI   h ();
  inline SI&  sx (int i);
  inline SI&  sy (int i);
  inline SI   sx1 (int i);
  inline SI   sy1 (int i);
  inline SI   sx2 (int i);
  inline SI   sy2 (int i);
  inline SI   sx3 (int i);
  inline SI   sy3 (int i);
  inline SI   sx4 (int i);
  inline SI   sy4 (int i);
  inline bool test_in (SI x, SI y);

  inline bool accessible ();
  inline bool decoration ();

  SI distance (int i, SI x, SI y, SI delta);
  bool in_rectangle (SI x1, SI y1, SI x2, SI y2);
  bool contains_rectangle (SI x1, SI y1, SI x2, SI y2);

  /******************* path conversions and cursor routines ******************/

  virtual path      find_lip ();
  virtual path      find_rip ();
  virtual path      find_left_box_path ();
  virtual path      find_right_box_path ();
  virtual path      find_box_path (SI x, SI y, SI delta, bool force);
  virtual cursor    find_cursor (path bp);
  virtual selection find_selection (path lbp, path rbp);
  virtual path      find_tree_path (path bp);
  virtual path      find_box_path (path p, bool& found);
       
  path      find_tree_path (SI x, SI y, SI delta);
  cursor    find_check_cursor (path p);
  selection find_check_selection (path lp, path rp);

  /************************ fine typesetting routines ************************/

  virtual double    left_slope ();
  virtual double    right_slope ();
  virtual SI        left_correction ();
  virtual SI        right_correction ();
  virtual SI        lsub_correction ();
  virtual SI        lsup_correction ();
  virtual SI        rsub_correction ();
  virtual SI        rsup_correction ();
  virtual SI        sub_lo_base (int level);
  virtual SI        sub_hi_lim  (int level);
  virtual SI        sup_lo_lim  (int level);
  virtual SI        sup_lo_base (int level);
  virtual SI        sup_hi_lim  (int level);

  /*************************** for graphical boxes ***************************/

  virtual frame     get_frame ();
  virtual grid      get_grid ();
  virtual void      get_limits (point& lim1, point& lim2);

  frame     find_frame (path bp, bool last= false);
  grid      find_grid (path bp);
  void      find_limits (path bp, point& lim1, point& lim2);

  virtual SI             graphical_distance (SI x, SI y);
  virtual gr_selections  graphical_select (SI x, SI y, SI dist);
  virtual gr_selections  graphical_select (SI x1, SI y1, SI x2, SI y2);

  /************************** retrieving information *************************/

  virtual int       get_type ();
  virtual tree      get_info (tree in);
  virtual int       get_leaf_left_pos ();
  virtual int       get_leaf_right_pos ();
  virtual string    get_leaf_string ();
  virtual font      get_leaf_font ();
  virtual color     get_leaf_color ();
  virtual language  get_leaf_language ();
  virtual tree      get_leaf_tree ();
  virtual lazy      get_leaf_lazy ();
  virtual SI        get_leaf_offset (string search);

  /******************************** animations *******************************/

  virtual int    anim_length ();
  virtual bool   anim_started ();
  virtual bool   anim_finished ();
  virtual void   anim_start_at (time_t at);
  virtual void   anim_finish_now ();
  virtual time_t anim_next_update ();
          void   anim_check_invalid (bool& flag, time_t& at, rectangles& rs);
  virtual void   anim_get_invalid (bool& flag, time_t& at, rectangles& rs);

  /********************************* obsolete ********************************/

  friend struct page_box_rep; // temporary friends for accessing x0 and y0
  friend struct lazy_paragraph_rep;
  friend class  phrase_box_rep;
  friend class  remember_box_rep;
  friend void make_eps (url dest, box b, int dpi= 600);
};
ABSTRACT_NULL_CODE(box);

extern int box_count;
inline box_rep::box_rep (path ip2):
  x0(0), y0(0), x1(0), y1(0), x2(0), y2(0), x3(0), y3(0), x4(0), y4(0),
  ip (ip2) { DEBUG(box_count++); }
inline box_rep::~box_rep () { DEBUG(box_count--); }
inline bool box_rep::test_in (SI x, SI y) {
  return (x>=x1) && (x<x2) && (y>=y1) && (y<y2); }
inline SI box_rep::w () { return x2-x1; }
inline SI box_rep::h () { return y2-y1; }
inline SI& box_rep::sx (int i) { return subbox(i)->x0; }
inline SI& box_rep::sy (int i) { return subbox(i)->y0; }
inline SI box_rep::sx1 (int i) { box b= subbox(i); return b->x0+ b->x1; }
inline SI box_rep::sy1 (int i) { box b= subbox(i); return b->y0+ b->y1; }
inline SI box_rep::sx2 (int i) { box b= subbox(i); return b->x0+ b->x2; }
inline SI box_rep::sy2 (int i) { box b= subbox(i); return b->y0+ b->y2; }
inline SI box_rep::sx3 (int i) { box b= subbox(i); return b->x0+ b->x3; }
inline SI box_rep::sy3 (int i) { box b= subbox(i); return b->y0+ b->y3; }
inline SI box_rep::sx4 (int i) { box b= subbox(i); return b->x0+ b->x4; }
inline SI box_rep::sy4 (int i) { box b= subbox(i); return b->y0+ b->y4; }

inline box box::operator [] (int i) { return rep->subbox(i); }
inline int N (box b) { return b.rep->subnr(); }
ostream& operator << (ostream& out, box b);
SI   get_delta (SI x, SI x1, SI x2);
bool outside (SI x, SI delta, SI x1, SI x2);
void make_eps (url dest, box b, int dpi);
path find_innermost_scroll (box b, path p);
path find_scrolled_tree_path (box b, path sp, SI x, SI y, SI delta);
void find_canvas_info (box b, path sp, SI& x, SI& y, SI& sx, SI& sy,
		       rectangle& outer, rectangle& inner);

extern bool   refresh_needed;
extern time_t refresh_next;
void          refresh_at (time_t t);

#define DECORATION        (-1)
#define DECORATION_LEFT   (-2)
#define DECORATION_MIDDLE (-3)
#define DECORATION_RIGHT  (-4)
#define DETACHED          (-5)
#define is_accessible(p) ((is_nil (p)) || ((p)->item >= 0))
#define is_decoration(p) ((!is_nil (p)) && ((p)->item < 0))
inline path descend (path ip, int i) {
  return (is_nil (ip) || (ip->item >= 0))? path (i, ip): ip; }
inline path decorate () {
  return path (DECORATION); }
inline path decorate (path ip) {
  return (is_nil (ip) || (ip->item >= 0))? path (DECORATION, ip): ip; }
inline path decorate_left (path ip) {
  return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_LEFT, ip): ip; }
inline path decorate_middle (path ip) {
  return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_MIDDLE, ip): ip; }
inline path decorate_right (path ip) {
  return (is_nil (ip) || (ip->item >= 0))? path (DECORATION_RIGHT, ip): ip; }
path descend_decode (path ip, int side);

inline bool box_rep::accessible () { return is_accessible (find_lip ()); }
inline bool box_rep::decoration () { return is_decoration (find_lip ()); }

tree attach_dip (tree ref, path ip);
#define attach_here(t,ip) attach_dip(t,ip),ip
#define attach_deco(t,ip) attach_dip(t,decorate(ip)),decorate(ip)
#define attach_left(t,ip) attach_dip(t,decorate_left(ip)),decorate_left(ip)
#define attach_middle(t,ip) \
  attach_dip(t,decorate_middle(ip)),decorate_middle(ip)
#define attach_right(t,ip) attach_dip(t,decorate_right(ip)),decorate_right(ip)

/******************************************************************************
* The graphical selection class (continued)
******************************************************************************/

struct gr_selection_rep: concrete_struct {
  array<path> cp;
  array<point> pts;
  point p;
  SI dist;
  curve c;
};
CONCRETE_CODE(gr_selection);

#endif // defined BOXES_H