Line data Source code
1 : /* Copyright 1989-2025 Free Software Foundation, Inc. 2 : Written by James Clark (jjc@jclark.com) 3 : 4 : This file is part of groff, the GNU roff typesetting system. 5 : 6 : groff is free software; you can redistribute it and/or modify it under 7 : the terms of the GNU General Public License as published by the Free 8 : Software Foundation, either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY 12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 : for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 : 19 : class statem; 20 : 21 : struct size_range { 22 : int min; 23 : int max; 24 : }; 25 : 26 : class font_size { 27 : static size_range *size_list; 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_list(int * /* sizes */); 39 : static void dump_size_list(); 40 : }; 41 : 42 : inline font_size::font_size() : p(0) 43 : { 44 : } 45 : 46 251211 : inline int font_size::operator==(font_size fs) 47 : { 48 251211 : return p == fs.p; 49 : } 50 : 51 12988933 : inline int font_size::operator!=(font_size fs) 52 : { 53 12988933 : return p != fs.p; 54 : } 55 : 56 35891676 : inline int font_size::to_scaled_points() 57 : { 58 35891676 : return p; 59 : } 60 : 61 4 : inline int font_size::to_points() 62 : { 63 4 : return (p / sizescale); 64 : } 65 : 66 : class environment; 67 : 68 : hunits env_digit_width(environment *); 69 : hunits env_space_width(environment *); 70 : hunits env_sentence_space_width(environment *); 71 : hunits env_narrow_space_width(environment *); 72 : hunits env_half_narrow_space_width(environment *); 73 : int env_get_zoom(environment *); 74 : 75 : struct tab; 76 : 77 : enum tab_type { TAB_NONE, TAB_LEFT, TAB_CENTER, TAB_RIGHT }; 78 : 79 : class tab_stops { 80 : tab *initial_list; 81 : tab *repeated_list; 82 : public: 83 : tab_stops(); 84 : tab_stops(hunits /* distance */, tab_type /* type */); 85 : tab_stops(const tab_stops &); 86 : ~tab_stops(); 87 : void operator=(const tab_stops &); 88 : tab_type distance_to_next_tab(hunits /* pos */, 89 : hunits * /* distance */); 90 : tab_type distance_to_next_tab(hunits /* curpos */, 91 : hunits * /* distance */, 92 : hunits * /* leftpos */); 93 : void clear(); 94 : void add_tab(hunits /* pos */, tab_type /* type */, 95 : bool /* is_repeated */); 96 : const char *to_string(); 97 : }; 98 : 99 : class charinfo; 100 : struct node; 101 : struct breakpoint; 102 : class font_family; 103 : class pending_output_line; 104 : 105 : // declarations to avoid friend name injection problems 106 : void title_length(); 107 : void space_size(); 108 : void fill(); 109 : void no_fill(); 110 : void adjust(); 111 : void no_adjust(); 112 : void center(); 113 : void right_justify(); 114 : void vertical_spacing(); 115 : void post_vertical_spacing(); 116 : void line_spacing(); 117 : void line_length(); 118 : void indent(); 119 : void temporary_indent(); 120 : void configure_underlining(bool); 121 : void do_input_trap(bool); 122 : void set_tabs(); 123 : void margin_character(); 124 : void no_number(); 125 : void number_lines(); 126 : void leader_character(); 127 : void tab_character(); 128 : void hyphenate_request(); 129 : void no_hyphenate(); 130 : void hyphen_line_max_request(); 131 : void hyphenation_space_request(); 132 : void hyphenation_margin_request(); 133 : void line_width(); 134 : #if 0 135 : void tabs_save(); 136 : void tabs_restore(); 137 : #endif 138 : void line_tabs_request(); 139 : void title(); 140 : #ifdef WIDOW_CONTROL 141 : void widow_control_request(); 142 : #endif /* WIDOW_CONTROL */ 143 : 144 : class environment { 145 : bool is_dummy_env; // dummy environment used for \w 146 : hunits prev_line_length; 147 : hunits line_length; 148 : hunits prev_title_length; 149 : hunits title_length; 150 : font_size prev_size; 151 : font_size size; 152 : int requested_size; 153 : int prev_requested_size; 154 : int char_height; 155 : int char_slant; 156 : int prev_fontno; 157 : int fontno; 158 : font_family *prev_family; 159 : font_family *family; 160 : int space_size; // in 36ths of an em 161 : int sentence_space_size; // same but for spaces at the end of sentences 162 : int adjust_mode; 163 : bool is_filling; 164 : bool was_line_interrupted; 165 : int was_previous_line_interrupted; // three-valued Boolean :-| 166 : int centered_line_count; 167 : int right_aligned_line_count; 168 : vunits prev_vertical_spacing; 169 : vunits vertical_spacing; 170 : vunits prev_post_vertical_spacing; 171 : vunits post_vertical_spacing; 172 : int prev_line_spacing; 173 : int line_spacing; 174 : hunits prev_indent; 175 : hunits indent; 176 : hunits temporary_indent; 177 : bool have_temporary_indent; 178 : hunits saved_indent; 179 : hunits target_text_length; 180 : int pre_underline_fontno; 181 : int underlined_line_count; 182 : bool underline_spaces; 183 : symbol input_trap; 184 : int input_trap_count; 185 : bool continued_input_trap; 186 : node *line; // in reverse order 187 : hunits prev_text_length; 188 : hunits width_total; 189 : int space_total; 190 : hunits input_line_start; 191 : node *tab_contents; 192 : hunits tab_width; 193 : hunits tab_distance; 194 : bool using_line_tabs; 195 : tab_type current_tab; 196 : node *leader_node; 197 : charinfo *tab_char; 198 : charinfo *leader_char; 199 : bool has_current_field; 200 : hunits field_distance; 201 : hunits pre_field_width; 202 : int field_spaces; 203 : int tab_field_spaces; 204 : bool tab_precedes_field; 205 : bool is_discarding; 206 : bool is_spreading; // set by \p 207 : unsigned char margin_character_flags; 208 : node *margin_character_node; 209 : hunits margin_character_distance; 210 : node *numbering_nodes; 211 : hunits line_number_digit_width; 212 : int number_text_separation; // in digit spaces 213 : int line_number_indent; // in digit spaces 214 : int line_number_multiple; 215 : int no_number_count; 216 : unsigned int hyphenation_mode; 217 : unsigned int hyphenation_mode_default; 218 : int hyphen_line_count; 219 : int hyphen_line_max; 220 : hunits hyphenation_space; 221 : hunits hyphenation_margin; 222 : bool composite; // used for construction of composite character 223 : pending_output_line *pending_lines; 224 : #ifdef WIDOW_CONTROL 225 : bool want_widow_control; 226 : #endif /* WIDOW_CONTROL */ 227 : color *stroke_color; 228 : color *prev_stroke_color; 229 : color *fill_color; 230 : color *prev_fill_color; 231 : unsigned char control_character; 232 : unsigned char no_break_control_character; 233 : 234 : tab_type distance_to_next_tab(hunits *); 235 : tab_type distance_to_next_tab(hunits * /* distance */, 236 : hunits * /* leftpos */); 237 : void start_line(); 238 : void output_line(node * /* nd */, hunits /* width */, 239 : bool /* was_centered */); 240 : void output(node * /* nd */, bool /* suppress_filling */, 241 : vunits /* vs */, vunits /* post_vs */, hunits /* width */, 242 : bool /* was_centered */); 243 : void output_title(node * /* nd */, bool /* suppress_filling */, 244 : vunits /* vs */, vunits /* post_vs */, 245 : hunits /* width */); 246 : #ifdef WIDOW_CONTROL 247 : void mark_last_line(); 248 : #endif /* WIDOW_CONTROL */ 249 : breakpoint *choose_breakpoint(); 250 : void possibly_hyphenate_line(bool /* must_break_here */ = false); 251 : void start_field(); 252 : void wrap_up_field(); 253 : void add_padding(); 254 : node *make_tab_node(hunits /* d */, 255 : node * /* next */ = 0 /* nullptr */); 256 : node *get_prev_char(); 257 : public: 258 : // C++11: Use `enum : unsigned char`. 259 : enum { 260 : MC_ON = 0x1, 261 : MC_NEXT = 0x2 262 : }; 263 : bool seen_space; 264 : bool seen_eol; 265 : bool suppress_next_eol; 266 : bool seen_break; 267 : tab_stops tabs; 268 : const symbol name; 269 : charinfo *hyphen_indicator_char; 270 : 271 : environment(symbol); 272 : environment(const environment *); // for temporary environment 273 : ~environment(); 274 : unsigned char get_control_character(); 275 : bool set_control_character(unsigned char); 276 : unsigned char get_no_break_control_character(); 277 : bool set_no_break_control_character(unsigned char); 278 : statem *construct_state(bool has_only_eol); 279 : void dump(); 280 : void copy(const environment *); 281 100070 : bool is_dummy() { return is_dummy_env; } 282 : bool is_empty(); 283 12991235 : bool is_composite() { return composite; } 284 50900 : void set_composite() { composite = true; } 285 : vunits get_vertical_spacing(); // .v 286 : vunits get_post_vertical_spacing(); // .pvs 287 : int get_line_spacing(); // .L 288 : vunits total_post_vertical_spacing(); 289 8362 : int get_point_size() { return size.to_scaled_points(); } 290 14819175 : font_size get_font_size() { return size; } 291 184826 : int get_size() { return size.to_units(); } 292 81240 : int get_requested_point_size() { return requested_size; } 293 12992072 : int get_char_height() { return char_height; } 294 12991235 : int get_char_slant() { return char_slant; } 295 : hunits get_digit_width(); 296 14611032 : int get_font() { return fontno; }; // .f 297 : int get_zoom(); // .zoom 298 : int get_numbering_nodes(); // .nm 299 14618017 : font_family *get_family() { return family; } 300 : hunits get_emboldening_offset(); // .b 301 : unsigned get_adjust_mode(); // .j 302 : int get_fill(); // .u 303 : hunits get_indent(); // .i 304 : hunits get_temporary_indent(); 305 : hunits get_line_length(); // .l 306 : hunits get_saved_line_length(); // .ll 307 : hunits get_saved_indent(); // .in 308 : hunits get_title_length(); 309 : hunits get_prev_char_width(); // .w 310 : hunits get_prev_char_skew(); 311 : vunits get_prev_char_height(); 312 : vunits get_prev_char_depth(); 313 : hunits get_text_length(); // .k 314 : hunits get_prev_text_length(); // .n 315 15373 : hunits get_space_width() { return env_space_width(this); } 316 805587 : int get_space_size() { return space_size; } // in ems/36 317 789386 : int get_sentence_space_size() { return sentence_space_size; } 318 5349 : hunits get_narrow_space_width() { return env_narrow_space_width(this); } 319 310 : hunits get_half_narrow_space_width() 320 310 : { return env_half_narrow_space_width(this); } 321 : hunits get_input_line_position(); 322 : const char *get_tabs(); 323 : int is_using_line_tabs(); 324 : unsigned get_hyphenation_mode(); 325 : unsigned get_hyphenation_mode_default(); 326 : int get_hyphen_line_max(); 327 : int get_hyphen_line_count(); 328 : hunits get_hyphenation_space(); 329 : hunits get_hyphenation_margin(); 330 : int get_centered_line_count(); 331 : int get_input_trap_line_count(); 332 : int get_input_trap_respects_continuation(); 333 : const char *get_input_trap_macro(); 334 : int get_right_aligned_line_count(); 335 : int get_no_number_count(); 336 13714862 : bool get_was_line_interrupted() { return was_line_interrupted; } 337 2583 : int get_was_previous_line_interrupted() { return was_previous_line_interrupted; } 338 : color *get_fill_color(); 339 : color *get_stroke_color(); 340 : color *get_prev_stroke_color(); 341 : color *get_prev_fill_color(); 342 : void set_stroke_color(color *c); 343 : void set_fill_color(color *c); 344 : node *make_char_node(charinfo *); 345 : node *extract_output_line(); 346 : void width_registers(); 347 : void wrap_up_tab(); 348 : bool set_font(int); 349 : bool set_font(symbol); 350 : void set_family(symbol); 351 : void set_size(int); 352 : void set_char_height(int); 353 : void set_char_slant(int); 354 : void set_input_line_position(hunits); // used by \n(hp 355 : void interrupt(); 356 16 : void spread() { is_spreading = true; } 357 : void possibly_break_line(bool /* must_break_here */ = false, 358 : bool /* must_adjust */ = false); 359 : void do_break(bool /* want_adjustment */ = false); // .br, .brp 360 : void final_break(); 361 : node *make_tag(const char *name, int i); 362 : void newline(); 363 : void advance_to_tab_stop(bool /* use_leader */ = false); 364 : void add_node(node *); 365 : void add_char(charinfo *); 366 : void add_hyphen_indicator(); 367 : void add_italic_correction(); 368 : void space(); 369 : void space(hunits, hunits); 370 : void space_newline(); 371 : const char *get_stroke_color_string(); 372 : const char *get_fill_color_string(); 373 : const char *get_prev_stroke_color_string(); 374 : const char *get_prev_fill_color_string(); 375 : const char *get_font_family_string(); 376 : const char *get_font_name_string(); 377 : const char *get_style_name_string(); 378 : const char *get_name_string(); 379 : const char *get_point_size_string(); 380 : const char *get_requested_point_size_string(); 381 : void output_pending_lines(); 382 : void construct_format_state(node * /* nd */, bool /* was_centered */, 383 : int /* fill */); 384 : void construct_new_line_state(node *n); 385 : void dump_troff_state(); 386 : void dump_pending_nodes(); 387 : 388 : friend void title_length(); 389 : friend void space_size(); 390 : friend void fill(); 391 : friend void no_fill(); 392 : friend void adjust(); 393 : friend void no_adjust(); 394 : friend void center(); 395 : friend void right_justify(); 396 : friend void vertical_spacing(); 397 : friend void post_vertical_spacing(); 398 : friend void line_spacing(); 399 : friend void line_length(); 400 : friend void indent(); 401 : friend void temporary_indent(); 402 : friend void configure_underlining(bool); 403 : friend void do_input_trap(bool); 404 : friend void set_tabs(); 405 : friend void margin_character(); 406 : friend void no_number(); 407 : friend void number_lines(); 408 : friend void leader_character_request(); 409 : friend void tab_character_request(); 410 : friend void hyphenate_request(); 411 : friend void set_hyphenation_mode_default(); 412 : friend void no_hyphenate(); 413 : friend void hyphen_line_max_request(); 414 : friend void hyphenation_space_request(); 415 : friend void hyphenation_margin_request(); 416 : friend void line_width(); 417 : #if 0 418 : friend void tabs_save(); 419 : friend void tabs_restore(); 420 : #endif 421 : friend void line_tabs_request(); 422 : friend void title(); 423 : #ifdef WIDOW_CONTROL 424 : friend void widow_control_request(); 425 : #endif /* WIDOW_CONTROL */ 426 : friend void do_divert(bool /* appending */, bool /* boxing */); 427 : }; 428 : 429 : extern environment *curenv; 430 : extern void pop_env(); 431 : extern void push_env(int); 432 : 433 : void select_font(symbol); 434 : void init_environments(); 435 : 436 : extern double spread_limit; 437 : 438 : extern symbol default_family; 439 : extern bool translate_space_to_dummy; 440 : 441 : extern unsigned char hpf_code_table[]; 442 : 443 : // Local Variables: 444 : // fill-column: 72 445 : // mode: C++ 446 : // End: 447 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: