From 5aee29f535290297d490fad3b2ef5c055715dcb3 Mon Sep 17 00:00:00 2001 From: wl Date: Mon, 20 Dec 2010 22:57:04 +0000 Subject: Replace patch from 2010-12-18 with a much faster implementation. * src/roff/troff/node.h (node): Add virtual function `get_break_code'. * src/roff/troff/node.cpp (inter_char_space_node): Remove class completely. (glyph_node::merge_glyph_node): Restore previous version. (break_char_node): Add `prev_break_code' field and update constructors. (node::get_break_code, break_char_node::get_break_code): Implement. (node::add_char): Pass remaining cflags values. (break_char_node::add_self): Use the logic of the now deleted `inter_char_space_node::add_self' function to insert a space node if necessary. --- ChangeLog | 21 ++++ src/roff/troff/node.cpp | 315 ++++++++---------------------------------------- src/roff/troff/node.h | 1 + 3 files changed, 75 insertions(+), 262 deletions(-) diff --git a/ChangeLog b/ChangeLog index 094af92e..213ecf0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-12-20 Werner LEMBERG + + Replace patch from 2010-12-18 with a much faster implementation. + + * src/roff/troff/node.h (node): Add virtual function + `get_break_code'. + + * src/roff/troff/node.cpp (inter_char_space_node): Remove class + completely. + (glyph_node::merge_glyph_node): Restore previous version. + + (break_char_node): Add `prev_break_code' field and update + constructors. + (node::get_break_code, break_char_node::get_break_code): Implement. + + (node::add_char): Pass remaining cflags values. + + (break_char_node::add_self): Use the logic of the now deleted + `inter_char_space_node::add_self' function to insert a space node if + necessary. + 2010-12-20 Daiki Ueno A new try to not changing srcdir if building in separate builddir. diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index ec082ff2..311a5cde 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -2111,47 +2111,6 @@ node *node::merge_glyph_node(glyph_node *) return 0; } -class inter_char_space_node : public node { - hunits amount; - char left_break_code; - char right_break_code; - color *col; - node *n1; - node *n2; -public: - inter_char_space_node(hunits, char, char, color *, node *, node *, - statem *, int, node * = 0); - ~inter_char_space_node(); - node *copy(); - node *merge_glyph_node(glyph_node *); - node *add_self(node *, hyphen_list **); - hyphen_list *get_hyphen_list(hyphen_list *, int *); - node *add_discretionary_hyphen(); - hunits width(); - node *last_char_node(); - hunits italic_correction(); - hunits subscript_correction(); - void tprint(troff_output_file *); - hyphenation_type get_hyphenation_type(); - int ends_sentence(); - void ascii_print(ascii_output_file *); - void asciify(macro *); - int same(node *); - const char *type(); - int force_tprint(); - int is_tag(); - void vertical_extent(vunits *, vunits *); -}; - -enum break_char_type { - CAN_BREAK_BEFORE = 0x01, - CAN_BREAK_AFTER = 0x02, - IGNORE_HCODES = 0x04, - PROHIBIT_BREAK_BEFORE = 0x08, - PROHIBIT_BREAK_AFTER = 0x10, - INTER_CHAR_SPACE = 0x20 -}; - node *glyph_node::merge_glyph_node(glyph_node *gn) { if (tf == gn->tf && gcol == gn->gcol && fcol == gn->fcol) { @@ -2170,28 +2129,6 @@ node *glyph_node::merge_glyph_node(glyph_node *gn) gn->div_nest_level, next1); } } - int left_bc = 0, right_bc = 0; - if (ci->prohibit_break_before()) - left_bc = PROHIBIT_BREAK_BEFORE; - if (gn->ci->prohibit_break_before()) - right_bc = PROHIBIT_BREAK_BEFORE; - if (ci->prohibit_break_after()) - left_bc |= PROHIBIT_BREAK_AFTER; - if (gn->ci->prohibit_break_after()) - right_bc |= PROHIBIT_BREAK_AFTER; - if (ci->inter_char_space()) - left_bc |= INTER_CHAR_SPACE; - if (gn->ci->inter_char_space()) - right_bc |= INTER_CHAR_SPACE; - if (left_bc && right_bc) { - node *next1 = next; - next = 0; - // ic_space not supported yet - int ic_space = 0; - return new inter_char_space_node(ic_space, left_bc, right_bc, - gcol, this, gn, state, - gn->div_nest_level, next1); - } return 0; } @@ -2605,6 +2542,11 @@ int node::is_tag() return 0; } +int node::get_break_code() +{ + return 0; +} + hunits hmotion_node::width() { return n; @@ -2823,10 +2765,11 @@ int italic_corrected_node::character_type() class break_char_node : public node { node *ch; char break_code; + char prev_break_code; color *col; public: - break_char_node(node *, int, color *, node * = 0); - break_char_node(node *, int, color *, statem *, int, node * = 0); + break_char_node(node *, int, int, color *, node * = 0); + break_char_node(node *, int, int, color *, statem *, int, node * = 0); ~break_char_node(); node *copy(); hunits width(); @@ -2849,16 +2792,17 @@ public: const char *type(); int force_tprint(); int is_tag(); + int get_break_code(); }; -break_char_node::break_char_node(node *n, int bc, color *c, node *x) -: node(x), ch(n), break_code(bc), col(c) +break_char_node::break_char_node(node *n, int bc, int pbc, color *c, node *x) +: node(x), ch(n), break_code(bc), prev_break_code(pbc), col(c) { } -break_char_node::break_char_node(node *n, int bc, color *c, statem *s, - int pop, node *x) -: node(x, s, pop), ch(n), break_code(bc), col(c) +break_char_node::break_char_node(node *n, int bc, int pbc, color *c, + statem *s, int pop, node *x) +: node(x, s, pop), ch(n), break_code(bc), prev_break_code(pbc), col(c) { } @@ -2869,8 +2813,8 @@ break_char_node::~break_char_node() node *break_char_node::copy() { - return new break_char_node(ch->copy(), break_code, col, state, - div_nest_level); + return new break_char_node(ch->copy(), break_code, prev_break_code, + col, state, div_nest_level); } hunits break_char_node::width() @@ -2898,13 +2842,37 @@ int break_char_node::ends_sentence() return ch->ends_sentence(); } +enum break_char_type { + CAN_BREAK_BEFORE = 0x01, + CAN_BREAK_AFTER = 0x02, + IGNORE_HCODES = 0x04, + PROHIBIT_BREAK_BEFORE = 0x08, + PROHIBIT_BREAK_AFTER = 0x10, + INTER_CHAR_SPACE = 0x20 +}; + node *break_char_node::add_self(node *n, hyphen_list **p) { + int have_space_node = 0; assert((*p)->hyphenation_code == 0); if (break_code & CAN_BREAK_BEFORE) { if ((*p)->breakable || break_code & IGNORE_HCODES) { n = new space_node(H0, col, n); n->freeze_space(); + have_space_node = 1; + } + } + if (!have_space_node) { + if (prev_break_code & INTER_CHAR_SPACE + || prev_break_code & PROHIBIT_BREAK_AFTER) { + if (break_code & PROHIBIT_BREAK_BEFORE) + // stretchable zero-width space not implemented yet + ; + else { + // breakable, stretchable zero-width space not implemented yet + n = new space_node(H0, col, n); + n->freeze_space(); + } } } next = n; @@ -5137,10 +5105,17 @@ node *node::add_char(charinfo *ci, environment *env, break_code |= CAN_BREAK_AFTER; if (ci->ignore_hcodes()) break_code |= IGNORE_HCODES; + if (ci->prohibit_break_before()) + break_code = PROHIBIT_BREAK_BEFORE; + if (ci->prohibit_break_after()) + break_code |= PROHIBIT_BREAK_AFTER; + if (ci->inter_char_space()) + break_code |= INTER_CHAR_SPACE; if (break_code) { node *next1 = res->next; res->next = 0; - res = new break_char_node(res, break_code, env->get_fill_color(), next1); + res = new break_char_node(res, break_code, get_break_code(), + env->get_fill_color(), next1); } return res; } @@ -5775,195 +5750,6 @@ int dbreak_node::is_tag() return 0; } -inter_char_space_node::inter_char_space_node(hunits n, - char left, char right, - color *c, node *first, node *second, - statem* s, int pop, node *x) -: node(x, s, pop), amount(n), left_break_code(left), right_break_code(right), - col(c), n1(first), n2(second) -{ -} - -inter_char_space_node::~inter_char_space_node() -{ - if (n1 != 0) - delete n1; - if (n2 != 0) - delete n2; -} - -node *inter_char_space_node::merge_glyph_node(glyph_node *gn) -{ - node *nd = n2->merge_glyph_node(gn); - if (nd == 0) - return 0; - n2 = nd; - nd = n2->merge_self(n1); - if (nd) { - nd->next = next; - n1 = 0; - n2 = 0; - delete this; - return nd; - } - return this; -} - -hunits inter_char_space_node::italic_correction() -{ - return n2->italic_correction(); -} - -hunits inter_char_space_node::subscript_correction() -{ - return n2->subscript_correction(); -} - -void inter_char_space_node::vertical_extent(vunits *min, vunits *max) -{ - n1->vertical_extent(min, max); - vunits min2, max2; - n2->vertical_extent(&min2, &max2); - if (min2 < *min) - *min = min2; - if (max2 > *max) - *max = max2; -} - -node *inter_char_space_node::add_discretionary_hyphen() -{ - tfont *tf = n1->get_tfont(); - if (tf) { - if (tf->contains(soft_hyphen_char)) { - color *gcol = n2->get_glyph_color(); - color *fcol = n2->get_fill_color(); - node *next1 = next; - next = 0; - node *n = copy(); - glyph_node *gn = new glyph_node(soft_hyphen_char, tf, gcol, fcol, - state, div_nest_level); - node *nn = n->merge_glyph_node(gn); - if (nn == 0) { - gn->next = n; - nn = gn; - } - return new dbreak_node(this, nn, state, div_nest_level, next1); - } - } - return this; -} - -node *inter_char_space_node::copy() -{ - return new inter_char_space_node(amount, left_break_code, right_break_code, - col, n1->copy(), n2->copy(), - state, div_nest_level); -} - -hyphen_list *inter_char_space_node::get_hyphen_list(hyphen_list *tail, - int *count) -{ - hyphen_list *hl = n2->get_hyphen_list(tail, count); - return n1->get_hyphen_list(hl, count); -} - -node *inter_char_space_node::add_self(node *n, hyphen_list **p) -{ - n = n1->add_self(n, p); - if (left_break_code & INTER_CHAR_SPACE - || left_break_code & PROHIBIT_BREAK_AFTER) { - if (right_break_code & PROHIBIT_BREAK_BEFORE) - // stretchable zero-width space not implemented yet - ; - else { - // breakable, stretchable zero-width space not implemented yet - n = new space_node(H0, col, n); - n->freeze_space(); - } - } - n = n2->add_self(n, p); - n1 = n2 = 0; - delete this; - return n; -} - -hunits inter_char_space_node::width() -{ - return n1->width() + n2->width(); -} - -node *inter_char_space_node::last_char_node() -{ - node *nd = n2->last_char_node(); - if (nd) - return nd; - return n1->last_char_node(); -} - -int inter_char_space_node::ends_sentence() -{ - switch (n2->ends_sentence()) { - case 0: - return 0; - case 1: - return 1; - case 2: - break; - default: - assert(0); - } - return n1->ends_sentence(); -} - -void inter_char_space_node::ascii_print(ascii_output_file *ascii) -{ - n1->ascii_print(ascii); - n2->ascii_print(ascii); -} - -void inter_char_space_node::asciify(macro *m) -{ - n1->asciify(m); - n2->asciify(m); - n1 = n2 = 0; - delete this; -} - -hyphenation_type inter_char_space_node::get_hyphenation_type() -{ - return HYPHEN_MIDDLE; -} - -void inter_char_space_node::tprint(troff_output_file *out) -{ - n1->tprint(out); - n2->tprint(out); -} - -int inter_char_space_node::same(node *nd) -{ - return (amount == ((inter_char_space_node *)nd)->amount - && left_break_code == ((inter_char_space_node *)nd)->left_break_code - && right_break_code == ((inter_char_space_node *)nd)->right_break_code - && same_node(n1, ((inter_char_space_node *)nd)->n1) - && same_node(n2, ((inter_char_space_node *)nd)->n2)); -} - -const char *inter_char_space_node::type() -{ - return "inter_char_space_node"; -} - -int inter_char_space_node::force_tprint() -{ - return 0; -} - -int inter_char_space_node::is_tag() -{ - return 0; -} - int break_char_node::same(node *nd) { return break_code == ((break_char_node *)nd)->break_code @@ -5986,6 +5772,11 @@ int break_char_node::is_tag() return 0; } +int break_char_node::get_break_code() +{ + return break_code; +} + int line_start_node::same(node * /*nd*/) { return 1; diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h index 615cc930..393e18d1 100644 --- a/src/roff/troff/node.h +++ b/src/roff/troff/node.h @@ -64,6 +64,7 @@ struct node { virtual int set_unformat_flag(); virtual int force_tprint() = 0; virtual int is_tag() = 0; + virtual int get_break_code(); virtual hunits width(); virtual hunits subscript_correction(); virtual hunits italic_correction(); -- cgit v1.2.1