Home | History | Annotate | Line # | Download | only in troff
      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 (at) 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 
    118 inline node::node()
    119 : next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0)
    120 {
    121 }
    122 
    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 
    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 
    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:
    156   line_start_node() {}
    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)
    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 *);
    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