From 5bbca339abd8ca056f1360a829cc9798bd6ecd8b Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Sat, 2 Jun 2007 20:41:51 +1000 Subject: [PATCH] Clean up spring stuff. --- lily/include/spring.hh | 27 +--- lily/include/staff-spacing.hh | 10 +- lily/paper-column.cc | 2 +- lily/spaceable-grob.cc | 13 +- lily/spacing-determine-loose-columns.cc | 8 +- lily/spacing-spanner.cc | 13 +- lily/spring-smob.cc | 17 +-- lily/staff-spacing.cc | 182 +++++++++--------------- 8 files changed, 110 insertions(+), 162 deletions(-) diff --git a/lily/include/spring.hh b/lily/include/spring.hh index 11989b3ad0..b49d3de1f4 100644 --- a/lily/include/spring.hh +++ b/lily/include/spring.hh @@ -12,33 +12,20 @@ #include "lily-proto.hh" #include "smobs.hh" -struct Spring_smob +struct Spring { Grob *other_; Real distance_; - bool expand_only_b_; - Real inverse_strength_; + Real min_distance_; - DECLARE_SIMPLE_SMOBS (Spring_smob); -public: - Spring_smob (); -}; -DECLARE_UNSMOB (Spring_smob, spring); + Real inverse_stretch_strength_; + Real inverse_compress_strength_; -struct Spring -{ - Drul_array item_drul_; - Real distance_; - bool expand_only_b_; - - /* - TODO: make 2 strengths: one for stretching, and one for shrinking. - */ - Real inverse_strength_; - void add_to_cols (); - void set_to_cols (); + DECLARE_SIMPLE_SMOBS (Spring); +public: Spring (); }; +DECLARE_UNSMOB (Spring, spring); #endif /* SPRING_HH */ diff --git a/lily/include/staff-spacing.hh b/lily/include/staff-spacing.hh index b4241f2800..6180e10202 100644 --- a/lily/include/staff-spacing.hh +++ b/lily/include/staff-spacing.hh @@ -11,15 +11,17 @@ #include "lily-proto.hh" #include "grob-interface.hh" +#include "spring.hh" class Staff_spacing { + static Real optical_correction (Grob *, Grob *, Interval); + static Real left_stickout (Grob *, Grob *); + static Real next_notes_correction (Grob *, Grob *, Real, Real); + public: - static void next_notes_correction (Grob *, Grob *, Real, Real, Real *, Real *); - static void next_note_correction (Grob *, Grob *, Interval, Real, Real, Real*, Real *, int *); DECLARE_GROB_INTERFACE(); - static void get_spacing_params (Grob *, Real *, Real *); - + static Spring get_spacing_params (Grob *); static Interval bar_y_positions (Grob *); }; diff --git a/lily/paper-column.cc b/lily/paper-column.cc index 1578688925..62f68b105e 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -175,7 +175,7 @@ Paper_column::print (SCM p) for (SCM s = me->get_object ("ideal-distances"); scm_is_pair (s); s = scm_cdr (s)) { - Spring_smob *sp = unsmob_spring (scm_car (s)); + Spring *sp = unsmob_spring (scm_car (s)); if (!sp->other_->get_system ()) continue; diff --git a/lily/spaceable-grob.cc b/lily/spaceable-grob.cc index 806e300cfa..77793e5492 100644 --- a/lily/spaceable-grob.cc +++ b/lily/spaceable-grob.cc @@ -79,7 +79,7 @@ Spaceable_grob::add_spring (Grob *me, Grob *other, SCM mins = me->get_object ("ideal-distances"); for (SCM s = mins; scm_is_pair (s); s = scm_cdr (s)) { - Spring_smob *sp = unsmob_spring (scm_car (s)); + Spring *sp = unsmob_spring (scm_car (s)); if (sp->other_ == other) { programming_error ("already have that spring"); @@ -88,8 +88,9 @@ Spaceable_grob::add_spring (Grob *me, Grob *other, } #endif - Spring_smob spring; - spring.inverse_strength_ = inverse_strength; + Spring spring; + spring.inverse_stretch_strength_ = inverse_strength; + spring.inverse_compress_strength_ = inverse_strength; spring.distance_ = distance; spring.other_ = other; @@ -101,13 +102,13 @@ Spaceable_grob::add_spring (Grob *me, Grob *other, void Spaceable_grob::get_spring (Grob *this_col, Grob *next_col, Real *dist, Real *inv_strength) { - Spring_smob *spring = 0; + Spring *spring = 0; for (SCM s = this_col->get_object ("ideal-distances"); !spring && scm_is_pair (s); s = scm_cdr (s)) { - Spring_smob *sp = unsmob_spring (scm_car (s)); + Spring *sp = unsmob_spring (scm_car (s)); if (sp && sp->other_ == next_col) spring = sp; @@ -118,7 +119,7 @@ Spaceable_grob::get_spring (Grob *this_col, Grob *next_col, Real *dist, Real *in Paper_column::get_rank (this_col))); *dist = (spring) ? spring->distance_ : 5.0; - *inv_strength = (spring) ? spring->inverse_strength_ : 1.0; + *inv_strength = (spring) ? spring->inverse_stretch_strength_ : 1.0; } diff --git a/lily/spacing-determine-loose-columns.cc b/lily/spacing-determine-loose-columns.cc index e491730869..45f2f0ae7c 100644 --- a/lily/spacing-determine-loose-columns.cc +++ b/lily/spacing-determine-loose-columns.cc @@ -166,12 +166,10 @@ Spacing_spanner::set_distances_for_loose_col (Grob *me, Grob *c, } else if (Staff_spacing::has_interface (sp)) { - Real space = 0; - Real fixed_space = 0; - Staff_spacing::get_spacing_params (sp, - &space, &fixed_space); + Spring spring = Staff_spacing::get_spacing_params (sp); + Real fixed = spring.distance_ - spring.inverse_compress_strength_; - dists[d] = max (dists[d], fixed_space); + dists[d] = max (dists[d], fixed); } else programming_error ("Subversive spacing wish"); diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 13c2964edb..568283846d 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -454,17 +454,15 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, if (!spacing_grob || !Staff_spacing::has_interface (spacing_grob)) continue; - Real space = 0.; - Real fixed_space = 0.; - /* column for the left one settings should be ok due automatic pointer munging. */ assert (spacing_grob->get_column () == l); - Staff_spacing::get_spacing_params (spacing_grob, - &space, &fixed_space); + Spring sp = Staff_spacing::get_spacing_params (spacing_grob); + Real space = sp.distance_; + Real fixed = sp.distance_ - sp.inverse_compress_strength_; if (Paper_column::when_mom (r).grace_part_) { @@ -477,10 +475,10 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, } max_space = max (max_space, space); - max_fixed = max (max_fixed, fixed_space); + max_fixed = max (max_fixed, fixed); compound_space += space; - compound_fixed += fixed_space; + compound_fixed += fixed; wish_count++; } } @@ -521,6 +519,7 @@ Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r, Real inverse_strength = (compound_space - compound_fixed); Real distance = compound_space; + message (_f ("adding spring of length %f", distance)); Spaceable_grob::add_spring (l, r, distance, inverse_strength); } diff --git a/lily/spring-smob.cc b/lily/spring-smob.cc index a57f5029f2..a466fb44bb 100644 --- a/lily/spring-smob.cc +++ b/lily/spring-smob.cc @@ -10,18 +10,19 @@ #include "warn.hh" #include "ly-smobs.icc" -Spring_smob::Spring_smob () +Spring::Spring () { - distance_ = 0.; - inverse_strength_ = 1.0; - expand_only_b_ = false; + distance_ = 1.0; + min_distance_ = 1.0; + inverse_stretch_strength_ = 1.0; + inverse_compress_strength_ = 1.0; other_ = 0; } -IMPLEMENT_SIMPLE_SMOBS (Spring_smob); +IMPLEMENT_SIMPLE_SMOBS (Spring); SCM -Spring_smob::mark_smob (SCM x) +Spring::mark_smob (SCM x) { (void)x; @@ -29,14 +30,14 @@ Spring_smob::mark_smob (SCM x) } int -Spring_smob::print_smob (SCM, SCM p, scm_print_state *) +Spring::print_smob (SCM, SCM p, scm_print_state *) { scm_puts ("#", p); return 1; } SCM -Spring_smob::equal_p (SCM a, SCM b) +Spring::equal_p (SCM a, SCM b) { return a == b? SCM_BOOL_T : SCM_BOOL_F; } diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index e688d60cfb..b93a4ee6b0 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -11,6 +11,7 @@ #include using namespace std; +#include "international.hh" #include "paper-column.hh" #include "separation-item.hh" #include "warn.hh" @@ -22,28 +23,14 @@ using namespace std; #include "pointer-group-interface.hh" #include "directional-element-interface.hh" -/* - Insert some more space for the next note, in case it has a stem in - the wrong direction -*/ -void -Staff_spacing::next_note_correction (Grob *me, - Grob *g, - Interval bar_size, - Real current_space, Real current_fixed, - Real *space, - Real *fix, - int *wish_count) +Real +Staff_spacing::left_stickout (Grob *me, Grob *g) { - (void) current_fixed; if (!g || !Note_column::has_interface (g)) - return ; + return 0; Item *col = dynamic_cast (g)->get_column (); - Real left_stickout_correction = max (0., (- g->extent (col, X_AXIS)[LEFT])); - - /* staff space -> positions */ - bar_size *= 2; + Real ret = max (0., (- g->extent (col, X_AXIS)[LEFT])); /* Duh. If this gets out of hand, we should invent something more generic. @@ -57,26 +44,25 @@ Staff_spacing::next_note_correction (Grob *me, else v = accs->extent (col, X_AXIS); - left_stickout_correction = max (left_stickout_correction, (- v[LEFT])); + ret = max (ret, (- v[LEFT])); } Grob *arpeggio = unsmob_grob (g->get_object ("arpeggio")); if (arpeggio) - left_stickout_correction = max (left_stickout_correction, - arpeggio->extent (col, X_AXIS)[LEFT]); + ret = max (ret, - arpeggio->extent (col, X_AXIS)[LEFT]); - - /* - Let's decrease the space a little if the problem is not located - after a barline. - */ - if (bar_size.is_empty ()) - left_stickout_correction *= 0.75; + return ret; +} + +Real +Staff_spacing::optical_correction (Grob *me, Grob *g, Interval bar_height) +{ + if (!g || !Note_column::has_interface (g)) + return 0; - Real optical_corr = 0.0; Grob *stem = Note_column::get_stem (g); - if (!bar_size.is_empty () - && !arpeggio - && !accs - && stem) + Real ret = 0.0; + + if (!bar_height.is_empty () && stem) { Direction d = get_grob_direction (stem); if (Stem::is_normal_stem (stem) && d == DOWN) @@ -93,28 +79,15 @@ Staff_spacing::next_note_correction (Grob *me, Interval stem_posns (min (stem_start, stem_end), max (stem_end, stem_start)); - stem_posns.intersect (bar_size); + stem_posns.intersect (bar_height); - optical_corr = min (abs (stem_posns.length () / 7.0), 1.0); - optical_corr *= robust_scm2double (me->get_property ("stem-spacing-correction"), 1); + ret = min (abs (stem_posns.length () / 7.0), 1.0); + ret *= robust_scm2double (me->get_property ("stem-spacing-correction"), 1); } } - - - Real correction = optical_corr + left_stickout_correction; - if (correction) - { - (*wish_count) ++; - - /* - This minute adjustments don't make sense for widely spaced scores. - Hence, we need to keep the stretchable (that is, space - fix) - distance equal. - */ - *space += correction; - *fix += correction; - } + return ret; } + /* Y-positions that are covered by BAR_GROB, in the case that it is a barline. */ @@ -148,68 +121,54 @@ Staff_spacing::bar_y_positions (Grob *bar_grob) note-spacings. */ -void -Staff_spacing::next_notes_correction (Grob *me, Grob *last_grob, - Real current_space, Real current_fixed, - Real *compound_space, Real *compound_fixed - ) +Real +Staff_spacing::next_notes_correction (Grob *me, + Grob *last_grob, + Real current_fixed, + Real right_stickout) { Interval bar_size = bar_y_positions (last_grob); Grob *orig = me->original () ? me->original () : me; extract_grob_set (orig, "right-items", right_items); - *compound_fixed = 0.0; - *compound_space = 0.0; - int wish_count = 0; + Real max_left_stickout = 0.0; + Real max_optical = 0.0; for (vsize i = right_items.size (); i--;) { Grob *g = right_items[i]; if (Note_column::has_interface (right_items[i])) { - Grob *g = right_items[i]; - - Real space = 0.0; - Real fixed = 0.0; - - next_note_correction (me, g, bar_size, - current_space, current_fixed, - &space, &fixed, &wish_count); - - *compound_space += space; - *compound_fixed += fixed; + max_left_stickout = max (max_left_stickout, left_stickout (me, g)); + max_optical = max (max_optical, optical_correction (me, g, bar_size)); } else { extract_grob_set (g, "elements", elts); for (vsize j = elts.size (); j--;) { - Real space = 0.0; - Real fixed = 0.0; - next_note_correction (me, elts[j], bar_size, - current_space, current_fixed, - &space, &fixed, - &wish_count); - *compound_fixed += fixed; - *compound_space += space; + max_left_stickout = max (max_left_stickout, left_stickout (me, elts[j])); + max_optical = max (max_optical, optical_correction (me, g, bar_size)); } } } - - if (wish_count > 1) - { - *compound_space /= wish_count; - *compound_fixed /= wish_count; - } + + /* we put a minimum distance of 0.3 between the right edge of the left grob and + the left edge of the right grob */ + max_left_stickout = max (0.0, max_left_stickout + right_stickout + 0.3 - current_fixed); + return max (max_left_stickout, max_optical); } -void -Staff_spacing::get_spacing_params (Grob *me, Real *space, Real *fixed) +/* This routine does not impose any minimum distances between columns; it only + affects springs. As such, the FIXED variable does not refer to a minimum + distance between columns, but instead to a minimum desired distance between + columns -- this ends up affecting the stiffness of a spring. In fact, FIXED + will be the distance between columns if there is a compression force of 1.0 + applied to the line. */ +Spring +Staff_spacing::get_spacing_params (Grob *me) { - *space = 1.0; - *fixed = 1.0; - Grob *separation_item = 0; Item *me_item = dynamic_cast (me); @@ -225,7 +184,7 @@ Staff_spacing::get_spacing_params (Grob *me, Real *space, Real *fixed) if (!separation_item) { programming_error ("no sep item"); - return; + return Spring (); } Interval last_ext; @@ -244,15 +203,12 @@ Staff_spacing::get_spacing_params (Grob *me, Real *space, Real *fixed) we used to have a warning here, but it generates a lot of spurious error messages. */ - return; + return Spring (); } - *fixed = last_ext[RIGHT]; - *space = *fixed + 1.0; - SCM alist = last_grob->get_property ("space-alist"); if (!scm_list_p (alist)) - return; + return Spring (); SCM space_def = scm_sloppy_assq (ly_symbol2scm ("first-note"), alist); if (me_item->break_status_dir () == CENTER) @@ -265,41 +221,45 @@ Staff_spacing::get_spacing_params (Grob *me, Real *space, Real *fixed) if (!scm_is_pair (space_def)) { programming_error ("unknown prefatory spacing"); - return; + return Spring (); } space_def = scm_cdr (space_def); Real distance = scm_to_double (scm_cdr (space_def)); SCM type = scm_car (space_def); - *fixed = last_ext[RIGHT]; + Real fixed = last_ext[RIGHT]; + Real ideal = fixed + 1.0; + if (type == ly_symbol2scm ("fixed-space")) { - *fixed += distance; - *space = *fixed; + fixed += distance; + ideal = fixed; } else if (type == ly_symbol2scm ("extra-space")) - *space = *fixed + distance; + ideal = fixed + distance; else if (type == ly_symbol2scm ("semi-fixed-space")) { - *fixed += distance / 2; - *space = *fixed + distance / 2; + fixed += distance / 2; + ideal = fixed + distance / 2; } else if (type == ly_symbol2scm ("minimum-space")) - *space = last_ext[LEFT] + max (last_ext.length (), distance); + ideal = last_ext[LEFT] + max (last_ext.length (), distance); else if (type == ly_symbol2scm ("minimum-fixed-space")) { - *space = last_ext[LEFT] + max (last_ext.length (), distance); - *fixed = *space; + fixed = last_ext[LEFT] + max (last_ext.length (), distance); + ideal = fixed; } - Real correction_fixed = 0.0; - Real correction_space = 0.0; - next_notes_correction (me, last_grob, - *space, *fixed, - &correction_space, &correction_fixed ); - *space += correction_space; - *fixed += correction_fixed; + Real correction = next_notes_correction (me, last_grob, fixed, last_ext[RIGHT]); + fixed += correction; + ideal += correction; + + Spring ret; + ret.min_distance_ = 0.0; + ret.distance_ = ideal; + ret.inverse_stretch_strength_ = ret.inverse_compress_strength_ = ideal - fixed; + return ret; } ADD_INTERFACE (Staff_spacing, -- 2.39.5