X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbreak-substitution.cc;h=8326cee5eeb8f045a3bf1cbc46158c6432c2848a;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=ce1b41c6cc4c23bf665b9540f352da4af5be9a5b;hpb=e6caaa132f59006e5c47d0007b24bfedd07ad145;p=lilypond.git diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc index ce1b41c6cc..8326cee5ee 100644 --- a/lily/break-substitution.cc +++ b/lily/break-substitution.cc @@ -3,16 +3,16 @@ source file of the GNU LilyPond music typesetter - (c) 2001--2005 Han-Wen Nienhuys - + (c) 2001--2008 Han-Wen Nienhuys */ #include #include +using namespace std; -#include "grob-array.hh" #include "item.hh" #include "system.hh" +#include "grob-array.hh" static SCM break_criterion; void @@ -24,7 +24,7 @@ set_break_subsititution (SCM criterion) /* Perform the substitution for a single grob. */ -SCM +Grob * substitute_grob (Grob *sc) { if (scm_is_integer (break_criterion)) @@ -34,7 +34,7 @@ substitute_grob (Grob *sc) if (i && i->break_status_dir () != d) { Item *br = i->find_prebroken_piece (d); - return (br) ? br->self_scm () : SCM_UNDEFINED; + return br; } } else @@ -42,17 +42,15 @@ substitute_grob (Grob *sc) System *line = dynamic_cast (unsmob_grob (break_criterion)); if (sc->get_system () != line) - { - sc = sc->find_broken_piece (line); - } + sc = sc->find_broken_piece (line); /* now: !sc || (sc && sc->get_system () == line) */ if (!sc) - return SCM_UNDEFINED; + return 0; /* now: sc && sc->get_system () == line */ if (!line) - return sc->self_scm (); + return sc; /* We don't return SCM_UNDEFINED for @@ -66,13 +64,11 @@ substitute_grob (Grob *sc) if (sc->common_refpoint (line, X_AXIS) && sc->common_refpoint (line, Y_AXIS)) - { - return sc->self_scm (); - } - return SCM_UNDEFINED; + return sc; + return 0; } - return sc->self_scm (); + return sc; } /* @@ -95,14 +91,17 @@ do_break_substitution (SCM src) again: if (unsmob_grob (src)) - return substitute_grob (unsmob_grob (src)); + { + Grob *new_ptr = substitute_grob (unsmob_grob (src)); + return new_ptr ? new_ptr->self_scm () : SCM_UNDEFINED; + } else if (scm_is_vector (src)) { int len = scm_c_vector_length (src); SCM nv = scm_c_make_vector (len, SCM_UNDEFINED); for (int i = 0; i < len; i++) { - SCM si = scm_int2num (i); + SCM si = scm_from_int (i); scm_vector_set_x (nv, si, do_break_substitution (scm_vector_ref (src, si))); } @@ -140,28 +139,29 @@ do_break_substitution (SCM src) /* Perform substitution on GROB_LIST using a constant amount of stack. */ +vector temporary_substition_array; void -substitute_grob_array (Grob_array *grob_arr, Grob_array * new_arr) +substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr) { - Link_array &old_grobs (grob_arr->array_reference ()); - Link_array *new_grobs (new_arr == grob_arr - ? new Link_array + vector &old_grobs (grob_arr->array_reference ()); + vector *new_grobs (new_arr == grob_arr + ? & temporary_substition_array : &new_arr->array_reference ()); - for (int i = 0; i < old_grobs.size (); i++) + new_grobs->resize (old_grobs.size ()); + Grob **array = (Grob **) new_grobs->data (); + Grob **ptr = array; + for (vsize i = 0; i < old_grobs.size (); i++) { - Grob * orig = old_grobs[i]; - SCM new_grob = substitute_grob (orig); - if (new_grob != SCM_UNDEFINED) - { - new_grobs->push (unsmob_grob (new_grob)); - } + Grob *orig = old_grobs[i]; + Grob *new_grob = substitute_grob (orig); + if (new_grob) + *ptr++ = new_grob; } + new_grobs->resize (ptr - array); if (new_arr == grob_arr) - { - new_arr->set_array (*new_grobs); - } + new_arr->set_array (*new_grobs); } /* @@ -220,14 +220,12 @@ spanner_system_range (Spanner *sp) Slice rv; if (System *st = sp->get_system ()) - { - rv = Slice (st->get_rank (), st->get_rank ()); - } + rv = Slice (st->get_rank (), st->get_rank ()); else { if (sp->broken_intos_.size ()) rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (), - sp->broken_intos_.top ()->get_system ()->get_rank()); + sp->broken_intos_.back ()->get_system ()->get_rank ()); } return rv; } @@ -265,6 +263,8 @@ grob_system_range (Grob *g) struct Substitution_entry { Grob *grob_; + + /* Assumption: we have less than 32k paper columns. */ short left_; short right_; @@ -314,19 +314,18 @@ bool Spanner::fast_substitute_grob_array (SCM sym, Grob_array *grob_array) { - int len = grob_array->size(); + int len = grob_array->size (); - /* - Only do this complicated thing for large sets. This has the added - advantage that we won't screw up the ordering for elements in - alignments (which typically don't have more than 10 grobs.) - */ + if (grob_array->ordered ()) + return false; - if (len < 300) + if (len < 15) return false; /* We store items on the left, spanners on the right in this vector. + + FIXME: will not multithread. */ static Substitution_entry *vec; static int vec_room; @@ -341,8 +340,8 @@ Spanner::fast_substitute_grob_array (SCM sym, int spanner_index = len; int item_index = 0; - - for (int i = 0 ; i < grob_array->size (); i++) + + for (vsize i = 0; i < grob_array->size (); i++) { Grob *g = grob_array->grob (i); @@ -351,13 +350,9 @@ Spanner::fast_substitute_grob_array (SCM sym, int idx = 0; if (dynamic_cast (g)) - { - idx = --spanner_index; - } + idx = --spanner_index; else if (dynamic_cast (g)) - { - idx = item_index++; - } + idx = item_index++; vec[idx].set (g, sr); } @@ -365,15 +360,15 @@ Spanner::fast_substitute_grob_array (SCM sym, qsort (vec, item_index, sizeof (Substitution_entry), &Substitution_entry::item_compare); - Array item_indices; - Array spanner_indices; + vector item_indices; + vector spanner_indices; for (int i = 0; i <= system_range.length (); i++) { - item_indices.push (Slice (len, 0)); - spanner_indices.push (Slice (len, 0)); + item_indices.push_back (Slice (len, 0)); + spanner_indices.push_back (Slice (len, 0)); } - - Array *arrs[] + + vector *arrs[] = { &item_indices, &spanner_indices }; @@ -381,9 +376,7 @@ Spanner::fast_substitute_grob_array (SCM sym, for (int i = 0; i < item_index;i++) { for (int j = vec[i].left_; j <= vec[i].right_; j++) - { - item_indices[j - system_range[LEFT]].add_point (i); - } + item_indices[j - system_range[LEFT]].add_point (i); } /* @@ -391,13 +384,14 @@ Spanner::fast_substitute_grob_array (SCM sym, is a waste of time -- the staff-spanners screw up the ordering, since they go across the entire score. */ - for (int i = spanner_indices.size (); i--;) + for (vsize i = spanner_indices.size (); i--;) spanner_indices[i] = Slice (spanner_index, len - 1); assert (item_index <= spanner_index); - assert (broken_intos_.size () == system_range.length () + 1); - for (int i = 0; i < broken_intos_.size (); i++) + assert ((broken_intos_.size () == (vsize)system_range.length () + 1) + || (broken_intos_.empty () && system_range.length () == 0)); + for (vsize i = 0; i < broken_intos_.size (); i++) { Grob *sc = broken_intos_[i]; System *l = sc->get_system (); @@ -407,18 +401,16 @@ Spanner::fast_substitute_grob_array (SCM sym, if (!unsmob_grob_array (newval)) { newval = Grob_array::make_array (); - sc->internal_set_object (sym, newval); + sc->set_object (sym, newval); } - - Grob_array *new_array = unsmob_grob_array (newval); + + Grob_array *new_array = unsmob_grob_array (newval); for (int k = 0; k < 2;k++) for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++) { - SCM subs = substitute_grob (vec[j].grob_); - if (subs != SCM_UNDEFINED) - { - new_array->add (unsmob_grob (subs)); - } + Grob *substituted = substitute_grob (vec[j].grob_); + if (substituted) + new_array->add (substituted); } #ifdef PARANOIA @@ -459,14 +451,14 @@ substitute_object_alist (SCM alist, SCM dest) SCM sym = scm_caar (s); SCM val = scm_cdar (s); - if (Grob_array * orig = unsmob_grob_array (val)) + if (Grob_array *orig = unsmob_grob_array (val)) { SCM handle = scm_assq (sym, dest); - SCM newval = - (scm_is_pair (handle)) + SCM newval + = (scm_is_pair (handle)) ? scm_cdr (handle) : Grob_array::make_array (); - + Grob_array *new_arr = unsmob_grob_array (newval); substitute_grob_array (orig, new_arr); @@ -495,12 +487,12 @@ Spanner::substitute_one_mutable_property (SCM sym, Spanner *s = this; bool fast_done = false; - Grob_array * grob_array = unsmob_grob_array (val); + Grob_array *grob_array = unsmob_grob_array (val); if (grob_array) fast_done = s->fast_substitute_grob_array (sym, grob_array); if (!fast_done) - for (int i = 0; i < s->broken_intos_.size (); i++) + for (vsize i = 0; i < s->broken_intos_.size (); i++) { Grob *sc = s->broken_intos_[i]; System *l = sc->get_system (); @@ -512,15 +504,21 @@ Spanner::substitute_one_mutable_property (SCM sym, if (!unsmob_grob_array (newval)) { newval = Grob_array::make_array (); - sc->internal_set_object (sym, newval); + sc->set_object (sym, newval); } substitute_grob_array (grob_array, unsmob_grob_array (newval)); } else { SCM newval = do_break_substitution (val); - sc->internal_set_object (sym, newval); + sc->set_object (sym, newval); } } } +void +Grob::substitute_object_links (SCM crit, SCM orig) +{ + set_break_subsititution (crit); + object_alist_ = substitute_object_alist (orig, object_alist_); +}