Update to groff 1.19.2.
[dragonfly.git] / contrib / groff-1.19 / src / roff / troff / node.h
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
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, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21
22 struct hyphen_list {
23   unsigned char hyphen;
24   unsigned char breakable;
25   unsigned char hyphenation_code;
26   hyphen_list *next;
27   hyphen_list(unsigned char code, hyphen_list *p = 0);
28 };
29
30 void hyphenate(hyphen_list *, unsigned);
31
32 enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT };
33
34 class ascii_output_file;
35
36 struct breakpoint;
37 struct vertical_size;
38 class charinfo;
39
40 class macro;
41
42 class troff_output_file;
43 class tfont;
44 class environment;
45
46 class glyph_node;
47 class diverted_space_node;
48 class token_node;
49
50 struct node {
51   node *next;
52   node *last;
53   statem *state;
54   statem *push_state;
55   int div_nest_level;
56   int is_special;
57   node();
58   node(node *);
59   node(node *, statem *, int);
60   node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0);
61
62   virtual ~node();
63   virtual node *copy() = 0;
64   virtual int set_unformat_flag();
65   virtual int force_tprint() = 0;
66   virtual int is_tag() = 0;
67   virtual hunits width();
68   virtual hunits subscript_correction();
69   virtual hunits italic_correction();
70   virtual hunits left_italic_correction();
71   virtual hunits skew();
72   virtual int nspaces();
73   virtual int merge_space(hunits, hunits, hunits);
74   virtual vunits vertical_width();
75   virtual node *last_char_node();
76   virtual void vertical_extent(vunits *, vunits *);
77   virtual int character_type();
78   virtual void set_vertical_size(vertical_size *);
79   virtual int ends_sentence();
80   virtual node *merge_self(node *);
81   virtual node *add_discretionary_hyphen();
82   virtual node *add_self(node *, hyphen_list **);
83   virtual hyphen_list *get_hyphen_list(hyphen_list *, int *);
84   virtual void ascii_print(ascii_output_file *);
85   virtual void asciify(macro *);
86   virtual int discardable();
87   virtual void spread_space(int *, hunits *);
88   virtual void freeze_space();
89   virtual void is_escape_colon();
90   virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
91   virtual int nbreaks();
92   virtual void split(int, node **, node **);
93   virtual hyphenation_type get_hyphenation_type();
94   virtual int reread(int *);
95   virtual token_node *get_token_node();
96   virtual int overlaps_vertically();
97   virtual int overlaps_horizontally();
98   virtual units size();
99   virtual int interpret(macro *);
100
101   virtual node *merge_glyph_node(glyph_node *);
102   virtual tfont *get_tfont();
103   virtual color *get_glyph_color();
104   virtual color *get_fill_color();
105   virtual void tprint(troff_output_file *);
106   virtual void zero_width_tprint(troff_output_file *);
107
108   node *add_italic_correction(hunits *);
109
110   virtual int same(node *) = 0;
111   virtual const char *type() = 0;
112   virtual void debug_node();
113   virtual void debug_node_list();
114 };
115
116 inline node::node()
117 : next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
118 {
119 }
120
121 inline node::node(node *n)
122 : next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
123 {
124 }
125
126 inline node::node(node *n, statem *s, int divlevel)
127 : next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0)
128 {
129   if (s)
130     state = new statem(s);
131   else
132     state = 0;
133 }
134
135 inline node::~node()
136 {
137 }
138
139 // 0 means it doesn't, 1 means it does, 2 means it's transparent
140
141 int node_list_ends_sentence(node *);
142
143 struct breakpoint {
144   breakpoint *next;
145   hunits width;
146   int nspaces;
147   node *nd;
148   int index;
149   char hyphenated;
150 };
151
152 class line_start_node : public node {
153 public:
154   line_start_node() {}
155   node *copy() { return new line_start_node; }
156   int same(node *);
157   int force_tprint();
158   int is_tag();
159   const char *type();
160   void asciify(macro *);
161 };
162
163 class space_node : public node {
164 private:
165 #if 0
166   enum { BLOCK = 1024 };
167   static space_node *free_list;
168   void operator delete(void *);
169 #endif
170 protected:
171   hunits n;
172   char set;
173   char was_escape_colon;
174   color *col;                   /* for grotty */
175   space_node(hunits, int, int, color *, statem *, int, node * = 0);
176 public:
177   space_node(hunits, color *, statem *, int, node * = 0);
178   space_node(hunits, color *, node * = 0);
179 #if 0
180   ~space_node();
181   void *operator new(size_t);
182 #endif
183   node *copy();
184   int nspaces();
185   hunits width();
186   int discardable();
187   int merge_space(hunits, hunits, hunits);
188   void freeze_space();
189   void is_escape_colon();
190   void spread_space(int *, hunits *);
191   void tprint(troff_output_file *);
192   breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
193   int nbreaks();
194   void split(int, node **, node **);
195   void ascii_print(ascii_output_file *);
196   int same(node *);
197   void asciify(macro *);
198   const char *type();
199   int force_tprint();
200   int is_tag();
201   hyphenation_type get_hyphenation_type();
202 };
203
204 struct width_list {
205   hunits width;
206   hunits sentence_width;
207   width_list *next;
208   width_list(hunits, hunits);
209   width_list(width_list *);
210 };
211
212 class word_space_node : public space_node {
213 protected:
214   width_list *orig_width;
215   unsigned char unformat;
216   word_space_node(hunits, int, color *, width_list *, int, statem *, int,
217                   node * = 0);
218 public:
219   word_space_node(hunits, color *, width_list *, node * = 0);
220   ~word_space_node();
221   node *copy();
222   int reread(int *);
223   int set_unformat_flag();
224   void tprint(troff_output_file *);
225   int same(node *);
226   void asciify(macro *);
227   const char *type();
228   int merge_space(hunits, hunits, hunits);
229   int force_tprint();
230   int is_tag();
231 };
232
233 class unbreakable_space_node : public word_space_node {
234   unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0);
235 public:
236   unbreakable_space_node(hunits, color *, node * = 0);
237   node *copy();
238   int reread(int *);
239   void tprint(troff_output_file *);
240   int same(node *);
241   void asciify(macro *);
242   const char *type();
243   int force_tprint();
244   int is_tag();
245   breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
246   int nbreaks();
247   void split(int, node **, node **);
248   int merge_space(hunits, hunits, hunits);
249   node *add_self(node *, hyphen_list **);
250   hyphen_list *get_hyphen_list(hyphen_list *, int *);
251   hyphenation_type get_hyphenation_type();
252 };
253
254 class diverted_space_node : public node {
255 public:
256   vunits n;
257   diverted_space_node(vunits, node * = 0);
258   diverted_space_node(vunits, statem *, int, node * = 0);
259   node *copy();
260   int reread(int *);
261   int same(node *);
262   const char *type();
263   int force_tprint();
264   int is_tag();
265 };
266
267 class diverted_copy_file_node : public node {
268   symbol filename;
269 public:
270   vunits n;
271   diverted_copy_file_node(symbol, node * = 0);
272   diverted_copy_file_node(symbol, statem *, int, node * = 0);
273   node *copy();
274   int reread(int *);
275   int same(node *);
276   const char *type();
277   int force_tprint();
278   int is_tag();
279 };
280
281 class extra_size_node : public node {
282   vunits n;
283 public:
284   extra_size_node(vunits);
285   extra_size_node(vunits, statem *, int);
286   void set_vertical_size(vertical_size *);
287   node *copy();
288   int same(node *);
289   const char *type();
290   int force_tprint();
291   int is_tag();
292 };
293
294 class vertical_size_node : public node {
295   vunits n;
296 public:
297   vertical_size_node(vunits, statem *, int);
298   vertical_size_node(vunits);
299   void set_vertical_size(vertical_size *);
300   void asciify(macro *);
301   node *copy();
302   int set_unformat_flag();
303   int same(node *);
304   const char *type();
305   int force_tprint();
306   int is_tag();
307 };
308
309 class hmotion_node : public node {
310 protected:
311   hunits n;
312   unsigned char was_tab;
313   unsigned char unformat;
314   color *col;                   /* for grotty */
315 public:
316   hmotion_node(hunits i, color *c, node *nxt = 0)
317     : node(nxt), n(i), was_tab(0), unformat(0), col(c) {}
318   hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0)
319     : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {}
320   hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s,
321                int divlevel, node *nxt = 0)
322     : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2),
323       col(c) {}
324   hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0)
325     : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {}
326   node *copy();
327   int reread(int *);
328   int set_unformat_flag();
329   void asciify(macro *);
330   void tprint(troff_output_file *);
331   hunits width();
332   void ascii_print(ascii_output_file *);
333   int same(node *);
334   const char *type();
335   int force_tprint();
336   int is_tag();
337   node *add_self(node *, hyphen_list **);
338   hyphen_list *get_hyphen_list(hyphen_list *, int *);
339   hyphenation_type get_hyphenation_type();
340 };
341
342 class space_char_hmotion_node : public hmotion_node {
343 public:
344   space_char_hmotion_node(hunits, color *, node * = 0);
345   space_char_hmotion_node(hunits, color *, statem *, int, node * = 0);
346   node *copy();
347   void ascii_print(ascii_output_file *);
348   void asciify(macro *);
349   void tprint(troff_output_file *);
350   int same(node *);
351   const char *type();
352   int force_tprint();
353   int is_tag();
354   node *add_self(node *, hyphen_list **);
355   hyphen_list *get_hyphen_list(hyphen_list *, int *);
356   hyphenation_type get_hyphenation_type();
357 };
358
359 class vmotion_node : public node {
360   vunits n;
361   color *col;                   /* for grotty */
362 public:
363   vmotion_node(vunits, color *);
364   vmotion_node(vunits, color *, statem *, int);
365   void tprint(troff_output_file *);
366   node *copy();
367   vunits vertical_width();
368   int same(node *);
369   const char *type();
370   int force_tprint();
371   int is_tag();
372 };
373
374 class hline_node : public node {
375   hunits x;
376   node *n;
377 public:
378   hline_node(hunits, node *, node * = 0);
379   hline_node(hunits, node *, statem *, int, node * = 0);
380   ~hline_node();
381   node *copy();
382   hunits width();
383   void tprint(troff_output_file *);
384   int same(node *);
385   const char *type();
386   int force_tprint();
387   int is_tag();
388 };
389
390 class vline_node : public node {
391   vunits x;
392   node *n;
393 public:
394   vline_node(vunits, node *, node * = 0);
395   vline_node(vunits, node *, statem *, int, node * = 0);
396   ~vline_node();
397   node *copy();
398   void tprint(troff_output_file *);
399   hunits width();
400   vunits vertical_width();
401   void vertical_extent(vunits *, vunits *);
402   int same(node *);
403   const char *type();
404   int force_tprint();
405   int is_tag();
406 };
407
408 class dummy_node : public node {
409 public:
410   dummy_node(node *nd = 0) : node(nd) {}
411   node *copy();
412   int same(node *);
413   const char *type();
414   int force_tprint();
415   int is_tag();
416   hyphenation_type get_hyphenation_type();
417 };
418
419 class transparent_dummy_node : public node {
420 public:
421   transparent_dummy_node(node *nd = 0) : node(nd) {}
422   node *copy();
423   int same(node *);
424   const char *type();
425   int force_tprint();
426   int is_tag();
427   int ends_sentence();
428   hyphenation_type get_hyphenation_type();
429 };
430
431 class zero_width_node : public node {
432   node *n;
433 public:
434   zero_width_node(node *);
435   zero_width_node(node *, statem *, int);
436   ~zero_width_node();
437   node *copy();
438   void tprint(troff_output_file *);
439   int same(node *);
440   const char *type();
441   int force_tprint();
442   int is_tag();
443   void append(node *);
444   int character_type();
445   void vertical_extent(vunits *, vunits *);
446 };
447
448 class left_italic_corrected_node : public node {
449   node *n;
450   hunits x;
451 public:
452   left_italic_corrected_node(node * = 0);
453   left_italic_corrected_node(statem *, int, node * = 0);
454   ~left_italic_corrected_node();
455   void tprint(troff_output_file *);
456   void ascii_print(ascii_output_file *);
457   void asciify(macro *);
458   node *copy();
459   int same(node *);
460   const char *type();
461   int force_tprint();
462   int is_tag();
463   hunits width();
464   node *last_char_node();
465   void vertical_extent(vunits *, vunits *);
466   int ends_sentence();
467   int overlaps_horizontally();
468   int overlaps_vertically();
469   hyphenation_type get_hyphenation_type();
470   tfont *get_tfont();
471   int character_type();
472   hunits skew();
473   hunits italic_correction();
474   hunits subscript_correction();
475   hyphen_list *get_hyphen_list(hyphen_list *, int *);
476   node *add_self(node *, hyphen_list **);
477   node *merge_glyph_node(glyph_node *);
478 };
479
480 class overstrike_node : public node {
481   node *list;
482   hunits max_width;
483 public:
484   overstrike_node();
485   overstrike_node(statem *, int);
486   ~overstrike_node();
487   node *copy();
488   void tprint(troff_output_file *);
489   void overstrike(node *);      // add another node to be overstruck
490   hunits width();
491   int same(node *);
492   const char *type();
493   int force_tprint();
494   int is_tag();
495   node *add_self(node *, hyphen_list **);
496   hyphen_list *get_hyphen_list(hyphen_list *, int *);
497   hyphenation_type get_hyphenation_type();
498 };
499
500 class bracket_node : public node {
501   node *list;
502   hunits max_width;
503 public:
504   bracket_node();
505   bracket_node(statem *, int);
506   ~bracket_node();
507   node *copy();
508   void tprint(troff_output_file *);
509   void bracket(node *); // add another node to be overstruck
510   hunits width();
511   int same(node *);
512   const char *type();
513   int force_tprint();
514   int is_tag();
515 };
516
517 class special_node : public node {
518   macro mac;
519   tfont *tf;
520   color *gcol;
521   color *fcol;
522   int no_init_string;
523   void tprint_start(troff_output_file *);
524   void tprint_char(troff_output_file *, unsigned char);
525   void tprint_end(troff_output_file *);
526 public:
527   special_node(const macro &, int = 0);
528   special_node(const macro &, tfont *, color *, color *, statem *, int,
529                int = 0);
530   node *copy();
531   void tprint(troff_output_file *);
532   int same(node *);
533   const char *type();
534   int force_tprint();
535   int is_tag();
536   int ends_sentence();
537   tfont *get_tfont();
538 };
539
540 class suppress_node : public node {
541   int is_on;
542   int emit_limits;      // must we issue the extent of the area written out?
543   symbol filename;
544   char position;
545   int  image_id;
546 public:
547   suppress_node(int, int);
548   suppress_node(symbol, char, int);
549   suppress_node(int, int, symbol, char, int, statem *, int);
550   suppress_node(int, int, symbol, char, int);
551   node *copy();
552   void tprint(troff_output_file *);
553   hunits width();
554   int same(node *);
555   const char *type();
556   int force_tprint();
557   int is_tag();
558 private:
559   void put(troff_output_file *, const char *);
560 };
561
562 class tag_node : public node {
563 public:
564   string tag_string;
565   int delayed;
566   tag_node();
567   tag_node(string, int);
568   tag_node(string, statem *, int, int);
569   node *copy();
570   void tprint(troff_output_file *);
571   int same(node *);
572   const char *type();
573   int force_tprint();
574   int is_tag();
575   int ends_sentence();
576 };
577
578 struct hvpair {
579   hunits h;
580   vunits v;
581   hvpair();
582 };
583
584 class draw_node : public node {
585   int npoints;
586   font_size sz;
587   color *gcol;
588   color *fcol;
589   char code;
590   hvpair *point;
591 public:
592   draw_node(char, hvpair *, int, font_size, color *, color *);
593   draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int);
594   ~draw_node();
595   hunits width();
596   vunits vertical_width();
597   node *copy();
598   void tprint(troff_output_file *);
599   int same(node *);
600   const char *type();
601   int force_tprint();
602   int is_tag();
603 };
604
605 class charinfo;
606 node *make_node(charinfo *, environment *);
607 int character_exists(charinfo *, environment *);
608
609 int same_node_list(node *, node *);
610 node *reverse_node_list(node *);
611 void delete_node_list(node *);
612 node *copy_node_list(node *);
613
614 int get_bold_fontno(int);
615
616 inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
617 : hyphen(0), breakable(0), hyphenation_code(code), next(p)
618 {
619 }
620
621 extern void read_desc();
622 extern int mount_font(int, symbol, symbol = NULL_SYMBOL);
623 extern int check_font(symbol, symbol);
624 extern int check_style(symbol);
625 extern void mount_style(int, symbol);
626 extern int is_good_fontno(int);
627 extern int symbol_fontno(symbol);
628 extern int next_available_font_position();
629 extern void init_size_table(int *);
630 extern int get_underline_fontno();
631
632 class output_file {
633   char make_g_plus_plus_shut_up;
634 public:
635   output_file();
636   virtual ~output_file();
637   virtual void trailer(vunits);
638   virtual void flush() = 0;
639   virtual void transparent_char(unsigned char) = 0;
640   virtual void print_line(hunits x, vunits y, node *n,
641                           vunits before, vunits after, hunits width) = 0;
642   virtual void begin_page(int pageno, vunits page_length) = 0;
643   virtual void copy_file(hunits x, vunits y, const char *filename) = 0;
644   virtual int is_printing() = 0;
645   virtual void put_filename(const char *);
646   virtual void on();
647   virtual void off();
648 #ifdef COLUMN
649   virtual void vjustify(vunits, symbol);
650 #endif /* COLUMN */
651   mtsm state;
652 };
653
654 #ifndef POPEN_MISSING
655 extern char *pipe_command;
656 #endif
657
658 extern output_file *the_output;
659 extern void init_output();
660 int in_output_page_list(int);
661
662 class font_family {
663   int *map;
664   int map_size;
665 public:
666   const symbol nm;
667   font_family(symbol);
668   ~font_family();
669   int make_definite(int);
670   static void invalidate_fontno(int);
671 };
672
673 font_family *lookup_family(symbol);
674 symbol get_font_name(int, environment *);
675 symbol get_style_name(int);
676 extern search_path include_search_path;