From 2985cedca5ff5304123fd1af3ca4a47630d3ce7b Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 19 Dec 2005 16:25:16 +0000 Subject: [PATCH] * lily/slur-engraver.cc (acknowledge_tuplet_number): new function. * scm/define-grob-properties.scm (all-user-grob-properties): remove number-visibility property. * scm/define-grobs.scm (all-grob-descriptions): new grob TupletNumber --- ChangeLog | 2 ++ Documentation/topdocs/NEWS.tely | 4 +++ lily/include/slur-scoring.hh | 20 +++--------- lily/slur-configuration.cc | 31 ++++++++++++++---- lily/slur-engraver.cc | 11 +++++++ lily/slur-scoring.cc | 58 ++++++++++++++++++++++++--------- lily/slur.cc | 12 ++++--- scm/define-grob-properties.scm | 2 -- scm/define-grobs.scm | 5 +-- scm/layout-slur.scm | 2 +- 10 files changed, 101 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 057ab8a315..860a6a8c21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2005-12-19 Han-Wen Nienhuys + * lily/slur-engraver.cc (acknowledge_tuplet_number): new function. + * flower/include/offset.hh (class Offset): new operator /= * lily/tuplet-number.cc (print): new file, new interface. diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 53a3d55120..b6dcf0d216 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -45,6 +45,10 @@ This document is also available in @uref{NEWS.pdf,PDF}. @itemize @bullet + +@item Tuplet brackets and numbers are implemented as separate grobs, +@code{TupletBracket} and @code{TupletNumber}. + @item String arguments for music functions may be specified without @code{#} marks. This allows syntactical constructs (like \clef and \bar) to be expressed in generic music functions. diff --git a/lily/include/slur-scoring.hh b/lily/include/slur-scoring.hh index 9e85ee857d..deeab48589 100644 --- a/lily/include/slur-scoring.hh +++ b/lily/include/slur-scoring.hh @@ -26,7 +26,7 @@ struct Slur_score_parameters Real non_horizontal_penalty_; Real max_slope_; Real max_slope_factor_; - Real extra_object_collision_; + Real extra_object_collision_penalty_; Real accidental_collision_; Real free_slur_distance_; Real free_head_distance_; @@ -45,21 +45,11 @@ struct Extra_collision_info Box extents_; Real penalty_; Grob *grob_; + SCM type_; + + Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p); + Extra_collision_info (); - Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p) - { - idx_ = idx; - extents_[X_AXIS] = x; - extents_[Y_AXIS] = y; - penalty_ = p; - grob_ = g; - } - Extra_collision_info () - { - idx_ = 0.0; - penalty_ = 0.; - grob_ = 0; - } }; struct Encompass_info diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index f5698104ad..be00da1490 100644 --- a/lily/slur-configuration.cc +++ b/lily/slur-configuration.cc @@ -301,6 +301,8 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) for (int j = 0; j < state.extra_encompass_infos_.size (); j++) { Drul_array attachment = attachment_; + Extra_collision_info const &info (state.extra_encompass_infos_[j]); + Interval slur_wid (attachment[LEFT][X_AXIS], attachment[RIGHT][X_AXIS]); /* @@ -333,8 +335,7 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) if (!found) { - Real x = state.extra_encompass_infos_[j].extents_[X_AXIS] - .linear_combination (state.extra_encompass_infos_[j].idx_); + Real x = info.extents_[X_AXIS].linear_combination (info.idx_); if (!slur_wid.contains (x)) continue; @@ -342,15 +343,33 @@ Slur_configuration::score_extra_encompass (Slur_score_state const &state) y = curve_.get_other_coordinate (X_AXIS, x); } - Real dist = state.extra_encompass_infos_[j].extents_[Y_AXIS].distance (y); + Real dist = 0.0; + if (info.type_ == ly_symbol2scm ("avoid")) + dist = info.extents_[Y_AXIS].distance (y); + + /* + Have to score too: the curve enumeration is limited in its + shape, and may produce curves which collide anyway. + */ + else if (info.type_ == ly_symbol2scm ("inside")) + dist = state.dir_ * (y - info.extents_[Y_AXIS][state.dir_]); + else + programming_error ("unknown avoidance type"); + + Real epsilon = 0.1; + Real factor + = (1.0 / (max (dist, 0.0) + epsilon * state.parameters_.extra_encompass_free_distance_)); + Real threshold + = 1.0 / ((1 + epsilon) * state.parameters_.extra_encompass_free_distance_); + + demerit - += fabs (max (0.0, (state.parameters_.extra_encompass_free_distance_ - dist))) - / state.parameters_.extra_encompass_free_distance_ - * state.extra_encompass_infos_[j].penalty_; + += max (info.penalty_ * (factor - threshold), 0.0); } #if DEBUG_SLUR_SCORING score_card_ += to_string ("X%.2f", demerit); #endif + score_ += demerit; } diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 4b6e645127..2dfe2fec10 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -39,6 +39,7 @@ protected: DECLARE_ACKNOWLEDGER (script); DECLARE_ACKNOWLEDGER (text_script); DECLARE_ACKNOWLEDGER (tie); + DECLARE_ACKNOWLEDGER (tuplet_number); void acknowledge_extra_object (Grob_info); void stop_translation_timestep (); virtual void finalize (); @@ -116,6 +117,8 @@ Slur_engraver::acknowledge_extra_object (Grob_info info) e->set_object ("slur", slur->self_scm ()); } } + else + e->warning ("Ignoring grob for slur. avoid-slur not set?"); } void @@ -136,6 +139,13 @@ Slur_engraver::acknowledge_fingering (Grob_info info) acknowledge_extra_object (info); } +void +Slur_engraver::acknowledge_tuplet_number (Grob_info info) +{ + acknowledge_extra_object (info); +} + + void Slur_engraver::acknowledge_script (Grob_info info) { @@ -213,6 +223,7 @@ ADD_ACKNOWLEDGER (Slur_engraver, note_column); ADD_ACKNOWLEDGER (Slur_engraver, script); ADD_ACKNOWLEDGER (Slur_engraver, text_script); ADD_ACKNOWLEDGER (Slur_engraver, tie); +ADD_ACKNOWLEDGER (Slur_engraver, tuplet_number); ADD_TRANSLATOR (Slur_engraver, /* doc */ "Build slur grobs from slur events", /* create */ "Slur", diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index 259ac08e6a..b808375fb7 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -77,7 +77,7 @@ get_detail (SCM alist, SCM sym) void Slur_score_parameters::fill (Grob *me) { - SCM details = me->get_property ("slur-details"); + SCM details = me->get_property ("details"); region_size_ = (int) get_detail (details, ly_symbol2scm ("region-size")); @@ -103,8 +103,8 @@ Slur_score_parameters::fill (Grob *me) = get_detail (details, ly_symbol2scm ("free-head-distance")); absolute_closeness_measure_ = get_detail (details, ly_symbol2scm ("absolute-closeness-measure")); - extra_object_collision_ - = get_detail (details, ly_symbol2scm ("extra-object-collision")); + extra_object_collision_penalty_ + = get_detail (details, ly_symbol2scm ("extra-object-collision-penalty")); accidental_collision_ = get_detail (details, ly_symbol2scm ("accidental-collision")); extra_encompass_free_distance_ @@ -635,19 +635,30 @@ Slur_score_state::generate_avoid_offsets () const extract_grob_set (slur_, "encompass-objects", extra_encompasses); for (int i = 0; i < extra_encompasses.size (); i++) - if (Slur::has_interface (extra_encompasses[i])) - { - Grob *small_slur = extra_encompasses[i]; - Bezier b = Slur::get_curve (small_slur); + { + if (Slur::has_interface (extra_encompasses[i])) + { + Grob *small_slur = extra_encompasses[i]; + Bezier b = Slur::get_curve (small_slur); - Offset z = b.curve_point (0.5); - z += Offset (small_slur->relative_coordinate (common_[X_AXIS], X_AXIS), - small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS)); + Offset z = b.curve_point (0.5); + z += Offset (small_slur->relative_coordinate (common_[X_AXIS], X_AXIS), + small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS)); - z[Y_AXIS] += dir_ * parameters_.free_slur_distance_; - avoid.push (z); - } + z[Y_AXIS] += dir_ * parameters_.free_slur_distance_; + avoid.push (z); + } + else if (extra_encompasses[i]->get_property ("avoid-slur") == ly_symbol2scm ("inside")) + { + Grob *g = extra_encompasses [i]; + Interval xe = g->extent (common_[X_AXIS], X_AXIS); + Interval ye = g->extent (common_[Y_AXIS], Y_AXIS); + if (!xe.is_empty () + && !ye.is_empty ()) + avoid.push (Offset (xe.center(), ye[dir_])); + } + } return avoid; } @@ -792,7 +803,7 @@ Slur_score_state::get_extra_encompass_infos () const k - 1.0, xext, yext, - parameters_.extra_object_collision_); + parameters_.extra_object_collision_penalty_); collision_infos.push (info); } } @@ -803,7 +814,7 @@ Slur_score_state::get_extra_encompass_infos () const Interval ye = g->extent (common_[Y_AXIS], Y_AXIS); Real xp = 0.0; - Real penalty = parameters_.extra_object_collision_; + Real penalty = parameters_.extra_object_collision_penalty_; if (Accidental_interface::has_interface (g)) { penalty = parameters_.accidental_collision_; @@ -847,4 +858,21 @@ Slur_score_state::get_extra_encompass_infos () const return collision_infos; } + +Extra_collision_info::Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p) +{ + idx_ = idx; + extents_[X_AXIS] = x; + extents_[Y_AXIS] = y; + penalty_ = p; + grob_ = g; + type_ = g->get_property ("avoid-slur"); +} +Extra_collision_info::Extra_collision_info () +{ + idx_ = 0.0; + penalty_ = 0.; + grob_ = 0; + type_ = SCM_EOL; +} diff --git a/lily/slur.cc b/lily/slur.cc index 7df04741eb..1672032d40 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -157,6 +157,10 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) if (!slur) return offset_scm; + SCM avoid = script->get_property ("avoid-slur"); + if (avoid != ly_symbol2scm ("outside")) + return scm_from_int (0); + Direction dir = get_grob_direction (script); if (dir == CENTER) return offset_scm; @@ -185,8 +189,7 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) bool consider[] = { false, false, false }; Real ys[] = {0, 0, 0}; bool do_shift = false; - SCM avoid = script->get_property ("avoid-slur"); - + for (int d = LEFT, k = 0; d <= RIGHT; d++, k++) { Real x = xext.linear_combination ((Direction) d); @@ -205,8 +208,7 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) /* Request shift if slur is contained script's Y, or if script is inside slur and avoid == outside. */ if (yext.contains (ys[k]) - || (avoid == ly_symbol2scm ("outside") - && dir * ys[k] > dir * yext[-dir])) + || dir * ys[k] > dir * yext[-dir]) do_shift = true; } } @@ -240,6 +242,6 @@ ADD_INTERFACE (Slur, "slur-interface", "positions " "quant-score " "ratio " - "slur-details " + "details " "thickness "); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index e4cb9ef1a1..12af9bcebb 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -370,8 +370,6 @@ object.") (size ,number? "Size of object, relative to standard size.") (slope ,number? "The slope of this object.") (slur-padding ,number? "Extra distance between slur and script.") - (slur-details ,list? - "An alist of scoring parameters for slur formatting") (space-alist ,list? "A table that specifies distances between prefatory items, like clef and time-signature. The format is an alist of spacing tuples: @code{(@var{break-align-symbol} @var{type} diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 89b4b243b3..58459d081b 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1153,7 +1153,7 @@ spaceable-grob-interface)))))) (PhrasingSlur - . ((slur-details . ,default-slur-details) + . ((details . ,default-slur-details) (control-points . ,Slur::calc_control_points) (direction . ,Slur::calc_direction) @@ -1342,7 +1342,7 @@ separation-spanner-interface)))))) (Slur - . ((slur-details . ,default-slur-details) + . ((details . ,default-slur-details) (control-points . ,Slur::calc_control_points) (direction . ,Slur::calc_direction) @@ -1820,6 +1820,7 @@ (stencil . ,Tuplet_number::print) (font-shape . italic) (font-size . -2) + (avoid-slur . inside) (meta . ((class . Spanner) (interfaces . (text-interface tuplet-number-interface font-interface)))))) diff --git a/scm/layout-slur.scm b/scm/layout-slur.scm index 777b4a86dd..6de5945bbc 100644 --- a/scm/layout-slur.scm +++ b/scm/layout-slur.scm @@ -18,7 +18,7 @@ (max-slope-factor . 10) (free-head-distance . 0.3) (free-slur-distance . 0.8) - (extra-object-collision . 50) + (extra-object-collision-penalty . 50) (accidental-collision . 3) (extra-encompass-free-distance . 0.3) (head-slur-distance-max-ratio . 3) -- 2.39.5