From ac7aef03ab9d459a6ea6f03d9c127be150871dd4 Mon Sep 17 00:00:00 2001 From: Mike Solomon Date: Wed, 17 Aug 2011 10:18:00 +0200 Subject: [PATCH] Fixes issue 620. Also fixes issue 591 (which was previously fixed, but is re-fixed here). Does this by making the extents of an axis group maleable depending on the interfaces one chooses to use for bounds in the property bound-alignment-interfaces See generic_bound_extent in axis-group-interface.cc to see how this works. All other changes get the data pumped into this function. --- input/regression/spanner-alignment.ly | 33 +++++++++++++++++++++++ lily/axis-group-interface.cc | 38 ++++++++++++++++++++++++++- lily/hairpin.cc | 5 +++- lily/include/axis-group-interface.hh | 3 +++ lily/line-spanner.cc | 8 ++++-- lily/rhythmic-column-engraver.cc | 5 +++- lily/separation-item.cc | 14 +--------- scm/define-grob-properties.scm | 2 ++ scm/define-grobs.scm | 2 ++ 9 files changed, 92 insertions(+), 18 deletions(-) create mode 100755 input/regression/spanner-alignment.ly diff --git a/input/regression/spanner-alignment.ly b/input/regression/spanner-alignment.ly new file mode 100755 index 0000000000..6d5e22e40e --- /dev/null +++ b/input/regression/spanner-alignment.ly @@ -0,0 +1,33 @@ +\version "2.15.8" + +\header { + texidoc = "Spanners align to musical grobs in paper columns, +ignoring things like pedal marks. + +" +} + +\score { + << + \new PianoStaff << + \new Staff = "up" { + \clef treble + \repeat unfold 32 c'4 + } + \new Dynamics = "dynamics" { + \repeat unfold 2 { + s1\cresc s1\f s1\dim s1\p + } + } + \new Staff = "down" { + \clef bass + \repeat unfold 32 c4 + } + \new Dynamics= "pedal" { + \repeat unfold 2 { + s1\sustainOn s1\sustainOff + } + } + >> + >> +} diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 3c428bca22..ac778b0536 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -74,6 +74,13 @@ Axis_group_interface::has_axis (Grob *me, Axis a) Interval Axis_group_interface::relative_group_extent (vector const &elts, Grob *common, Axis a) +{ + return relative_maybe_bound_group_extent (elts, common, a, false); +} + +Interval +Axis_group_interface::relative_maybe_bound_group_extent (vector const &elts, + Grob *common, Axis a, bool bound) { Interval r; for (vsize i = 0; i < elts.size (); i++) @@ -81,7 +88,9 @@ Axis_group_interface::relative_group_extent (vector const &elts, Grob *se = elts[i]; if (!to_boolean (se->get_property ("cross-staff"))) { - Interval dims = se->extent (common, a); + Interval dims = (bound && has_interface (se) + ? generic_bound_extent (se, common, a) + : se->extent (common, a)); if (!dims.is_empty ()) r.unite (dims); } @@ -89,6 +98,32 @@ Axis_group_interface::relative_group_extent (vector const &elts, return r; } +Interval +Axis_group_interface::generic_bound_extent (Grob *me, Grob *common, Axis a) +{ + /* trigger the callback to do skyline-spacing on the children */ + if (a == Y_AXIS) + (void) me->get_property ("vertical-skylines"); + + extract_grob_set (me, "elements", elts); + vector new_elts; + + SCM interfaces = me->get_property ("bound-alignment-interfaces"); + + for (vsize i = 0; i < elts.size (); i++) + for (SCM l = interfaces; scm_is_pair (l); l = scm_cdr (l)) + if (elts[i]->internal_has_interface (scm_car (l))) + new_elts.push_back (elts[i]); + + if (!new_elts.size ()) + return robust_relative_extent (me, common, a); + + if (!common) + common = common_refpoint_of_array (new_elts, me, a); + + return relative_maybe_bound_group_extent (new_elts, common, a, true); +} + Interval Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end) { @@ -808,6 +843,7 @@ ADD_INTERFACE (Axis_group_interface, /* properties */ "adjacent-pure-heights " "axes " + "bound-alignment-interfaces " "default-staff-staff-spacing " "elements " "max-stretch " diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 3962b5e14d..31e7840a23 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -19,6 +19,7 @@ #include "hairpin.hh" +#include "axis-group-interface.hh" #include "dimensions.hh" #include "international.hh" #include "line-interface.hh" @@ -140,7 +141,9 @@ Hairpin::print (SCM smob) } } - Interval e = robust_relative_extent (b, common, X_AXIS); + Interval e = (Axis_group_interface::has_interface (b) + ? Axis_group_interface::generic_bound_extent (b, common, X_AXIS) + : robust_relative_extent (b, common, X_AXIS)); if (neighbor_found) { if (Hairpin::has_interface (adjacent)) diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index 6eb52c4df2..93d70ee54c 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -28,6 +28,7 @@ struct Axis_group_interface { static SCM generic_group_extent (Grob *me, Axis a); + static Interval generic_bound_extent (Grob *me, Grob *common, Axis a); static Interval pure_group_height (Grob *me, int start, int end); DECLARE_SCHEME_CALLBACK (width, (SCM smob)); DECLARE_SCHEME_CALLBACK (calc_x_common, (SCM smob)); @@ -46,6 +47,8 @@ struct Axis_group_interface DECLARE_SCHEME_CALLBACK (calc_pure_y_common, (SCM)); static Interval relative_group_extent (vector const &list, Grob *common, Axis); + static Interval relative_maybe_bound_group_extent (vector const &list, + Grob *common, Axis, bool); static Interval relative_pure_height (Grob *me, int start, int end); static Interval combine_pure_heights (Grob *me, SCM, int, int); static Interval sum_partial_pure_heights (Grob *me, int, int); diff --git a/lily/line-spanner.cc b/lily/line-spanner.cc index b2877211f1..962f772a50 100644 --- a/lily/line-spanner.cc +++ b/lily/line-spanner.cc @@ -25,6 +25,7 @@ #include "lily-proto.hh" #include "line-interface.hh" #include "output-def.hh" +#include "paper-column.hh" #include "pointer-group-interface.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" @@ -108,9 +109,12 @@ Line_spanner::calc_bound_info (SCM smob, Direction dir) ? columns[0] : columns.back (); } + Interval extent = (Paper_column::has_interface (bound_grob) + ? Axis_group_interface::generic_bound_extent (bound_grob, commonx, X_AXIS) + : robust_relative_extent (bound_grob, commonx, X_AXIS)); + details = scm_acons (ly_symbol2scm ("X"), - scm_from_double (robust_relative_extent (bound_grob, commonx, X_AXIS) - .linear_combination (attach)), + scm_from_double (extent.linear_combination (attach)), details); } diff --git a/lily/rhythmic-column-engraver.cc b/lily/rhythmic-column-engraver.cc index d02a985cf2..f29ac4bfe8 100644 --- a/lily/rhythmic-column-engraver.cc +++ b/lily/rhythmic-column-engraver.cc @@ -102,7 +102,10 @@ Rhythmic_column_engraver::process_acknowledged () } if (arpeggio_) - note_column_->set_object ("arpeggio", arpeggio_->self_scm ()); + { + Pointer_group_interface::add_grob (note_column_, ly_symbol2scm ("elements"), arpeggio_); + note_column_->set_object ("arpeggio", arpeggio_->self_scm ()); + } } } diff --git a/lily/separation-item.cc b/lily/separation-item.cc index fc22dd50f2..ac14f7cf85 100644 --- a/lily/separation-item.cc +++ b/lily/separation-item.cc @@ -113,19 +113,7 @@ Separation_item::boxes (Grob *me, Grob *left) if (left) elts = Accidental_placement::get_relevant_accidentals (read_only_elts, left); else - { - elts = read_only_elts; - - /* This is a special-case for NoteColumn: we want to include arpeggio in its - skyline (so spacing takes it into account) but we don't want to include it - in the NoteColumn's extent because some spanners (eg. Hairpin) bound themselves - on the NoteColumn and we don't want them to include arpeggios in their bounds. - */ - if (Grob *a = Note_column::arpeggio (me)) - { - elts.push_back (a); - } - } + elts = read_only_elts; Grob *ycommon = common_refpoint_of_array (elts, me, Y_AXIS); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 1b318deaf2..283db6faec 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -994,6 +994,8 @@ function is to protect objects from being garbage collected.") (bars ,ly:grob-array? "An array of bar line pointers.") (beam ,ly:grob? "A pointer to the beam, if applicable.") + (bound-alignment-interfaces ,list "Interfaces to be used +for positioning elements that align with a column.") (bounded-by-me ,ly:grob-array? "An array of spanners that have this column as start/begin point. Only columns that have grobs or act as bounds are spaced.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index ff792baedb..bfe0323b8f 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1414,6 +1414,7 @@ (NoteColumn . ( (axes . (,X ,Y)) + (bound-alignment-interfaces . (rhythmic-head-interface stem-interface)) (horizontal-skylines . ,ly:separation-item::calc-skylines) (skyline-vertical-padding . 0.15) (X-extent . ,ly:axis-group-interface::width) @@ -1518,6 +1519,7 @@ (allow-loose-spacing . #t) (axes . (,X)) (before-line-breaking . ,ly:paper-column::before-line-breaking) + (bound-alignment-interfaces . (note-column-interface)) (horizontal-skylines . ,ly:separation-item::calc-skylines) (keep-inside-line . #t) ;; (stencil . ,ly:paper-column::print) -- 2.39.5