1// -*- C++ -*-
2/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2004, 2005
3   Free Software Foundation, Inc.
4     Written by James Clark (jjc@jclark.com)
5
6This file is part of groff.
7
8groff is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13groff is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with groff; see the file COPYING.  If not, write to the Free Software
20Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21
22class statem;
23
24struct size_range {
25  int min;
26  int max;
27};
28
29class font_size {
30  static size_range *size_table;
31  static int nranges;
32  int p;
33public:
34  font_size();
35  font_size(int points);
36  int to_points();
37  int to_scaled_points();
38  int to_units();
39  int operator==(font_size);
40  int operator!=(font_size);
41  static void init_size_table(int *sizes);
42};
43
44inline font_size::font_size() : p(0)
45{
46}
47
48inline int font_size::operator==(font_size fs)
49{
50  return p == fs.p;
51}
52
53inline int font_size::operator!=(font_size fs)
54{
55  return p != fs.p;
56}
57
58inline int font_size::to_scaled_points()
59{
60  return p;
61}
62
63inline int font_size::to_points()
64{
65  return p/sizescale;
66}
67
68class environment;
69
70hunits env_digit_width(environment *);
71hunits env_space_width(environment *);
72hunits env_sentence_space_width(environment *);
73hunits env_narrow_space_width(environment *);
74hunits env_half_narrow_space_width(environment *);
75
76struct tab;
77
78enum tab_type { TAB_NONE, TAB_LEFT, TAB_CENTER, TAB_RIGHT };
79
80class tab_stops {
81  tab *initial_list;
82  tab *repeated_list;
83public:
84  tab_stops();
85  tab_stops(hunits distance, tab_type type);
86  tab_stops(const tab_stops &);
87  ~tab_stops();
88  void operator=(const tab_stops &);
89  tab_type distance_to_next_tab(hunits pos, hunits *distance);
90  tab_type distance_to_next_tab(hunits curpos, hunits *distance, hunits *leftpos);
91  void clear();
92  void add_tab(hunits pos, tab_type type, int repeated);
93  const char *to_string();
94};
95
96const unsigned MARGIN_CHARACTER_ON = 1;
97const unsigned MARGIN_CHARACTER_NEXT = 2;
98
99class charinfo;
100struct node;
101struct breakpoint;
102class font_family;
103class pending_output_line;
104
105// declarations to avoid friend name injection problems
106void title_length();
107void space_size();
108void fill();
109void no_fill();
110void adjust();
111void no_adjust();
112void center();
113void right_justify();
114void vertical_spacing();
115void post_vertical_spacing();
116void line_spacing();
117void line_length();
118void indent();
119void temporary_indent();
120void do_underline(int);
121void do_input_trap(int);
122void set_tabs();
123void margin_character();
124void no_number();
125void number_lines();
126void leader_character();
127void tab_character();
128void hyphenate_request();
129void no_hyphenate();
130void hyphen_line_max_request();
131void hyphenation_space_request();
132void hyphenation_margin_request();
133void line_width();
134#if 0
135void tabs_save();
136void tabs_restore();
137#endif
138void line_tabs_request();
139void title();
140#ifdef WIDOW_CONTROL
141void widow_control_request();
142#endif /* WIDOW_CONTROL */
143
144void do_divert(int append, int boxing);
145
146class environment {
147  int dummy;			// dummy environment used for \w
148  hunits prev_line_length;
149  hunits line_length;
150  hunits prev_title_length;
151  hunits title_length;
152  font_size prev_size;
153  font_size size;
154  int requested_size;
155  int prev_requested_size;
156  int char_height;
157  int char_slant;
158  int prev_fontno;
159  int fontno;
160  font_family *prev_family;
161  font_family *family;
162  int space_size;		// in 36ths of an em
163  int sentence_space_size;	// same but for spaces at the end of sentences
164  int adjust_mode;
165  int fill;
166  int interrupted;
167  int prev_line_interrupted;
168  int center_lines;
169  int right_justify_lines;
170  vunits prev_vertical_spacing;
171  vunits vertical_spacing;
172  vunits prev_post_vertical_spacing;
173  vunits post_vertical_spacing;
174  int prev_line_spacing;
175  int line_spacing;
176  hunits prev_indent;
177  hunits indent;
178  hunits temporary_indent;
179  int have_temporary_indent;
180  hunits saved_indent;
181  hunits target_text_length;
182  int pre_underline_fontno;
183  int underline_lines;
184  int underline_spaces;
185  symbol input_trap;
186  int input_trap_count;
187  int continued_input_trap;
188  node *line;			// in reverse order
189  hunits prev_text_length;
190  hunits width_total;
191  int space_total;
192  hunits input_line_start;
193  node *tab_contents;
194  hunits tab_width;
195  hunits tab_distance;
196  int line_tabs;
197  tab_type current_tab;
198  node *leader_node;
199  charinfo *tab_char;
200  charinfo *leader_char;
201  int current_field;		// is there a current field?
202  hunits field_distance;
203  hunits pre_field_width;
204  int field_spaces;
205  int tab_field_spaces;
206  int tab_precedes_field;
207  int discarding;
208  int spread_flag;		// set by \p
209  unsigned margin_character_flags;
210  node *margin_character_node;
211  hunits margin_character_distance;
212  node *numbering_nodes;
213  hunits line_number_digit_width;
214  int number_text_separation;	// in digit spaces
215  int line_number_indent;	// in digit spaces
216  int line_number_multiple;
217  int no_number_count;
218  unsigned hyphenation_flags;
219  int hyphen_line_count;
220  int hyphen_line_max;
221  hunits hyphenation_space;
222  hunits hyphenation_margin;
223  int composite;		// used for construction of composite char?
224  pending_output_line *pending_lines;
225#ifdef WIDOW_CONTROL
226  int widow_control;
227#endif /* WIDOW_CONTROL */
228  color *glyph_color;
229  color *prev_glyph_color;
230  color *fill_color;
231  color *prev_fill_color;
232
233  tab_type distance_to_next_tab(hunits *);
234  tab_type distance_to_next_tab(hunits *distance, hunits *leftpos);
235  void start_line();
236  void output_line(node *, hunits, int);
237  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
238	      hunits width, int was_centered);
239  void output_title(node *nd, int retain_size, vunits vs, vunits post_vs,
240		    hunits width);
241#ifdef WIDOW_CONTROL
242  void mark_last_line();
243#endif /* WIDOW_CONTROL */
244  breakpoint *choose_breakpoint();
245  void hyphenate_line(int start_here = 0);
246  void start_field();
247  void wrap_up_field();
248  void add_padding();
249  node *make_tab_node(hunits d, node *next = 0);
250  node *get_prev_char();
251public:
252  int seen_space;
253  int seen_eol;
254  int suppress_next_eol;
255  int seen_break;
256  tab_stops tabs;
257  const symbol name;
258  unsigned char control_char;
259  unsigned char no_break_control_char;
260  charinfo *hyphen_indicator_char;
261
262  environment(symbol);
263  environment(const environment *);	// for temporary environment
264  ~environment();
265  statem *construct_state(int only_eol);
266  void copy(const environment *);
267  int is_dummy() { return dummy; }
268  int is_empty();
269  int is_composite() { return composite; }
270  void set_composite() { composite = 1; }
271  vunits get_vertical_spacing();	// .v
272  vunits get_post_vertical_spacing();	// .pvs
273  int get_line_spacing();		// .L
274  vunits total_post_vertical_spacing();
275  int get_point_size() { return size.to_scaled_points(); }
276  font_size get_font_size() { return size; }
277  int get_size() { return size.to_units(); }
278  int get_requested_point_size() { return requested_size; }
279  int get_char_height() { return char_height; }
280  int get_char_slant() { return char_slant; }
281  hunits get_digit_width();
282  int get_font() { return fontno; };	// .f
283  font_family *get_family() { return family; }
284  int get_bold();			// .b
285  int get_adjust_mode();		// .j
286  int get_fill();			// .u
287  hunits get_indent();			// .i
288  hunits get_temporary_indent();
289  hunits get_line_length();		// .l
290  hunits get_saved_line_length();	// .ll
291  hunits get_saved_indent();		// .in
292  hunits get_title_length();
293  hunits get_prev_char_width();		// .w
294  hunits get_prev_char_skew();
295  vunits get_prev_char_height();
296  vunits get_prev_char_depth();
297  hunits get_text_length();		// .k
298  hunits get_prev_text_length();	// .n
299  hunits get_space_width() { return env_space_width(this); }
300  int get_space_size() { return space_size; }	// in ems/36
301  int get_sentence_space_size() { return sentence_space_size; }
302  hunits get_narrow_space_width() { return env_narrow_space_width(this); }
303  hunits get_half_narrow_space_width()
304    { return env_half_narrow_space_width(this); }
305  hunits get_input_line_position();
306  const char *get_tabs();
307  int get_line_tabs();
308  int get_hyphenation_flags();
309  int get_hyphen_line_max();
310  int get_hyphen_line_count();
311  hunits get_hyphenation_space();
312  hunits get_hyphenation_margin();
313  int get_center_lines();
314  int get_right_justify_lines();
315  int get_prev_line_interrupted() { return prev_line_interrupted; }
316  color *get_fill_color();
317  color *get_glyph_color();
318  color *get_prev_glyph_color();
319  color *get_prev_fill_color();
320  void set_glyph_color(color *c);
321  void set_fill_color(color *c);
322  node *make_char_node(charinfo *);
323  node *extract_output_line();
324  void width_registers();
325  void wrap_up_tab();
326  void set_font(int);
327  void set_font(symbol);
328  void set_family(symbol);
329  void set_size(int);
330  void set_char_height(int);
331  void set_char_slant(int);
332  void set_input_line_position(hunits);	// used by \n(hp
333  void interrupt();
334  void spread() { spread_flag = 1; }
335  void possibly_break_line(int start_here = 0, int forced = 0);
336  void do_break(int spread = 0);	// .br
337  void final_break();
338  node *make_tag(const char *name, int i);
339  void newline();
340  void handle_tab(int is_leader = 0);	// do a tab or leader
341  void add_node(node *);
342  void add_char(charinfo *);
343  void add_hyphen_indicator();
344  void add_italic_correction();
345  void space();
346  void space(hunits, hunits);
347  void space_newline();
348  const char *get_glyph_color_string();
349  const char *get_fill_color_string();
350  const char *get_font_family_string();
351  const char *get_font_name_string();
352  const char *get_style_name_string();
353  const char *get_name_string();
354  const char *get_point_size_string();
355  const char *get_requested_point_size_string();
356  void output_pending_lines();
357  void construct_format_state(node *n, int was_centered, int fill);
358  void construct_new_line_state(node *n);
359  void dump_troff_state();
360
361  friend void title_length();
362  friend void space_size();
363  friend void fill();
364  friend void no_fill();
365  friend void adjust();
366  friend void no_adjust();
367  friend void center();
368  friend void right_justify();
369  friend void vertical_spacing();
370  friend void post_vertical_spacing();
371  friend void line_spacing();
372  friend void line_length();
373  friend void indent();
374  friend void temporary_indent();
375  friend void do_underline(int);
376  friend void do_input_trap(int);
377  friend void set_tabs();
378  friend void margin_character();
379  friend void no_number();
380  friend void number_lines();
381  friend void leader_character();
382  friend void tab_character();
383  friend void hyphenate_request();
384  friend void no_hyphenate();
385  friend void hyphen_line_max_request();
386  friend void hyphenation_space_request();
387  friend void hyphenation_margin_request();
388  friend void line_width();
389#if 0
390  friend void tabs_save();
391  friend void tabs_restore();
392#endif
393  friend void line_tabs_request();
394  friend void title();
395#ifdef WIDOW_CONTROL
396  friend void widow_control_request();
397#endif /* WIDOW_CONTROL */
398
399  friend void do_divert(int append, int boxing);
400};
401
402extern environment *curenv;
403extern void pop_env();
404extern void push_env(int);
405
406void init_environments();
407void read_hyphen_file(const char *name);
408
409extern double spread_limit;
410
411extern int break_flag;
412extern symbol default_family;
413extern int translate_space_to_dummy;
414
415extern unsigned char hpf_code_table[];
416