175584Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004, 2005
375584Sru   Free Software Foundation, Inc.
475584Sru     Written by James Clark (jjc@jclark.com)
575584Sru
675584SruThis file is part of groff.
775584Sru
875584Srugroff is free software; you can redistribute it and/or modify it under
975584Sruthe terms of the GNU General Public License as published by the Free
1075584SruSoftware Foundation; either version 2, or (at your option) any later
1175584Sruversion.
1275584Sru
1375584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1475584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1575584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1675584Srufor more details.
1775584Sru
1875584SruYou should have received a copy of the GNU General Public License along
1975584Sruwith groff; see the file COPYING.  If not, write to the Free Software
20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
2175584Sru
22151497Sruclass statem;
23151497Sru
2475584Srustruct size_range {
2575584Sru  int min;
2675584Sru  int max;
2775584Sru};
2875584Sru
2975584Sruclass font_size {
3075584Sru  static size_range *size_table;
3175584Sru  static int nranges;
3275584Sru  int p;
3375584Srupublic:
3475584Sru  font_size();
3575584Sru  font_size(int points);
3675584Sru  int to_points();
3775584Sru  int to_scaled_points();
3875584Sru  int to_units();
3975584Sru  int operator==(font_size);
4075584Sru  int operator!=(font_size);
4175584Sru  static void init_size_table(int *sizes);
4275584Sru};
4375584Sru
4475584Sruinline font_size::font_size() : p(0)
4575584Sru{
4675584Sru}
4775584Sru
4875584Sruinline int font_size::operator==(font_size fs)
4975584Sru{
5075584Sru  return p == fs.p;
5175584Sru}
5275584Sru
5375584Sruinline int font_size::operator!=(font_size fs)
5475584Sru{
5575584Sru  return p != fs.p;
5675584Sru}
5775584Sru
5875584Sruinline int font_size::to_scaled_points()
5975584Sru{
6075584Sru  return p;
6175584Sru}
6275584Sru
6375584Sruinline int font_size::to_points()
6475584Sru{
6575584Sru  return p/sizescale;
6675584Sru}
6775584Sru
68151497Sruclass environment;
6975584Sru
7075584Sruhunits env_digit_width(environment *);
7175584Sruhunits env_space_width(environment *);
7275584Sruhunits env_sentence_space_width(environment *);
7375584Sruhunits env_narrow_space_width(environment *);
7475584Sruhunits env_half_narrow_space_width(environment *);
7575584Sru
7675584Srustruct tab;
7775584Sru
7875584Sruenum tab_type { TAB_NONE, TAB_LEFT, TAB_CENTER, TAB_RIGHT };
7975584Sru
8075584Sruclass tab_stops {
8175584Sru  tab *initial_list;
8275584Sru  tab *repeated_list;
8375584Srupublic:
8475584Sru  tab_stops();
8575584Sru  tab_stops(hunits distance, tab_type type);
8675584Sru  tab_stops(const tab_stops &);
8775584Sru  ~tab_stops();
8875584Sru  void operator=(const tab_stops &);
8975584Sru  tab_type distance_to_next_tab(hunits pos, hunits *distance);
90104862Sru  tab_type distance_to_next_tab(hunits curpos, hunits *distance, hunits *leftpos);
9175584Sru  void clear();
9275584Sru  void add_tab(hunits pos, tab_type type, int repeated);
9375584Sru  const char *to_string();
9475584Sru};
9575584Sru
9675584Sruconst unsigned MARGIN_CHARACTER_ON = 1;
9775584Sruconst unsigned MARGIN_CHARACTER_NEXT = 2;
9875584Sru
99151497Sruclass charinfo;
10075584Srustruct node;
10175584Srustruct breakpoint;
102151497Sruclass font_family;
103151497Sruclass pending_output_line;
10475584Sru
105151497Sru// declarations to avoid friend name injection problems
106151497Sruvoid title_length();
107151497Sruvoid space_size();
108151497Sruvoid fill();
109151497Sruvoid no_fill();
110151497Sruvoid adjust();
111151497Sruvoid no_adjust();
112151497Sruvoid center();
113151497Sruvoid right_justify();
114151497Sruvoid vertical_spacing();
115151497Sruvoid post_vertical_spacing();
116151497Sruvoid line_spacing();
117151497Sruvoid line_length();
118151497Sruvoid indent();
119151497Sruvoid temporary_indent();
120151497Sruvoid do_underline(int);
121151497Sruvoid do_input_trap(int);
122151497Sruvoid set_tabs();
123151497Sruvoid margin_character();
124151497Sruvoid no_number();
125151497Sruvoid number_lines();
126151497Sruvoid leader_character();
127151497Sruvoid tab_character();
128151497Sruvoid hyphenate_request();
129151497Sruvoid no_hyphenate();
130151497Sruvoid hyphen_line_max_request();
131151497Sruvoid hyphenation_space_request();
132151497Sruvoid hyphenation_margin_request();
133151497Sruvoid line_width();
134151497Sru#if 0
135151497Sruvoid tabs_save();
136151497Sruvoid tabs_restore();
137151497Sru#endif
138151497Sruvoid line_tabs_request();
139151497Sruvoid title();
140151497Sru#ifdef WIDOW_CONTROL
141151497Sruvoid widow_control_request();
142151497Sru#endif /* WIDOW_CONTROL */
143151497Sru
144151497Sruvoid do_divert(int append, int boxing);
145151497Sru
14675584Sruclass environment {
14775584Sru  int dummy;			// dummy environment used for \w
14875584Sru  hunits prev_line_length;
14975584Sru  hunits line_length;
15075584Sru  hunits prev_title_length;
15175584Sru  hunits title_length;
15275584Sru  font_size prev_size;
15375584Sru  font_size size;
15475584Sru  int requested_size;
15575584Sru  int prev_requested_size;
15675584Sru  int char_height;
15775584Sru  int char_slant;
15875584Sru  int prev_fontno;
15975584Sru  int fontno;
16075584Sru  font_family *prev_family;
16175584Sru  font_family *family;
16275584Sru  int space_size;		// in 36ths of an em
16375584Sru  int sentence_space_size;	// same but for spaces at the end of sentences
16475584Sru  int adjust_mode;
16575584Sru  int fill;
16675584Sru  int interrupted;
16775584Sru  int prev_line_interrupted;
16875584Sru  int center_lines;
16975584Sru  int right_justify_lines;
17075584Sru  vunits prev_vertical_spacing;
17175584Sru  vunits vertical_spacing;
17275584Sru  vunits prev_post_vertical_spacing;
17375584Sru  vunits post_vertical_spacing;
17475584Sru  int prev_line_spacing;
17575584Sru  int line_spacing;
17675584Sru  hunits prev_indent;
17775584Sru  hunits indent;
17875584Sru  hunits temporary_indent;
17975584Sru  int have_temporary_indent;
18075584Sru  hunits saved_indent;
18175584Sru  hunits target_text_length;
18275584Sru  int pre_underline_fontno;
18375584Sru  int underline_lines;
18475584Sru  int underline_spaces;
18575584Sru  symbol input_trap;
18675584Sru  int input_trap_count;
187104862Sru  int continued_input_trap;
18875584Sru  node *line;			// in reverse order
18975584Sru  hunits prev_text_length;
19075584Sru  hunits width_total;
19175584Sru  int space_total;
19275584Sru  hunits input_line_start;
19375584Sru  node *tab_contents;
19475584Sru  hunits tab_width;
19575584Sru  hunits tab_distance;
19675584Sru  int line_tabs;
19775584Sru  tab_type current_tab;
19875584Sru  node *leader_node;
19975584Sru  charinfo *tab_char;
20075584Sru  charinfo *leader_char;
20175584Sru  int current_field;		// is there a current field?
20275584Sru  hunits field_distance;
20375584Sru  hunits pre_field_width;
20475584Sru  int field_spaces;
20575584Sru  int tab_field_spaces;
20675584Sru  int tab_precedes_field;
20775584Sru  int discarding;
20875584Sru  int spread_flag;		// set by \p
20975584Sru  unsigned margin_character_flags;
21075584Sru  node *margin_character_node;
21175584Sru  hunits margin_character_distance;
21275584Sru  node *numbering_nodes;
21375584Sru  hunits line_number_digit_width;
21475584Sru  int number_text_separation;	// in digit spaces
21575584Sru  int line_number_indent;	// in digit spaces
21675584Sru  int line_number_multiple;
21775584Sru  int no_number_count;
21875584Sru  unsigned hyphenation_flags;
21975584Sru  int hyphen_line_count;
22075584Sru  int hyphen_line_max;
22175584Sru  hunits hyphenation_space;
22275584Sru  hunits hyphenation_margin;
22375584Sru  int composite;		// used for construction of composite char?
22475584Sru  pending_output_line *pending_lines;
22575584Sru#ifdef WIDOW_CONTROL
22675584Sru  int widow_control;
22775584Sru#endif /* WIDOW_CONTROL */
228104862Sru  color *glyph_color;
229104862Sru  color *prev_glyph_color;
230104862Sru  color *fill_color;
231104862Sru  color *prev_fill_color;
23275584Sru
23375584Sru  tab_type distance_to_next_tab(hunits *);
234104862Sru  tab_type distance_to_next_tab(hunits *distance, hunits *leftpos);
23575584Sru  void start_line();
236151497Sru  void output_line(node *, hunits, int);
23775584Sru  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
238151497Sru	      hunits width, int was_centered);
23975584Sru  void output_title(node *nd, int retain_size, vunits vs, vunits post_vs,
24075584Sru		    hunits width);
24175584Sru#ifdef WIDOW_CONTROL
24275584Sru  void mark_last_line();
24375584Sru#endif /* WIDOW_CONTROL */
24475584Sru  breakpoint *choose_breakpoint();
24575584Sru  void hyphenate_line(int start_here = 0);
24675584Sru  void start_field();
24775584Sru  void wrap_up_field();
24875584Sru  void add_padding();
24975584Sru  node *make_tab_node(hunits d, node *next = 0);
25075584Sru  node *get_prev_char();
25175584Srupublic:
252151497Sru  int seen_space;
253151497Sru  int seen_eol;
254151497Sru  int suppress_next_eol;
255151497Sru  int seen_break;
256151497Sru  tab_stops tabs;
25775584Sru  const symbol name;
25875584Sru  unsigned char control_char;
25975584Sru  unsigned char no_break_control_char;
26075584Sru  charinfo *hyphen_indicator_char;
26175584Sru
26275584Sru  environment(symbol);
26375584Sru  environment(const environment *);	// for temporary environment
26475584Sru  ~environment();
265151497Sru  statem *construct_state(int only_eol);
26675584Sru  void copy(const environment *);
26775584Sru  int is_dummy() { return dummy; }
26875584Sru  int is_empty();
26975584Sru  int is_composite() { return composite; }
27075584Sru  void set_composite() { composite = 1; }
271151497Sru  vunits get_vertical_spacing();	// .v
272151497Sru  vunits get_post_vertical_spacing();	// .pvs
273151497Sru  int get_line_spacing();		// .L
27475584Sru  vunits total_post_vertical_spacing();
27575584Sru  int get_point_size() { return size.to_scaled_points(); }
27675584Sru  font_size get_font_size() { return size; }
27775584Sru  int get_size() { return size.to_units(); }
27875584Sru  int get_requested_point_size() { return requested_size; }
27975584Sru  int get_char_height() { return char_height; }
28075584Sru  int get_char_slant() { return char_slant; }
28175584Sru  hunits get_digit_width();
282151497Sru  int get_font() { return fontno; };	// .f
28375584Sru  font_family *get_family() { return family; }
284151497Sru  int get_bold();			// .b
285151497Sru  int get_adjust_mode();		// .j
286151497Sru  int get_fill();			// .u
287151497Sru  hunits get_indent();			// .i
28875584Sru  hunits get_temporary_indent();
289151497Sru  hunits get_line_length();		// .l
290151497Sru  hunits get_saved_line_length();	// .ll
291151497Sru  hunits get_saved_indent();		// .in
29275584Sru  hunits get_title_length();
293151497Sru  hunits get_prev_char_width();		// .w
29475584Sru  hunits get_prev_char_skew();
29575584Sru  vunits get_prev_char_height();
29675584Sru  vunits get_prev_char_depth();
297151497Sru  hunits get_text_length();		// .k
298151497Sru  hunits get_prev_text_length();	// .n
29975584Sru  hunits get_space_width() { return env_space_width(this); }
30075584Sru  int get_space_size() { return space_size; }	// in ems/36
30175584Sru  int get_sentence_space_size() { return sentence_space_size; }
30275584Sru  hunits get_narrow_space_width() { return env_narrow_space_width(this); }
30375584Sru  hunits get_half_narrow_space_width()
30475584Sru    { return env_half_narrow_space_width(this); }
30575584Sru  hunits get_input_line_position();
30675584Sru  const char *get_tabs();
30775584Sru  int get_line_tabs();
30875584Sru  int get_hyphenation_flags();
30975584Sru  int get_hyphen_line_max();
31075584Sru  int get_hyphen_line_count();
31175584Sru  hunits get_hyphenation_space();
31275584Sru  hunits get_hyphenation_margin();
31375584Sru  int get_center_lines();
31475584Sru  int get_right_justify_lines();
31575584Sru  int get_prev_line_interrupted() { return prev_line_interrupted; }
316104862Sru  color *get_fill_color();
317104862Sru  color *get_glyph_color();
318104862Sru  color *get_prev_glyph_color();
319104862Sru  color *get_prev_fill_color();
320104862Sru  void set_glyph_color(color *c);
321104862Sru  void set_fill_color(color *c);
32275584Sru  node *make_char_node(charinfo *);
32375584Sru  node *extract_output_line();
32475584Sru  void width_registers();
32575584Sru  void wrap_up_tab();
32675584Sru  void set_font(int);
32775584Sru  void set_font(symbol);
32875584Sru  void set_family(symbol);
32975584Sru  void set_size(int);
33075584Sru  void set_char_height(int);
33175584Sru  void set_char_slant(int);
33275584Sru  void set_input_line_position(hunits);	// used by \n(hp
33375584Sru  void interrupt();
33475584Sru  void spread() { spread_flag = 1; }
33575584Sru  void possibly_break_line(int start_here = 0, int forced = 0);
33679543Sru  void do_break(int spread = 0);	// .br
33775584Sru  void final_break();
338151497Sru  node *make_tag(const char *name, int i);
33975584Sru  void newline();
340151497Sru  void handle_tab(int is_leader = 0);	// do a tab or leader
34175584Sru  void add_node(node *);
34275584Sru  void add_char(charinfo *);
34375584Sru  void add_hyphen_indicator();
34475584Sru  void add_italic_correction();
34575584Sru  void space();
34675584Sru  void space(hunits, hunits);
34775584Sru  void space_newline();
348151497Sru  const char *get_glyph_color_string();
349151497Sru  const char *get_fill_color_string();
35075584Sru  const char *get_font_family_string();
351104862Sru  const char *get_font_name_string();
352151497Sru  const char *get_style_name_string();
35375584Sru  const char *get_name_string();
35475584Sru  const char *get_point_size_string();
35575584Sru  const char *get_requested_point_size_string();
35675584Sru  void output_pending_lines();
357151497Sru  void construct_format_state(node *n, int was_centered, int fill);
358151497Sru  void construct_new_line_state(node *n);
359151497Sru  void dump_troff_state();
36075584Sru
36175584Sru  friend void title_length();
36275584Sru  friend void space_size();
36375584Sru  friend void fill();
36475584Sru  friend void no_fill();
36575584Sru  friend void adjust();
36675584Sru  friend void no_adjust();
36775584Sru  friend void center();
36875584Sru  friend void right_justify();
36975584Sru  friend void vertical_spacing();
37075584Sru  friend void post_vertical_spacing();
37175584Sru  friend void line_spacing();
37275584Sru  friend void line_length();
37375584Sru  friend void indent();
37475584Sru  friend void temporary_indent();
37575584Sru  friend void do_underline(int);
376104862Sru  friend void do_input_trap(int);
37775584Sru  friend void set_tabs();
37875584Sru  friend void margin_character();
37975584Sru  friend void no_number();
38075584Sru  friend void number_lines();
38175584Sru  friend void leader_character();
38275584Sru  friend void tab_character();
38375584Sru  friend void hyphenate_request();
38475584Sru  friend void no_hyphenate();
38575584Sru  friend void hyphen_line_max_request();
38675584Sru  friend void hyphenation_space_request();
38775584Sru  friend void hyphenation_margin_request();
38875584Sru  friend void line_width();
38975584Sru#if 0
39075584Sru  friend void tabs_save();
39175584Sru  friend void tabs_restore();
39275584Sru#endif
39375584Sru  friend void line_tabs_request();
39475584Sru  friend void title();
39575584Sru#ifdef WIDOW_CONTROL
39675584Sru  friend void widow_control_request();
39775584Sru#endif /* WIDOW_CONTROL */
39875584Sru
39975584Sru  friend void do_divert(int append, int boxing);
40075584Sru};
40175584Sru
40275584Sruextern environment *curenv;
40375584Sruextern void pop_env();
40475584Sruextern void push_env(int);
40575584Sru
40675584Sruvoid init_environments();
40775584Sruvoid read_hyphen_file(const char *name);
40875584Sru
409104862Sruextern double spread_limit;
410104862Sru
41175584Sruextern int break_flag;
41275584Sruextern symbol default_family;
41375584Sruextern int translate_space_to_dummy;
414104862Sru
415104862Sruextern unsigned char hpf_code_table[];
416