diff options
Diffstat (limited to 'src/roff/troff/node.h')
-rw-r--r-- | src/roff/troff/node.h | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h new file mode 100644 index 0000000..de82753 --- /dev/null +++ b/src/roff/troff/node.h @@ -0,0 +1,670 @@ +// -*- C++ -*- +/* Copyright (C) 1989-2020 Free Software Foundation, Inc. + Written by James Clark (jjc@jclark.com) + +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 3 of the License, or +(at your option) any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +struct hyphen_list { + unsigned char hyphen; + unsigned char breakable; + unsigned char hyphenation_code; + hyphen_list *next; + hyphen_list(unsigned char code, hyphen_list *p = 0); +}; + +void hyphenate(hyphen_list *, unsigned); + +enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT }; + +class ascii_output_file; + +struct breakpoint; +struct vertical_size; +class charinfo; + +class macro; + +class troff_output_file; +class tfont; +class environment; + +class glyph_node; +class diverted_space_node; +class token_node; + +struct node { + node *next; + node *last; + statem *state; + statem *push_state; + int div_nest_level; + int is_special; + node(); + node(node *); + node(node *, statem *, int); + node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0); + + virtual ~node(); + virtual node *copy() = 0; + virtual int set_unformat_flag(); + virtual int force_tprint() = 0; + virtual int is_tag() = 0; + virtual int get_break_code(); + virtual hunits width(); + virtual hunits subscript_correction(); + virtual hunits italic_correction(); + virtual hunits left_italic_correction(); + virtual hunits skew(); + virtual int nspaces(); + virtual int merge_space(hunits, hunits, hunits); + virtual vunits vertical_width(); + virtual node *last_char_node(); + virtual void vertical_extent(vunits *, vunits *); + virtual int character_type(); + virtual void set_vertical_size(vertical_size *); + virtual int ends_sentence(); + virtual node *merge_self(node *); + virtual node *add_discretionary_hyphen(); + virtual node *add_self(node *, hyphen_list **); + virtual hyphen_list *get_hyphen_list(hyphen_list *, int *); + virtual void ascii_print(ascii_output_file *); + virtual void asciify(macro *); + virtual int discardable(); + virtual void spread_space(int *, hunits *); + virtual void freeze_space(); + virtual void is_escape_colon(); + virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + virtual int nbreaks(); + virtual void split(int, node **, node **); + virtual hyphenation_type get_hyphenation_type(); + virtual int reread(int *); + virtual token_node *get_token_node(); + virtual int overlaps_vertically(); + virtual int overlaps_horizontally(); + virtual units size(); + virtual int interpret(macro *); + + virtual node *merge_glyph_node(glyph_node *); + virtual tfont *get_tfont(); + virtual color *get_glyph_color(); + virtual color *get_fill_color(); + virtual void tprint(troff_output_file *); + virtual void zero_width_tprint(troff_output_file *); + + node *add_italic_correction(hunits *); + + virtual int same(node *) = 0; + virtual const char *type() = 0; + virtual void debug_node(); + virtual void debug_node_list(); +}; + +inline node::node() +: next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) +{ +} + +inline node::node(node *n) +: next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) +{ +} + +inline node::node(node *n, statem *s, int divlevel) +: next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0) +{ + if (s) + state = new statem(s); + else + state = 0; +} + +inline node::~node() +{ + if (state != 0) + delete state; + if (push_state != 0) + delete push_state; +} + +// 0 means it doesn't, 1 means it does, 2 means it's transparent + +int node_list_ends_sentence(node *); + +struct breakpoint { + breakpoint *next; + hunits width; + int nspaces; + node *nd; + int index; + char hyphenated; +}; + +class line_start_node : public node { +public: + line_start_node() {} + node *copy() { return new line_start_node; } + int same(node *); + int force_tprint(); + int is_tag(); + const char *type(); + void asciify(macro *); +}; + +class space_node : public node { +private: +protected: + hunits n; + char set; + char was_escape_colon; + color *col; /* for grotty */ + space_node(hunits, int, int, color *, statem *, int, node * = 0); +public: + space_node(hunits, color *, node * = 0); + node *copy(); + int nspaces(); + hunits width(); + int discardable(); + int merge_space(hunits, hunits, hunits); + void freeze_space(); + void is_escape_colon(); + void spread_space(int *, hunits *); + void tprint(troff_output_file *); + breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + int nbreaks(); + void split(int, node **, node **); + void ascii_print(ascii_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int force_tprint(); + int is_tag(); + hyphenation_type get_hyphenation_type(); +}; + +struct width_list { + hunits width; + hunits sentence_width; + width_list *next; + width_list(hunits, hunits); + width_list(width_list *); +}; + +class word_space_node : public space_node { +protected: + width_list *orig_width; + unsigned char unformat; + word_space_node(hunits, int, color *, width_list *, int, statem *, int, + node * = 0); +public: + word_space_node(hunits, color *, width_list *, node * = 0); + ~word_space_node(); + node *copy(); + int reread(int *); + int set_unformat_flag(); + void tprint(troff_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int merge_space(hunits, hunits, hunits); + int force_tprint(); + int is_tag(); +}; + +class unbreakable_space_node : public word_space_node { + unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0); +public: + unbreakable_space_node(hunits, color *, node * = 0); + node *copy(); + int reread(int *); + void tprint(troff_output_file *); + int same(node *); + void asciify(macro *); + const char *type(); + int force_tprint(); + int is_tag(); + breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); + int nbreaks(); + void split(int, node **, node **); + int merge_space(hunits, hunits, hunits); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class diverted_space_node : public node { +public: + vunits n; + diverted_space_node(vunits, node * = 0); + diverted_space_node(vunits, statem *, int, node * = 0); + node *copy(); + int reread(int *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class diverted_copy_file_node : public node { + symbol filename; +public: + vunits n; + diverted_copy_file_node(symbol, node * = 0); + diverted_copy_file_node(symbol, statem *, int, node * = 0); + node *copy(); + int reread(int *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class extra_size_node : public node { + vunits n; +public: + extra_size_node(vunits); + extra_size_node(vunits, statem *, int); + void set_vertical_size(vertical_size *); + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class vertical_size_node : public node { + vunits n; +public: + vertical_size_node(vunits, statem *, int); + vertical_size_node(vunits); + void set_vertical_size(vertical_size *); + void asciify(macro *); + node *copy(); + int set_unformat_flag(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class hmotion_node : public node { +protected: + hunits n; + unsigned char was_tab; + unsigned char unformat; + color *col; /* for grotty */ +public: + hmotion_node(hunits i, color *c, node *nxt = 0) + : node(nxt), n(i), was_tab(0), unformat(0), col(c) {} + hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0) + : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {} + hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s, + int divlevel, node *nxt = 0) + : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2), + col(c) {} + hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0) + : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {} + node *copy(); + int reread(int *); + int set_unformat_flag(); + void asciify(macro *); + void tprint(troff_output_file *); + hunits width(); + void ascii_print(ascii_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class space_char_hmotion_node : public hmotion_node { +public: + space_char_hmotion_node(hunits, color *, node * = 0); + space_char_hmotion_node(hunits, color *, statem *, int, node * = 0); + node *copy(); + void ascii_print(ascii_output_file *); + void asciify(macro *); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class vmotion_node : public node { + vunits n; + color *col; /* for grotty */ +public: + vmotion_node(vunits, color *); + vmotion_node(vunits, color *, statem *, int); + void tprint(troff_output_file *); + node *copy(); + vunits vertical_width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class hline_node : public node { + hunits x; + node *n; +public: + hline_node(hunits, node *, node * = 0); + hline_node(hunits, node *, statem *, int, node * = 0); + ~hline_node(); + node *copy(); + hunits width(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class vline_node : public node { + vunits x; + node *n; +public: + vline_node(vunits, node *, node * = 0); + vline_node(vunits, node *, statem *, int, node * = 0); + ~vline_node(); + node *copy(); + void tprint(troff_output_file *); + hunits width(); + vunits vertical_width(); + void vertical_extent(vunits *, vunits *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class dummy_node : public node { +public: + dummy_node(node *nd = 0) : node(nd) {} + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + hyphenation_type get_hyphenation_type(); +}; + +class transparent_dummy_node : public node { +public: + transparent_dummy_node(node *nd = 0) : node(nd) {} + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); + hyphenation_type get_hyphenation_type(); +}; + +class zero_width_node : public node { + node *n; +public: + zero_width_node(node *); + zero_width_node(node *, statem *, int); + ~zero_width_node(); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + void append(node *); + int character_type(); + void vertical_extent(vunits *, vunits *); +}; + +class left_italic_corrected_node : public node { + node *n; + hunits x; +public: + left_italic_corrected_node(node * = 0); + left_italic_corrected_node(statem *, int, node * = 0); + ~left_italic_corrected_node(); + void tprint(troff_output_file *); + void ascii_print(ascii_output_file *); + void asciify(macro *); + node *copy(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + hunits width(); + node *last_char_node(); + void vertical_extent(vunits *, vunits *); + int ends_sentence(); + int overlaps_horizontally(); + int overlaps_vertically(); + hyphenation_type get_hyphenation_type(); + tfont *get_tfont(); + int character_type(); + hunits skew(); + hunits italic_correction(); + hunits subscript_correction(); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + node *add_self(node *, hyphen_list **); + node *merge_glyph_node(glyph_node *); +}; + +class overstrike_node : public node { + node *list; + hunits max_width; +public: + overstrike_node(); + overstrike_node(statem *, int); + ~overstrike_node(); + node *copy(); + void tprint(troff_output_file *); + void overstrike(node *); // add another node to be overstruck + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + node *add_self(node *, hyphen_list **); + hyphen_list *get_hyphen_list(hyphen_list *, int *); + hyphenation_type get_hyphenation_type(); +}; + +class bracket_node : public node { + node *list; + hunits max_width; +public: + bracket_node(); + bracket_node(statem *, int); + ~bracket_node(); + node *copy(); + void tprint(troff_output_file *); + void bracket(node *); // add another node to be overstruck + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class special_node : public node { + macro mac; + tfont *tf; + color *gcol; + color *fcol; + int no_init_string; + void tprint_start(troff_output_file *); + void tprint_char(troff_output_file *, unsigned char); + void tprint_end(troff_output_file *); +public: + special_node(const macro &, int = 0); + special_node(const macro &, tfont *, color *, color *, statem *, int, + int = 0); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); + tfont *get_tfont(); +}; + +class suppress_node : public node { + int is_on; + int emit_limits; // must we issue the extent of the area written out? + symbol filename; + char position; + int image_id; +public: + suppress_node(int, int); + suppress_node(symbol, char, int); + suppress_node(int, int, symbol, char, int, statem *, int); + suppress_node(int, int, symbol, char, int); + node *copy(); + void tprint(troff_output_file *); + hunits width(); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +private: + void put(troff_output_file *, const char *); +}; + +class tag_node : public node { +public: + string tag_string; + int delayed; + tag_node(); + tag_node(string, int); + tag_node(string, statem *, int, int); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); + int ends_sentence(); +}; + +struct hvpair { + hunits h; + vunits v; + hvpair(); +}; + +class draw_node : public node { + int npoints; + font_size sz; + color *gcol; + color *fcol; + char code; + hvpair *point; +public: + draw_node(char, hvpair *, int, font_size, color *, color *); + draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int); + ~draw_node(); + hunits width(); + vunits vertical_width(); + node *copy(); + void tprint(troff_output_file *); + int same(node *); + const char *type(); + int force_tprint(); + int is_tag(); +}; + +class charinfo; +node *make_node(charinfo *, environment *); +bool character_exists(charinfo *, environment *); + +int same_node_list(node *, node *); +node *reverse_node_list(node *); +void delete_node_list(node *); +node *copy_node_list(node *); + +int get_bold_fontno(int); + +inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p) +: hyphen(0), breakable(0), hyphenation_code(code), next(p) +{ +} + +extern void read_desc(); +extern bool mount_font(int, symbol, symbol = NULL_SYMBOL); +extern int check_font(symbol, symbol); +extern int check_style(symbol); +extern bool mount_style(int, symbol); +extern int is_good_fontno(int); +extern int symbol_fontno(symbol); +extern int next_available_font_position(); +extern void init_size_table(int *); +extern int get_underline_fontno(); + +class output_file { + char make_g_plus_plus_shut_up; +public: + output_file(); + bool is_dying; + virtual ~output_file(); + virtual void trailer(vunits); + virtual void flush() = 0; + virtual void transparent_char(unsigned char) = 0; + virtual void print_line(hunits x, vunits y, node *n, + vunits before, vunits after, hunits width) = 0; + virtual void begin_page(int pageno, vunits page_length) = 0; + virtual void copy_file(hunits x, vunits y, const char *filename) = 0; + virtual int is_printing() = 0; + virtual void put_filename(const char *, int); + virtual void on(); + virtual void off(); +#ifdef COLUMN + virtual void vjustify(vunits, symbol); +#endif /* COLUMN */ + mtsm state; +}; + +#ifndef POPEN_MISSING +extern char *pipe_command; +#endif + +extern output_file *the_output; +extern void init_output(); +int in_output_page_list(int); + +class font_family { + int *map; + int map_size; +public: + const symbol nm; + font_family(symbol); + ~font_family(); + int make_definite(int); + static void invalidate_fontno(int); +}; + +font_family *lookup_family(symbol); +symbol get_font_name(int, environment *); +symbol get_style_name(int); +extern search_path include_search_path; |