From 8daea73d1db6182485bd4f9a0654b63d2fcedfb7 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Sat, 1 Aug 2009 00:21:54 -0700 Subject: [PATCH] Filter out dead staves in layout-page-layout. --- lily/include/page-layout-problem.hh | 1 + lily/page-layout-problem.cc | 158 ++++++++++++---------------- 2 files changed, 70 insertions(+), 89 deletions(-) diff --git a/lily/include/page-layout-problem.hh b/lily/include/page-layout-problem.hh index 9a28bd7b54..e7e8d73dba 100644 --- a/lily/include/page-layout-problem.hh +++ b/lily/include/page-layout-problem.hh @@ -39,6 +39,7 @@ protected: static Grob* find_vertical_alignment (System*); static void build_system_skyline (vector const&, vector const&, Skyline* up, Skyline* down); + static vector filter_dead_elements (vector const&); // This is a union (in spirit). // Either staves must be empty or prob must be null. diff --git a/lily/page-layout-problem.cc b/lily/page-layout-problem.cc index ef69e8cb24..61a7ebb901 100644 --- a/lily/page-layout-problem.cc +++ b/lily/page-layout-problem.cc @@ -10,6 +10,7 @@ #include "page-layout-problem.hh" #include "align-interface.hh" +#include "hara-kiri-group-spanner.hh" #include "international.hh" #include "item.hh" #include "output-def.hh" @@ -156,7 +157,8 @@ Page_layout_problem::append_system (System *sys, Spring const& spring, Real padd align->set_property ("positioning-done", SCM_BOOL_T); - extract_grob_set (align, "elements", elts); + extract_grob_set (align, "elements", all_elts); + vector elts = filter_dead_elements (all_elts); vector minimum_offsets = Align_interface::get_minimum_translations (align, elts, Y_AXIS, false, 0, 0); @@ -180,19 +182,19 @@ Page_layout_problem::append_system (System *sys, Spring const& spring, Real padd SCM details = get_details (elements_.back ()); SCM manual_dists = ly_assoc_get (ly_symbol2scm ("alignment-distances"), details, SCM_EOL); vsize last_spaceable_staff = 0; - bool first_live_element = true; + bool found_spaceable_staff = false; for (vsize i = 0; i < elts.size (); ++i) { - if (elts[i]->is_live () && is_spaceable (elts[i])) + if (is_spaceable (elts[i])) { - // We don't add a spring for the first live element, since + // We don't add a spring for the first staff, since // we are only adding springs _between_ staves here. - if (first_live_element) + if (!found_spaceable_staff) { if (i > 0) add_loose_lines_as_spaceable_lines (elts, minimum_offsets, 0, i-1); - first_live_element = false; + found_spaceable_staff = true; last_spaceable_staff = i; continue; } @@ -222,71 +224,50 @@ Page_layout_problem::append_system (System *sys, Spring const& spring, Real padd } // Any loose lines hanging off the end are treated as spaceable // lines. This might give slightly weird results if the hanging - // systems have staff-affinity != UP. It's not quite clear what + // systems have staff-affinity != UP. It's not quite clear what // should happen in that case, though. if (last_spaceable_staff + 1 < elts.size ()) add_loose_lines_as_spaceable_lines (elts, minimum_offsets, - first_live_element ? 0 : last_spaceable_staff + 1, + found_spaceable_staff ? last_spaceable_staff + 1 : 0, elts.size () - 1); + // Corner case: there was only one staff, and it wasn't spaceable. + // Mark it spaceable, because we do not allow non-spaceable staves + // to be at the top or bottom of a system. + else if (!found_spaceable_staff && elts.size ()) + mark_as_spaceable (elts[0]); } +// first and last are inclusive void Page_layout_problem::add_loose_lines_as_spaceable_lines (vector const& elts, vector const& minimum_offsets, vsize first, vsize last) { - Direction last_affinity = UP; - SCM last_spec = SCM_EOL; - bool found_live_line = false; - for (vsize i = first; i <= last; ++i) + vsize start = first; + vsize end = last; + if (start > 0) + --start; + if (end + 1 < elts.size ()) + ++end; + + for (vsize i = start; i < end; ++i) { - if (elts[i]->is_live ()) + SCM spec = get_spacing_spec (elts[i], elts[i+1]); + Spring spring (1.0, 0.0); + alter_spring_from_spacing_spec (spec, &spring); + if (spec == SCM_BOOL_F) { - Direction affinity = robust_scm2dir (elts[i]->get_property ("staff-affinity"), CENTER); - if (affinity > last_affinity) - { - warning (_ ("staff-affinities should only decrease")); - affinity = last_affinity; - } - - SCM spec = elts[i]->get_property ("inter-staff-spacing"); - if ((affinity != DOWN && found_live_line) - || (affinity == DOWN && i != last)) // FIXME: we want to know if we are the last _live_ line. - spec = elts[i]->get_property ("inter-loose-line-spacing"); - - Spring spring (1.0, 0.0); - // When affinity == DOWN, the spacing spec specifies the - // spacing to the staff below. - if (affinity == DOWN) - alter_spring_from_spacing_spec (last_spec, &spring); - else - alter_spring_from_spacing_spec (spec, &spring); - - Real min_distance = (i > 0 ? minimum_offsets[i-1] : 0) - minimum_offsets[i]; - spring.ensure_min_distance (min_distance); - - // The first line in a system doesn't get a spring. - if (first > 0 || found_live_line) - springs_.push_back (spring); - - mark_as_spaceable (elts[i]); - last_spec = spec; - last_affinity = affinity; - found_live_line = true; + spring.set_inverse_compress_strength (10000); + spring.set_inverse_stretch_strength (10000); } - } - - if (found_live_line && last + 1 < elts.size ()) - { - Spring spring (1.0, 0.0); - if (last_affinity == UP) - warning (_ ("a system with staff-affinity UP is stranded above the system")); - alter_spring_from_spacing_spec (last_spec, &spring); - Real min_distance = minimum_offsets[last] - minimum_offsets[last+1]; + Real min_distance = minimum_offsets[i] - minimum_offsets[i+1]; spring.ensure_min_distance (min_distance); springs_.push_back (spring); } + + for (vsize i = first; i <= last; ++i) + mark_as_spaceable (elts[i]); } void @@ -389,68 +370,51 @@ Page_layout_problem::find_system_offsets () // Position the staves within this system. Real translation = 0; - bool found_live_staff = false; vector loose_lines; vector const& min_offsets = elements_[i].min_offsets; vector loose_line_min_distances; Grob *last_spaceable_line = 0; Real last_spaceable_line_translation = 0; - vsize last_live_staff = 0; for (vsize staff_idx = 0; staff_idx < elements_[i].staves.size (); ++staff_idx) { Grob *staff = elements_[i].staves[staff_idx]; - // Dead VerticalAxisGroups didn't participate in the - // rod-and-spring problem, but they still need to be - // translated. We translate them by the same amount as - // the VerticalAxisGroup directly before. (but we don't - // increment spring_idx!) - if (is_spaceable (staff) || !staff->is_live ()) + if (is_spaceable (staff)) { - if (staff->is_live ()) + // this is relative to the system: negative numbers are down. + translation = system_position - solution_[spring_idx]; + spring_idx++; + + // Lay out any non-spaceable lines between this line and + // the last one. + if (loose_lines.size ()) { - // this is relative to the system: negative numbers are down. - translation = system_position - solution_[spring_idx]; - found_live_staff = true; - spring_idx++; - - // Lay out any non-spaceable lines between this line and - // the last one. - if (loose_lines.size ()) - { - loose_line_min_distances.push_back (min_offsets[last_live_staff] - min_offsets[staff_idx]); - loose_lines.push_back (staff); - distribute_loose_lines (loose_lines, loose_line_min_distances, - last_spaceable_line_translation, translation); - loose_lines.clear (); - loose_line_min_distances.clear (); - } - last_spaceable_line = staff; - last_spaceable_line_translation = translation; - last_live_staff = staff_idx; + loose_line_min_distances.push_back (min_offsets[staff_idx-1] - min_offsets[staff_idx]); + loose_lines.push_back (staff); + distribute_loose_lines (loose_lines, loose_line_min_distances, + last_spaceable_line_translation, translation); + loose_lines.clear (); + loose_line_min_distances.clear (); } + last_spaceable_line = staff; + last_spaceable_line_translation = translation; staff->translate_axis (translation, Y_AXIS); } - // We only need to deal with loose lines if we've - // already found a live staff (because any loose lines - // that occur before our first live staff are treated as - // spaced lines anyway). - else if (found_live_staff) + else { if (loose_lines.empty ()) loose_lines.push_back (last_spaceable_line); loose_lines.push_back (staff); - loose_line_min_distances.push_back (min_offsets[last_live_staff] - min_offsets[staff_idx]); - last_live_staff = staff_idx; + loose_line_min_distances.push_back (min_offsets[staff_idx-1] - min_offsets[staff_idx]); } } // Corner case: even if a system has no live staves, it still takes up // one spring (a system with one live staff also takes up one spring), // which we need to increment past. - if (!found_live_staff) + if (elements_[i].staves.empty ()) spring_idx++; *tail = scm_cons (scm_from_double (system_position), SCM_EOL); @@ -677,3 +641,19 @@ Page_layout_problem::alter_spring_from_spacing_spec (SCM spec, Spring* spring) spring->set_inverse_compress_strength (stretch); } } + +vector +Page_layout_problem::filter_dead_elements (vector const& input) +{ + vector output; + for (vsize i = 0; i < input.size (); ++i) + { + if (Hara_kiri_group_spanner::has_interface (input[i])) + Hara_kiri_group_spanner::consider_suicide (input[i]); + + if (input[i]->is_live ()) + output.push_back (input[i]); + } + + return output; +} -- 2.39.5