+++ /dev/null
-\version "2.17.0"
-
-\header {
- texidoc = "Cross-staff slurs are accounted for in vertical spacing.
-"
-}
-
-%#(ly:set-option 'debug-skylines #t)
-
-\new PianoStaff <<
- \new Staff = "up" {
- <e' c'>8
- \change Staff = "down"
- \slurDown
- g,,8 ( fis g
- \change Staff = "up"
- <g'' c''>8 )
- \change Staff = "down"
- e8 dis e
- \change Staff = "up"
- \break
- a'8 a'8 a'8^\markup \column { "f" "o" "o" } a'8 a'8 a'8 a'8 a'8
- }
- \new Staff = "down" {
- \clef bass
- % keep staff alive
- s1 s1
- }
->>
-
-\new PianoStaff <<
- \new Staff = "up" {
- <e' c'>8
- \change Staff = "down"
- \slurDown
- g,,8 (
- \change Staff = "up"
- fis'' g <g c''>8 )
- \change Staff = "down"
- e8 dis e
- \change Staff = "up"
- \break
- a'8 a'8 a'8^\markup \column { "f" "o" "o" } a'8 a'8 a'8 a'8 a'8
- }
- \new Staff = "down" {
- \clef bass
- % keep staff alive
- s1 s1
- }
->>
-
-\new PianoStaff <<
- \new Staff = "up" {
- R1
- <e' c'>8
- \change Staff = "down"
- \slurUp
- g,,8 (
- \change Staff = "up"
- fis'' g \override Stem #'direction = #UP
- <g'' c''>8 )
- \change Staff = "down"
- e8 dis e
- \change Staff = "up"
- }
- \new Staff = "down" {
- \clef bass
- % keep staff alive
- a8 a8 a8_\markup \column { "f" "o" "o" }
- a8 a8 a8 a8 a8
- \break s1
- }
->>
if (!pure)
{
- Skyline_pair *skys = a == Y_AXIS
- ? Skyline_pair::unsmob (g->get_property ("vertical-skylines"))
- : Skyline_pair::unsmob (g->get_property ("horizontal-skylines"));
-
+ Skyline_pair *skys = Skyline_pair::unsmob (g->get_property (a == Y_AXIS
+ ? "vertical-skylines"
+ : "horizontal-skylines"));
if (skys)
skylines = *skys;
return priority_1 < priority_2;
}
+static void
+add_interior_skylines (Grob *me, Grob *x_common, Grob *y_common, vector<Skyline_pair> *skylines)
+{
+ if (Grob_array *elements = unsmob_grob_array (me->get_object ("elements")))
+ {
+ for (vsize i = 0; i < elements->size (); i++)
+ add_interior_skylines (elements->grob (i), x_common, y_common, skylines);
+ }
+ else if (!scm_is_number (me->get_property ("outside-staff-priority"))
+ && !to_boolean (me->get_property ("cross-staff")))
+ {
+ Skyline_pair *maybe_pair = Skyline_pair::unsmob (me->get_property ("vertical-skylines"));
+ if (!maybe_pair)
+ return;
+ if (maybe_pair->is_empty ())
+ return;
+ skylines->push_back (Skyline_pair (*maybe_pair));
+ skylines->back ().shift (me->relative_coordinate (x_common, X_AXIS));
+ skylines->back ().raise (me->relative_coordinate (y_common, Y_AXIS));
+ }
+}
+
// Raises the grob elt (whose skylines are given by h_skyline
// and v_skyline) so that it doesn't intersect with staff_skyline,
// or with anything in other_h_skylines and other_v_skylines.
return outside_staff_ancestor (parent);
}
-void
-Axis_group_interface::add_interior_skylines
-(Grob *me, Grob *x_common, Grob *y_common, vector<Skyline_pair> *skylines, bool pure)
-{
- if (Grob_array *elements = unsmob_grob_array (me->get_object ("elements")))
- {
- for (vsize i = 0; i < elements->size (); i++)
- add_interior_skylines (elements->grob (i), x_common, y_common, skylines, pure);
- }
- else if (pure ||
- (!scm_is_number (me->get_property ("outside-staff-priority"))
- && !to_boolean (me->get_property ("cross-staff"))))
- {
- Skyline_pair *maybe_pair = Skyline_pair::unsmob (me->get_property ("vertical-skylines"));
- if (!maybe_pair)
- return;
- if (maybe_pair->is_empty ())
- return;
- skylines->push_back (Skyline_pair (*maybe_pair));
- skylines->back ().shift (me->relative_coordinate (x_common, X_AXIS));
- skylines->back ().raise (me->maybe_pure_coordinate (y_common, Y_AXIS, pure, 0, INT_MAX));
- }
-}
-
// It is tricky to correctly handle skyline placement of cross-staff grobs.
// For example, cross-staff beams cannot be formatted until the distance between
// staves is known and therefore any grobs that depend on the beam cannot be placed
{
Grob *elt = elements[i];
Grob *ancestor = outside_staff_ancestor (elt);
- if (!(to_boolean (elt->get_property ("cross-staff")) || ancestor)
- || elt->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")))
- add_interior_skylines (elt, x_common, y_common, &inside_staff_skylines, elt->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")));
+ if (!(to_boolean (elt->get_property ("cross-staff")) || ancestor))
+ add_interior_skylines (elt, x_common, y_common, &inside_staff_skylines);
if (ancestor)
riders.insert (pair<Grob *, Grob *> (ancestor, elt));
}
void
Figured_bass_position_engraver::acknowledge_slur (Grob_info info)
{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")))
- span_support_.push_back (info.grob ());
+ span_support_.push_back (info.grob ());
}
void
return common;
}
-Interval
-maybe_pure_robust_relative_extent (Grob *me, Grob *refp, Axis a, bool pure, int start, int end)
-{
- if (pure && a != Y_AXIS)
- programming_error ("tried to get pure X-offset");
- return (pure && a == Y_AXIS) ? pure_robust_relative_extent (me, refp, start, end)
- : robust_relative_extent (me, refp, a);
-}
-
-Interval
-pure_robust_relative_extent (Grob *me, Grob *refpoint, int start, int end)
-{
- Interval ext = me->pure_height (refpoint, start, end);
- if (ext.is_empty ())
- ext.add_point (me->pure_relative_y_coordinate (refpoint, start, end));
-
- return ext;
-}
-
Interval
robust_relative_extent (Grob *me, Grob *refpoint, Axis a)
{
class Axis_group_interface
{
static Real default_outside_staff_padding_;
- public :
-
+ public
+:
static SCM generic_group_extent (Grob *me, Axis a);
static Real get_default_outside_staff_padding ();
static Interval generic_bound_extent (Grob *me, Grob *common, Axis a);
static Grob *outside_staff_ancestor (Grob *me);
static Skyline_pair skyline_spacing (Grob *me, vector<Grob *> elements);
- static void add_interior_skylines (Grob *me, Grob *x_common, Grob *y_common, vector<Skyline_pair> *skylines, bool pure = false);
static void add_element (Grob *me, Grob *);
static void set_axes (Grob *, Axis, Axis);
static bool has_axis (Grob *, Axis);
System *get_root_system (Grob *me);
/* extents */
-Interval maybe_pure_robust_relative_extent (Grob *, Grob *, Axis, bool, int, int);
-Interval pure_robust_relative_extent (Grob *, Grob *, int, int);
Interval robust_relative_extent (Grob *, Grob *, Axis);
/* offset/extent callbacks. */
{
Spanner *slur_;
Grob *common_[NO_AXES];
- bool stub_;
bool valid_;
bool edge_has_beams_;
bool is_broken_;
#include "std-vector.hh"
#include "grob-interface.hh"
-struct Slur_info
-{
- Slur_info (Grob *slur);
- Grob *slur_;
- vector<Grob *> stubs_;
-};
-
class Slur
{
public:
static void add_column (Grob *me, Grob *col);
static void add_extra_encompass (Grob *me, Grob *col);
- static void main_to_stub (Grob *main, Grob *stub);
static void replace_breakable_encompass_objects (Grob *me);
- static void auxiliary_acknowledge_extra_object (Grob_info const &, vector<Slur_info> &, vector<Slur_info> &);
+ static void auxiliary_acknowledge_extra_object (Grob_info const &, vector<Grob *> &, vector<Grob *> &);
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
DECLARE_SCHEME_CALLBACK (height, (SCM));
- DECLARE_SCHEME_CALLBACK (extremal_stub_vertical_skylines, (SCM));
DECLARE_SCHEME_CALLBACK (vertical_skylines, (SCM));
DECLARE_SCHEME_CALLBACK (outside_slur_callback, (SCM, SCM));
DECLARE_SCHEME_CALLBACK (pure_outside_slur_callback, (SCM, SCM, SCM, SCM));
}
void
-Melody_engraver::acknowledge_slur (Grob_info info)
+Melody_engraver::acknowledge_slur (Grob_info /* info */)
{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")))
- melody_item_ = 0;
+ melody_item_ = 0;
}
void
#include "translator.icc"
-#include <algorithm>
-
/*
NOTE NOTE NOTE
(on principle, engravers don't use inheritance for code sharing)
- For info on SlurStubs, check out slur-engraver.cc.
-
*/
/*
{
vector<Stream_event *> start_events_;
vector<Stream_event *> stop_events_;
- vector<Slur_info> slur_infos_;
- vector<Slur_info> end_slur_infos_;
+ vector<Grob *> slurs_;
+ vector<Grob *> end_slurs_;
vector<Grob_info> objects_to_acknowledge_;
protected:
Phrasing_slur_engraver::acknowledge_note_column (Grob_info info)
{
Grob *e = info.grob ();
- for (vsize i = slur_infos_.size (); i--;)
- {
- Slur::add_column (slur_infos_[i].slur_, e);
- Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
- slur_infos_[i].stubs_.push_back (stub);
- }
- for (vsize i = end_slur_infos_.size (); i--;)
- {
- Slur::add_column (end_slur_infos_[i].slur_, e);
- Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
- end_slur_infos_[i].stubs_.push_back (stub);
- }
+ for (vsize i = slurs_.size (); i--;)
+ Slur::add_column (slurs_[i], e);
+ for (vsize i = end_slurs_.size (); i--;)
+ Slur::add_column (end_slurs_[i], e);
}
void
Phrasing_slur_engraver::acknowledge_script (Grob_info info)
{
if (!info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface")))
-
acknowledge_extra_object (info);
}
void
Phrasing_slur_engraver::acknowledge_slur (Grob_info info)
{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")))
- acknowledge_extra_object (info);
+ acknowledge_extra_object (info);
}
void
Phrasing_slur_engraver::finalize ()
{
- for (vsize i = 0; i < slur_infos_.size (); i++)
+ for (vsize i = 0; i < slurs_.size (); i++)
{
- slur_infos_[i].slur_->warning (_ ("unterminated phrasing slur"));
- slur_infos_[i].slur_->suicide ();
- for (vsize j = 0; j < slur_infos_[i].stubs_.size (); j++)
- slur_infos_[i].stubs_[j]->suicide ();
+ slurs_[i]->warning (_ ("unterminated phrasing slur"));
+ slurs_[i]->suicide ();
}
- slur_infos_.clear ();
+ slurs_.clear ();
}
void
// Find the slurs that are ended with this event (by checking the spanner-id)
bool ended = false;
- for (vsize j = slur_infos_.size (); j--;)
+ for (vsize j = slurs_.size (); j--;)
{
- if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("spanner-id"), ""))
+ if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
{
ended = true;
- end_slur_infos_.push_back (slur_infos_[j].slur_);
- slur_infos_.erase (slur_infos_.begin () + j);
+ end_slurs_.push_back (slurs_[j]);
+ slurs_.erase (slurs_.begin () + j);
}
}
if (ended)
ev->origin ()->warning (_ ("cannot end phrasing slur"));
}
- vsize old_slurs = slur_infos_.size ();
+ vsize old_slurs = slurs_.size ();
for (vsize i = start_events_.size (); i--;)
{
Stream_event *ev = start_events_[i];
Direction updown = to_dir (ev->get_property ("direction"));
bool completed;
- for (vsize j = slur_infos_.size (); !(completed = (j-- == 0));)
+ for (vsize j = slurs_.size (); !(completed = (j-- == 0));)
{
// Check if we already have a slur with the same spanner-id.
- if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("spanner-id"), ""))
+ if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
{
if (j < old_slurs)
{
if (!updown)
break;
- Stream_event *c = unsmob_stream_event (slur_infos_[j].slur_->get_property ("cause"));
+ Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("cause"));
if (!c)
{
- slur_infos_[j].slur_->programming_error ("phrasing slur without a cause");
+ slurs_[j]->programming_error ("phrasing slur without a cause");
continue;
}
if (!slur_dir)
{
- slur_infos_[j].slur_->suicide ();
- for (vsize k = 0; k < slur_infos_[i].stubs_.size (); k++)
- slur_infos_[j].stubs_[k]->suicide ();
- slur_infos_.erase (slur_infos_.begin () + j);
+ slurs_[j]->suicide ();
+ slurs_.erase (slurs_.begin () + j);
continue;
}
slur->set_property ("spanner-id", ly_string2scm (id));
if (updown)
set_grob_direction (slur, updown);
- slur_infos_.push_back (slur);
+ slurs_.push_back (slur);
}
}
}
{
if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
{
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
- Slur::add_extra_encompass (end_slur_infos_[i].slur_, g);
+ for (vsize i = 0; i < end_slurs_.size (); i++)
+ Slur::add_extra_encompass (end_slurs_[i], g);
if (!start_events_.size ())
- for (vsize i = 0; i < slur_infos_.size (); i++)
- Slur::add_extra_encompass (slur_infos_[i].slur_, g);
+ for (vsize i = 0; i < slurs_.size (); i++)
+ Slur::add_extra_encompass (slurs_[i], g);
}
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
+ for (vsize i = 0; i < end_slurs_.size (); i++)
{
- Spanner *s = dynamic_cast<Spanner *> (end_slur_infos_[i].slur_);
+ Spanner *s = dynamic_cast<Spanner *> (end_slurs_[i]);
if (!s->get_bound (RIGHT))
s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")));
announce_end_grob (s, SCM_EOL);
}
for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
- Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slur_infos_, end_slur_infos_);
-
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
- {
- // There are likely SlurStubs we don't need. Get rid of them.
- vector<Grob *> vags;
- vector<Grob *> stubs;
- for (vsize j = 0; j < end_slur_infos_[i].stubs_.size (); j++)
- {
- Grob *stub = end_slur_infos_[i].stubs_[j];
- Grob *vag = Grob::get_vertical_axis_group (stub);
- if (vag)
- {
- vector<Grob *>::const_iterator it =
- find (vags.begin (), vags.end (), vag);
- if (it != vags.end ())
- stub->suicide ();
- else
- {
- vags.push_back (vag);
- stubs.push_back (stub);
- }
- }
- else
- {
- end_slur_infos_[i].slur_->programming_error ("Cannot find vertical axis group for NoteColumn.");
- stub->suicide ();
- }
- }
- for (vsize j = 0; j < stubs.size (); j++)
- Slur::main_to_stub (end_slur_infos_[i].slur_, stubs[j]);
- }
+ Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_);
objects_to_acknowledge_.clear ();
- end_slur_infos_.clear ();
+ end_slurs_.clear ();
start_events_.clear ();
stop_events_.clear ();
}
Pointer_group_interface::add_grob (me, ly_symbol2scm ("scripts"), script);
}
-int
-pushed_by_slur (Grob *g)
-{
- return g->get_property ("avoid-slur") == ly_symbol2scm ("outside")
- || g->get_property ("avoid-slur") == ly_symbol2scm ("around");
-}
-
LY_DEFINE (ly_grob_script_priority_less, "ly:grob-script-priority-less",
2, 0, 0, (SCM a, SCM b),
"Compare two grobs by script priority. For internal use.")
Grob *i1 = unsmob_grob (a);
Grob *i2 = unsmob_grob (b);
- /*
- * avoid-staff of slur trumps script priority. If one grob is
- * supposed to be printed outside a slur and another grob inside,
- * we place the inside grob below the outside even if the inside
- * grob has a higher script-priority.
- */
- if (unsmob_grob (i1->get_object ("slur"))
- && unsmob_grob (i2->get_object ("slur")))
- {
- int push1 = pushed_by_slur (i1);
- int push2 = pushed_by_slur (i2);
- if (push1 != push2)
- return push1 < push2 ? SCM_BOOL_T : SCM_BOOL_F;
- }
-
SCM p1 = i1->get_property ("script-priority");
SCM p2 = i2->get_property ("script-priority");
Grob *staff = state.extremes_[LEFT].staff_;
- Real p = 2 * (y - staff->maybe_pure_coordinate (state.common_[Y_AXIS], Y_AXIS, state.stub_, 0, INT_MAX))
+ Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS))
/ state.staff_space_;
Real const round = my_round (p);
#include "translator.icc"
-#include <algorithm>
-
/*
NOTE NOTE NOTE
least, it is for phrasing slurs: a note can be both beginning and
ending of a phrase.
*/
-
-Slur_info::Slur_info (Grob *slur)
-{
- slur_ = slur;
-}
-
class Slur_engraver : public Engraver
{
vector<Stream_event *> start_events_;
vector<Stream_event *> stop_events_;
- vector<Slur_info> slur_infos_;
- vector<Slur_info> end_slur_infos_;
+ vector<Grob *> slurs_;
+ vector<Grob *> end_slurs_;
vector<Grob_info> objects_to_acknowledge_;
void set_melisma (bool);
void
Slur_engraver::acknowledge_note_column (Grob_info info)
{
- /*
- * For every active slur, we create a slur stub.
- * As we do not yet know what vertical axis groups note columns belong to,
- * we create a stub for each note and then suicide duplicate stubs on
- * axis groups.
- * These slurs should be used ONLY to approximate cross-staff slurs
- * in vertical skylines.
- */
-
Grob *e = info.grob ();
- for (vsize i = slur_infos_.size (); i--;)
- {
- Slur::add_column (slur_infos_[i].slur_, e);
- Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
- slur_infos_[i].stubs_.push_back (stub);
- }
- for (vsize i = end_slur_infos_.size (); i--;)
- {
- Slur::add_column (end_slur_infos_[i].slur_, e);
- Grob *stub = make_spanner ("SlurStub", info.grob ()->self_scm ());
- end_slur_infos_[i].stubs_.push_back (stub);
- }
+ for (vsize i = slurs_.size (); i--;)
+ Slur::add_column (slurs_[i], e);
+ for (vsize i = end_slurs_.size (); i--;)
+ Slur::add_column (end_slurs_[i], e);
}
void
void
Slur_engraver::finalize ()
{
- for (vsize i = 0; i < slur_infos_.size (); i++)
+ for (vsize i = 0; i < slurs_.size (); i++)
{
- slur_infos_[i].slur_->warning (_ ("unterminated slur"));
- slur_infos_[i].slur_->suicide ();
- for (vsize j = 0; j < slur_infos_[i].stubs_.size (); j++)
- slur_infos_[i].stubs_[j]->suicide ();
+ slurs_[i]->warning (_ ("unterminated slur"));
+ slurs_[i]->suicide ();
}
-
- slur_infos_.clear ();
+ slurs_.clear ();
}
void
// Find the slurs that are ended with this event (by checking the spanner-id)
bool ended = false;
- for (vsize j = slur_infos_.size (); j--;)
+ for (vsize j = slurs_.size (); j--;)
{
- if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("spanner-id"), ""))
+ if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
{
ended = true;
- end_slur_infos_.push_back (slur_infos_[j]);
- slur_infos_.erase (slur_infos_.begin () + j);
+ end_slurs_.push_back (slurs_[j]);
+ slurs_.erase (slurs_.begin () + j);
}
}
if (ended)
ev->origin ()->warning (_ ("cannot end slur"));
}
- vsize old_slurs = slur_infos_.size ();
+ vsize old_slurs = slurs_.size ();
for (vsize i = start_events_.size (); i--;)
{
Stream_event *ev = start_events_[i];
Direction updown = to_dir (ev->get_property ("direction"));
bool completed;
- for (vsize j = slur_infos_.size (); !(completed = (j-- == 0));)
+ for (vsize j = slurs_.size (); !(completed = (j-- == 0));)
{
// Check if we already have a slur with the same spanner-id.
- if (id == robust_scm2string (slur_infos_[j].slur_->get_property ("spanner-id"), ""))
+ if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
{
if (j < old_slurs)
{
if (!updown)
break;
- Stream_event *c = unsmob_stream_event (slur_infos_[j].slur_->get_property ("cause"));
+ Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("cause"));
if (!c)
{
- slur_infos_[j].slur_->programming_error ("slur without a cause");
+ slurs_[j]->programming_error ("slur without a cause");
continue;
}
if (!slur_dir)
{
- slur_infos_[j].slur_->suicide ();
- for (vsize k = 0; k < slur_infos_[j].stubs_.size (); k++)
- slur_infos_[j].stubs_[k]->suicide ();
- slur_infos_.erase (slur_infos_.begin () + j);
+ slurs_[j]->suicide ();
+ slurs_.erase (slurs_.begin () + j);
continue;
}
slur->set_property ("spanner-id", ly_string2scm (id));
if (updown)
set_grob_direction (slur, updown);
- slur_infos_.push_back (Slur_info (slur));
+ slurs_.push_back (slur);
if (to_boolean (get_property ("doubleSlurs")))
{
slur = make_spanner ("Slur", ev->self_scm ());
slur->set_property ("spanner-id", ly_string2scm (id));
set_grob_direction (slur, UP);
- slur_infos_.push_back (Slur_info (slur));
+ slurs_.push_back (slur);
}
}
}
- set_melisma (slur_infos_.size ());
+ set_melisma (slurs_.size ());
}
void
{
if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
{
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
- Slur::add_extra_encompass (end_slur_infos_[i].slur_, g);
+ for (vsize i = 0; i < end_slurs_.size (); i++)
+ Slur::add_extra_encompass (end_slurs_[i], g);
if (!start_events_.size ())
- for (vsize i = 0; i < slur_infos_.size (); i++)
- Slur::add_extra_encompass (slur_infos_[i].slur_, g);
+ for (vsize i = 0; i < slurs_.size (); i++)
+ Slur::add_extra_encompass (slurs_[i], g);
}
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
+ for (vsize i = 0; i < end_slurs_.size (); i++)
{
- Spanner *s = dynamic_cast<Spanner *> (end_slur_infos_[i].slur_);
+ Spanner *s = dynamic_cast<Spanner *> (end_slurs_[i]);
if (!s->get_bound (RIGHT))
s->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")));
announce_end_grob (s, SCM_EOL);
}
for (vsize i = 0; i < objects_to_acknowledge_.size (); i++)
- Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slur_infos_, end_slur_infos_);
-
- for (vsize i = 0; i < end_slur_infos_.size (); i++)
- {
- // There are likely SlurStubs we don't need. Get rid of them
- // and only keep one per VerticalAxisGroup.
- vector<Grob *> vags;
- vector<Grob *> stubs;
- for (vsize j = 0; j < end_slur_infos_[i].stubs_.size (); j++)
- {
- Grob *stub = end_slur_infos_[i].stubs_[j];
- Grob *vag = Grob::get_vertical_axis_group (stub);
- if (vag)
- {
- vector<Grob *>::const_iterator it =
- find (vags.begin (), vags.end (), vag);
- if (it != vags.end ())
- stub->suicide ();
- else
- {
- vags.push_back (vag);
- stubs.push_back (stub);
- }
- }
- else
- {
- end_slur_infos_[i].slur_->programming_error ("Cannot find vertical axis group for NoteColumn.");
- stub->suicide ();
- }
- }
- for (vsize j = 0; j < stubs.size (); j++)
- Slur::main_to_stub (end_slur_infos_[i].slur_, stubs[j]);
- }
+ Slur::auxiliary_acknowledge_extra_object (objects_to_acknowledge_[i], slurs_, end_slurs_);
objects_to_acknowledge_.clear ();
- end_slur_infos_.clear ();
+ end_slurs_.clear ();
start_events_.clear ();
stop_events_.clear ();
}
{
musical_dy_ = 0.0;
valid_ = false;
- stub_ = false;
edge_has_beams_ = false;
has_same_beam_ = false;
is_broken_ = false;
{
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);
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);
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 ())
{
/*
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;
}
Slur_score_state::fill (Grob *me)
{
slur_ = dynamic_cast<Spanner *> (me);
- stub_ = slur_->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface"));
-
columns_
= internal_extract_grob_array (me, ly_symbol2scm ("note-columns"));
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_
{
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;
- }
-
Slur_score_state state;
state.fill (me);
{
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);
}
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_ * (dir_ + extremes_[d].note_column_->extent (common_[Y_AXIS], Y_AXIS)[dir_])),
dir_ * base_attachments_[-d][Y_AXIS]);
}
else
|| 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);
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_
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
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);
{
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 ())
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++)
{
{
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);
+ Interval ye = g->extent (common_[Y_AXIS], Y_AXIS);
if (Dots::has_interface (g))
ye.widen (0.2);
Slur::print (SCM smob)
{
Grob *me = unsmob_grob (smob);
-
extract_grob_set (me, "note-columns", encompasses);
if (encompasses.empty ())
{
Pointer_group_interface::add_grob (me, ly_symbol2scm ("encompass-objects"), n);
}
-void
-Slur::main_to_stub (Grob *main, Grob *stub)
-{
- extract_grob_set (main, "note-columns", nc);
- for (vsize i = 0; i < nc.size (); i++)
- add_column (stub, nc[i]);
-
- extract_grob_set (main, "encompass-objects", eo);
- for (vsize i = 0; i < eo.size (); i++)
- add_extra_encompass (stub, eo[i]);
-
- stub->set_object ("surrogate", main->self_scm ());
-
- dynamic_cast<Spanner *> (stub)->set_bound
- (LEFT, dynamic_cast<Spanner *> (main)->get_bound (LEFT));
- dynamic_cast<Spanner *> (stub)->set_bound
- (RIGHT, dynamic_cast<Spanner *> (main)->get_bound (RIGHT));
-}
-
MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, pure_outside_slur_callback, 4, 1, "");
SCM
Slur::pure_outside_slur_callback (SCM grob, SCM start_scm, SCM end_scm, SCM offset_scm)
return Skyline_pair (boxes, X_AXIS).smobbed_copy ();
}
-/*
- * USE ME ONLY FOR CROSS STAFF SLURS!
- * We only want to keep the topmost skyline of the topmost axis group(s)
- * and the bottommost skyline of the bottommost axis group(s). Otherwise,
- * the VerticalAxisGroups will be spaced very far apart to accommodate the
- * slur, which we don't want, as it is cross staff.
- *
- * TODO: Currently, the code below keeps the topmost and bottommost axis
- * groups and gets rid of the rest. This should be more nuanced for
- * cases like ossias where the topmost staff changes over the course of
- * the slur. Ditto for the bottommost staff.
- */
-
-MAKE_SCHEME_CALLBACK (Slur, extremal_stub_vertical_skylines, 1);
-SCM
-Slur::extremal_stub_vertical_skylines (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- Grob *my_vag = Grob::get_vertical_axis_group (me);
- extract_grob_set (me, "note-columns", ro_note_columns);
- vector<Grob *> note_columns (ro_note_columns);
- vector_sort (note_columns, Grob::vertical_less);
- bool highest = my_vag == Grob::get_vertical_axis_group (note_columns[0]);
- bool lowest = my_vag == Grob::get_vertical_axis_group (note_columns.back ());
- if (!highest && !lowest)
- return Skyline_pair ().smobbed_copy ();
-
- Skyline_pair sky = *Skyline_pair::unsmob (vertical_skylines (smob));
-
- if (highest)
- sky[DOWN] = Skyline (DOWN);
- else
- sky[UP] = Skyline (UP);
-
- return sky.smobbed_copy ();
-}
-
/*
* Used by Slur_engraver:: and Phrasing_slur_engraver::
*/
void
Slur::auxiliary_acknowledge_extra_object (Grob_info const &info,
- vector<Slur_info> &slur_infos,
- vector<Slur_info> &end_slur_infos)
+ vector<Grob *> &slurs,
+ vector<Grob *> &end_slurs)
{
- if (slur_infos.empty () && end_slur_infos.empty ())
+ if (slurs.empty () && end_slurs.empty ())
return;
Grob *e = info.grob ();
SCM avoid = e->get_property ("avoid-slur");
Grob *slur;
- if (end_slur_infos.size () && !slur_infos.size ())
- slur = end_slur_infos[0].slur_;
+ if (end_slurs.size () && !slurs.size ())
+ slur = end_slurs[0];
else
- slur = slur_infos[0].slur_;
+ slur = slurs[0];
if (Tie::has_interface (e)
|| avoid == ly_symbol2scm ("inside"))
{
- for (vsize i = slur_infos.size (); i--;)
- add_extra_encompass (slur_infos[i].slur_, e);
- for (vsize i = end_slur_infos.size (); i--;)
- add_extra_encompass (end_slur_infos[i].slur_, e);
+ for (vsize i = slurs.size (); i--;)
+ add_extra_encompass (slurs[i], e);
+ for (vsize i = end_slurs.size (); i--;)
+ add_extra_encompass (end_slurs[i], e);
if (slur)
e->set_object ("slur", slur->self_scm ());
}
void
Tab_tie_follow_engraver::acknowledge_slur (Grob_info info)
{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("cross-staff-stub-interface")))
- slurs_.push_back (info.spanner ());
+ slurs_.push_back (info.spanner ());
}
void
%% slurs
% directions
-slurUp = { \override Slur #'direction = #UP \override SlurStub #'direction = #UP }
-slurDown = { \override Slur #'direction = #DOWN \override SlurStub #'direction = #DOWN }
-slurNeutral = { \revert Slur #'direction \revert SlurStub #'direction }
+slurUp = \override Slur #'direction = #UP
+slurDown = \override Slur #'direction = #DOWN
+slurNeutral = \revert Slur #'direction
% dash-patterns (make-simple-dash-definition defined at top of file)
slurDashPattern =
"A doit or drop."
'(thickness delta-position))
-(ly:add-interface
- 'cross-staff-stub-interface
- "Used to approximate vertical skylines in cross-staff grobs."
- '(surrogate))
-
(ly:add-interface
'dynamic-interface
"Any kind of loudness sign."
(staff-symbol ,ly:grob? "The staff symbol grob that we are in.")
(stem ,ly:grob? "A pointer to a @code{Stem} object.")
(stems ,ly:grob-array? "An array of stem objects.")
- (surrogate ,ly:grob? "The grob that a cross-staff stub is shadowing.")
(tie ,ly:grob? "A pointer to a @code{Tie} object.")
(ties ,ly:grob-array? "A grob array of @code{Tie} objects.")
(meta . ((class . Spanner)
(interfaces . (slur-interface))))))
- ;; Only should be used to approximate vertical skylines
- ;; of a cross-staff slur.
- (SlurStub
- . (
- (avoid-slur . inside)
- (control-points . ,ly:slur::calc-control-points)
- (cross-staff . ,slur::if-not-cross-staff-suicide)
- (details . ,default-slur-details)
- (direction . ,ly:slur::calc-direction)
- (height-limit . 2.0)
- (line-thickness . 0.8)
- (minimum-length . 1.5)
- (ratio . 0.25)
- (spanner-id . "")
- (springs-and-rods . ,ly:spanner::set-spacing-rods)
- (stencil . ,ly:slur::print)
- (thickness . 1.2)
- (transparent . #t)
- (vertical-skylines . ,ly:slur::extremal-stub-vertical-skylines)
- (Y-extent . ,ly:slur::height)
- (meta . ((class . Spanner)
- (interfaces . (cross-staff-stub-interface
- slur-interface))))))
-
(SostenutoPedal
. (
(direction . ,RIGHT)
(ly:side-position-interface::calc-cross-staff g)))
-(define-public (slur::if-not-cross-staff-suicide g)
- (let ((cs (ly:slur::calc-cross-staff g)))
- (if (not cs)
- (begin
- (ly:grob-suicide! g)
- #f)
- #t)))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; note heads
(define-public spanbar-begin-of-line-invisible #(#t #f #f))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; neighbor-interface routines