1 /* $NetBSD: node.h,v 1.1.1.1 2016/01/13 18:41:48 christos Exp $ */ 2 3 // -*- C++ -*- 4 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004 5 Free Software Foundation, Inc. 6 Written by James Clark (jjc@jclark.com) 7 8 This file is part of groff. 9 10 groff is free software; you can redistribute it and/or modify it under 11 the terms of the GNU General Public License as published by the Free 12 Software Foundation; either version 2, or (at your option) any later 13 version. 14 15 groff is distributed in the hope that it will be useful, but WITHOUT ANY 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 for more details. 19 20 You should have received a copy of the GNU General Public License along 21 with groff; see the file COPYING. If not, write to the Free Software 22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24 struct hyphen_list { 25 unsigned char hyphen; 26 unsigned char breakable; 27 unsigned char hyphenation_code; 28 hyphen_list *next; 29 hyphen_list(unsigned char code, hyphen_list *p = 0); 30 }; 31 32 void hyphenate(hyphen_list *, unsigned); 33 34 enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT }; 35 36 class ascii_output_file; 37 38 struct breakpoint; 39 struct vertical_size; 40 class charinfo; 41 42 class macro; 43 44 class troff_output_file; 45 class tfont; 46 class environment; 47 48 class glyph_node; 49 class diverted_space_node; 50 class token_node; 51 52 struct node { 53 node *next; 54 node *last; 55 statem *state; 56 statem *push_state; 57 int div_nest_level; 58 int is_special; 59 node(); 60 node(node *); 61 node(node *, statem *, int); 62 node *add_char(charinfo *, environment *, hunits *, int *, node ** = 0); 63 64 virtual ~node(); 65 virtual node *copy() = 0; 66 virtual int set_unformat_flag(); 67 virtual int force_tprint() = 0; 68 virtual int is_tag() = 0; 69 virtual hunits width(); 70 virtual hunits subscript_correction(); 71 virtual hunits italic_correction(); 72 virtual hunits left_italic_correction(); 73 virtual hunits skew(); 74 virtual int nspaces(); 75 virtual int merge_space(hunits, hunits, hunits); 76 virtual vunits vertical_width(); 77 virtual node *last_char_node(); 78 virtual void vertical_extent(vunits *, vunits *); 79 virtual int character_type(); 80 virtual void set_vertical_size(vertical_size *); 81 virtual int ends_sentence(); 82 virtual node *merge_self(node *); 83 virtual node *add_discretionary_hyphen(); 84 virtual node *add_self(node *, hyphen_list **); 85 virtual hyphen_list *get_hyphen_list(hyphen_list *, int *); 86 virtual void ascii_print(ascii_output_file *); 87 virtual void asciify(macro *); 88 virtual int discardable(); 89 virtual void spread_space(int *, hunits *); 90 virtual void freeze_space(); 91 virtual void is_escape_colon(); 92 virtual breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); 93 virtual int nbreaks(); 94 virtual void split(int, node **, node **); 95 virtual hyphenation_type get_hyphenation_type(); 96 virtual int reread(int *); 97 virtual token_node *get_token_node(); 98 virtual int overlaps_vertically(); 99 virtual int overlaps_horizontally(); 100 virtual units size(); 101 virtual int interpret(macro *); 102 103 virtual node *merge_glyph_node(glyph_node *); 104 virtual tfont *get_tfont(); 105 virtual color *get_glyph_color(); 106 virtual color *get_fill_color(); 107 virtual void tprint(troff_output_file *); 108 virtual void zero_width_tprint(troff_output_file *); 109 110 node *add_italic_correction(hunits *); 111 112 virtual int same(node *) = 0; 113 virtual const char *type() = 0; 114 virtual void debug_node(); 115 virtual void debug_node_list(); 116 }; 117 118 inline node::node() 119 : next(0), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) 120 { 121 } 122 123 inline node::node(node *n) 124 : next(n), last(0), state(0), push_state(0), div_nest_level(0), is_special(0) 125 { 126 } 127 128 inline node::node(node *n, statem *s, int divlevel) 129 : next(n), last(0), push_state(0), div_nest_level(divlevel), is_special(0) 130 { 131 if (s) 132 state = new statem(s); 133 else 134 state = 0; 135 } 136 137 inline node::~node() 138 { 139 } 140 141 // 0 means it doesn't, 1 means it does, 2 means it's transparent 142 143 int node_list_ends_sentence(node *); 144 145 struct breakpoint { 146 breakpoint *next; 147 hunits width; 148 int nspaces; 149 node *nd; 150 int index; 151 char hyphenated; 152 }; 153 154 class line_start_node : public node { 155 public: 156 line_start_node() {} 157 node *copy() { return new line_start_node; } 158 int same(node *); 159 int force_tprint(); 160 int is_tag(); 161 const char *type(); 162 void asciify(macro *); 163 }; 164 165 class space_node : public node { 166 private: 167 #if 0 168 enum { BLOCK = 1024 }; 169 static space_node *free_list; 170 void operator delete(void *); 171 #endif 172 protected: 173 hunits n; 174 char set; 175 char was_escape_colon; 176 color *col; /* for grotty */ 177 space_node(hunits, int, int, color *, statem *, int, node * = 0); 178 public: 179 space_node(hunits, color *, statem *, int, node * = 0); 180 space_node(hunits, color *, node * = 0); 181 #if 0 182 ~space_node(); 183 void *operator new(size_t); 184 #endif 185 node *copy(); 186 int nspaces(); 187 hunits width(); 188 int discardable(); 189 int merge_space(hunits, hunits, hunits); 190 void freeze_space(); 191 void is_escape_colon(); 192 void spread_space(int *, hunits *); 193 void tprint(troff_output_file *); 194 breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); 195 int nbreaks(); 196 void split(int, node **, node **); 197 void ascii_print(ascii_output_file *); 198 int same(node *); 199 void asciify(macro *); 200 const char *type(); 201 int force_tprint(); 202 int is_tag(); 203 hyphenation_type get_hyphenation_type(); 204 }; 205 206 struct width_list { 207 hunits width; 208 hunits sentence_width; 209 width_list *next; 210 width_list(hunits, hunits); 211 width_list(width_list *); 212 }; 213 214 class word_space_node : public space_node { 215 protected: 216 width_list *orig_width; 217 unsigned char unformat; 218 word_space_node(hunits, int, color *, width_list *, int, statem *, int, 219 node * = 0); 220 public: 221 word_space_node(hunits, color *, width_list *, node * = 0); 222 ~word_space_node(); 223 node *copy(); 224 int reread(int *); 225 int set_unformat_flag(); 226 void tprint(troff_output_file *); 227 int same(node *); 228 void asciify(macro *); 229 const char *type(); 230 int merge_space(hunits, hunits, hunits); 231 int force_tprint(); 232 int is_tag(); 233 }; 234 235 class unbreakable_space_node : public word_space_node { 236 unbreakable_space_node(hunits, int, color *, statem *, int, node * = 0); 237 public: 238 unbreakable_space_node(hunits, color *, node * = 0); 239 node *copy(); 240 int reread(int *); 241 void tprint(troff_output_file *); 242 int same(node *); 243 void asciify(macro *); 244 const char *type(); 245 int force_tprint(); 246 int is_tag(); 247 breakpoint *get_breakpoints(hunits, int, breakpoint * = 0, int = 0); 248 int nbreaks(); 249 void split(int, node **, node **); 250 int merge_space(hunits, hunits, hunits); 251 node *add_self(node *, hyphen_list **); 252 hyphen_list *get_hyphen_list(hyphen_list *, int *); 253 hyphenation_type get_hyphenation_type(); 254 }; 255 256 class diverted_space_node : public node { 257 public: 258 vunits n; 259 diverted_space_node(vunits, node * = 0); 260 diverted_space_node(vunits, statem *, int, node * = 0); 261 node *copy(); 262 int reread(int *); 263 int same(node *); 264 const char *type(); 265 int force_tprint(); 266 int is_tag(); 267 }; 268 269 class diverted_copy_file_node : public node { 270 symbol filename; 271 public: 272 vunits n; 273 diverted_copy_file_node(symbol, node * = 0); 274 diverted_copy_file_node(symbol, statem *, int, node * = 0); 275 node *copy(); 276 int reread(int *); 277 int same(node *); 278 const char *type(); 279 int force_tprint(); 280 int is_tag(); 281 }; 282 283 class extra_size_node : public node { 284 vunits n; 285 public: 286 extra_size_node(vunits); 287 extra_size_node(vunits, statem *, int); 288 void set_vertical_size(vertical_size *); 289 node *copy(); 290 int same(node *); 291 const char *type(); 292 int force_tprint(); 293 int is_tag(); 294 }; 295 296 class vertical_size_node : public node { 297 vunits n; 298 public: 299 vertical_size_node(vunits, statem *, int); 300 vertical_size_node(vunits); 301 void set_vertical_size(vertical_size *); 302 void asciify(macro *); 303 node *copy(); 304 int set_unformat_flag(); 305 int same(node *); 306 const char *type(); 307 int force_tprint(); 308 int is_tag(); 309 }; 310 311 class hmotion_node : public node { 312 protected: 313 hunits n; 314 unsigned char was_tab; 315 unsigned char unformat; 316 color *col; /* for grotty */ 317 public: 318 hmotion_node(hunits i, color *c, node *nxt = 0) 319 : node(nxt), n(i), was_tab(0), unformat(0), col(c) {} 320 hmotion_node(hunits i, color *c, statem *s, int divlevel, node *nxt = 0) 321 : node(nxt, s, divlevel), n(i), was_tab(0), unformat(0), col(c) {} 322 hmotion_node(hunits i, int flag1, int flag2, color *c, statem *s, 323 int divlevel, node *nxt = 0) 324 : node(nxt, s, divlevel), n(i), was_tab(flag1), unformat(flag2), 325 col(c) {} 326 hmotion_node(hunits i, int flag1, int flag2, color *c, node *nxt = 0) 327 : node(nxt), n(i), was_tab(flag1), unformat(flag2), col(c) {} 328 node *copy(); 329 int reread(int *); 330 int set_unformat_flag(); 331 void asciify(macro *); 332 void tprint(troff_output_file *); 333 hunits width(); 334 void ascii_print(ascii_output_file *); 335 int same(node *); 336 const char *type(); 337 int force_tprint(); 338 int is_tag(); 339 node *add_self(node *, hyphen_list **); 340 hyphen_list *get_hyphen_list(hyphen_list *, int *); 341 hyphenation_type get_hyphenation_type(); 342 }; 343 344 class space_char_hmotion_node : public hmotion_node { 345 public: 346 space_char_hmotion_node(hunits, color *, node * = 0); 347 space_char_hmotion_node(hunits, color *, statem *, int, node * = 0); 348 node *copy(); 349 void ascii_print(ascii_output_file *); 350 void asciify(macro *); 351 void tprint(troff_output_file *); 352 int same(node *); 353 const char *type(); 354 int force_tprint(); 355 int is_tag(); 356 node *add_self(node *, hyphen_list **); 357 hyphen_list *get_hyphen_list(hyphen_list *, int *); 358 hyphenation_type get_hyphenation_type(); 359 }; 360 361 class vmotion_node : public node { 362 vunits n; 363 color *col; /* for grotty */ 364 public: 365 vmotion_node(vunits, color *); 366 vmotion_node(vunits, color *, statem *, int); 367 void tprint(troff_output_file *); 368 node *copy(); 369 vunits vertical_width(); 370 int same(node *); 371 const char *type(); 372 int force_tprint(); 373 int is_tag(); 374 }; 375 376 class hline_node : public node { 377 hunits x; 378 node *n; 379 public: 380 hline_node(hunits, node *, node * = 0); 381 hline_node(hunits, node *, statem *, int, node * = 0); 382 ~hline_node(); 383 node *copy(); 384 hunits width(); 385 void tprint(troff_output_file *); 386 int same(node *); 387 const char *type(); 388 int force_tprint(); 389 int is_tag(); 390 }; 391 392 class vline_node : public node { 393 vunits x; 394 node *n; 395 public: 396 vline_node(vunits, node *, node * = 0); 397 vline_node(vunits, node *, statem *, int, node * = 0); 398 ~vline_node(); 399 node *copy(); 400 void tprint(troff_output_file *); 401 hunits width(); 402 vunits vertical_width(); 403 void vertical_extent(vunits *, vunits *); 404 int same(node *); 405 const char *type(); 406 int force_tprint(); 407 int is_tag(); 408 }; 409 410 class dummy_node : public node { 411 public: 412 dummy_node(node *nd = 0) : node(nd) {} 413 node *copy(); 414 int same(node *); 415 const char *type(); 416 int force_tprint(); 417 int is_tag(); 418 hyphenation_type get_hyphenation_type(); 419 }; 420 421 class transparent_dummy_node : public node { 422 public: 423 transparent_dummy_node(node *nd = 0) : node(nd) {} 424 node *copy(); 425 int same(node *); 426 const char *type(); 427 int force_tprint(); 428 int is_tag(); 429 int ends_sentence(); 430 hyphenation_type get_hyphenation_type(); 431 }; 432 433 class zero_width_node : public node { 434 node *n; 435 public: 436 zero_width_node(node *); 437 zero_width_node(node *, statem *, int); 438 ~zero_width_node(); 439 node *copy(); 440 void tprint(troff_output_file *); 441 int same(node *); 442 const char *type(); 443 int force_tprint(); 444 int is_tag(); 445 void append(node *); 446 int character_type(); 447 void vertical_extent(vunits *, vunits *); 448 }; 449 450 class left_italic_corrected_node : public node { 451 node *n; 452 hunits x; 453 public: 454 left_italic_corrected_node(node * = 0); 455 left_italic_corrected_node(statem *, int, node * = 0); 456 ~left_italic_corrected_node(); 457 void tprint(troff_output_file *); 458 void ascii_print(ascii_output_file *); 459 void asciify(macro *); 460 node *copy(); 461 int same(node *); 462 const char *type(); 463 int force_tprint(); 464 int is_tag(); 465 hunits width(); 466 node *last_char_node(); 467 void vertical_extent(vunits *, vunits *); 468 int ends_sentence(); 469 int overlaps_horizontally(); 470 int overlaps_vertically(); 471 hyphenation_type get_hyphenation_type(); 472 tfont *get_tfont(); 473 int character_type(); 474 hunits skew(); 475 hunits italic_correction(); 476 hunits subscript_correction(); 477 hyphen_list *get_hyphen_list(hyphen_list *, int *); 478 node *add_self(node *, hyphen_list **); 479 node *merge_glyph_node(glyph_node *); 480 }; 481 482 class overstrike_node : public node { 483 node *list; 484 hunits max_width; 485 public: 486 overstrike_node(); 487 overstrike_node(statem *, int); 488 ~overstrike_node(); 489 node *copy(); 490 void tprint(troff_output_file *); 491 void overstrike(node *); // add another node to be overstruck 492 hunits width(); 493 int same(node *); 494 const char *type(); 495 int force_tprint(); 496 int is_tag(); 497 node *add_self(node *, hyphen_list **); 498 hyphen_list *get_hyphen_list(hyphen_list *, int *); 499 hyphenation_type get_hyphenation_type(); 500 }; 501 502 class bracket_node : public node { 503 node *list; 504 hunits max_width; 505 public: 506 bracket_node(); 507 bracket_node(statem *, int); 508 ~bracket_node(); 509 node *copy(); 510 void tprint(troff_output_file *); 511 void bracket(node *); // add another node to be overstruck 512 hunits width(); 513 int same(node *); 514 const char *type(); 515 int force_tprint(); 516 int is_tag(); 517 }; 518 519 class special_node : public node { 520 macro mac; 521 tfont *tf; 522 color *gcol; 523 color *fcol; 524 int no_init_string; 525 void tprint_start(troff_output_file *); 526 void tprint_char(troff_output_file *, unsigned char); 527 void tprint_end(troff_output_file *); 528 public: 529 special_node(const macro &, int = 0); 530 special_node(const macro &, tfont *, color *, color *, statem *, int, 531 int = 0); 532 node *copy(); 533 void tprint(troff_output_file *); 534 int same(node *); 535 const char *type(); 536 int force_tprint(); 537 int is_tag(); 538 int ends_sentence(); 539 tfont *get_tfont(); 540 }; 541 542 class suppress_node : public node { 543 int is_on; 544 int emit_limits; // must we issue the extent of the area written out? 545 symbol filename; 546 char position; 547 int image_id; 548 public: 549 suppress_node(int, int); 550 suppress_node(symbol, char, int); 551 suppress_node(int, int, symbol, char, int, statem *, int); 552 suppress_node(int, int, symbol, char, int); 553 node *copy(); 554 void tprint(troff_output_file *); 555 hunits width(); 556 int same(node *); 557 const char *type(); 558 int force_tprint(); 559 int is_tag(); 560 private: 561 void put(troff_output_file *, const char *); 562 }; 563 564 class tag_node : public node { 565 public: 566 string tag_string; 567 int delayed; 568 tag_node(); 569 tag_node(string, int); 570 tag_node(string, statem *, int, int); 571 node *copy(); 572 void tprint(troff_output_file *); 573 int same(node *); 574 const char *type(); 575 int force_tprint(); 576 int is_tag(); 577 int ends_sentence(); 578 }; 579 580 struct hvpair { 581 hunits h; 582 vunits v; 583 hvpair(); 584 }; 585 586 class draw_node : public node { 587 int npoints; 588 font_size sz; 589 color *gcol; 590 color *fcol; 591 char code; 592 hvpair *point; 593 public: 594 draw_node(char, hvpair *, int, font_size, color *, color *); 595 draw_node(char, hvpair *, int, font_size, color *, color *, statem *, int); 596 ~draw_node(); 597 hunits width(); 598 vunits vertical_width(); 599 node *copy(); 600 void tprint(troff_output_file *); 601 int same(node *); 602 const char *type(); 603 int force_tprint(); 604 int is_tag(); 605 }; 606 607 class charinfo; 608 node *make_node(charinfo *, environment *); 609 int character_exists(charinfo *, environment *); 610 611 int same_node_list(node *, node *); 612 node *reverse_node_list(node *); 613 void delete_node_list(node *); 614 node *copy_node_list(node *); 615 616 int get_bold_fontno(int); 617 618 inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p) 619 : hyphen(0), breakable(0), hyphenation_code(code), next(p) 620 { 621 } 622 623 extern void read_desc(); 624 extern int mount_font(int, symbol, symbol = NULL_SYMBOL); 625 extern int check_font(symbol, symbol); 626 extern int check_style(symbol); 627 extern void mount_style(int, symbol); 628 extern int is_good_fontno(int); 629 extern int symbol_fontno(symbol); 630 extern int next_available_font_position(); 631 extern void init_size_table(int *); 632 extern int get_underline_fontno(); 633 634 class output_file { 635 char make_g_plus_plus_shut_up; 636 public: 637 output_file(); 638 virtual ~output_file(); 639 virtual void trailer(vunits); 640 virtual void flush() = 0; 641 virtual void transparent_char(unsigned char) = 0; 642 virtual void print_line(hunits x, vunits y, node *n, 643 vunits before, vunits after, hunits width) = 0; 644 virtual void begin_page(int pageno, vunits page_length) = 0; 645 virtual void copy_file(hunits x, vunits y, const char *filename) = 0; 646 virtual int is_printing() = 0; 647 virtual void put_filename(const char *); 648 virtual void on(); 649 virtual void off(); 650 #ifdef COLUMN 651 virtual void vjustify(vunits, symbol); 652 #endif /* COLUMN */ 653 mtsm state; 654 }; 655 656 #ifndef POPEN_MISSING 657 extern char *pipe_command; 658 #endif 659 660 extern output_file *the_output; 661 extern void init_output(); 662 int in_output_page_list(int); 663 664 class font_family { 665 int *map; 666 int map_size; 667 public: 668 const symbol nm; 669 font_family(symbol); 670 ~font_family(); 671 int make_definite(int); 672 static void invalidate_fontno(int); 673 }; 674 675 font_family *lookup_family(symbol); 676 symbol get_font_name(int, environment *); 677 symbol get_style_name(int); 678 extern search_path include_search_path; 679