X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fsystem.cc;h=8c9ad1ff16e89dda86b39ba019fb5a5833f4ad3d;hb=62e36043035ba8e0a9c1137077ff45d794a7003e;hp=8aadfedb6d73b325d52a80a76ac30666b99e3903;hpb=78d515e9c342e1760b4e8a966dd77cb1cc0218d7;p=lilypond.git diff --git a/lily/system.cc b/lily/system.cc index 8aadfedb6d..8c9ad1ff16 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -21,6 +21,7 @@ #include "molecule.hh" #include "all-font-metrics.hh" #include "spacing-interface.hh" +#include "staff-symbol-referencer.hh" // todo: use map. void @@ -60,10 +61,58 @@ System::spanner_count () const } +int +scm_default_compare (const void * a, const void *b) +{ + SCM pa = *(SCM *)a; + SCM pb = *(SCM *)b; + + if (pa < pb) return -1 ; + else if (pa > pb) return 1; + else return 0; +} + +/* + modify L in place: sort it +*/ + +SCM +uniquify_list (SCM l) +{ + int len = scm_ilength (l); + SCM * arr = new SCM[len]; + int k = 0; + for (SCM s =l ; SCM_NNULLP (s); s = SCM_CDR(s)) + arr[k++] = SCM_CAR(s); + + assert (k == len); + qsort (arr, len, sizeof (SCM), &scm_default_compare); + + k = 0; + SCM s =l; + for (int i = 0; i < len ; i++) + { + if (i && arr[i] == arr[i-1]) + continue; + + SCM_SETCAR(s, arr[i]); + + if (i < len - 1) + s = SCM_CDR(s); + } + + SCM_SETCDR(s, SCM_EOL); + delete arr; + + return l; +} void System::typeset_grob (Grob * elem) { + if (elem->pscore_) + programming_error ("Adding element twice."); + elem->pscore_ = pscore_; Pointer_group_interface::add_grob (this, ly_symbol2scm ("all-elements"),elem); scm_gc_unprotect_object (elem->self_scm ()); @@ -76,7 +125,7 @@ System::output_lines () gh_pair_p (s); s = ly_cdr (s)) { Grob * g = unsmob_grob (ly_car (s)); - if (Spacing_interface::has_interface (g)) + if (g->internal_has_interface (ly_symbol2scm ("only-prebreak-interface"))) { /* Kill no longer needed grobs. @@ -121,6 +170,22 @@ System::output_lines () } handle_broken_dependencies (); + /* + Because the this->get_grob_property (all-elements) contains items + in 3 versions, handle_broken_dependencies () will leave duplicated + items in all-elements. Strictly speaking this is harmless, but it + leads to duplicated symbols in the output. uniquify_list() makes + sure that no duplicates are in the list. + */ + for (int i=0; i < broken_intos_.size (); i++) + { + /* + don't do this: strange side effects. + */ + // SCM al = broken_intos_[i]->get_grob_property ("all-elements"); + // al = uniquify_list (al); + } + if (verbose_global_b) progress_indication (_f ("Element count %d.", count + element_count ())); @@ -131,7 +196,8 @@ System::output_lines () if (verbose_global_b) progress_indication ("["); - system->post_processing (i+1 == broken_intos_.size ()); + bool last = i+1 == broken_intos_.size (); + system->post_processing (last); if (verbose_global_b) { @@ -173,7 +239,6 @@ set_loose_columns (System* which, Column_x_positions const *posns) if (col->system_) continue; - Item * left = 0; Item * right = 0; @@ -193,13 +258,17 @@ set_loose_columns (System* which, Column_x_positions const *posns) if (!left && l) { left = l->get_column (); + if (!left->get_system ()) + left = left->find_prebroken_piece (RIGHT); } divide_over ++; - loose = right = r->get_column (); } while (1); + + if (!right->get_system ()) + right = right->find_prebroken_piece (LEFT); /* We divide the remaining space of the column over the left and @@ -209,7 +278,7 @@ set_loose_columns (System* which, Column_x_positions const *posns) Grob * common = right->common_refpoint (left, X_AXIS); Real rx = right->extent(common, X_AXIS)[LEFT]; - Real lx = left->extent(common, X_AXIS)[RIGHT]; + Real lx = left->extent(common, X_AXIS)[RIGHT]; Real total_dx = rx - lx; Interval cval =col->extent (col, X_AXIS); @@ -237,6 +306,7 @@ set_loose_columns (System* which, Column_x_positions const *posns) dx *= 0.5; col->system_ = which; + col->translate_axis (- col->relative_coordinate (common, X_AXIS), X_AXIS); col->translate_axis (lx + dx - cval[LEFT], X_AXIS); } } @@ -265,11 +335,9 @@ System::break_into_pieces (Array const &breaking) } } - void System::output_molecule (SCM expr, Offset o) { - while (1) { if (!gh_pair_p (expr)) @@ -367,6 +435,11 @@ System::pre_processing () } } + + const int LAYER_COUNT= 3; + + + void System::post_processing (bool last_line) { @@ -379,7 +452,7 @@ System::post_processing (bool last_line) } Interval i (extent (this, Y_AXIS)); - if (i.empty_b ()) + if (i.is_empty ()) programming_error ("Huh? Empty System?"); else translate_axis (- i[MAX], Y_AXIS); @@ -395,11 +468,23 @@ System::post_processing (bool last_line) generate all molecules to trigger all font loads. (ugh. This is not very memory efficient.) */ + + SCM all = get_grob_property ("all-elements") ; + all = uniquify_list (all); + + /* + triger font loads first. + + This might seem inefficient, but Molecules are cached per grob + anyway. + */ this->get_molecule(); - for (SCM s = get_grob_property ("all-elements"); gh_pair_p (s); s = ly_cdr (s)) + for (SCM s = all; gh_pair_p (s); s = ly_cdr (s)) { - unsmob_grob (ly_car (s))->get_molecule (); + Grob * g = unsmob_grob (ly_car (s)); + g->get_molecule (); } + /* font defs; */ @@ -447,8 +532,10 @@ System::post_processing (bool last_line) SCM e = sc->get_grob_property ("extra-offset"); if (gh_pair_p (e)) { - o[X_AXIS] += gh_scm2double (ly_car (e)); - o[Y_AXIS] += gh_scm2double (ly_cdr (e)); + Offset z = ly_scm2offset (e); + z *= Staff_symbol_referencer::staff_space (sc); + + o += z; } output_molecule (m->get_expr (), o);