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