--- /dev/null
+\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
+ }
+ }
+ >>
+ >>
+}
Interval
Axis_group_interface::relative_group_extent (vector<Grob *> 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<Grob *> const &elts,
+ Grob *common, Axis a, bool bound)
{
Interval r;
for (vsize i = 0; i < elts.size (); i++)
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);
}
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<Grob *> 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)
{
/* properties */
"adjacent-pure-heights "
"axes "
+ "bound-alignment-interfaces "
"default-staff-staff-spacing "
"elements "
"max-stretch "
#include "hairpin.hh"
+#include "axis-group-interface.hh"
#include "dimensions.hh"
#include "international.hh"
#include "line-interface.hh"
}
}
- 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))
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));
DECLARE_SCHEME_CALLBACK (calc_pure_y_common, (SCM));
static Interval relative_group_extent (vector<Grob *> const &list,
Grob *common, Axis);
+ static Interval relative_maybe_bound_group_extent (vector<Grob *> 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);
#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"
? 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);
}
}
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 ());
+ }
}
}
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);
(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.")
(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)
(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)