1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
// -*- 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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;
vunits prev_post_vertical_spacing;
vunits post_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, vunits post_vs,
hunits width);
void output_title(node *nd, int retain_size, vunits vs, vunits post_vs,
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
vunits get_post_vertical_spacing(); // .pvs
int get_line_spacing(); // .L
vunits total_post_vertical_spacing();
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 post_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;
|