Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / groff / src / roff / troff / node.h
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4      Written by James Clark (jjc@jclark.com)
5
6 This file is part of groff.
7
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with groff; see the file COPYING.  If not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22
23 struct hyphen_list {
24   unsigned char hyphen;
25   unsigned char breakable;
26   unsigned char hyphenation_code;
27   hyphen_list *next;
28   hyphen_list(unsigned char code, hyphen_list *p = 0);
29 };
30
31 void hyphenate(hyphen_list *, unsigned);
32
33 enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT };
34
35 class ascii_output_file;
36
37 struct breakpoint;
38 struct vertical_size;
39 struct charinfo;
40
41 class macro;
42
43 class troff_output_file;
44 class tfont;
45 class environment;
46
47 class glyph_node;
48 class diverted_space_node;
49 class token_node;
50
51 struct node {
52   node *next;
53   node *last;
54   node();
55   node(node *n);
56   node *add_char(charinfo *c, environment *, hunits *widthp, int *spacep);
57
58   virtual ~node();
59   virtual node *copy() = 0;
60   virtual int set_unformat_flag();
61   virtual int force_tprint() = 0;
62   virtual hunits width();
63   virtual hunits subscript_correction();
64   virtual hunits italic_correction();
65   virtual hunits left_italic_correction();
66   virtual hunits skew();
67   virtual int nspaces();
68   virtual int merge_space(hunits, hunits, hunits);
69   virtual vunits vertical_width();
70   virtual node *last_char_node();
71   virtual void vertical_extent(vunits *min, vunits *max);
72   virtual int character_type();
73   virtual void set_vertical_size(vertical_size *);
74   virtual int ends_sentence();
75   virtual node *merge_self(node *);
76   virtual node *add_discretionary_hyphen();
77   virtual node *add_self(node *, hyphen_list **);
78   virtual hyphen_list *get_hyphen_list(hyphen_list *s = 0);
79   virtual void ascii_print(ascii_output_file *);
80   virtual void asciify(macro *);
81   virtual int discardable();
82   virtual void spread_space(int *, hunits *);
83   virtual void freeze_space();
84   virtual void is_escape_colon();
85   virtual breakpoint *get_breakpoints(hunits width, int nspaces,
86                                       breakpoint *rest = 0,
87                                       int is_inner = 0);
88   virtual int nbreaks();
89   virtual void split(int, node **, node **);
90   virtual hyphenation_type get_hyphenation_type();
91   virtual int reread(int *);
92   virtual token_node *get_token_node();
93   virtual int overlaps_vertically();
94   virtual int overlaps_horizontally();
95   virtual units size();
96   virtual int interpret(macro *);
97
98   virtual node *merge_glyph_node(glyph_node *);
99   virtual tfont *get_tfont();
100   virtual color *get_glyph_color();
101   virtual color *get_fill_color();
102   virtual void tprint(troff_output_file *);
103   virtual void zero_width_tprint(troff_output_file *);
104
105   node *add_italic_correction(hunits *);
106
107   virtual int same(node *) = 0;
108   virtual const char *type() = 0;
109 };
110
111 inline node::node()
112 : next(0), last(0)
113 {
114 }
115
116 inline node::node(node *n)
117 : next(n), last(0)
118 {
119 }
120
121 inline node::~node()
122 {
123 }
124
125 // 0 means it doesn't, 1 means it does, 2 means it's transparent
126
127 int node_list_ends_sentence(node *);
128
129 struct breakpoint {
130   breakpoint *next;
131   hunits width;
132   int nspaces;
133   node *nd;
134   int index;
135   char hyphenated;
136 };
137
138 class line_start_node : public node {
139 public:
140   line_start_node() {}
141   node *copy() { return new line_start_node; }
142   int same(node *);
143   int force_tprint();
144   const char *type();
145   void asciify(macro *);
146 };
147
148 class space_node : public node {
149 private:
150 #if 0
151   enum { BLOCK = 1024 };
152   static space_node *free_list;
153   void operator delete(void *);
154 #endif
155 protected:
156   hunits n;
157   char set;
158   char was_escape_colon;
159   color *col;                   /* for grotty */
160   space_node(hunits, int, int, color *, node * = 0);
161 public:
162   space_node(hunits, color *, node * = 0);
163 #if 0
164   ~space_node();
165   void *operator new(size_t);
166 #endif
167   node *copy();
168   int nspaces();
169   hunits width();
170   int discardable();
171   int merge_space(hunits, hunits, hunits);
172   void freeze_space();
173   void is_escape_colon();
174   void spread_space(int *, hunits *);
175   void tprint(troff_output_file *);
176   breakpoint *get_breakpoints(hunits width, int nspaces, breakpoint *rest = 0,
177                               int is_inner = 0);
178   int nbreaks();
179   void split(int, node **, node **);
180   void ascii_print(ascii_output_file *);
181   int same(node *);
182   void asciify(macro *);
183   const char *type();
184   int force_tprint();
185   hyphenation_type get_hyphenation_type();
186 };
187
188 struct width_list {
189   hunits width;
190   hunits sentence_width;
191   width_list *next;
192   width_list(hunits, hunits);
193   width_list(width_list *);
194 };
195
196 class word_space_node : public space_node {
197 protected:
198   width_list *orig_width;
199   unsigned char unformat;
200   word_space_node(hunits, int, color *, width_list *, int, node * = 0);
201 public:
202   word_space_node(hunits, color *, width_list *, node * = 0);
203   ~word_space_node();
204   node *copy();
205   int reread(int *);
206   int set_unformat_flag();
207   void tprint(troff_output_file *);
208   int same(node *);
209   void asciify(macro *);
210   const char *type();
211   int merge_space(hunits, hunits, hunits);
212   int force_tprint();
213 };
214
215 class unbreakable_space_node : public word_space_node {
216   unbreakable_space_node(hunits, int, color *, node * = 0);
217 public:
218   unbreakable_space_node(hunits, color *, node * = 0);
219   node *copy();
220   int reread(int *);
221   int same(node *);
222   void asciify(macro *);
223   const char *type();
224   int force_tprint();
225   breakpoint *get_breakpoints(hunits width, int nspaces, breakpoint *rest = 0,
226                               int is_inner = 0);
227   int nbreaks();
228   void split(int, node **, node **);
229   int merge_space(hunits, hunits, hunits);
230   node *add_self(node *, hyphen_list **);
231   hyphen_list *get_hyphen_list(hyphen_list *ss = 0);
232   hyphenation_type get_hyphenation_type();
233 };
234
235 class diverted_space_node : public node {
236 public:
237   vunits n;
238   diverted_space_node(vunits d, node *p = 0);
239   node *copy();
240   int reread(int *);
241   int same(node *);
242   const char *type();
243   int force_tprint();
244 };
245
246 class diverted_copy_file_node : public node {
247   symbol filename;
248 public:
249   vunits n;
250   diverted_copy_file_node(symbol s, node *p = 0);
251   node *copy();
252   int reread(int *);
253   int same(node *);
254   const char *type();
255   int force_tprint();
256 };
257
258 class extra_size_node : public node {
259   vunits n;
260 public:
261   extra_size_node(vunits i) : n(i) {}
262   void set_vertical_size(vertical_size *);
263   node *copy();
264   int same(node *);
265   const char *type();
266   int force_tprint();
267 };
268
269 class vertical_size_node : public node {
270   vunits n;
271 public:
272   vertical_size_node(vunits i) : n(i) {}
273   void set_vertical_size(vertical_size *);
274   void asciify(macro *);
275   node *copy();
276   int set_unformat_flag();
277   int same(node *);
278   const char *type();
279   int force_tprint();
280 };
281
282 class hmotion_node : public node {
283 protected:
284   hunits n;
285   unsigned char was_tab;
286   unsigned char unformat;
287   color *col;                   /* for grotty */
288 public:
289   hmotion_node(hunits i, color *c, node *next = 0)
290     : node(next), n(i), was_tab(0), unformat(0), col(c) {}
291   hmotion_node(hunits i, int flag1, int flag2, color *c, node *next = 0)
292     : node(next), n(i), was_tab(flag1), unformat(flag2), col(c) {}
293   node *copy();
294   int reread(int *);
295   int set_unformat_flag();
296   void asciify(macro *);
297   void tprint(troff_output_file *);
298   hunits width();
299   void ascii_print(ascii_output_file *);
300   int same(node *);
301   const char *type();
302   int force_tprint();
303   node *add_self(node *, hyphen_list **);
304   hyphen_list *get_hyphen_list(hyphen_list *ss = 0);
305   hyphenation_type get_hyphenation_type();
306 };
307
308 class space_char_hmotion_node : public hmotion_node {
309 public:
310   space_char_hmotion_node(hunits, color *, node * = 0);
311   node *copy();
312   void ascii_print(ascii_output_file *);
313   void asciify(macro *);
314   int same(node *);
315   const char *type();
316   int force_tprint();
317   node *add_self(node *, hyphen_list **);
318   hyphen_list *get_hyphen_list(hyphen_list *ss = 0);
319   hyphenation_type get_hyphenation_type();
320 };
321
322 class vmotion_node : public node {
323   vunits n;
324   color *col;                   /* for grotty */
325 public:
326   vmotion_node(vunits i, color *c) : n(i), col(c) {}
327   void tprint(troff_output_file *);
328   node *copy();
329   vunits vertical_width();
330   int same(node *);
331   const char *type();
332   int force_tprint();
333 };
334
335 class hline_node : public node {
336   hunits x;
337   node *n;
338 public:
339   hline_node(hunits i, node *c, node *next = 0) : node(next), x(i), n(c) {}
340   ~hline_node();
341   node *copy();
342   hunits width();
343   void tprint(troff_output_file *);
344   int same(node *);
345   const char *type();
346   int force_tprint();
347 };
348
349 class vline_node : public node {
350   vunits x;
351   node *n;
352 public:
353   vline_node(vunits i, node *c, node *next= 0) : node(next), x(i), n(c) {}
354   ~vline_node();
355   node *copy();
356   void tprint(troff_output_file *);
357   hunits width();
358   vunits vertical_width();
359   void vertical_extent(vunits *, vunits *);
360   int same(node *);
361   const char *type();
362   int force_tprint();
363 };
364
365
366 class dummy_node : public node {
367 public:
368   dummy_node(node *nd = 0) : node(nd) {}
369   node *copy();
370   int same(node *);
371   const char *type();
372   int force_tprint();
373   hyphenation_type get_hyphenation_type();
374 };
375
376 class transparent_dummy_node : public node {
377 public:
378   transparent_dummy_node(node *nd = 0) : node(nd) {}
379   node *copy();
380   int same(node *);
381   const char *type();
382   int force_tprint();
383   int ends_sentence();
384   hyphenation_type get_hyphenation_type();
385 };
386
387 class zero_width_node : public node {
388   node *n;
389 public:
390   zero_width_node(node *gn);
391   ~zero_width_node();
392   node *copy();
393   void tprint(troff_output_file *);
394   int same(node *);
395   const char *type();
396   int force_tprint();
397   void append(node *);
398   int character_type();
399   void vertical_extent(vunits *min, vunits *max);
400 };
401
402 class left_italic_corrected_node : public node {
403   node *n;
404   hunits x;
405 public:
406   left_italic_corrected_node(node * = 0);
407   ~left_italic_corrected_node();
408   void tprint(troff_output_file *);
409   void ascii_print(ascii_output_file *);
410   void asciify(macro *);
411   node *copy();
412   int same(node *);
413   const char *type();
414   int force_tprint();
415   hunits width();
416   node *last_char_node();
417   void vertical_extent(vunits *, vunits *);
418   int ends_sentence();
419   int overlaps_horizontally();
420   int overlaps_vertically();
421   hyphenation_type get_hyphenation_type();
422   tfont *get_tfont();
423   int character_type();
424   hunits skew();
425   hunits italic_correction();
426   hunits subscript_correction();
427   hyphen_list *get_hyphen_list(hyphen_list *ss = 0);
428   node *add_self(node *, hyphen_list **);
429   node *merge_glyph_node(glyph_node *);
430 };
431
432 class overstrike_node : public node {
433   node *list;
434   hunits max_width;
435 public:
436   overstrike_node();
437   ~overstrike_node();
438   node *copy();
439   void tprint(troff_output_file *);
440   void overstrike(node *);      // add another node to be overstruck
441   hunits width();
442   int same(node *);
443   const char *type();
444   int force_tprint();
445   node *add_self(node *, hyphen_list **);
446   hyphen_list *get_hyphen_list(hyphen_list *ss = 0);
447   hyphenation_type get_hyphenation_type();
448 };
449
450 class bracket_node : public node {
451   node *list;
452   hunits max_width;
453 public:
454   bracket_node();
455   ~bracket_node();
456   node *copy();
457   void tprint(troff_output_file *);
458   void bracket(node *); // add another node to be overstruck
459   hunits width();
460   int same(node *);
461   const char *type();
462   int force_tprint();
463 };
464
465 class special_node : public node {
466   macro mac;
467   tfont *tf;
468   color *gcol;
469   color *fcol;
470   int no_init_string;
471   void tprint_start(troff_output_file *);
472   void tprint_char(troff_output_file *, unsigned char);
473   void tprint_end(troff_output_file *);
474 public:
475   special_node(const macro &, int = 0);
476   special_node(const macro &, tfont *, color *, color *, int = 0);
477   node *copy();
478   void tprint(troff_output_file *);
479   int same(node *);
480   const char *type();
481   int force_tprint();
482   int ends_sentence();
483   tfont *get_tfont();
484 };
485
486 class suppress_node : public node {
487   int is_on;
488   int emit_limits;      // must we issue the extent of the area written out?
489   symbol filename;
490   char position;
491   int  image_id;
492 public:
493   suppress_node(int, int);
494   suppress_node(symbol f, char p, int id);
495   suppress_node(int, int, symbol f, char p, int id);
496   node *copy();
497   void tprint(troff_output_file *);
498   hunits width();
499   int same(node *);
500   const char *type();
501   int force_tprint();
502 private:
503   void put(troff_output_file *out, const char *s);
504 };
505
506 struct hvpair {
507   hunits h;
508   vunits v;
509   hvpair();
510 };
511
512 class draw_node : public node {
513   int npoints;
514   font_size sz;
515   color *gcol;
516   color *fcol;
517   char code;
518   hvpair *point;
519 public:
520   draw_node(char, hvpair *, int, font_size, color *, color *);
521   ~draw_node();
522   hunits width();
523   vunits vertical_width();
524   node *copy();
525   void tprint(troff_output_file *);
526   int same(node *);
527   const char *type();
528   int force_tprint();
529 };
530
531 class charinfo;
532 node *make_node(charinfo *ci, environment *);
533 int character_exists(charinfo *, environment *);
534
535 int same_node_list(node *n1, node *n2);
536 node *reverse_node_list(node *n);
537 void delete_node_list(node *);
538 node *copy_node_list(node *);
539
540 int get_bold_fontno(int f);
541
542 inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
543 : hyphen(0), breakable(0), hyphenation_code(code), next(p)
544 {
545 }
546
547 extern void read_desc();
548 extern int mount_font(int n, symbol, symbol = NULL_SYMBOL);
549 extern void mount_style(int n, symbol);
550 extern int is_good_fontno(int n);
551 extern int symbol_fontno(symbol);
552 extern int next_available_font_position();
553 extern void init_size_table(int *);
554 extern int get_underline_fontno();
555
556 class output_file {
557   char make_g_plus_plus_shut_up;
558 public:
559   output_file();
560   virtual ~output_file();
561   virtual void trailer(vunits page_length);
562   virtual void flush() = 0;
563   virtual void transparent_char(unsigned char) = 0;
564   virtual void print_line(hunits x, vunits y, node *n,
565                           vunits before, vunits after, hunits width) = 0;
566   virtual void begin_page(int pageno, vunits page_length) = 0;
567   virtual void copy_file(hunits x, vunits y, const char *filename) = 0;
568   virtual int is_printing() = 0;
569   virtual void put_filename(const char *filename);
570   virtual void on();
571   virtual void off();
572 #ifdef COLUMN
573   virtual void vjustify(vunits, symbol);
574 #endif /* COLUMN */
575 };
576
577 #ifndef POPEN_MISSING
578 extern char *pipe_command;
579 #endif
580
581 extern output_file *the_output;
582 extern void init_output();
583 int in_output_page_list(int n);
584
585 class font_family {
586   int *map;
587   int map_size;
588 public:
589   const symbol nm;
590   font_family(symbol);
591   ~font_family();
592   int make_definite(int);
593   static void invalidate_fontno(int);
594 };
595
596 font_family *lookup_family(symbol);
597 symbol get_font_name(int, environment *);