xref: /netbsd-src/external/gpl2/groff/dist/src/roff/troff/node.h (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: node.h,v 1.1.1.1 2016/01/13 18:41:48 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
5    Free Software Foundation, Inc.
6      Written by James Clark (jjc@jclark.com)
7 
8 This file is part of groff.
9 
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
14 
15 groff is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19 
20 You should have received a copy of the GNU General Public License along
21 with groff; see the file COPYING.  If not, write to the Free Software
22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
23 
24 struct hyphen_list {
25   unsigned char hyphen;
26   unsigned char breakable;
27   unsigned char hyphenation_code;
28   hyphen_list *next;
29   hyphen_list(unsigned char code, hyphen_list *p = 0);
30 };
31 
32 void hyphenate(hyphen_list *, unsigned);
33 
34 enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT };
35 
36 class ascii_output_file;
37 
38 struct breakpoint;
39 struct vertical_size;
40 class charinfo;
41 
42 class macro;
43 
44 class troff_output_file;
45 class tfont;
46 class environment;
47 
48 class glyph_node;
49 class diverted_space_node;
50 class token_node;
51 
52 struct node {
53   node *next;
54   node *last;
55   statem *state;
56   statem *push_state;
57   int div_nest_level;
58   int is_special;
59   node();
60   node(node *);
61   node(node *, statem *, int);
62   node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0);
63 
64   virtual ~node();
65   virtual node *copy() = 0;
66   virtual int set_unformat_flag();
67   virtual int force_tprint() = 0;
68   virtual int is_tag() = 0;
69   virtual hunits width();
70   virtual hunits subscript_correction();
71   virtual hunits italic_correction();
72   virtual hunits left_italic_correction();
73   virtual hunits skew();
74   virtual int nspaces();
75   virtual int merge_space(hunits, hunits, hunits);
76   virtual vunits vertical_width();
77   virtual node *last_char_node();
78   virtual void vertical_extent(vunits *, vunits *);
79   virtual int character_type();
80   virtual void set_vertical_size(vertical_size *);
81   virtual int ends_sentence();
82   virtual node *merge_self(node *);
83   virtual node *add_discretionary_hyphen();
84   virtual node *add_self(node *, hyphen_list **);
85   virtual hyphen_list *get_hyphen_list(hyphen_list *, int *);
86   virtual void ascii_print(ascii_output_file *);
87   virtual void asciify(macro *);
88   virtual int discardable();
89   virtual void spread_space(int *, hunits *);
90   virtual void freeze_space();
91   virtual void is_escape_colon();
92   virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0);
93   virtual int nbreaks();
94   virtual void split(int, node **, node **);
95   virtual hyphenation_type get_hyphenation_type();
96   virtual int reread(int *);
97   virtual token_node *get_token_node();
98   virtual int overlaps_vertically();
99   virtual int overlaps_horizontally();
100   virtual units size();
101   virtual int interpret(macro *);
102 
103   virtual node *merge_glyph_node(glyph_node *);
104   virtual tfont *get_tfont();
105   virtual color *get_glyph_color();
106   virtual color *get_fill_color();
107   virtual void tprint(troff_output_file *);
108   virtual void zero_width_tprint(troff_output_file *);
109 
110   node *add_italic_correction(hunits *);
111 
112   virtual int same(node *) = 0;
113   virtual const char *type() = 0;
114   virtual void debug_node();
115   virtual void debug_node_list();
116 };
117 
node()118 inline node::node()
119 : next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
120 {
121 }
122 
node(node * n)123 inline node::node(node *n)
124 : next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
125 {
126 }
127 
node(node * n,statem * s,int divlevel)128 inline node::node(node *n, statem *s, int divlevel)
129 : next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0)
130 {
131   if (s)
132     state = new statem(s);
133   else
134     state = 0;
135 }
136 
~node()137 inline node::~node()
138 {
139 }
140 
141 // 0 means it doesn't, 1 means it does, 2 means it's transparent
142 
143 int node_list_ends_sentence(node *);
144 
145 struct breakpoint {
146   breakpoint *next;
147   hunits width;
148   int nspaces;
149   node *nd;
150   int index;
151   char hyphenated;
152 };
153 
154 class line_start_node : public node {
155 public:
line_start_node()156   line_start_node() {}
copy()157   node *copy() { return new line_start_node; }
158   int same(node *);
159   int force_tprint();
160   int is_tag();
161   const char *type();
162   void asciify(macro *);
163 };
164 
165 class space_node : public node {
166 private:
167 #if 0
168   enum { BLOCK = 1024 };
169   static space_node *free_list;
170   void operator delete(void *);
171 #endif
172 protected:
173   hunits n;
174   char set;
175   char was_escape_colon;
176   color *col;			/* for grotty */
177   space_node(hunits, int, int, color *, statem *, int, node * = 0);
178 public:
179   space_node(hunits, color *, statem *, int, node * = 0);
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)
node(nxt)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)
node(nxt,s,divlevel)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)
node(nxt,s,divlevel)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)
node(nxt)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:
node(nd)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:
node(nd)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 
hyphen_list(unsigned char code,hyphen_list * p)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 *);
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;
679