// -*- C++ -*- /* Copyright (C) 1989, 1990, 1991, 1992 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 2, 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 groff; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ struct size_range { int min; int max; }; class font_size { static size_range *size_table; static int nranges; int p; public: font_size(); font_size(int points); int to_points(); int to_scaled_points(); int to_units(); int operator==(font_size); int operator!=(font_size); static void init_size_table(int *sizes); }; inline font_size::font_size() : p(0) { } inline int font_size::operator==(font_size fs) { return p == fs.p; } inline int font_size::operator!=(font_size fs) { return p != fs.p; } inline int font_size::to_scaled_points() { return p; } inline int font_size::to_points() { return p/sizescale; } struct environment; hunits env_digit_width(environment *); hunits env_space_width(environment *); hunits env_sentence_space_width(environment *); hunits env_narrow_space_width(environment *); hunits env_half_narrow_space_width(environment *); struct tab; enum tab_type { TAB_NONE, TAB_LEFT, TAB_CENTER, TAB_RIGHT }; class tab_stops { tab *initial_list; tab *repeated_list; public: tab_stops(); tab_stops(hunits distance, tab_type type); tab_stops(const tab_stops &); ~tab_stops(); void operator=(const tab_stops &); tab_type distance_to_next_tab(hunits pos, hunits *distance); void clear(); void add_tab(hunits pos, tab_type type, int repeated); const char *to_string(); }; const unsigned MARGIN_CHARACTER_ON = 1; const unsigned MARGIN_CHARACTER_NEXT = 2; struct charinfo; struct node; struct breakpoint; struct font_family; struct pending_output_line; class environment { int dummy; // dummy environment used for \w hunits prev_line_length; hunits line_length; hunits prev_title_length; hunits title_length; font_size prev_size; font_size size; int requested_size; int prev_requested_size; int char_height; int char_slant; int prev_fontno; int fontno; font_family *prev_family; font_family *family; int space_size; // in 36ths of an em int sentence_space_size; // same but for spaces at the end of sentences int adjust_mode; int fill; int interrupted; int prev_line_interrupted; int center_lines; int right_justify_lines; vunits prev_vertical_spacing; vunits vertical_spacing; int prev_line_spacing; int line_spacing; hunits prev_indent; hunits indent; hunits temporary_indent; int have_temporary_indent; hunits saved_indent; hunits target_text_length; int pre_underline_fontno; int underline_lines; symbol input_trap; int input_trap_count; node *line; // in reverse order hunits prev_text_length; hunits width_total; int space_total; hunits input_line_start; tab_stops tabs; node *tab_contents; hunits tab_width; hunits tab_distance; tab_type current_tab; node *leader_node; charinfo *tab_char; charinfo *leader_char; int current_field; // is there a current field? hunits field_distance; hunits pre_field_width; int field_spaces; int tab_field_spaces; int tab_precedes_field; int discarding; int spread_flag; // set by \p unsigned margin_character_flags; node *margin_character_node; hunits margin_character_distance; node *numbering_nodes; hunits line_number_digit_width; int number_text_separation; // in digit spaces int line_number_indent; // in digit spaces int line_number_multiple; int no_number_count; unsigned hyphenation_flags; int hyphen_line_count; int hyphen_line_max; hunits hyphenation_space; hunits hyphenation_margin; int composite; // used for construction of composite char? pending_output_line *pending_lines; #ifdef WIDOW_CONTROL int widow_control; #endif /* WIDOW_CONTROL */ tab_type distance_to_next_tab(hunits *); void start_line(); void output_line(node *, hunits); void output(node *nd, int retain_size, vunits vs, int ls, hunits width); void output_title(node *nd, int retain_size, vunits vs, int ls, hunits width); #ifdef WIDOW_CONTROL void mark_last_line(); #endif /* WIDOW_CONTROL */ void possibly_break_line(int forced = 0); breakpoint *choose_breakpoint(); void hyphenate_line(); void start_field(); void wrap_up_field(); void add_padding(); node *make_tab_node(hunits d, node *next = 0); node *get_prev_char(); public: const symbol name; unsigned char control_char; unsigned char no_break_control_char; charinfo *hyphen_indicator_char; environment(symbol); environment(const environment *); // for temporary environment ~environment(); int is_dummy() { return dummy; } int is_empty(); int is_composite() { return composite; } void set_composite() { composite = 1; } vunits get_vertical_spacing(); // .v int get_line_spacing(); // .L int get_point_size() { return size.to_scaled_points(); } font_size get_font_size() { return size; } int get_size() { return size.to_units(); } int get_requested_point_size() { return requested_size; } int get_char_height() { return char_height; } int get_char_slant() { return char_slant; } hunits get_digit_width(); int get_font() { return fontno; }; // .f font_family *get_family() { return family; } int get_bold(); // .b int get_adjust_mode(); // .j int get_fill(); // .u hunits get_indent(); // .i hunits get_temporary_indent(); hunits get_line_length(); // .l hunits get_saved_line_length(); // .ll hunits get_saved_indent(); // .in hunits get_title_length(); hunits get_prev_char_width(); // .w hunits get_prev_char_skew(); vunits get_prev_char_height(); vunits get_prev_char_depth(); hunits get_text_length(); // .k hunits get_prev_text_length(); // .n hunits get_space_width() { return env_space_width(this); } int get_space_size() { return space_size; } // in ems/36 int get_sentence_space_size() { return sentence_space_size; } hunits get_narrow_space_width() { return env_narrow_space_width(this); } hunits get_half_narrow_space_width() { return env_half_narrow_space_width(this); } hunits get_input_line_position(); const char *get_tabs(); int get_hyphenation_flags(); int get_hyphen_line_max(); int get_hyphen_line_count(); hunits get_hyphenation_space(); hunits get_hyphenation_margin(); int get_center_lines(); int get_right_justify_lines(); int get_prev_line_interrupted() { return prev_line_interrupted; } node *make_char_node(charinfo *); node *extract_output_line(); void width_registers(); void wrap_up_tab(); void set_font(int); void set_font(symbol); void set_family(symbol); void set_size(int); void set_char_height(int); void set_char_slant(int); void set_input_line_position(hunits); // used by \n(hp void interrupt(); void spread() { spread_flag = 1; } void do_break(); // .br void final_break(); void newline(); void handle_tab(int is_leader = 0); // do a tab or leader void add_node(node *); void add_char(charinfo *); void add_hyphen_indicator(); void add_italic_correction(); void space(); void space_newline(); const char *get_font_family_string(); const char *get_name_string(); const char *get_point_size_string(); const char *get_requested_point_size_string(); void output_pending_lines(); friend void title_length(); friend void space_size(); friend void fill(); friend void no_fill(); friend void adjust(); friend void no_adjust(); friend void center(); friend void right_justify(); friend void vertical_spacing(); friend void line_spacing(); friend void line_length(); friend void indent(); friend void temporary_indent(); friend void underline(); friend void input_trap(); friend void set_tabs(); friend void margin_character(); friend void no_number(); friend void number_lines(); friend void leader_character(); friend void tab_character(); friend void hyphenate_request(); friend void no_hyphenate(); friend void hyphen_line_max_request(); friend void hyphenation_space_request(); friend void hyphenation_margin_request(); friend void line_width(); #if 0 friend void tabs_save(); friend void tabs_restore(); #endif friend void title(); #ifdef WIDOW_CONTROL friend void widow_control_request(); #endif /* WIDOW_CONTROL */ }; extern environment *curenv; extern void pop_env(); extern void push_env(int); void init_environments(); void read_hyphen_file(const char *name); extern int break_flag; extern symbol default_family; extern int translate_space_to_dummy;