X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fslur-scoring.cc;h=a3dad6fb5e9785888b05b119ac5320b24c0b36b0;hb=750b714488c5af6eae22d07163bba8b554734ac6;hp=3d929ca750038217ed528e571bc10161ba80afa8;hpb=89b7e75f6888d2020f7fe8b258e818c0c5e7a223;p=lilypond.git diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index 3d929ca750..a3dad6fb5e 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1996--2012 Han-Wen Nienhuys + Copyright (C) 1996--2015 Han-Wen Nienhuys Jan Nieuwenhuizen LilyPond is free software: you can redistribute it and/or modify @@ -32,6 +32,7 @@ #include "main.hh" #include "misc.hh" #include "note-column.hh" +#include "note-head.hh" #include "output-def.hh" #include "paper-column.hh" #include "pitch.hh" @@ -42,7 +43,6 @@ #include "staff-symbol-referencer.hh" #include "staff-symbol.hh" #include "stem.hh" -#include "time-signature.hh" #include "warn.hh" /* @@ -69,7 +69,6 @@ Slur_score_state::Slur_score_state () { musical_dy_ = 0.0; valid_ = false; - stub_ = false; edge_has_beams_ = false; has_same_beam_ = false; is_broken_ = false; @@ -108,15 +107,15 @@ Slur_score_state::slur_direction () const Encompass_info Slur_score_state::get_encompass_info (Grob *col) const { - Grob *stem = unsmob_grob (col->get_object ("stem")); + Grob *stem = unsmob (col->get_object ("stem")); Encompass_info ei; if (!stem) { programming_error ("no stem for note column"); ei.x_ = col->relative_coordinate (common_[X_AXIS], X_AXIS); - ei.head_ = ei.stem_ = col->maybe_pure_extent (common_[Y_AXIS], - Y_AXIS, stub_, 0, INT_MAX)[dir_]; + ei.head_ = ei.stem_ = col->extent (common_[Y_AXIS], + Y_AXIS)[dir_]; return ei; } Direction stem_dir = get_grob_direction (stem); @@ -129,16 +128,16 @@ Slur_score_state::get_encompass_info (Grob *col) const Grob *h = Stem::extremal_heads (stem)[Direction (dir_)]; if (!h) { - ei.head_ = ei.stem_ = col->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_]; + ei.head_ = ei.stem_ = col->extent (common_[Y_AXIS], Y_AXIS)[dir_]; return ei; } - ei.head_ = h->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_]; + ei.head_ = h->extent (common_[Y_AXIS], Y_AXIS)[dir_]; if ((stem_dir == dir_) - && !stem->maybe_pure_extent (stem, Y_AXIS, stub_, 0, INT_MAX).is_empty ()) + && !stem->extent (stem, Y_AXIS).is_empty ()) { - ei.stem_ = stem->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_]; + ei.stem_ = stem->extent (common_[Y_AXIS], Y_AXIS)[dir_]; if (Grob *b = Stem::get_beam (stem)) ei.stem_ += stem_dir * 0.5 * Beam::get_beam_thickness (b); @@ -163,7 +162,7 @@ Slur_score_state::get_bound_info () const for (LEFT_and_RIGHT (d)) { extremes[d].bound_ = slur_->get_bound (d); - if (Note_column::has_interface (extremes[d].bound_)) + if (has_interface (extremes[d].bound_)) { extremes[d].note_column_ = extremes[d].bound_; extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_); @@ -176,13 +175,9 @@ Slur_score_state::get_bound_info () const for (int a = X_AXIS; a < NO_AXES; a++) { Axis ax = Axis (a); - Interval s = ax == Y_AXIS - ? extremes[d].stem_->maybe_pure_extent (common_[ax], ax, stub_, 0, INT_MAX) - : extremes[d].stem_->extent (common_[ax], ax); + Interval s = extremes[d].stem_->extent (common_[ax], ax); if (extremes[d].flag_) - s.unite (ax == Y_AXIS - ? extremes[d].flag_->maybe_pure_extent (common_[ax], ax, stub_, 0, INT_MAX) - : extremes[d].flag_->extent (common_[ax], ax)); + s.unite (extremes[d].flag_->extent (common_[ax], ax)); if (s.is_empty ()) { /* @@ -190,9 +185,7 @@ Slur_score_state::get_bound_info () const whole notes. */ s = Interval (0, 0) - + (ax == Y_AXIS - ? extremes[d].stem_->maybe_pure_coordinate (common_[ax], ax, stub_, 0, INT_MAX) - : extremes[d].stem_->relative_coordinate (common_[ax], ax)); + + extremes[d].stem_->relative_coordinate (common_[ax], ax); } extremes[d].stem_extent_[ax] = s; } @@ -208,11 +201,14 @@ Slur_score_state::get_bound_info () const ::staff_space (extremes[d].stem_); } - if (extremes[d].slur_head_) - extremes[d].slur_head_x_extent_ - = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS); - } + else if (has_interface (extremes[d].bound_)) + { + extremes[d].slur_head_ = extremes[d].bound_; + } + if (extremes[d].slur_head_) + extremes[d].slur_head_x_extent_ + = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS); } return extremes; @@ -222,8 +218,6 @@ void Slur_score_state::fill (Grob *me) { slur_ = dynamic_cast (me); - stub_ = slur_->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")); - columns_ = internal_extract_grob_array (me, ly_symbol2scm ("note-columns")); @@ -235,8 +229,8 @@ Slur_score_state::fill (Grob *me) Slur::replace_breakable_encompass_objects (me); staff_space_ = Staff_symbol_referencer::staff_space (me); - Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); - thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * lt; + line_thickness_ = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness")); + thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * line_thickness_; dir_ = slur_direction (); parameters_.fill (me); @@ -264,8 +258,8 @@ Slur_score_state::fill (Grob *me) } extremes_ = get_bound_info (); - is_broken_ = (!extremes_[LEFT].note_column_ - || !extremes_[RIGHT].note_column_); + is_broken_ = (!(extremes_[LEFT].note_column_ || extremes_[LEFT].slur_head_) + || !(extremes_[RIGHT].note_column_ || extremes_[RIGHT].slur_head_)); has_same_beam_ = (extremes_[LEFT].stem_ && extremes_[RIGHT].stem_ @@ -291,11 +285,12 @@ Slur_score_state::fill (Grob *me) end_ys[RIGHT], end_ys[LEFT]); Real encompass_place = extra_encompass_infos_[i].extents_[Y_AXIS][dir_]; - if (extra_encompass_infos_[i].type_ == ly_symbol2scm ("inside") + if (scm_is_eq (extra_encompass_infos_[i].type_, + ly_symbol2scm ("inside")) && minmax (dir_, encompass_place, y_place) == encompass_place && (!extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("key-signature-interface")) - && !Clef::has_interface (extra_encompass_infos_[i].grob_) - && !Time_signature::has_interface (extra_encompass_infos_[i].grob_))) + && !has_interface (extra_encompass_infos_[i].grob_) + && !extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("time-signature-interface")))) { for (LEFT_and_RIGHT (d)) additional_ys[d] = minmax (dir_, @@ -325,7 +320,7 @@ Slur_score_state::fill (Grob *me) if (!is_broken_ && extremes_[d].slur_head_) musical_dy_ += d - * extremes_[d].slur_head_->maybe_pure_coordinate (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX); + * extremes_[d].slur_head_->relative_coordinate (common_[Y_AXIS], Y_AXIS); } edge_has_beams_ @@ -340,14 +335,7 @@ MAKE_SCHEME_CALLBACK (Slur, calc_control_points, 1) SCM Slur::calc_control_points (SCM smob) { - Spanner *me = unsmob_spanner (smob); - - if (!to_boolean (me->get_property ("cross-staff")) - && me->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface"))) - { - me->suicide (); - return SCM_EOL; - } + Spanner *me = unsmob (smob); Slur_score_state state; state.fill (me); @@ -388,9 +376,7 @@ Slur::calc_control_points (SCM smob) { Offset o = best->curve_.control_[i] - Offset (me->relative_coordinate (state.common_[X_AXIS], X_AXIS), - me->maybe_pure_coordinate (state.common_[Y_AXIS], Y_AXIS, - state.stub_, 0, INT_MAX)); - + me->relative_coordinate (state.common_[Y_AXIS], Y_AXIS)); controls = scm_cons (ly_offset2scm (o), controls); } @@ -477,12 +463,21 @@ Slur_score_state::get_y_attachment_range () const { if (extremes_[d].note_column_) { - end_ys[d] = dir_ - * max (max (dir_ * (base_attachments_[d][Y_AXIS] - + parameters_.region_size_ * dir_), - dir_ * (dir_ + extremes_[d].note_column_->maybe_pure_extent - (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_])), - dir_ * base_attachments_[-d][Y_AXIS]); + Interval nc_extent = extremes_[d].note_column_ + ->extent (common_[Y_AXIS], Y_AXIS); + if (nc_extent.is_empty ()) + slur_->warning ("slur trying to encompass an empty note column."); + else + end_ys[d] = dir_ + * max (max (dir_ * (base_attachments_[d][Y_AXIS] + + parameters_.region_size_ * dir_), + dir_ * (dir_ + nc_extent[dir_])), + dir_ * base_attachments_[-d][Y_AXIS]); + } + else if (extremes_[d].slur_head_) + { + // allow only minimal movement + end_ys[d] = base_attachments_[d][Y_AXIS] + 0.3 * dir_; } else end_ys[d] = base_attachments_[d][Y_AXIS] + parameters_.region_size_ * dir_; @@ -531,7 +526,7 @@ Slur_score_state::get_base_attachments () const || has_same_beam_)) y = extremes_[d].stem_extent_[Y_AXIS][dir_]; else if (head) - y = head->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_]; + y = head->extent (common_[Y_AXIS], Y_AXIS)[dir_]; y += dir_ * 0.5 * staff_space_; y = move_away_from_staffline (y, head); @@ -542,12 +537,22 @@ Slur_score_state::get_base_attachments () const : extremes_[d].bound_->extent (common_[X_AXIS], X_AXIS)) .linear_combination (CENTER); } + else if (head) + { + y = head->extent (common_[Y_AXIS], Y_AXIS) + .linear_combination (0.5*dir_); + + // Don't "move_away_from_staffline" because that makes it + // harder to recognize the specific attachment point + x = head->extent (common_[X_AXIS], X_AXIS)[-d]; + } + base_attachment[d] = Offset (x, y); } for (LEFT_and_RIGHT (d)) { - if (!extremes_[d].note_column_) + if (!extremes_[d].note_column_ && !extremes_[d].slur_head_) { Real x = 0; Real y = 0; @@ -563,7 +568,7 @@ Slur_score_state::get_base_attachments () const if (extremes_[-d].bound_ != col) { - y = maybe_pure_robust_relative_extent (col, common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)[dir_]; + y = robust_relative_extent (col, common_[Y_AXIS], Y_AXIS)[dir_]; y += dir_ * 0.5 * staff_space_; if (get_grob_direction (col) == dir_ @@ -609,8 +614,8 @@ Slur_score_state::move_away_from_staffline (Real y, return y; Real pos - = (y - staff_symbol->maybe_pure_coordinate (common_[Y_AXIS], - Y_AXIS, stub_, 0, INT_MAX)) + = (y - staff_symbol->relative_coordinate (common_[Y_AXIS], + Y_AXIS)) * 2.0 / staff_space_; if (fabs (pos - my_round (pos)) < 0.2 @@ -641,23 +646,24 @@ Slur_score_state::generate_avoid_offsets () const extract_grob_set (slur_, "encompass-objects", extra_encompasses); for (vsize i = 0; i < extra_encompasses.size (); i++) { - if (Slur::has_interface (extra_encompasses[i])) + if (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->maybe_pure_coordinate (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)); + small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS)); z[Y_AXIS] += dir_ * parameters_.free_slur_distance_; avoid.push_back (z); } - else if (extra_encompasses[i]->get_property ("avoid-slur") == ly_symbol2scm ("inside")) + else if (scm_is_eq (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->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX); + Interval ye = g->extent (common_[Y_AXIS], Y_AXIS); if (!xe.is_empty () && !ye.is_empty ()) @@ -734,7 +740,7 @@ Slur_score_state::enumerate_attachments (Drul_array end_ys) const } } - dz = os[RIGHT] - os[LEFT]; + dz = (os[RIGHT] - os[LEFT]).direction (); for (LEFT_and_RIGHT (d)) { if (extremes_[d].slur_head_ @@ -746,7 +752,7 @@ Slur_score_state::enumerate_attachments (Drul_array end_ys) const TODO: parameter */ os[d][X_AXIS] -= dir_ * extremes_[d].slur_head_x_extent_.length () - * sin (dz.arg ()) / 3; + * dz[Y_AXIS] / 3; } } @@ -769,13 +775,13 @@ Slur_score_state::get_extra_encompass_infos () const vector collision_infos; for (vsize i = encompasses.size (); i--;) { - if (Slur::has_interface (encompasses[i])) + if (has_interface (encompasses[i])) { Spanner *small_slur = dynamic_cast (encompasses[i]); Bezier b = Slur::get_curve (small_slur); Offset relative (small_slur->relative_coordinate (common_[X_AXIS], X_AXIS), - small_slur->maybe_pure_coordinate (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX)); + small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS)); for (int k = 0; k < 3; k++) { @@ -809,13 +815,13 @@ Slur_score_state::get_extra_encompass_infos () const { Grob *g = encompasses [i]; Interval xe = g->extent (common_[X_AXIS], X_AXIS); - Interval ye = g->maybe_pure_extent (common_[Y_AXIS], Y_AXIS, stub_, 0, INT_MAX); - if (Dots::has_interface (g)) + Interval ye = g->extent (common_[Y_AXIS], Y_AXIS); + if (has_interface (g)) ye.widen (0.2); Real xp = 0.0; Real penalty = parameters_.extra_object_collision_penalty_; - if (Accidental_interface::has_interface (g)) + if (has_interface (g)) { penalty = parameters_.accidental_collision_;