+++ /dev/null
-
-\version "2.15.10"
-
-\header {
- texidoc = "The @code{SpanBarStub} grob takes care of horizontal spacing
-for @code{SpanBar} grobs. When the @code{SpanBar} is disallowed, objects
-in contexts that the span bar would have otherwise crossed align as if the
-span bar were not there.
-"
-}
-
-<<
- \new Staff {
- \repeat unfold 64 { c''8 }
- }
- \new GrandStaff <<
- \new Staff
- \new Voice = "upper"
- \relative c'' {
- c2 c c c
- \once \override Staff . BarLine #'allow-span-bar = ##f
- c2 c c c
- c2 c c c
- \once \override Staff . BarLine #'allow-span-bar = ##f
- c2 c c c
- }
- \new Lyrics \lyricsto "upper" \lyricmode {
- long-syllable a b c long-syllable a b c
- long-syllable a b c long-syllable a b c
- }
-
- \new Staff
- \new Voice = "middle"
- \relative c'' {
- c2 c c c
- c2 c c c
- c2 c c c
- \once \override Staff . BarLine #'allow-span-bar = ##f
- c2 c c c
- }
- \new Lyrics \lyricsto "middle" \lyricmode {
- syllable a b c syllable a b c
- syllable a b c syllable a b c
- }
-
- \new Staff
- \new Voice = "lower"
- \relative c'' {
- c2 c c c
- c2 c c c
- c2 c c c
- c2 c c c
- }
- \new Lyrics \lyricsto "lower" \lyricmode {
- word a b c word a b c
- word a b c word a b c
- }
- >>
->>
}
}
-/****************************************************************
- VERTICAL ORDERING
-****************************************************************/
-
-Grob*
-get_maybe_root_vertical_alignment (Grob *g, Grob *maybe)
-{
- if (!g)
- return maybe;
- if (Align_interface::has_interface (g))
- return get_maybe_root_vertical_alignment (g->get_parent (Y_AXIS), g);
- return get_maybe_root_vertical_alignment (g->get_parent (Y_AXIS), maybe);
-
-}
-
-Grob*
-Grob::get_root_vertical_alignment (Grob *g)
-{
- return get_maybe_root_vertical_alignment (g, 0);
-}
-
-Grob*
-Grob::get_vertical_axis_group (Grob *g)
-{
- if (!g)
- return 0;
- if (Axis_group_interface::has_interface (g)
- && Align_interface::has_interface (g->get_parent (Y_AXIS)))
- return g;
- return get_vertical_axis_group (g->get_parent (Y_AXIS));
-
-}
-
-int
-Grob::get_vertical_axis_group_index (Grob *g)
-{
- Grob *val = get_root_vertical_alignment (g);
- if (!val)
- return -1;
- Grob *vax = get_vertical_axis_group (g);
- extract_grob_set (val, "elements", elts);
- for (vsize i = 0; i < elts.size (); i++)
- if (elts[i] == vax)
- return (int) i;
- g->programming_error ("could not find this grob's vertical axis group in the vertical alignment");
- return -1;
-}
-
-bool
-Grob::vertical_less (Grob *g1, Grob *g2)
-{
- Grob *vag = get_root_vertical_alignment (g1);
- if (!vag)
- return false;
- if (!vag)
- {
- g1->programming_error ("grob does not belong to a VerticalAlignment?");
- return false;
- }
- Grob *ag1 = get_vertical_axis_group (g1);
- Grob *ag2 = get_vertical_axis_group (g2);
-
- extract_grob_set (vag, "elements", elts);
-
- for (vsize i = 0; i < elts.size (); i++)
- {
- if (elts[i] == ag1)
- return true;
- if (elts[i] == ag2)
- return false;
- }
-
- g1->programming_error ("could not place this grob in its axis group");
- return false;
-}
-
/****************************************************************
MESSAGES
****************************************************************/
Grob *get_parent (Axis a) const;
void fixup_refpoint ();
- /* vertical ordering */
- static Grob *get_root_vertical_alignment (Grob *g);
- static Grob *get_vertical_axis_group (Grob *g);
- static bool vertical_less (Grob *g1, Grob *g2);
- static int get_vertical_axis_group_index (Grob *g);
-
virtual Interval_t<int> spanned_rank_interval () const;
virtual bool pure_is_visible (int start, int end) const;
bool check_cross_staff (Grob *common);
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef PURE_FROM_NEIGHBOR_INTERFACE_HH
-#define PURE_FROM_NEIGHBOR_INTERFACE_HH
-
-#include "lily-proto.hh"
-#include "grob-interface.hh"
-
-class Pure_from_neighbor_interface
-{
-public:
- DECLARE_SCHEME_CALLBACK (filter_elements, (SCM));
- DECLARE_GROB_INTERFACE ();
-
-};
-
-#endif
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <map>
-#include <algorithm>
-
-#include "grob.hh"
-#include "item.hh"
-#include "pointer-group-interface.hh"
-#include "pure-from-neighbor-interface.hh"
-#include "engraver.hh"
-
-class Pure_from_neighbor_engraver : public Engraver
-{
- vector<Grob *> items_then_;
- vector<Grob *> items_now_;
- vector<Grob *> pures_then_;
- vector<Grob *> pures_now_;
-
-public:
- TRANSLATOR_DECLARATIONS (Pure_from_neighbor_engraver);
-protected:
- DECLARE_ACKNOWLEDGER (pure_from_neighbor);
- DECLARE_ACKNOWLEDGER (item);
- void stop_translation_timestep ();
-};
-
-Pure_from_neighbor_engraver::Pure_from_neighbor_engraver ()
-{
-}
-
-void
-Pure_from_neighbor_engraver::acknowledge_item (Grob_info i)
-{
- SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
- if (!Pure_from_neighbor_interface::has_interface (i.grob ())
- && to_boolean (scm_call_1 (pure_relevant_p, i.item ()->self_scm ())))
- items_now_.push_back (i.item ());
-}
-
-// note that this can get out of hand if there are lots of vertical axis groups...
-
-void
-Pure_from_neighbor_engraver::acknowledge_pure_from_neighbor (Grob_info i)
-{
- pures_now_.push_back (i.item ());
-}
-
-void
-Pure_from_neighbor_engraver::stop_translation_timestep ()
-{
- if (pures_now_.size ())
- {
- for (vsize i = 0; i < pures_now_.size (); i++)
- for (vsize j = 0; j < items_then_.size (); j++)
- Pointer_group_interface::add_grob (pures_now_[i], ly_symbol2scm ("elements"), items_then_[j]);
-
- for (vsize i = 0; i < pures_then_.size (); i++)
- for (vsize j = 0; j < items_now_.size (); j++)
- Pointer_group_interface::add_grob (pures_then_[i], ly_symbol2scm ("elements"), items_now_[j]);
-
- items_then_.clear ();
- items_then_.insert (items_then_.end (), items_now_.begin (), items_now_.end ());
- items_now_.clear ();
-
- pures_then_.clear ();
- pures_then_.insert (pures_then_.end (), pures_now_.begin (), pures_now_.end ());
- pures_now_.clear ();
- }
-}
-
-#include "translator.icc"
-
-ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, item);
-ADD_ACKNOWLEDGER (Pure_from_neighbor_engraver, pure_from_neighbor);
-ADD_TRANSLATOR (Pure_from_neighbor_engraver,
- /* doc */
- "Coordinates items that get their pure heights from their neighbors.",
-
- /* create */
- "",
-
- /* read */
- "",
-
- /* write */
- ""
- );
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "grob.hh"
-#include "grob-array.hh"
-#include "pointer-group-interface.hh"
-#include "pure-from-neighbor-interface.hh"
-#include "spanner.hh"
-#include "system.hh"
-
-MAKE_SCHEME_CALLBACK (Pure_from_neighbor_interface, filter_elements, 1);
-SCM
-Pure_from_neighbor_interface::filter_elements (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- extract_grob_set (me, "elements", elts);
- vector<Grob *> new_elts;
- Interval_t<int> srl = me->get_system ()->spanned_rank_interval ();
- for (vsize i = 0; i < elts.size (); i++)
- if (srl.contains (elts[i]->spanned_rank_interval ()[LEFT]))
- new_elts.push_back (elts[i]);
-
- SCM elements_scm = me->get_object ("elements");
- if (Grob_array::unsmob (elements_scm))
- {
- vector<Grob *> &arr
- = unsmob_grob_array (elements_scm)->array_reference ();
- arr = new_elts;
- }
-
- return SCM_BOOL_T;
-}
-
-ADD_INTERFACE (Pure_from_neighbor_interface,
- "A collection of routines to allow for objects' pure"
- "heights and heights to be calculated based on the"
- "heights of the objects' neighbors.",
-
- /* properties */
- "elements-filtered "
- );
class Span_bar_engraver : public Engraver
{
Item *spanbar_;
- bool make_spanbar_;
vector<Item *> bars_;
public:
protected:
DECLARE_ACKNOWLEDGER (bar_line);
void stop_translation_timestep ();
- void process_acknowledged ();
};
Span_bar_engraver::Span_bar_engraver ()
{
spanbar_ = 0;
- make_spanbar_ = false;
}
void
bars_.push_back (it);
if (bars_.size () >= 2 && !spanbar_)
- make_spanbar_ = true;
- }
-}
-
-void
-Span_bar_engraver::process_acknowledged ()
-{
- if (make_spanbar_)
- {
- Grob *vag = Grob::get_root_vertical_alignment (bars_[0]);
- if (vag)
- vector_sort (bars_, Grob::vertical_less);
- spanbar_ = make_item ("SpanBar", SCM_EOL);
+ {
+ spanbar_ = make_item ("SpanBar", SCM_EOL);
- spanbar_->set_parent (bars_[0], X_AXIS);
- for (vsize i = 0; i < bars_.size (); i++)
- Span_bar::add_bar (spanbar_, bars_[i]);
- make_spanbar_ = false;
+ spanbar_->set_parent (bars_[0], X_AXIS);
+ }
}
}
{
if (spanbar_)
{
- vector_sort (bars_, Grob::vertical_less);
for (vsize i = 0; i < bars_.size (); i++)
Span_bar::add_bar (spanbar_, bars_[i]);
+++ /dev/null
-/*
- This file is part of LilyPond, the GNU music typesetter.
-
- Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
-
- LilyPond is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- LilyPond is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <map>
-#include <algorithm>
-
-#include "align-interface.hh"
-#include "bar-line.hh"
-#include "context.hh"
-#include "grob.hh"
-#include "item.hh"
-#include "pointer-group-interface.hh"
-#include "span-bar.hh"
-#include "engraver.hh"
-
-class Span_bar_stub_engraver : public Engraver
-{
- vector<Grob *> spanbars_;
- map<Grob *, Context *> axis_groups_;
-
-public:
- TRANSLATOR_DECLARATIONS (Span_bar_stub_engraver);
-protected:
- DECLARE_ACKNOWLEDGER (span_bar);
- DECLARE_ACKNOWLEDGER (hara_kiri_group_spanner);
- void process_acknowledged ();
-};
-
-Span_bar_stub_engraver::Span_bar_stub_engraver ()
-{
-}
-
-void
-Span_bar_stub_engraver::acknowledge_span_bar (Grob_info i)
-{
- spanbars_.push_back (i.grob ());
-}
-
-// note that this can get out of hand if there are lots of vertical axis groups...
-
-void
-Span_bar_stub_engraver::acknowledge_hara_kiri_group_spanner (Grob_info i)
-{
- axis_groups_[i.grob ()] = i.context ();
-}
-
-void
-Span_bar_stub_engraver::process_acknowledged ()
-{
- if (!spanbars_.size ())
- return;
-
- Grob *vertical_alignment = Grob::get_root_vertical_alignment ((*axis_groups_.begin ()).first);
- if (!vertical_alignment) // we are at the beginning of a score, so no need for stubs
- return;
-
- extract_grob_set (vertical_alignment, "elements", elts);
-
- for (vsize i = 0; i < spanbars_.size (); i++)
- {
- extract_grob_set (spanbars_[i], "elements", bars);
- vector<vsize> bar_axis_indices;
- for (vsize j = 0; j < bars.size (); j++)
- {
- int i = Grob::get_vertical_axis_group_index (bars[j]);
- if (i >= 0)
- bar_axis_indices.push_back ((vsize) i);
- }
- vector<Context *> affected_contexts;
- vector<Grob *> y_parents;
- vector<bool> keep_extent;
- for (vsize j = 0; j < elts.size (); j++)
- {
- if (j > bar_axis_indices[0]
- && j < bar_axis_indices.back ()
- && find (bar_axis_indices.begin (), bar_axis_indices.end (), j) == bar_axis_indices.end ())
- {
- vsize k = 0;
- for (; k < bar_axis_indices.size (); k++)
- if (bar_axis_indices[k] > j)
- break;
-
- k--;
- keep_extent.push_back (to_boolean (bars[k]->get_property ("allow-span-bar")));
-
- Context *c = axis_groups_[elts[j]];
- if (c && c->get_parent_context ())
- {
- y_parents.push_back (elts[j]);
- affected_contexts.push_back (c);
- }
- }
- }
- reverse (affected_contexts); // from bottom to top
- reverse (y_parents); // from bottom to top
- reverse (keep_extent); // from bottom to top
- for (vsize j = 0; j < affected_contexts.size (); j++)
- {
- Item *it = new Item (updated_grob_properties (affected_contexts[j], ly_symbol2scm ("SpanBarStub")));
- it->set_parent (spanbars_[i], X_AXIS);
- Grob_info gi = make_grob_info (it, spanbars_[i]->self_scm ());
- gi.rerouting_daddy_context_ = affected_contexts[j];
- announce_grob (gi);
- if (!keep_extent[j])
- it->set_property ("Y-extent", ly_interval2scm (Interval (infinity_f, -infinity_f)));
- }
- }
- spanbars_.clear ();
-}
-
-#include "translator.icc"
-
-ADD_ACKNOWLEDGER (Span_bar_stub_engraver, span_bar);
-ADD_ACKNOWLEDGER (Span_bar_stub_engraver, hara_kiri_group_spanner);
-ADD_TRANSLATOR (Span_bar_stub_engraver,
- /* doc */
- "Make stubs for span bars in all contexts that the span bars cross.",
-
- /* create */
- "SpanBarStub ",
-
- /* read */
- "",
-
- /* write */
- ""
- );
\consists "Instrument_name_engraver"
\consists "Span_bar_engraver"
- \consists "Span_bar_stub_engraver"
\consists "Span_arpeggio_engraver"
\consists "System_start_delimiter_engraver"
\consists "Vertical_align_engraver"
\consists "Instrument_name_engraver"
\consists "Font_size_engraver"
\consists "Hara_kiri_engraver"
- \consists "Pure_from_neighbor_engraver"
searchForVoice = ##f
%% explicitly set instrument, so it is not inherited from the parent
instrumentName = #'()
the vertical edges: @code{(@var{left-height} . @var{right-height})}.")
(edge-text ,pair? "A pair specifying the texts to be set at the
edges: @code{(@var{left-text} . @var{right-text})}.")
- (elements-filtered ,boolean? "Callback to filter an element list.")
(round-up-exceptions ,list? "A list of pairs where car is the numerator
and cdr the denominator of a moment. Each pair in this list means that
the multi-measure rests of the corresponding length will be rounded up to
(non-musical . #t)
(stencil . ,ly:span-bar::print)
(X-extent . ,ly:span-bar::width)
- (Y-extent . #f)
+ (Y-extent . ,ly:axis-group-interface::height)
(meta . ((class . Item)
+ (object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
+ (pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(interfaces . (bar-line-interface
font-interface
span-bar-interface))))))
- (SpanBarStub
- . (
- (elements-filtered . ,ly:pure-from-neighbor-interface::filter-elements)
- (X-extent . ,grob::x-parent-width)
- (Y-extent . ,span-bar-stub::height)
- (meta . ((class . Item)
- (object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
- (pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
- (interfaces . (pure-from-neighbor-interface))))))
-
(StaffGrouper
. (
(staff-staff-spacing . ((basic-distance . 9)
(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
(,ly:slur::height . ,ly:slur::pure-height)
(,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback)
- (,span-bar-stub::height . ,ly:axis-group-interface::pure-height)
(,ly:stem::calc-stem-begin-position . ,ly:stem::pure-calc-stem-begin-position)
(,ly:stem::calc-stem-end-position . ,ly:stem::pure-calc-stem-end-position)
(,stem::length . ,stem::pure-length)
(define-public (grob::is-live? grob)
(pair? (ly:grob-basic-properties grob)))
-(define-public (grob::x-parent-width grob)
- (ly:grob-property (ly:grob-parent grob X) 'X-extent))
-
(define-public (make-stencil-boxer thickness padding callback)
"Return function that adds a box around the grob passed as argument."
(lambda (grob)
(equal? (ly:item-break-dir g) RIGHT))
(ly:grob-translate-axis! g 3.5 X)))
-(define-public (span-bar-stub::height grob)
- (ly:grob-property grob 'elements-filtered)
- (ly:axis-group-interface::height grob))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Tuplets