From 1c24c56886cd85f04283ac61e8a0deea172035ed Mon Sep 17 00:00:00 2001 From: Mike Solomon Date: Wed, 18 Jan 2012 08:22:31 +0100 Subject: [PATCH] Prevents DotColumns from triggering VerticalAlignment --- .../dot-column-vertical-positioning.ly | 13 ++++++ lily/dot-column.cc | 13 ++++-- lily/include/staff-symbol-referencer.hh | 8 ++++ lily/staff-symbol-referencer.cc | 43 ++++++++++++++++++- 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 input/regression/dot-column-vertical-positioning.ly diff --git a/input/regression/dot-column-vertical-positioning.ly b/input/regression/dot-column-vertical-positioning.ly new file mode 100644 index 0000000000..bf89013409 --- /dev/null +++ b/input/regression/dot-column-vertical-positioning.ly @@ -0,0 +1,13 @@ +\version "2.15.27" + +\header { + texidoc = "Dot columns should not trigger vertical spacing before +line breaking. If the regtest issues a programming_error saying that +vertical spacing has been called before line breaking, it has failed. +" +} + +\context Staff << + \new Voice { \voiceOne f''8.[ e''16] } + \new Voice { \voiceThree r8. a'16} +>> diff --git a/lily/dot-column.cc b/lily/dot-column.cc index 2292d2fe09..03f368d76b 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -143,7 +143,14 @@ Dot_column::calc_positioning_done (SCM smob) } } - vector_sort (dots, position_less); + /* + The use of pure_position_less and pure_get_rounded_position below + are due to the fact that this callback is called before line breaking + occurs. Because dots' actual Y posiitons may be linked to that of + beams (dots are attached to rests, which are shifted to avoid beams), + we instead must use their pure Y positions. + */ + vector_sort (dots, pure_position_less); for (vsize i = dots.size (); i--;) { if (!dots[i]->is_live ()) @@ -170,7 +177,7 @@ Dot_column::calc_positioning_done (SCM smob) dp.x_extent_ = note->extent (commonx, X_AXIS); } - int p = Staff_symbol_referencer::get_rounded_position (dp.dot_); + int p = Staff_symbol_referencer::pure_get_rounded_position (dp.dot_); /* icky, since this should go via a Staff_symbol_referencer offset callback but adding a dot overwrites Y-offset. */ @@ -191,7 +198,7 @@ Dot_column::calc_positioning_done (SCM smob) /* Junkme? */ - Staff_symbol_referencer::set_position (i->second.dot_, i->first); + Staff_symbol_referencer::pure_set_position (i->second.dot_, i->first); } me->translate_axis (cfg.x_offset () - me->relative_coordinate (commonx, X_AXIS), diff --git a/lily/include/staff-symbol-referencer.hh b/lily/include/staff-symbol-referencer.hh index a3dd915c9a..179bae828f 100644 --- a/lily/include/staff-symbol-referencer.hh +++ b/lily/include/staff-symbol-referencer.hh @@ -33,6 +33,7 @@ public: DECLARE_GROB_INTERFACE (); static bool ugly_hack (Grob *); static void set_position (Grob *, Real); + static void pure_set_position (Grob *, Real); DECLARE_SCHEME_CALLBACK (callback, (SCM element)); /** @@ -46,12 +47,19 @@ public: static bool on_staff_line (Grob *, int); static int line_count (Grob *); static Real get_position (Grob *); + static Real pure_get_position (Grob *); static Real staff_radius (Grob *); static int get_rounded_position (Grob *); + static int pure_get_rounded_position (Grob *); static Interval extent_in_staff (Grob *); + +private: + static void internal_set_position (Grob *, Real, bool); + static Real internal_get_position (Grob *, bool); }; int compare_position (Grob *const &, Grob *const &); bool position_less (Grob *const &, Grob *const &); +bool pure_position_less (Grob *const &, Grob *const &); #endif /* STAFF_SYMBOL_REFERENCER_HH */ diff --git a/lily/staff-symbol-referencer.cc b/lily/staff-symbol-referencer.cc index 1cda85f2a7..74c2c448c6 100644 --- a/lily/staff-symbol-referencer.cc +++ b/lily/staff-symbol-referencer.cc @@ -74,13 +74,27 @@ Staff_symbol_referencer::line_thickness (Grob *me) Real Staff_symbol_referencer::get_position (Grob *me) +{ + return internal_get_position (me, false); +} + +Real +Staff_symbol_referencer::pure_get_position (Grob *me) +{ + return internal_get_position (me, true); +} + +Real +Staff_symbol_referencer::internal_get_position (Grob *me, bool pure) { Real p = 0.0; Grob *st = get_staff_symbol (me); Grob *c = st ? me->common_refpoint (st, Y_AXIS) : 0; if (st && c) { - Real y = me->relative_coordinate (c, Y_AXIS) + Real y = (pure + ? me->pure_relative_y_coordinate (c, 0, INT_MAX) + : me->relative_coordinate (c, Y_AXIS)) - st->relative_coordinate (c, Y_AXIS); Real space = Staff_symbol::staff_space (st); p = (space == 0) ? 0 : 2.0 * y / space; @@ -113,6 +127,12 @@ Staff_symbol_referencer::get_rounded_position (Grob *me) return int (rint (get_position (me))); } +int +Staff_symbol_referencer::pure_get_rounded_position (Grob *me) +{ + return int (rint (pure_get_position (me))); +} + MAKE_SCHEME_CALLBACK (Staff_symbol_referencer, callback, 1); SCM Staff_symbol_referencer::callback (SCM smob) @@ -144,12 +164,24 @@ will be extracted from staff-position */ void Staff_symbol_referencer::set_position (Grob *me, Real p) +{ + internal_set_position (me, p, false); +} + +void +Staff_symbol_referencer::pure_set_position (Grob *me, Real p) +{ + internal_set_position (me, p, true); +} + +void +Staff_symbol_referencer::internal_set_position (Grob *me, Real p, bool pure) { Grob *st = get_staff_symbol (me); Real oldpos = 0.0; if (st && me->common_refpoint (st, Y_AXIS)) { - oldpos = get_position (me); + oldpos = pure ? pure_get_position (me) : get_position (me); } Real ss = Staff_symbol_referencer::staff_space (me); @@ -177,6 +209,13 @@ position_less (Grob *const &a, Grob *const &b) < Staff_symbol_referencer::get_position (b); } +bool +pure_position_less (Grob *const &a, Grob *const &b) +{ + return Staff_symbol_referencer::pure_get_position (a) + < Staff_symbol_referencer::pure_get_position (b); +} + ADD_INTERFACE (Staff_symbol_referencer, "An object whose Y@tie{}position is meant relative to a staff" " symbol. These usually" -- 2.39.5