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