Imported Upstream version 1.22.4
[platform/upstream/groff.git] / src / roff / troff / node.h
1 // -*- C++ -*-
2 /* Copyright (C) 1989-2018 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 protected:
169   hunits n;
170   char set;
171   char was_escape_colon;
172   color *col;                   /* for grotty */
173   space_node(hunits, int, int, color *, statem *, int, node * = 0);
174 public:
175   space_node(hunits, color *, node * = 0);
176   node *copy();
177   int nspaces();
178   hunits width();
179   int discardable();
180   int merge_space(hunits, hunits, hunits);
181   void freeze_space();
182   void is_escape_colon();
183   void spread_space(int *, hunits *);
184   void tprint(troff_output_file *);
185   breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
186   int nbreaks();
187   void split(int, node **, node **);
188   void ascii_print(ascii_output_file *);
189   int same(node *);
190   void asciify(macro *);
191   const char *type();
192   int force_tprint();
193   int is_tag();
194   hyphenation_type get_hyphenation_type();
195 };
196
197 struct width_list {
198   hunits width;
199   hunits sentence_width;
200   width_list *next;
201   width_list(hunits, hunits);
202   width_list(width_list *);
203 };
204
205 class word_space_node : public space_node {
206 protected:
207   width_list *orig_width;
208   unsigned char unformat;
209   word_space_node(hunits, int, color *, width_list *, int, statem *, int,
210                   node * = 0);
211 public:
212   word_space_node(hunits, color *, width_list *, node * = 0);
213   ~word_space_node();
214   node *copy();
215   int reread(int *);
216   int set_unformat_flag();
217   void tprint(troff_output_file *);
218   int same(node *);
219   void asciify(macro *);
220   const char *type();
221   int merge_space(hunits, hunits, hunits);
222   int force_tprint();
223   int is_tag();
224 };
225
226 class unbreakable_space_node : public word_space_node {
227   unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0);
228 public:
229   unbreakable_space_node(hunits, color *, node * = 0);
230   node *copy();
231   int reread(int *);
232   void tprint(troff_output_file *);
233   int same(node *);
234   void asciify(macro *);
235   const char *type();
236   int force_tprint();
237   int is_tag();
238   breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
239   int nbreaks();
240   void split(int, node **, node **);
241   int merge_space(hunits, hunits, hunits);
242   node *add_self(node *, hyphen_list **);
243   hyphen_list *get_hyphen_list(hyphen_list *, int *);
244   hyphenation_type get_hyphenation_type();
245 };
246
247 class diverted_space_node : public node {
248 public:
249   vunits n;
250   diverted_space_node(vunits, node * = 0);
251   diverted_space_node(vunits, statem *, int, node * = 0);
252   node *copy();
253   int reread(int *);
254   int same(node *);
255   const char *type();
256   int force_tprint();
257   int is_tag();
258 };
259
260 class diverted_copy_file_node : public node {
261   symbol filename;
262 public:
263   vunits n;
264   diverted_copy_file_node(symbol, node * = 0);
265   diverted_copy_file_node(symbol, statem *, int, node * = 0);
266   node *copy();
267   int reread(int *);
268   int same(node *);
269   const char *type();
270   int force_tprint();
271   int is_tag();
272 };
273
274 class extra_size_node : public node {
275   vunits n;
276 public:
277   extra_size_node(vunits);
278   extra_size_node(vunits, statem *, int);
279   void set_vertical_size(vertical_size *);
280   node *copy();
281   int same(node *);
282   const char *type();
283   int force_tprint();
284   int is_tag();
285 };
286
287 class vertical_size_node : public node {
288   vunits n;
289 public:
290   vertical_size_node(vunits, statem *, int);
291   vertical_size_node(vunits);
292   void set_vertical_size(vertical_size *);
293   void asciify(macro *);
294   node *copy();
295   int set_unformat_flag();
296   int same(node *);
297   const char *type();
298   int force_tprint();
299   int is_tag();
300 };
301
302 class hmotion_node : public node {
303 protected:
304   hunits n;
305   unsigned char was_tab;
306   unsigned char unformat;
307   color *col;                   /* for grotty */
308 public:
309   hmotion_node(hunits i, color *c, node *nxt = 0)
310     : node(nxt), n(i), was_tab(0), unformat(0), col(c) {}
311   hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0)
312     : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {}
313   hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s,
314                int divlevel, node *nxt = 0)
315     : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2),
316       col(c) {}
317   hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0)
318     : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {}
319   node *copy();
320   int reread(int *);
321   int set_unformat_flag();
322   void asciify(macro *);
323   void tprint(troff_output_file *);
324   hunits width();
325   void ascii_print(ascii_output_file *);
326   int same(node *);
327   const char *type();
328   int force_tprint();
329   int is_tag();
330   node *add_self(node *, hyphen_list **);
331   hyphen_list *get_hyphen_list(hyphen_list *, int *);
332   hyphenation_type get_hyphenation_type();
333 };
334
335 class space_char_hmotion_node : public hmotion_node {
336 public:
337   space_char_hmotion_node(hunits, color *, node * = 0);
338   space_char_hmotion_node(hunits, color *, statem *, int, node * = 0);
339   node *copy();
340   void ascii_print(ascii_output_file *);
341   void asciify(macro *);
342   void tprint(troff_output_file *);
343   int same(node *);
344   const char *type();
345   int force_tprint();
346   int is_tag();
347   node *add_self(node *, hyphen_list **);
348   hyphen_list *get_hyphen_list(hyphen_list *, int *);
349   hyphenation_type get_hyphenation_type();
350 };
351
352 class vmotion_node : public node {
353   vunits n;
354   color *col;                   /* for grotty */
355 public:
356   vmotion_node(vunits, color *);
357   vmotion_node(vunits, color *, statem *, int);
358   void tprint(troff_output_file *);
359   node *copy();
360   vunits vertical_width();
361   int same(node *);
362   const char *type();
363   int force_tprint();
364   int is_tag();
365 };
366
367 class hline_node : public node {
368   hunits x;
369   node *n;
370 public:
371   hline_node(hunits, node *, node * = 0);
372   hline_node(hunits, node *, statem *, int, node * = 0);
373   ~hline_node();
374   node *copy();
375   hunits width();
376   void tprint(troff_output_file *);
377   int same(node *);
378   const char *type();
379   int force_tprint();
380   int is_tag();
381 };
382
383 class vline_node : public node {
384   vunits x;
385   node *n;
386 public:
387   vline_node(vunits, node *, node * = 0);
388   vline_node(vunits, node *, statem *, int, node * = 0);
389   ~vline_node();
390   node *copy();
391   void tprint(troff_output_file *);
392   hunits width();
393   vunits vertical_width();
394   void vertical_extent(vunits *, vunits *);
395   int same(node *);
396   const char *type();
397   int force_tprint();
398   int is_tag();
399 };
400
401 class dummy_node : public node {
402 public:
403   dummy_node(node *nd = 0) : node(nd) {}
404   node *copy();
405   int same(node *);
406   const char *type();
407   int force_tprint();
408   int is_tag();
409   hyphenation_type get_hyphenation_type();
410 };
411
412 class transparent_dummy_node : public node {
413 public:
414   transparent_dummy_node(node *nd = 0) : node(nd) {}
415   node *copy();
416   int same(node *);
417   const char *type();
418   int force_tprint();
419   int is_tag();
420   int ends_sentence();
421   hyphenation_type get_hyphenation_type();
422 };
423
424 class zero_width_node : public node {
425   node *n;
426 public:
427   zero_width_node(node *);
428   zero_width_node(node *, statem *, int);
429   ~zero_width_node();
430   node *copy();
431   void tprint(troff_output_file *);
432   int same(node *);
433   const char *type();
434   int force_tprint();
435   int is_tag();
436   void append(node *);
437   int character_type();
438   void vertical_extent(vunits *, vunits *);
439 };
440
441 class left_italic_corrected_node : public node {
442   node *n;
443   hunits x;
444 public:
445   left_italic_corrected_node(node * = 0);
446   left_italic_corrected_node(statem *, int, node * = 0);
447   ~left_italic_corrected_node();
448   void tprint(troff_output_file *);
449   void ascii_print(ascii_output_file *);
450   void asciify(macro *);
451   node *copy();
452   int same(node *);
453   const char *type();
454   int force_tprint();
455   int is_tag();
456   hunits width();
457   node *last_char_node();
458   void vertical_extent(vunits *, vunits *);
459   int ends_sentence();
460   int overlaps_horizontally();
461   int overlaps_vertically();
462   hyphenation_type get_hyphenation_type();
463   tfont *get_tfont();
464   int character_type();
465   hunits skew();
466   hunits italic_correction();
467   hunits subscript_correction();
468   hyphen_list *get_hyphen_list(hyphen_list *, int *);
469   node *add_self(node *, hyphen_list **);
470   node *merge_glyph_node(glyph_node *);
471 };
472
473 class overstrike_node : public node {
474   node *list;
475   hunits max_width;
476 public:
477   overstrike_node();
478   overstrike_node(statem *, int);
479   ~overstrike_node();
480   node *copy();
481   void tprint(troff_output_file *);
482   void overstrike(node *);      // add another node to be overstruck
483   hunits width();
484   int same(node *);
485   const char *type();
486   int force_tprint();
487   int is_tag();
488   node *add_self(node *, hyphen_list **);
489   hyphen_list *get_hyphen_list(hyphen_list *, int *);
490   hyphenation_type get_hyphenation_type();
491 };
492
493 class bracket_node : public node {
494   node *list;
495   hunits max_width;
496 public:
497   bracket_node();
498   bracket_node(statem *, int);
499   ~bracket_node();
500   node *copy();
501   void tprint(troff_output_file *);
502   void bracket(node *); // add another node to be overstruck
503   hunits width();
504   int same(node *);
505   const char *type();
506   int force_tprint();
507   int is_tag();
508 };
509
510 class special_node : public node {
511   macro mac;
512   tfont *tf;
513   color *gcol;
514   color *fcol;
515   int no_init_string;
516   void tprint_start(troff_output_file *);
517   void tprint_char(troff_output_file *, unsigned char);
518   void tprint_end(troff_output_file *);
519 public:
520   special_node(const macro &, int = 0);
521   special_node(const macro &, tfont *, color *, color *, statem *, int,
522                int = 0);
523   node *copy();
524   void tprint(troff_output_file *);
525   int same(node *);
526   const char *type();
527   int force_tprint();
528   int is_tag();
529   int ends_sentence();
530   tfont *get_tfont();
531 };
532
533 class suppress_node : public node {
534   int is_on;
535   int emit_limits;      // must we issue the extent of the area written out?
536   symbol filename;
537   char position;
538   int  image_id;
539 public:
540   suppress_node(int, int);
541   suppress_node(symbol, char, int);
542   suppress_node(int, int, symbol, char, int, statem *, int);
543   suppress_node(int, int, symbol, char, int);
544   node *copy();
545   void tprint(troff_output_file *);
546   hunits width();
547   int same(node *);
548   const char *type();
549   int force_tprint();
550   int is_tag();
551 private:
552   void put(troff_output_file *, const char *);
553 };
554
555 class tag_node : public node {
556 public:
557   string tag_string;
558   int delayed;
559   tag_node();
560   tag_node(string, int);
561   tag_node(string, statem *, int, int);
562   node *copy();
563   void tprint(troff_output_file *);
564   int same(node *);
565   const char *type();
566   int force_tprint();
567   int is_tag();
568   int ends_sentence();
569 };
570
571 struct hvpair {
572   hunits h;
573   vunits v;
574   hvpair();
575 };
576
577 class draw_node : public node {
578   int npoints;
579   font_size sz;
580   color *gcol;
581   color *fcol;
582   char code;
583   hvpair *point;
584 public:
585   draw_node(char, hvpair *, int, font_size, color *, color *);
586   draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int);
587   ~draw_node();
588   hunits width();
589   vunits vertical_width();
590   node *copy();
591   void tprint(troff_output_file *);
592   int same(node *);
593   const char *type();
594   int force_tprint();
595   int is_tag();
596 };
597
598 class charinfo;
599 node *make_node(charinfo *, environment *);
600 int character_exists(charinfo *, environment *);
601
602 int same_node_list(node *, node *);
603 node *reverse_node_list(node *);
604 void delete_node_list(node *);
605 node *copy_node_list(node *);
606
607 int get_bold_fontno(int);
608
609 inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p)
610 : hyphen(0), breakable(0), hyphenation_code(code), next(p)
611 {
612 }
613
614 extern void read_desc();
615 extern int mount_font(int, symbol, symbol = NULL_SYMBOL);
616 extern int check_font(symbol, symbol);
617 extern int check_style(symbol);
618 extern void mount_style(int, symbol);
619 extern int is_good_fontno(int);
620 extern int symbol_fontno(symbol);
621 extern int next_available_font_position();
622 extern void init_size_table(int *);
623 extern int get_underline_fontno();
624
625 class output_file {
626   char make_g_plus_plus_shut_up;
627 public:
628   output_file();
629   virtual ~output_file();
630   virtual void trailer(vunits);
631   virtual void flush() = 0;
632   virtual void transparent_char(unsigned char) = 0;
633   virtual void print_line(hunits x, vunits y, node *n,
634                           vunits before, vunits after, hunits width) = 0;
635   virtual void begin_page(int pageno, vunits page_length) = 0;
636   virtual void copy_file(hunits x, vunits y, const char *filename) = 0;
637   virtual int is_printing() = 0;
638   virtual void put_filename(const char *, int);
639   virtual void on();
640   virtual void off();
641 #ifdef COLUMN
642   virtual void vjustify(vunits, symbol);
643 #endif /* COLUMN */
644   mtsm state;
645 };
646
647 #ifndef POPEN_MISSING
648 extern char *pipe_command;
649 #endif
650
651 extern output_file *the_output;
652 extern void init_output();
653 int in_output_page_list(int);
654
655 class font_family {
656   int *map;
657   int map_size;
658 public:
659   const symbol nm;
660   font_family(symbol);
661   ~font_family();
662   int make_definite(int);
663   static void invalidate_fontno(int);
664 };
665
666 font_family *lookup_family(symbol);
667 symbol get_font_name(int, environment *);
668 symbol get_style_name(int);
669 extern search_path include_search_path;