@end ignore
+@item
+The meaning of @code{instrumentTransposition} has been reversed.
+After
+@example
+\set instrumentTransposition = #@{ b #@}
+@end example
+a written @code{c'} now sounds like @code{b}. Previously, this
+would have been the other way round. This and the following change
+should make dealing with transposing instruments more
+straightforward.
+
+@item
+The music generated by @code{\set} and @code{\override} commands
+is no longer affected by @code{\transpose}. The main consequence
+is that @code{\transpose} will transpose audible/@/concert pitch and
+printed pitch by the same amount even when the transposed music
+contains @code{\transposition}. Previously,
+@example
+\transpose c' f' \transposition bes'
+@end example
+was equivalent to @code{\transposition f'}. Now it stays
+equivalent to @code{\transposition bes'}.
+
@item
Tuplets are now created with the @code{\tuplet} command, which
takes a fraction @code{@var{t}/@var{n}} to specify that @var{t}
@divClass{column-center-top}
@subheading Was sind @qq{Minimalbeispiele}?
-Ein Minimalbeispiel ist ein Beispiel, von dem @strong{nichts} mehr entfernt
-werden kann.
+Ein Minimalbeispiel ist eine vollständige Quelldatei, die
+@strong{nicht} mehr weiter reduziert werden kann, ohne dass das
+illustrierte Problem verschwindet. Es sollten keine Warnungen und
+Fehlermeldungen produziert werden, die nicht mit dem Problem im
+Zusammenhang stehen.
+
@divEnd
@divClass{column-left-bottom}
-@subheading Warum sollte ich so etwas tun?
+@subheading Warum sollte ich Minimalbeispiele erstellen?
@divClass{keep-bullets}
@itemize
@item
Je einfacher ein Beispiel ist, um so schneller können mögliche
-Hilfeleistende es verstehen und Ihnen helfen.
+Hilfeleistende das Beispiel untersuchen, das auftretende Problem
+einkreisen und Ihnen helfen.
@item
-Ein kleines Beispiel zeigt, dass Sie sich zuerst Mühe gegeben
-haben, das Problem selber zu lösen. Wenn Leute große Abschnitte
-an Code einschicken, sieht es so aus, dass sie sich auch nicht
-interessieren, ob ihnen geholfen wird oder nicht.
+Die effiziente Analyse eines Problems erfordert ohnehin eine
+Reduktion auf das wesentliche. Kippen Sie umfangreiches Material
+in der Liste ab, so scheint Ihnen die Lösung Ihres Problems keine
+eigene Mühe wert.
@item
-Ein Minimalbeispiel zu erstellen hilft Ihnen zu verstehen,
-was vorgeht. Viele falsche Problemberichte können vermieden werden,
-wenn man versucht, erst einmal ein Minimalbeispiel zu erstellen.
-Wenn Sie einen @qq{Bug} in Ihrem Minimalbeispiel nicht reproduzieren
-können, was das Problem wohl eher zu geringes Verständnis von
-LilyPond, nicht jedoch ein Fehler.
+Ein Minimalbeispiel zu erstellen hilft Ihnen zu verstehen, was
+vorgeht. Viele Problemberichte erübrigen sich schon während der
+Erstellung eines Minimalbeispiels. Ist ein @qq{Bug} mit einem
+bestimmten Minimalbeispiel nicht reproduzierbar, ist es
+wahrscheinlich, daß er andere Ursachen als vermutet hat.
@end itemize
@divEnd
@downloadStableDarwinNormal
Für MacOS X 10.4 und höher auf Intel-Prozessoren (wenn Sie Zweifel haben, benutzen Sie diese Version).
-MacOS X 10.7 Lion wird noch nicht unterstützt.
-
@item
@sourceimage{logo-macosx,,,}
@downloadStableDarwinPPC
* Kievan notes::
* Kievan accidentals::
* Kievan bar line::
+* Kievan melismata::
@end menu
@node Kievan contexts
@ref{Bars},
@ref{The Feta font}
+@node Kievan melismata
+@unnumberedsubsubsec Kievan melismata
+
+@cindex Ligatures
+
+Notes within a Kievan melisma are usually placed close to each other
+and the melismata separated by whitespace. This is done to allow
+the chanter to quickly identify the melodic structures of Znamenny
+chant. In LilyPond, melismata are treated as ligatures and the
+spacing is implemented by the @code{Kievan_ligature_engraver}.
+
+When the @code{KievanVoice} and @code{KievanStaff} contexts are used,
+the @code{Kievan_ligature_engraver} is enabled by default. In other
+contexts, it can be invoked by replacing the @code{Ligature_bracket_engraver}
+with the @code{Kievan_ligature_engraver} in the layout block:
+
+@example
+\layout @{
+ \context @{
+ \Voice
+ \remove "Ligature_bracket_engraver"
+ \consists "Kievan_ligature_engraver"
+ @}
+@}
+@end example
+
+The spacing between the notes within a Kievan ligature can be controlled
+by setting the @code{padding} property of the @code{KievanLigature}.
+
+The following example demonstrates the use of Kievan ligatures:
+
+@lilypond[quote,ragged-right,verbatim]
+\score {
+ <<
+ \new KievanVoice = "melody" \transpose c c' {
+ \cadenzaOn
+ e2 \[ e4( d4 ) \] \[ c4( d e d ) \] e1 \bar "k"
+ }
+ \new Lyrics \lyricsto "melody" {
+ Га -- врі -- и -- лу
+ }
+ >>
+}
+@end lilypond
+
+@seealso
+Music Glossary:
+@rglos{ligature}.
+
+Notation Reference:
+@ref{White mensural ligatures},
+@ref{Gregorian square neume ligatures},
+@ref{Ligatures}.
+
+@knownissues
+Horizontal spacing of ligatures is poor.
+
@node Working with ancient music---scenarios and solutions
@subsection Working with ancient music---scenarios and solutions
@unnumberedsubsubsec Bottom-level contexts - voices
Voice-level contexts initialise certain properties and start
-appropriate engravers. Being bottom-level contexts, they cannot
-contain other contexts.
+appropriate engravers. A bottom-level context is one without
+@code{defaultchild}. While it is possible to let it
+accept/@/contain subcontexts, they can only be created and entered
+explicitly.
@strong{@emph{Voice}}
@c used for news about the upcoming release; see CG 10.2
@newsItem
-@subsubheading LilyPond 2.17.12 released! @emph{February 8, 2013}
+@subsubheading LilyPond 2.17.13 released! @emph{February 23, 2013}
-We are happy to announce the release of LilyPond 2.17.12. This
+We are happy to announce the release of LilyPond 2.17.13. This
release contains the usual number of bugfixes and enhancements, and contains
some work in progress. You will have access to the very latest features, but
some may be incomplete, and you may encounter bugs and crashes. If you require
* don't duplicate entries from news-front.itexi
@end ignore
+@newsItem
+@subsubheading LilyPond 2.17.12 released! @emph{February 8, 2013}
+
+We are happy to announce the release of LilyPond 2.17.12. This
+release contains the usual number of bugfixes and enhancements, and contains
+some work in progress. You will have access to the very latest features, but
+some may be incomplete, and you may encounter bugs and crashes. If you require
+a stable version of Lilypond, we recommend using the 2.16 version.
+
+@newsEnd
+
@newsItem
@subsubheading LilyPond 2.17.11 released! @emph{January 26, 2013}
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=17
-PATCH_LEVEL=13
+PATCH_LEVEL=14
MY_PATCH_LEVEL=
VERSION_STABLE=2.16.2
-VERSION_DEVEL=2.17.12
+VERSION_DEVEL=2.17.13
--- /dev/null
+\version "2.17.14"
+
+\header {
+ texidoc =
+"Property @code{chord-dots}: If set, remove dots which the
+@code{DotColumn} algorithm would vertically position too far away from
+note heads."
+}
+
+\layout{ ragged-right = ##t }
+
+
+\relative c'' {
+ \override Score.DotColumn.chord-dots = ##f
+ << { <d e f g a>4. } \\
+ { <a, b c d e>4. } >>
+
+ \override Score.DotColumn.chord-dots = ##t
+ << { <d' e f g a>4. } \\
+ { <a, b c d e>4. } >>
+}
grob
(if (eq? axis X)
ly:side-position-interface::x-aligned-side
- ly:side-position-interface::y-aligned-side)
+ side-position-interface::y-aligned-side)
(axis-offset-symbol axis)))))
schemeTextSpannerEngraver =
ragged-right = ##f
}
-\relative c' { c4 d f8_\f[ g-.] }
+\new PianoStaff << \new Staff \relative c' { c4 d f8_\f[ g-.] r4 }
+ \new Staff { \clef "bass" R1 }
+ >>
MODULE_LIBS=$(depth)/flower
MODULE_INCLUDES= $(depth)/flower/include
-# need this to convert between function pointers and member function pointers.
-MODULE_CXXFLAGS= -Wno-pmf-conversions
-
HELP2MAN_EXECS = lilypond
STEPMAKE_TEMPLATES=c c++ executable po help2man
return SCM_BOOL_T;
}
-/* for each grob, find its upper and lower skylines. If the grob has
- an empty extent, delete it from the list instead. If the extent is
+/* for each grob, find its upper and lower skylines. If the extent is
non-empty but there is no skyline available (or pure is true), just
create a flat skyline from the bounding box */
// TODO(jneem): the pure and non-pure parts seem to share very little
// code. Split them into 2 functions, perhaps?
static void
get_skylines (Grob *me,
- vector<Grob *> *const elements,
+ vector<Grob *> const &elements,
Axis a,
bool pure, int start, int end,
- vector<Skyline_pair> *const ret)
+ vector<Skyline_pair> *ret,
+ vector<bool> const *skip_elt)
{
- Grob *other_common = common_refpoint_of_array (*elements, me, other_axis (a));
+ Grob *other_common = common_refpoint_of_array (elements, me, other_axis (a));
- for (vsize i = elements->size (); i--;)
+ for (vsize i = elements.size (); i--;)
{
- Grob *g = (*elements)[i];
+ Grob *g = elements[i];
Skyline_pair skylines;
if (!pure)
Real offset = g->relative_coordinate (other_common, other_axis (a));
skylines.shift (offset);
}
- else
+ else if (!(*skip_elt)[i])
{
assert (a == Y_AXIS);
Interval extent = g->pure_height (g, start, end);
// of the system. This way, the tall treble clefs are only compared with the treble
// clefs of the other staff and they will be ignored if the staff above is, for example,
// lyrics.
- if (Axis_group_interface::has_interface (g)
- && !Hara_kiri_group_spanner::request_suicide (g, start, end))
+ if (Axis_group_interface::has_interface (g))
{
extent = Axis_group_interface::rest_of_line_pure_height (g, start, end);
Interval begin_of_line_extent = Axis_group_interface::begin_of_line_pure_height (g, start);
}
}
- if (skylines.is_empty ())
- elements->erase (elements->begin () + i);
- else
- ret->push_back (skylines);
+ // even if the skyline is empty, we want to push it back
+ // the heap because we will use things like system-system-distance
+ // to account for its presence
+ ret->push_back (skylines);
}
reverse (*ret);
}
// else centered dynamics will break when there is a fixed alignment).
vector<Real>
Align_interface::internal_get_minimum_translations (Grob *me,
- vector<Grob *> const &all_grobs,
+ vector<Grob *> const &elems,
Axis a,
bool include_fixed_spacing,
bool pure, int start, int end)
Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
DOWN);
- vector<Grob *> elems (all_grobs); // writable copy
vector<Skyline_pair> skylines;
+ vector<bool> skip_elt;
+ // only add to skip elt if pure
+ // if not pure, no dead element should be in the list
+ for (vsize i = 0; i < elems.size (); i++)
+ {
+ if (!pure && !elems[i]->is_live ())
+ elems[i]->programming_error ("I should be dead by now...");
+ skip_elt.push_back (pure && Hara_kiri_group_spanner::request_suicide (elems[i], start, end));
+ }
- get_skylines (me, &elems, a, pure, start, end, &skylines);
+ get_skylines (me, elems, a, pure, start, end, &skylines, &skip_elt);
Real where = 0;
Real default_padding = robust_scm2double (me->get_property ("padding"), 0.0);
int spaceable_count = 0;
for (vsize j = 0; j < elems.size (); j++)
{
+ // This means that it will be suicided later downstream, so we
+ // skip it so that its padding is not added in.
+ if (pure && skip_elt[j])
+ continue;
+
Real dy = 0;
Real padding = default_padding;
// So far, we've computed the translates for all the non-empty elements.
// Here, we set the translates for the empty elements: an empty element
// gets the same translation as the last non-empty element before it.
+ vector<Grob *> non_empty_elems;
+ for (vsize i = 0; i < elems.size (); i++)
+ if (!skip_elt[i])
+ non_empty_elems.push_back (elems[i]);
+
vector<Real> all_translates;
if (!translates.empty ())
{
Real w = translates[0];
- for (vsize i = 0, j = 0; j < all_grobs.size (); j++)
+ for (vsize i = 0, j = 0; j < elems.size (); j++)
{
- if (i < elems.size () && all_grobs[j] == elems[i])
+ if (i < non_empty_elems.size () && elems[j] == non_empty_elems[i])
w = translates[i++];
all_translates.push_back (w);
}
&& !has_interface (g))
continue;
+ if (!g->is_live ())
+ continue;
+
bool outside_staff = scm_is_number (g->get_property ("outside-staff-priority"));
Real padding = robust_scm2double (g->get_property ("outside-staff-padding"), get_default_outside_staff_padding ());
extract_grob_set (me, grob_set_name.c_str (), elts);
vector<Grob *> relevant_grobs;
- SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
for (vsize i = 0; i < elts.size (); i++)
{
- if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
- relevant_grobs.push_back (elts[i]);
-
- if (Item *it = dynamic_cast<Item *> (elts[i]))
+ if (elts[i] && elts[i]->is_live ())
{
- for (LEFT_and_RIGHT (d))
+ relevant_grobs.push_back (elts[i]);
+ if (Item *it = dynamic_cast<Item *> (elts[i]))
{
- Item *piece = it->find_prebroken_piece (d);
- if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
- relevant_grobs.push_back (piece);
+ for (LEFT_and_RIGHT (d))
+ {
+ Item *piece = it->find_prebroken_piece (d);
+ if (piece && piece->is_live ())
+ relevant_grobs.push_back (piece);
+ }
}
}
}
programming_error ("no pure Y common refpoint");
return Interval ();
}
- Real my_coord = me->relative_coordinate (common, Y_AXIS);
+ Real my_coord = me->pure_relative_y_coordinate (common, start, end);
Interval r (relative_pure_height (me, start, end));
return r - my_coord;
Check bar checks. We do this outside the engravers so that you can
race through the score using skipTypesetting to correct durations.
*/
-class Bar_check_iterator : Simple_music_iterator
+class Bar_check_iterator : Music_iterator
{
public:
virtual void process (Moment);
void
Bar_check_iterator::process (Moment m)
{
- Simple_music_iterator::process (m);
+ Music_iterator::process (m);
if (!m.to_bool ())
{
Context *tr = get_outlet ();
#include "spanner.hh"
#include "stream-event.hh"
#include "stem.hh"
+#include "unpure-pure-container.hh"
#include "warn.hh"
#include "translator.icc"
if (beam_
&& !scm_is_number (info.grob ()->get_property_data ("staff-position")))
chain_offset_callback (info.grob (),
- Beam::rest_collision_callback_proc, Y_AXIS);
+ ly_make_unpure_pure_container
+ (Beam::rest_collision_callback_proc,
+ Beam::pure_rest_collision_callback_proc),
+ Y_AXIS);
}
void
*
* - delegate actual creation of ligature to concrete subclass,
*
- * - collect all accidentals that occur within the ligature and put
- * them at the left side of the ligature (TODO; see function
- * collect_accidentals ()),
+ * - except in Kievan notation, collect all accidentals that occur
+ * within the ligature and put them at the left side of the ligature
+ * (TODO; see function collect_accidentals ()),
*
* - collapse superflous space after each ligature (TODO).
*
vector<Grob_info> const &)
{
/* TODO */
+ /* NOTE: if implementing such a function, note that in Kievan notation,
+ * the B-flat accidental should not be "collected", but rather prints
+ * immediately before the note head as usual. */
}
void
context->definition_mods_ = ops;
context->aliases_ = context_aliases_;
context->accepts_list_ = get_accepted (ops);
+ context->default_child_ = get_default_child (ops);
return context;
}
get_translator_names (SCM_EOL)), ell);
ell = scm_cons (scm_cons (ly_symbol2scm ("description"), description_), ell);
ell = scm_cons (scm_cons (ly_symbol2scm ("aliases"), context_aliases_), ell);
+ ell = scm_cons (scm_cons (ly_symbol2scm ("accepts"), get_accepted (SCM_EOL)),
+ ell);
+ if (scm_is_symbol (default_child_))
+ ell = scm_acons (ly_symbol2scm ("default-child"), default_child_, ell);
ell = scm_cons (scm_cons (ly_symbol2scm ("accepts"), get_accepted (SCM_EOL)),
ell);
ell = scm_cons (scm_cons (ly_symbol2scm ("property-ops"), property_ops_),
Context_def::is_alias (SCM sym) const
{
if (scm_is_eq (sym, ly_symbol2scm ("Bottom")))
- return !scm_is_pair (get_accepted (SCM_EOL));
+ return !scm_is_symbol (get_default_child (SCM_EOL));
if (scm_is_eq (sym, get_context_name ()))
return true;
implementation_ = 0;
properties_scm_ = SCM_EOL;
accepts_list_ = SCM_EOL;
+ default_child_ = SCM_EOL;
context_list_ = SCM_EOL;
definition_ = SCM_EOL;
definition_mods_ = SCM_EOL;
SCM
Context::default_child_context_name () const
{
- return scm_is_pair (accepts_list_)
- ? scm_car (accepts_list_)
- : SCM_EOL;
+ return default_child_;
}
bool
bool
Context::is_alias (SCM sym) const
{
- if (sym == ly_symbol2scm ("Bottom")
- && !scm_is_pair (accepts_list_))
- return true;
- if (sym == unsmob_context_def (definition_)->get_context_name ())
+ if (scm_is_eq (sym, ly_symbol2scm ("Bottom")))
+ return is_bottom_context ();
+ if (scm_is_eq (sym, context_name_symbol ()))
return true;
return scm_c_memq (sym, aliases_) != SCM_BOOL_F;
scm_gc_mark (me->definition_mods_);
scm_gc_mark (me->properties_scm_);
scm_gc_mark (me->accepts_list_);
+ scm_gc_mark (me->default_child_);
if (me->implementation_)
scm_gc_mark (me->implementation_->self_scm ());
extent_ = d.extent_ ? new Interval (*d.extent_) : 0;
}
+Dimension_cache &
+Dimension_cache::operator = (Dimension_cache const &d)
+{
+ clear ();
+ offset_ = d.offset_ ? new Real (*d.offset_) : 0;
+ parent_ = d.parent_;
+ extent_ = d.extent_ ? new Interval (*d.extent_) : 0;
+ return *this;
+}
+
Dimension_cache::Dimension_cache ()
{
init ();
= extract_grob_array (me, "dots");
vector<Grob *> main_heads;
+ vector<Interval> allowed_y_positions;
Real ss = 0;
Grob *commonx = me;
commonx = stem->common_refpoint (commonx, X_AXIS);
if (Stem::first_head (stem) == n)
- main_heads.push_back (n);
+ {
+ main_heads.push_back (n);
+
+ // Get vertical interval of the chord's notehead positions.
+ // We widen this interval since dots always sit between staff
+ // lines. Be careful to make it work also for unusual
+ // overrides of `NoteHead.Y-offset'.
+ //
+ // Possible solutions to improve this code (namely, to handle
+ // the `staff-position' property also) -- in case there is
+ // ever the desire or necessity to do so -- can be found in
+ // the Rietveld comments at
+ //
+ // https://codereview.appspot.com/7319049
+
+ Interval hp = Stem::head_positions (stem);
+
+ int top = int (ceil (hp[UP]));
+ if (Staff_symbol_referencer::on_line (stem, top))
+ top += 1;
+ hp[UP] = top;
+
+ int bottom = int (floor (hp[DOWN]));
+ if (Staff_symbol_referencer::on_line (stem, bottom))
+ bottom -= 1;
+ hp[DOWN] = bottom;
+
+ allowed_y_positions.push_back (hp);
+ }
}
}
problem.register_configuration (cfg);
+ // If in a chord, remove dots which have vertical positions above or below
+ // the topmost or bottommost note, respectively ([Gould], p. 56).
+ // Note that a dot configuration can contain more than a single chord or
+ // rest (the latter gets ignored).
+ //
+ // The dot positioning algorithm vertically shifts dots; it thus can
+ // happen that, say, a dot of the upper voice's chord is positioned
+ // beneath a note head of the lower voice's chord, while the dots of the
+ // lower voice's chord are shifted down even more. We thus check all
+ // vertical ranges for valid positions and not only the range of the dot's
+ // parent chord.
+ //
+ // Do nothing if there is either no staff line, or no note head, or the
+ // `chord-dots' property not set.
+ Grob *st = Staff_symbol_referencer::get_staff_symbol (me);
+ vsize num_positions = allowed_y_positions.size ();
+ bool chord_dots = to_boolean (me->get_property ("chord-dots"));
+
+ if (st && num_positions && chord_dots)
+ {
+ for (Dot_configuration::const_iterator i (cfg.begin ());
+ i != cfg.end (); i++)
+ {
+ vsize j;
+
+ for (j = 0; j < num_positions; j++)
+ if (allowed_y_positions[j].contains (i->first))
+ break;
+
+ if (j == num_positions)
+ {
+ Grob *dot = i->second.dot_;
+ Grob *n = dot->get_parent (Y_AXIS);
+ if (n && Note_head::has_interface (n))
+ dot->suicide ();
+ }
+ }
+ }
+
for (Dot_configuration::const_iterator i (cfg.begin ());
i != cfg.end (); i++)
{
" dots so they do not clash with staff lines.",
/* properties */
- "dots "
- "positioning-done "
+ "chord-dots "
"direction "
+ "dots "
"note-collision "
+ "positioning-done "
);
for (; scm_is_pair (p); p = scm_cdr (p))
scm_hashq_set_x (ancestor_lookup_, scm_caar (p), scm_car (p));
- accepts_list_ = scm_list_1 (ly_symbol2scm ("Score"));
+ default_child_ = ly_symbol2scm ("Score");
+ accepts_list_ = scm_list_1 (default_child_);
}
Output_def *
#include "grob.hh"
#include "simple-closure.hh"
+#include "unpure-pure-container.hh"
SCM
axis_offset_symbol (Axis a)
return;
}
- if (ly_is_procedure (data))
+ if (ly_is_procedure (data) || is_unpure_pure_container (data))
data = ly_make_simple_closure (scm_list_1 (data));
else if (is_simple_closure (data))
data = simple_closure_expression (data);
{
SCM data = g->get_property_data (sym);
- if (ly_is_procedure (data))
+ if (ly_is_procedure (data) || is_unpure_pure_container (data))
data = ly_make_simple_closure (scm_list_1 (data));
else if (is_simple_closure (data))
data = simple_closure_expression (data);
if (is_unpure_pure_container (val))
val = unpure_pure_container_unpure_part (val);
+
if (ly_is_procedure (val)
|| is_simple_closure (val))
{
SCM
call_pure_function (SCM unpure, SCM args, int start, int end)
{
- SCM scm_call_pure_function = ly_lily_module_constant ("call-pure-function");
+ if (is_unpure_pure_container (unpure))
+ {
+ SCM pure = unpure_pure_container_pure_part (unpure);
+
+ if (is_simple_closure (pure))
+ {
+ SCM expr = simple_closure_expression (pure);
+ return evaluate_with_simple_closure (scm_car (args), expr, true, start, end);
+ }
+
+ if (ly_is_procedure (pure))
+ return scm_apply_0 (pure,
+ scm_append (scm_list_2 (scm_list_3 (scm_car (args),
+ scm_from_int (start),
+ scm_from_int (end)),
+ scm_cdr (args))));
+
+ return pure;
+ }
+
+ if (is_simple_closure (unpure))
+ {
+ SCM expr = simple_closure_expression (unpure);
+ return evaluate_with_simple_closure (scm_car (args), expr, true, start, end);
+ }
+
+ if (!ly_is_procedure (unpure))
+ return unpure;
- return scm_apply_0 (scm_call_pure_function,
- scm_list_4 (unpure, args, scm_from_int (start), scm_from_int (end)));
+ return SCM_BOOL_F;
}
#include "paper-score.hh"
#include "simple-closure.hh"
#include "system.hh"
+#include "unpure-pure-container.hh"
#include "warn.hh" // error ()
LY_DEFINE (ly_grob_property_data, "ly:grob-property-data",
Grob *gr = unsmob_grob (grob);
LY_ASSERT_SMOB (Grob, grob, 1);
- LY_ASSERT_TYPE (ly_is_procedure, proc, 2);
+ SCM_ASSERT_TYPE (ly_is_procedure (proc) || is_unpure_pure_container (proc), proc, SCM_ARG2, __FUNCTION__, "procedure or unpure pure container");
LY_ASSERT_TYPE (ly_is_symbol, sym, 3);
chain_callback (gr, proc, sym);
#include "stencil.hh"
#include "stream-event.hh"
#include "system.hh"
+#include "unpure-pure-container.hh"
#include "warn.hh"
#include "ly-smobs.icc"
if (get_property_data ("X-extent") == SCM_EOL)
set_property ("X-extent", Grob::stencil_width_proc);
if (get_property_data ("Y-extent") == SCM_EOL)
- set_property ("Y-extent", Grob::stencil_height_proc);
+ set_property ("Y-extent",
+ ly_make_unpure_pure_container (Grob::stencil_height_proc,
+ Grob::pure_stencil_height_proc));
if (get_property_data ("vertical-skylines") == SCM_EOL)
- set_property ("vertical-skylines", Grob::simple_vertical_skylines_from_extents_proc);
+ set_property ("vertical-skylines",
+ ly_make_unpure_pure_container (Grob::simple_vertical_skylines_from_extents_proc,
+ Grob::pure_simple_vertical_skylines_from_extents_proc));
if (get_property_data ("horizontal-skylines") == SCM_EOL)
- set_property ("horizontal-skylines", Grob::simple_horizontal_skylines_from_extents_proc);
+ set_property ("horizontal-skylines",
+ ly_make_unpure_pure_container (Grob::simple_horizontal_skylines_from_extents_proc,
+ Grob::pure_simple_horizontal_skylines_from_extents_proc));
}
Grob::Grob (Grob const &s)
- : dim_cache_ (s.dim_cache_)
{
original_ = (Grob *) & s;
self_scm_ = SCM_EOL;
immutable_property_alist_ = s.immutable_property_alist_;
mutable_property_alist_ = SCM_EOL;
+
+ for (Axis a = X_AXIS; a < NO_AXES; incr (a))
+ dim_cache_ [a] = s.dim_cache_ [a];
+
interfaces_ = s.interfaces_;
object_alist_ = SCM_EOL;
Grob::pure_height (Grob *refp, int start, int end)
{
SCM iv_scm = get_pure_property ("Y-extent", start, end);
- // TODO: Why is this Interval (0,0)
- // Shouldn't it just be an empty interval?
- // 0,0 puts an arbitrary point at 0,0 which will influence spacing
- Interval iv = robust_scm2interval (iv_scm, Interval (0, 0));
+ Interval iv = robust_scm2interval (iv_scm, Interval ());
Real offset = pure_relative_y_coordinate (refp, start, end);
SCM min_ext = get_property ("minimum-Y-extent");
return grob_stencil_extent (me, Y_AXIS);
}
+MAKE_SCHEME_CALLBACK (Grob, pure_stencil_height, 3);
+SCM
+Grob::pure_stencil_height (SCM smob, SCM /* beg */, SCM /* end */)
+{
+ Grob *me = unsmob_grob (smob);
+ if (unsmob_stencil (me->get_property_data ("stencil")))
+ return grob_stencil_extent (me, Y_AXIS);
+
+ return ly_interval2scm (Interval ());
+
+}
+
MAKE_SCHEME_CALLBACK (Grob, y_parent_positioning, 1);
SCM
Grob::y_parent_positioning (SCM smob)
SCM properties_scm_;
SCM context_list_;
SCM accepts_list_;
+ SCM default_child_;
SCM aliases_;
Translator_group *implementation_;
string id_string_;
friend class Grob;
Dimension_cache (Dimension_cache const &);
+ Dimension_cache & operator = (Dimension_cache const &d);
~Dimension_cache ();
Dimension_cache ();
};
/* standard callbacks */
DECLARE_SCHEME_CALLBACK (x_parent_positioning, (SCM));
DECLARE_SCHEME_CALLBACK (y_parent_positioning, (SCM));
+ DECLARE_SCHEME_CALLBACK (pure_stencil_height, (SCM smob, SCM, SCM));
DECLARE_SCHEME_CALLBACK (stencil_height, (SCM smob));
DECLARE_SCHEME_CALLBACK (stencil_width, (SCM smob));
DECLARE_SCHEME_CALLBACK (pure_simple_vertical_skylines_from_extents, (SCM smob, SCM, SCM));
DECLARE_SCHEME_CALLBACK (simple_vertical_skylines_from_extents, (SCM smob));
DECLARE_SCHEME_CALLBACK (vertical_skylines_from_stencil, (SCM smob));
+ DECLARE_SCHEME_CALLBACK (pure_vertical_skylines_from_element_stencils, (SCM smob, SCM, SCM));
DECLARE_SCHEME_CALLBACK (vertical_skylines_from_element_stencils, (SCM smob));
DECLARE_SCHEME_CALLBACK (pure_simple_horizontal_skylines_from_extents, (SCM smob, SCM, SCM));
DECLARE_SCHEME_CALLBACK (simple_horizontal_skylines_from_extents, (SCM smob));
DECLARE_SCHEME_CALLBACK (horizontal_skylines_from_stencil, (SCM smob));
+ DECLARE_SCHEME_CALLBACK (pure_horizontal_skylines_from_element_stencils, (SCM smob, SCM, SCM));
DECLARE_SCHEME_CALLBACK (horizontal_skylines_from_element_stencils, (SCM smob));
/* R/O access */
bool check_cross_staff (Grob *common);
static bool less (Grob *g1, Grob *g2);
static SCM maybe_pure_internal_simple_skylines_from_extents (Grob *, Axis, bool, int, int, bool, bool);
+ static SCM internal_skylines_from_element_stencils (Grob *me, Axis a, bool pure, int beg, int end);
static SCM internal_skylines_from_element_stencils (SCM, Axis);
};
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2013 Aleksandr Andreev <aleksandr.andreev@gmail.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 KIEVAN_LIGATURE_HH
+#define KIEVAN_LIGATURE_HH
+
+#include "lily-proto.hh"
+#include "grob-interface.hh"
+
+struct Kievan_ligature
+{
+ DECLARE_SCHEME_CALLBACK (print, (SCM));
+ DECLARE_GROB_INTERFACE ();
+};
+
+#endif /* KIEVAN_LIGATURE_HH */
class Transposed_music;
class yyFlexLexer;
-typedef void (*Engraver_void_function_engraver_grob_info) (Engraver *,
- Grob_info);
-typedef void (*Translator_void_method_ptr) (Translator *);
+typedef void (Engraver::*Engraver_void_function_engraver_grob_info) (Grob_info);
+typedef void (Translator::*Translator_void_method_ptr) ();
#endif /* LILY_PROTO_HH */
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2013 Mike Solomon <mike@mikesolomon.org>
+
+ 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 SLUR_PROTO_ENGRAVER_HH
+#define SLUR_PROTO_ENGRAVER_HH
+
+#include "engraver.hh"
+#include "moment.hh"
+
+class Slur_proto_engraver : public Engraver
+{
+protected:
+ Slur_proto_engraver (const char* double_property_name,
+ const char* grob_name, const char* object_name, const char* event_name) :
+ double_property_name_ (double_property_name),
+ grob_name_ (grob_name), object_name_ (object_name),
+ event_name_ (event_name) {}
+
+ // protected so that subclasses can see them
+ vector<Stream_event *> start_events_;
+ vector<Stream_event *> stop_events_;
+ vector<Grob *> slurs_;
+ vector<Grob *> end_slurs_;
+ vector<Grob_info> objects_to_acknowledge_;
+ const char* double_property_name_;
+ const char* grob_name_;
+ const char* object_name_;
+ const char* event_name_;
+
+ DECLARE_ACKNOWLEDGER (inline_accidental);
+ DECLARE_ACKNOWLEDGER (fingering);
+ DECLARE_ACKNOWLEDGER (note_column);
+ DECLARE_ACKNOWLEDGER (script);
+ DECLARE_ACKNOWLEDGER (dots);
+ DECLARE_ACKNOWLEDGER (text_script);
+ DECLARE_END_ACKNOWLEDGER (tie);
+ DECLARE_ACKNOWLEDGER (tuplet_number);
+
+ void internal_listen_slur (Stream_event *ev);
+ void acknowledge_extra_object (Grob_info);
+ void stop_translation_timestep ();
+ void process_music ();
+
+ bool can_create_slur (string, vsize, vsize *, Stream_event *);
+ void create_slur (string spanner_id, Stream_event *ev_cause, Grob *g_cause, Direction dir, bool left_broken);
+ bool try_to_end (Stream_event *ev);
+
+ virtual void set_melisma (bool);
+ virtual void finalize ();
+ virtual void derived_mark () const;
+
+public:
+ // no TRANSLATOR_DECLARATIONS (Slur_proto_engraver) needed since this
+ // class is abstract
+};
+
+#endif // SLUR_PROTO_ENGRAVER_HH
void invoke ()
{
if (method_)
- (*method_) (translator_);
+ (translator_->*method_) ();
}
};
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2013 Aleksandr Andreev <aleksandr.andreev@gmail.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 "coherent-ligature-engraver.hh"
+#include "font-interface.hh"
+#include "international.hh"
+#include "kievan-ligature.hh"
+#include "paper-column.hh"
+#include "rhythmic-head.hh"
+#include "spanner.hh"
+#include "stream-event.hh"
+#include "warn.hh"
+
+#include "translator.icc"
+
+class Kievan_ligature_engraver : public Coherent_ligature_engraver
+{
+
+protected:
+ virtual Spanner *create_ligature_spanner ();
+ virtual void build_ligature (Spanner *ligature,
+ vector<Grob_info> const &primitives);
+ DECLARE_TRANSLATOR_LISTENER (ligature);
+
+public:
+ TRANSLATOR_DECLARATIONS (Kievan_ligature_engraver);
+
+private:
+ void fold_up_primitives (vector<Grob_info> const &primitives, Real padding, Real &min_length);
+};
+
+IMPLEMENT_TRANSLATOR_LISTENER (Kievan_ligature_engraver, ligature);
+void
+Kievan_ligature_engraver::listen_ligature (Stream_event *ev)
+{
+ Ligature_engraver::listen_ligature (ev);
+}
+
+Kievan_ligature_engraver::Kievan_ligature_engraver ()
+{
+
+}
+
+Spanner *
+Kievan_ligature_engraver::create_ligature_spanner ()
+{
+ return make_spanner ("KievanLigature", SCM_EOL);
+}
+
+void
+Kievan_ligature_engraver::fold_up_primitives (vector<Grob_info> const &primitives,
+ Real padding, Real &min_length)
+{
+ Item *first = 0;
+ Real accumul_acc_space = 0.0;
+ // start us off with some padding on the left
+ min_length = padding;
+
+ for (vsize i = 0; i < primitives.size (); i++)
+ {
+ Item *current = dynamic_cast<Item *> (primitives[i].grob ());
+ Interval my_ext = current->extent (current, X_AXIS);
+ Real head_width = my_ext.length ();
+ if (i == 0)
+ first = current;
+
+ // must keep track of accidentals in spacing problem
+ Grob *acc_gr = unsmob_grob (current->get_object ("accidental-grob"));
+ if (acc_gr && i > 0)
+ {
+ Interval acc_ext = acc_gr->extent (acc_gr, X_AXIS);
+ accumul_acc_space += acc_ext.length();
+ }
+
+ move_related_items_to_column (current, first->get_column (),
+ min_length);
+
+ // check if we have any dots
+ if (size_t const dot_count = Rhythmic_head::dot_count (current))
+ {
+ Grob *dot_gr = Rhythmic_head::get_dots (current);
+
+ head_width += Font_interface::get_default_font (current)->
+ find_by_name ("dots.dotkievan").extent (X_AXIS).length() -
+ 0.5 * (padding - accumul_acc_space);
+
+ dot_gr->translate_axis (0.5 * (padding - accumul_acc_space), X_AXIS);
+ }
+
+ // add more padding if we have an accidental coming up
+ if (i < primitives.size () - 1)
+ {
+ Item *next = dynamic_cast<Item *> (primitives[i + 1].grob ());
+ Grob *acc_gr = unsmob_grob (next->get_object ("accidental-grob"));
+ if (acc_gr)
+ {
+ Interval acc_ext = acc_gr->extent (acc_gr, X_AXIS);
+ padding += acc_ext.length();
+ }
+ }
+
+ min_length += head_width + padding - accumul_acc_space;
+
+ }
+
+}
+
+void
+Kievan_ligature_engraver::build_ligature (Spanner *ligature,
+ vector<Grob_info> const &primitives)
+{
+ Real min_length;
+
+ Real padding = robust_scm2double (ligature->get_property ("padding"), 0.0);
+ fold_up_primitives (primitives, padding, min_length);
+ if (robust_scm2double (ligature->get_property ("minimum-length"), 0.0)
+ < min_length)
+ ligature->set_property ("minimum-length", scm_from_double (min_length));
+
+}
+
+ADD_ACKNOWLEDGER (Kievan_ligature_engraver, rest);
+ADD_ACKNOWLEDGER (Kievan_ligature_engraver, ligature_head);
+
+ADD_TRANSLATOR (Kievan_ligature_engraver,
+ /* doc */
+ "Handle @code{Kievan_ligature_events} by glueing Kievan"
+ " heads together.",
+
+ /* create */
+ "KievanLigature ",
+
+ /* read */
+ "",
+
+ /* write */
+ ""
+ );
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2013 Aleksandr Andreev <aleksandr.andreev@gmail.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 "kievan-ligature.hh"
+
+#include "international.hh"
+#include "item.hh"
+#include "warn.hh"
+
+MAKE_SCHEME_CALLBACK (Kievan_ligature, print, 1);
+SCM
+Kievan_ligature::print (SCM)
+{
+ return SCM_EOL;
+}
+
+ADD_INTERFACE (Kievan_ligature,
+ "A kievan ligature.",
+
+ /* properties */
+ "primitive "
+ "padding "
+ );
* produce a single connected graphical object of fixed width,
* consisting of noteheads and other primitives. Space may be
* inserted only after each ligature, if necessary, but in no case
- * between the primitives of the ligature. Accidentals have to be put
+ * between the primitives of the ligature. The same approach is
+ * used for Kievan notation ligatures, or, rather melismas.
+ * Though these are not single connected objects, they behave much
+ * in the same way and have a fixed, small amount of space between
+ * noteheads. Except in Kievan "ligatures", accidentals have to be put
* to the left of the ligature, and not to the left of individual
- * noteheads. Class Coherent_ligature_engraver is the common
+ * noteheads. In Kievan ligatures, the B-flat may be part of the
+ * ligature itself. Class Coherent_ligature_engraver is the common
* superclass for all of these engravers.
*
* The second category is for engravers that are relaxed in the sense
ly_deep_copy (SCM src)
{
if (scm_is_pair (src))
- return scm_cons (ly_deep_copy (scm_car (src)), ly_deep_copy (scm_cdr (src)));
- else if (scm_is_vector (src))
+ {
+ SCM res = SCM_EOL;
+ do
+ {
+ res = scm_cons (ly_deep_copy (scm_car (src)), res);
+ src = scm_cdr (src);
+ }
+ while (scm_is_pair (src));
+ // Oh, come on, GUILE. Why do you require the second argument
+ // of scm_reverse_x to be a proper list? That makes no sense.
+ // return scm_reverse_x (res, ly_deep_copy (src));
+ SCM last_cons = res;
+ res = scm_reverse_x (res, SCM_EOL);
+ scm_set_cdr_x (last_cons, ly_deep_copy (src));
+ return res;
+ }
+ if (scm_is_vector (src))
{
int len = scm_c_vector_length (src);
SCM nv = scm_c_make_vector (len, SCM_UNDEFINED);
SCM si = scm_from_int (i);
scm_vector_set_x (nv, si, ly_deep_copy (scm_vector_ref (src, si)));
}
+ return nv;
}
return src;
}
if (val == SCM_EOL || val == SCM_BOOL_F)
return ok;
+ // If undefined, some internal function caused it...should never happen.
+ assert (val != SCM_UNDEFINED);
if (!scm_is_symbol (sym))
return false;
DECLARE_ACKNOWLEDGER (slur);
TRANSLATOR_DECLARATIONS (Melody_engraver);
void stop_translation_timestep ();
+ void process_acknowledged ();
void process_music ();
};
melody_item_ = 0;
}
+/*
+ Used to be in stop_translation_timestep, but grobs can't
+ be created here.
+*/
void
-Melody_engraver::stop_translation_timestep ()
+Melody_engraver::process_acknowledged ()
{
if (stem_
&& !is_direction (stem_->get_property_data ("neutral-direction")))
Melody_spanner::add_stem (melody_item_, stem_);
}
}
+}
+
+void
+Melody_engraver::stop_translation_timestep ()
+{
stem_ = 0;
}
Multi_measure_rest::height (SCM smob)
{
Grob *me = unsmob_grob (smob);
- Spanner *sp = dynamic_cast<Spanner *> (me);
Real space = 1000000; // something very large...
LY_DEFINE (ly_music_deep_copy, "ly:music-deep-copy",
1, 0, 0, (SCM m),
- "Copy @var{m} and all sub expressions of@tie{}@var{m}.")
+ "Copy @var{m} and all sub expressions of@tie{}@var{m}."
+ " @var{m} may be an arbitrary type; cons cells and music"
+ " are copied recursively.")
{
- SCM copy = m;
if (unsmob_music (m))
+ return unsmob_music (m)->clone ()->unprotect ();
+ if (scm_is_pair (m))
{
- Music *mcopy = unsmob_music (m)->clone ();
- copy = mcopy->unprotect ();
+ SCM copy = SCM_EOL;
+ do
+ {
+ copy = scm_cons (ly_music_deep_copy (scm_car (m)), copy);
+ m = scm_cdr (m);
+ }
+ while (scm_is_pair (m));
+ // Oh, come on, GUILE. Why do you require the second argument
+ // of scm_reverse_x to be a proper list? That makes no sense.
+ // return scm_reverse_x (copy, ly_music_deep_copy (m));
+ SCM last_cons = copy;
+ copy = scm_reverse_x (copy, SCM_EOL);
+ scm_set_cdr_x (last_cons, ly_music_deep_copy (m));
+ return copy;
}
- else if (scm_is_pair (m))
- copy = scm_cons (ly_music_deep_copy (scm_car (m)),
- ly_music_deep_copy (scm_cdr (m)));
- return copy;
+ return m;
}
LY_DEFINE (ly_music_transpose, "ly:music-transpose",
Moment len = get_event_length (n, now_mom ());
Audio_note *p = new Audio_note (*pitp, len,
- tie_event, transposing.negated ());
+ tie_event, transposing);
Audio_element_info info (p, n);
announce_element (info);
notes_.push_back (p);
;
markup_top:
- markup_list {
+ simple_markup_list {
$$ = scm_list_2 (ly_lily_module_constant ("line-markup"), $1);
}
| markup_head_1_list simple_markup {
;
-markup_list:
+simple_markup_list:
markup_composed_list {
$$ = $1;
}
}
;
+markup_list:
+ simple_markup_list
+ | markup_score
+ {
+ $$ = scm_list_1 (scm_list_2 (ly_lily_module_constant ("score-lines-markup-list"), $1));
+ }
+ ;
+
+markup_score:
+ SCORE {
+ SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
+ parser->lexer_->push_note_state (nn);
+ } '{' score_body '}' {
+ $$ = $4;
+ parser->lexer_->pop_state ();
+ }
+ ;
+
markup_composed_list:
markup_head_1_list markup_braced_list {
$$ = scm_call_2 (ly_lily_module_constant ("map-markup-command-list"), $1, $2);
| markup_braced_list_body markup {
$$ = scm_cons ($2, $1);
}
- | markup_braced_list_body markup_list {
+ | markup_braced_list_body simple_markup_list {
$$ = scm_reverse_x ($2, $1);
}
;
STRING {
$$ = make_simple_markup ($1);
}
- | SCORE {
- SCM nn = parser->lexer_->lookup_identifier ("pitchnames");
- parser->lexer_->push_note_state (nn);
- } '{' score_body '}' {
- $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $4);
- parser->lexer_->pop_state ();
- }
| MARKUP_FUNCTION markup_command_basic_arguments {
$$ = scm_cons ($1, scm_reverse_x ($2, SCM_EOL));
}
{
$$ = $2;
}
+ | markup_score
+ {
+ $$ = scm_list_2 (ly_lily_module_constant ("score-markup"), $1);
+ }
;
markup:
char const *charset = "UTF-8"; // Input is ALWAYS UTF-8!
gsize bytes_written = 0;
+#if 0
+
/* First, try to convert to ISO-8859-1 (no encodings required). This will
* fail, if the string contains accented characters, so we do not check
* for errors. */
g = g_convert (p, -1, "ISO-8859-1", charset, 0, &bytes_written, 0);
+
+#else
+
+ /* In contrast to the above comment, we do _not_ try full ISO-8859-1
+ * since a number of Ghostscript versions fail to properly convert
+ * this into PDF. UTF-16BE, in contrast, works better with recent
+ * versions of Ghostscript.
+ */
+
+ g = g_convert (p, -1, "ASCII", charset, 0, &bytes_written, 0);
+
+#endif
+
/* If that fails, we have to resolve to full UTF-16BE */
if (!g)
{
#include "international.hh"
#include "note-column.hh"
#include "slur.hh"
+#include "slur-proto-engraver.hh"
#include "spanner.hh"
#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
-/*
- NOTE NOTE NOTE
-
- This is largely similar to Slur_engraver. Check if fixes
- apply there too.
-
- (on principle, engravers don't use inheritance for code sharing)
-
- */
-
-/*
- It is possible that a slur starts and ends on the same note. At
- least, it is for phrasing slurs: a note can be both beginning and
- ending of a phrase.
-*/
-class Phrasing_slur_engraver : public Engraver
+class Phrasing_slur_engraver : public Slur_proto_engraver
{
- vector<Stream_event *> start_events_;
- vector<Stream_event *> stop_events_;
- vector<Grob *> slurs_;
- vector<Grob *> end_slurs_;
- vector<Grob_info> objects_to_acknowledge_;
-
protected:
DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
- DECLARE_ACKNOWLEDGER (inline_accidental);
- DECLARE_ACKNOWLEDGER (fingering);
- DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (slur);
- DECLARE_ACKNOWLEDGER (script);
- DECLARE_ACKNOWLEDGER (dots);
- DECLARE_ACKNOWLEDGER (text_script);
- DECLARE_END_ACKNOWLEDGER (tie);
- DECLARE_ACKNOWLEDGER (tuplet_number);
-
- void acknowledge_extra_object (Grob_info);
- void stop_translation_timestep ();
- void process_music ();
-
- virtual void finalize ();
- virtual void derived_mark () const;
public:
TRANSLATOR_DECLARATIONS (Phrasing_slur_engraver);
};
-Phrasing_slur_engraver::Phrasing_slur_engraver ()
+Phrasing_slur_engraver::Phrasing_slur_engraver () :
+ Slur_proto_engraver (0, "PhrasingSlur", "phrasing slur", "phrasing-slur-event")
{
}
-void
-Phrasing_slur_engraver::derived_mark () const
-{
- for (vsize i = start_events_.size (); i--;)
- scm_gc_mark (start_events_[i]->self_scm ());
- for (vsize i = stop_events_.size (); i--;)
- scm_gc_mark (stop_events_[i]->self_scm ());
-}
-
IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur);
void
Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- if (d == START)
- start_events_.push_back (ev);
- else if (d == STOP)
- stop_events_.push_back (ev);
- else ev->origin ()->warning (_f ("direction of %s invalid: %d",
- "phrasing-slur-event", int (d)));
-}
-
-void
-Phrasing_slur_engraver::acknowledge_note_column (Grob_info info)
-{
- Grob *e = info.grob ();
- 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_extra_object (Grob_info info)
-{
- objects_to_acknowledge_.push_back (info);
-}
-
-void
-Phrasing_slur_engraver::acknowledge_inline_accidental (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Phrasing_slur_engraver::acknowledge_dots (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Phrasing_slur_engraver::acknowledge_fingering (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Phrasing_slur_engraver::acknowledge_tuplet_number (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-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_text_script (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Phrasing_slur_engraver::acknowledge_end_tie (Grob_info info)
-{
- acknowledge_extra_object (info);
+ internal_listen_slur (ev);
}
void
acknowledge_extra_object (info);
}
-void
-Phrasing_slur_engraver::finalize ()
-{
- for (vsize i = 0; i < slurs_.size (); i++)
- {
- slurs_[i]->warning (_ ("unterminated phrasing slur"));
- slurs_[i]->suicide ();
- }
- slurs_.clear ();
-}
-
-void
-Phrasing_slur_engraver::process_music ()
-{
- for (vsize i = 0; i < stop_events_.size (); i++)
- {
- Stream_event *ev = stop_events_[i];
- string id = robust_scm2string (ev->get_property ("spanner-id"), "");
-
- // Find the slurs that are ended with this event (by checking the spanner-id)
- bool ended = false;
- for (vsize j = slurs_.size (); j--;)
- {
- if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
- {
- ended = true;
- end_slurs_.push_back (slurs_[j]);
- slurs_.erase (slurs_.begin () + j);
- }
- }
- if (ended)
- {
- // Ignore redundant stop events for this id
- for (vsize j = stop_events_.size (); --j > i;)
- {
- if (id == robust_scm2string (stop_events_[j]->get_property ("spanner-id"), ""))
- stop_events_.erase (stop_events_.begin () + j);
- }
- }
- else
- ev->origin ()->warning (_ ("cannot end phrasing slur"));
- }
-
- vsize old_slurs = slurs_.size ();
- for (vsize i = start_events_.size (); i--;)
- {
- Stream_event *ev = start_events_[i];
- string id = robust_scm2string (ev->get_property ("spanner-id"), "");
- Direction updown = to_dir (ev->get_property ("direction"));
-
- bool completed;
- for (vsize j = slurs_.size (); !(completed = (j-- == 0));)
- {
- // Check if we already have a slur with the same spanner-id.
- if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
- {
- if (j < old_slurs)
- {
- // We already have an old slur, so give a warning
- // and completely ignore the new slur.
- ev->origin ()->warning (_ ("already have phrasing slur"));
- start_events_.erase (start_events_.begin () + i);
- break;
- }
-
- // If this slur event has no direction, it will not
- // contribute anything new to the existing slur(s), so
- // we can ignore it.
-
- if (!updown)
- break;
-
- Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("cause"));
-
- if (!c)
- {
- slurs_[j]->programming_error ("phrasing slur without a cause");
- continue;
- }
-
- Direction slur_dir = to_dir (c->get_property ("direction"));
-
- // If the existing slur does not have a direction yet,
- // we'd rather take the new one.
-
- if (!slur_dir)
- {
- slurs_[j]->suicide ();
- slurs_.erase (slurs_.begin () + j);
- continue;
- }
-
- // If the existing slur has the same direction as ours, drop ours
-
- if (slur_dir == updown)
- break;
- }
- }
- // If the loop completed, our slur is new
- if (completed)
- {
- Grob *slur = make_spanner ("PhrasingSlur", ev->self_scm ());
- slur->set_property ("spanner-id", ly_string2scm (id));
- if (updown)
- set_grob_direction (slur, updown);
- slurs_.push_back (slur);
- }
- }
-}
-
-void
-Phrasing_slur_engraver::stop_translation_timestep ()
-{
- if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
- {
- 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 < slurs_.size (); i++)
- Slur::add_extra_encompass (slurs_[i], g);
- }
-
- for (vsize i = 0; i < end_slurs_.size (); i++)
- {
- 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], slurs_, end_slurs_);
-
- objects_to_acknowledge_.clear ();
- end_slurs_.clear ();
- start_events_.clear ();
- stop_events_.clear ();
-}
-
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, inline_accidental);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, fingering)
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, note_column);
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.item ())
- && to_boolean (scm_call_1 (pure_relevant_p, i.item ()->self_scm ())))
+ if (!Pure_from_neighbor_interface::has_interface (i.item ()))
pure_relevants_.push_back (i.item ());
}
Pitch *quote_pitch = unsmob_pitch (scm_cdar (entry));
/*
- The pitch that sounds like central C
+ The pitch that sounds when written central C is played.
*/
+ Pitch temp_pitch;
Pitch *me_pitch = unsmob_pitch (get_music ()->get_property ("quoted-transposition"));
if (!me_pitch)
me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition"));
+ else
+ {
+ // We are not going to win a beauty contest with this one,
+ // but it is slated for replacement and touches little code.
+ // quoted-transposition currently has a different sign
+ // convention than instrumentTransposition
+ temp_pitch = me_pitch->negated ();
+ me_pitch = &temp_pitch;
+ }
SCM cid = get_music ()->get_property ("quoted-context-id");
bool is_cue = scm_is_string (cid) && (ly_scm2string (cid) == "cue");
if (me_pitch)
mp = *me_pitch;
- Pitch diff = pitch_interval (qp, mp);
+ Pitch diff = pitch_interval (mp, qp);
ev = ev->clone ();
ev->make_transposable ();
#include "staff-symbol-referencer.hh"
#include "stem.hh"
#include "grob.hh"
+#include "unpure-pure-container.hh"
#include "warn.hh"
MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Rest_collision, force_shift_callback_rest, 2, 1, "");
if (rest)
{
chain_offset_callback (rest,
- Rest_collision::force_shift_callback_rest_proc, Y_AXIS);
+ ly_make_unpure_pure_container
+ (Rest_collision::force_shift_callback_rest_proc,
+ ly_lily_module_constant ("pure-chain-offset-callback")),
+ Y_AXIS);
}
}
"The interface for a column of l.v. (laissez vibrer) ties.",
/* properties */
+ "direction "
"positioning-done "
"head-direction "
"tie-configuration "
Interval extra_height = robust_scm2interval (elts[i]->get_property ("extra-spacing-height"),
Interval (0.0, 0.0));
- x[LEFT] += extra_width[LEFT];
- x[RIGHT] += extra_width[RIGHT];
- y[DOWN] += extra_height[DOWN];
- y[UP] += extra_height[UP];
+ // The conventional empty extent is (+inf.0 . -inf.0)
+ // but (-inf.0 . +inf.0) is used as extra-spacing-height
+ // on items that must not overlap other note-columns.
+ // If these two uses of inf combine, leave the empty extent.
+
+ if (!isinf (x[LEFT]))
+ x[LEFT] += extra_width[LEFT];
+ if (!isinf (x[RIGHT]))
+ x[RIGHT] += extra_width[RIGHT];
+ if (!isinf (y[DOWN]))
+ y[DOWN] += extra_height[DOWN];
+ if (!isinf (y[UP]))
+ y[UP] += extra_height[UP];
if (!x.is_empty () && !y.is_empty ())
out.push_back (Box (x, y));
#include "string-convert.hh"
#include "system.hh"
#include "warn.hh"
+#include "unpure-pure-container.hh"
void
Side_position_interface::add_support (Grob *me, Grob *e)
SCM
Side_position_interface::aligned_side (Grob *me, Axis a, bool pure, int start, int end,
Real *current_off)
-{//printf (" %s\n", me->name ().c_str ());
+{
Direction dir = get_grob_direction (me);
set<Grob *> support = get_support_set (me);
ax);
Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me);
+ bool quantize_position = to_boolean (me->get_maybe_pure_property ("quantize-position", pure, start, end));
bool include_staff
= staff_symbol
&& a == Y_AXIS
- && scm_is_number (me->get_property ("staff-padding"))
- && !to_boolean (me->get_property ("quantize-position"));
+ && scm_is_number (me->get_maybe_pure_property ("staff-padding", pure, start, end))
+ && !quantize_position;
if (include_staff)
common[Y_AXIS] = staff_symbol->common_refpoint (common[Y_AXIS], Y_AXIS);
for (it = support.begin (); it != support.end (); it++)
{
Grob *e = *it;
-//printf (" %s\n", e->name ().c_str ());
+
// In the case of a stem, we will find a note head as well
// ignoring the stem solves cyclic dependencies if the stem is
// attached to a cross-staff beam.
Skyline_pair copy = Skyline_pair (*sp);
if (a == Y_AXIS
&& Stem::has_interface (e)
- && to_boolean (me->get_property ("add-stem-support")))
+ && to_boolean (me->get_maybe_pure_property ("add-stem-support", pure, start, end)))
copy[dir].set_minimum_height (copy[dir].max_height ());
copy.shift (a == X_AXIS ? yc : xc);
copy.raise (a == X_AXIS ? xc : yc);
dim.set_minimum_height (dim.max_height ());
Real ss = Staff_symbol_referencer::staff_space (me);
- Real dist = dim.distance (my_dim, robust_scm2double (me->get_property ("horizon-padding"), 0.0));
+ Real dist = dim.distance (my_dim, robust_scm2double (me->get_maybe_pure_property ("horizon-padding", pure, start, end), 0.0));
Real total_off = !isinf (dist) ? dir * dist : 0.0;
- total_off += dir * ss * robust_scm2double (me->get_property ("padding"), 0.0);
+ total_off += dir * ss * robust_scm2double (me->get_maybe_pure_property ("padding", pure, start, end), 0.0);
- Real minimum_space = ss * robust_scm2double (me->get_property ("minimum-space"), -1);
+ Real minimum_space = ss * robust_scm2double (me->get_maybe_pure_property ("minimum-space", pure, start, end), -1);
if (minimum_space >= 0
&& dir
Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
if (staff && a == Y_AXIS)
{
- if (to_boolean (me->get_property ("quantize-position")))
+ if (quantize_position)
{
Grob *common = me->common_refpoint (staff, Y_AXIS);
Real my_off = me->get_parent (Y_AXIS)->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
total_off += dir * 0.5 * ss;
}
}
- else if (scm_is_number (me->get_property ("staff-padding")) && dir)
+ else if (scm_is_number (me->get_maybe_pure_property ("staff-padding", pure, start, end)) && dir)
{
Interval iv = me->maybe_pure_extent (me, a, pure, start, end);
Real staff_padding
= Staff_symbol_referencer::staff_space (me)
- * scm_to_double (me->get_property ("staff-padding"));
+ * scm_to_double (me->get_maybe_pure_property ("staff-padding", pure, start, end));
Grob *parent = me->get_parent (Y_AXIS);
Grob *common = me->common_refpoint (staff, Y_AXIS);
chain_offset_callback (me,
(a == X_AXIS)
? x_aligned_side_proc
- : y_aligned_side_proc,
+ : ly_make_unpure_pure_container (y_aligned_side_proc, pure_y_aligned_side_proc),
a);
}
}
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
#include "simple-closure.hh"
+#include "unpure-pure-container.hh"
#include "grob.hh"
if (is_simple_closure (expr))
{
SCM inside = simple_closure_expression (expr);
+ SCM proc = is_unpure_pure_container (scm_car (inside))
+ ? (pure ? scm_car (inside) : unpure_pure_container_unpure_part (scm_car (inside)))
+ : scm_car (inside);
SCM args = scm_cons (delayed_argument,
evaluate_args (delayed_argument, scm_cdr (inside),
pure, start, end));
if (scm_cdr (args) == SCM_UNSPECIFIED)
return SCM_UNSPECIFIED;
if (pure)
- return call_pure_function (scm_car (inside), args, start, end);
- return scm_apply_0 (scm_car (inside), args);
+ return call_pure_function (proc, args, start, end);
+ return scm_apply_0 (proc, args);
}
else if (!scm_is_pair (expr))
return expr;
else if (scm_car (expr) == ly_symbol2scm ("quote"))
return scm_cadr (expr);
- else if (ly_is_procedure (scm_car (expr)))
+ else if (is_unpure_pure_container (scm_car (expr))
+ || ly_is_procedure (scm_car (expr)))
{
+ SCM proc = is_unpure_pure_container (scm_car (expr))
+ ? (pure ? scm_car (expr) : unpure_pure_container_unpure_part (scm_car (expr)))
+ : scm_car (expr);
SCM args = evaluate_args (delayed_argument, scm_cdr (expr), pure, start, end);
if (args == SCM_UNSPECIFIED)
return SCM_UNSPECIFIED;
if (pure)
- return call_pure_function (scm_car (expr), args, start, end);
- return scm_apply_0 (scm_car (expr), args);
+ return call_pure_function (proc, args, start, end);
+ return scm_apply_0 (proc, args);
}
else
// ugh. deviation from standard. Should print error?
Real x = robust_scm2double (x_scm, 0.0);
return scm_from_double (Skyline::unsmob (skyline_scm)->height (x));
}
+
+LY_DEFINE (ly_skyline_empty_p, "ly:skyline-empty?",
+ 1, 0, 0, (SCM sky),
+ "Return whether @var{sky} is empty.")
+{
+ Skyline *s = Skyline::unsmob (sky);
+ LY_ASSERT_SMOB (Skyline, sky, 1);
+ return scm_from_bool (s->is_empty ());
+}
#include "international.hh"
#include "note-column.hh"
#include "slur.hh"
+#include "slur-proto-engraver.hh"
#include "spanner.hh"
#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
-/*
- NOTE NOTE NOTE
-
- This is largely similar to Phrasing_slur_engraver. Check if fixes
- apply there too.
-
- (on principle, engravers don't use inheritance for code sharing)
-
- */
-
-/*
- It is possible that a slur starts and ends on the same note. At
- least, it is for phrasing slurs: a note can be both beginning and
- ending of a phrase.
-*/
-class Slur_engraver : public Engraver
+class Slur_engraver : public Slur_proto_engraver
{
- vector<Stream_event *> start_events_;
- vector<Stream_event *> stop_events_;
- vector<Grob *> slurs_;
- vector<Grob *> end_slurs_;
- vector<Grob_info> objects_to_acknowledge_;
-
- void set_melisma (bool);
+ virtual void set_melisma (bool);
protected:
DECLARE_TRANSLATOR_LISTENER (slur);
- DECLARE_ACKNOWLEDGER (inline_accidental);
- DECLARE_ACKNOWLEDGER (fingering);
- DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (script);
- DECLARE_ACKNOWLEDGER (dots);
- DECLARE_ACKNOWLEDGER (text_script);
- DECLARE_END_ACKNOWLEDGER (tie);
- DECLARE_ACKNOWLEDGER (tuplet_number);
-
- void acknowledge_extra_object (Grob_info);
- void stop_translation_timestep ();
- void process_music ();
-
- virtual void finalize ();
- virtual void derived_mark () const;
public:
TRANSLATOR_DECLARATIONS (Slur_engraver);
};
-Slur_engraver::Slur_engraver ()
+Slur_engraver::Slur_engraver () :
+ Slur_proto_engraver ("doubleSlurs", "Slur", "slur", "slur-event")
{
}
-void
-Slur_engraver::derived_mark () const
-{
- for (vsize i = start_events_.size (); i--;)
- scm_gc_mark (start_events_[i]->self_scm ());
- for (vsize i = stop_events_.size (); i--;)
- scm_gc_mark (stop_events_[i]->self_scm ());
-}
-
IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, slur);
void
Slur_engraver::listen_slur (Stream_event *ev)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- if (d == START)
- start_events_.push_back (ev);
- else if (d == STOP)
- stop_events_.push_back (ev);
- else ev->origin ()->warning (_f ("direction of %s invalid: %d",
- "slur-event", int (d)));
+ internal_listen_slur (ev);
}
void
Slur_engraver::set_melisma (bool m)
{
- context ()->set_property ("slurMelismaBusy", m ? SCM_BOOL_T : SCM_BOOL_F);
-}
-
-void
-Slur_engraver::acknowledge_note_column (Grob_info info)
-{
- Grob *e = info.grob ();
- 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
-Slur_engraver::acknowledge_extra_object (Grob_info info)
-{
- objects_to_acknowledge_.push_back (info);
-}
-
-void
-Slur_engraver::acknowledge_inline_accidental (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_dots (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_fingering (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_tuplet_number (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_script (Grob_info info)
-{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface")))
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_text_script (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::acknowledge_end_tie (Grob_info info)
-{
- acknowledge_extra_object (info);
-}
-
-void
-Slur_engraver::finalize ()
-{
- for (vsize i = 0; i < slurs_.size (); i++)
- {
- slurs_[i]->warning (_ ("unterminated slur"));
- slurs_[i]->suicide ();
- }
- slurs_.clear ();
-}
-
-void
-Slur_engraver::process_music ()
-{
- for (vsize i = 0; i < stop_events_.size (); i++)
- {
- Stream_event *ev = stop_events_[i];
- string id = robust_scm2string (ev->get_property ("spanner-id"), "");
-
- // Find the slurs that are ended with this event (by checking the spanner-id)
- bool ended = false;
- for (vsize j = slurs_.size (); j--;)
- {
- if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
- {
- ended = true;
- end_slurs_.push_back (slurs_[j]);
- slurs_.erase (slurs_.begin () + j);
- }
- }
- if (ended)
- {
- // Ignore redundant stop events for this id
- for (vsize j = stop_events_.size (); --j > i;)
- {
- if (id == robust_scm2string (stop_events_[j]->get_property ("spanner-id"), ""))
- stop_events_.erase (stop_events_.begin () + j);
- }
- }
- else
- ev->origin ()->warning (_ ("cannot end slur"));
- }
-
- vsize old_slurs = slurs_.size ();
- for (vsize i = start_events_.size (); i--;)
- {
- Stream_event *ev = start_events_[i];
- string id = robust_scm2string (ev->get_property ("spanner-id"), "");
- Direction updown = to_dir (ev->get_property ("direction"));
-
- bool completed;
- for (vsize j = slurs_.size (); !(completed = (j-- == 0));)
- {
- // Check if we already have a slur with the same spanner-id.
- if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
- {
- if (j < old_slurs)
- {
- // We already have an old slur, so give a warning
- // and completely ignore the new slur.
- ev->origin ()->warning (_ ("already have slur"));
- start_events_.erase (start_events_.begin () + i);
- break;
- }
-
- // If this slur event has no direction, it will not
- // contribute anything new to the existing slur(s), so
- // we can ignore it.
-
- if (!updown)
- break;
-
- Stream_event *c = unsmob_stream_event (slurs_[j]->get_property ("cause"));
-
- if (!c)
- {
- slurs_[j]->programming_error ("slur without a cause");
- continue;
- }
-
- Direction slur_dir = to_dir (c->get_property ("direction"));
-
- // If the existing slur does not have a direction yet,
- // we'd rather take the new one.
-
- if (!slur_dir)
- {
- slurs_[j]->suicide ();
- slurs_.erase (slurs_.begin () + j);
- continue;
- }
-
- // If the existing slur has the same direction as ours, drop ours
-
- if (slur_dir == updown)
- break;
- }
- }
- // If the loop completed, our slur is new
- if (completed)
- {
- Grob *slur = make_spanner ("Slur", ev->self_scm ());
- slur->set_property ("spanner-id", ly_string2scm (id));
- if (updown)
- set_grob_direction (slur, updown);
- slurs_.push_back (slur);
-
- if (to_boolean (get_property ("doubleSlurs")))
- {
- set_grob_direction (slur, DOWN);
- slur = make_spanner ("Slur", ev->self_scm ());
- slur->set_property ("spanner-id", ly_string2scm (id));
- set_grob_direction (slur, UP);
- slurs_.push_back (slur);
- }
- }
- }
- set_melisma (slurs_.size ());
-}
-
-void
-Slur_engraver::stop_translation_timestep ()
-{
- if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
- {
- 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 < slurs_.size (); i++)
- Slur::add_extra_encompass (slurs_[i], g);
- }
-
- for (vsize i = 0; i < end_slurs_.size (); i++)
- {
- 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], slurs_, end_slurs_);
-
- objects_to_acknowledge_.clear ();
- end_slurs_.clear ();
- start_events_.clear ();
- stop_events_.clear ();
+ context ()->set_property ("slurMelismaBusy", ly_bool2scm (m));
}
ADD_ACKNOWLEDGER (Slur_engraver, inline_accidental);
--- /dev/null
+/*
+ This file is part of LilyPond, the GNU music typesetter.
+
+ Copyright (C) 2013 Mike Solomon <mike@mikesolomon.org>
+
+ 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 "engraver.hh"
+
+#include "context.hh"
+#include "directional-element-interface.hh"
+#include "international.hh"
+#include "note-column.hh"
+#include "slur.hh"
+#include "slur-proto-engraver.hh"
+#include "spanner.hh"
+#include "stream-event.hh"
+#include "warn.hh"
+
+#include "translator.icc"
+
+void
+Slur_proto_engraver::derived_mark () const
+{
+ for (vsize i = start_events_.size (); i--;)
+ scm_gc_mark (start_events_[i]->self_scm ());
+ for (vsize i = stop_events_.size (); i--;)
+ scm_gc_mark (stop_events_[i]->self_scm ());
+}
+
+void
+Slur_proto_engraver::internal_listen_slur (Stream_event *ev)
+{
+ Direction d = to_dir (ev->get_property ("span-direction"));
+ if (d == START)
+ start_events_.push_back (ev);
+ else if (d == STOP)
+ stop_events_.push_back (ev);
+ else ev->origin ()->warning (_f ("direction of %s invalid: %d",
+ event_name_, int (d)));
+}
+
+void
+Slur_proto_engraver::acknowledge_note_column (Grob_info info)
+{
+ Grob *e = info.grob ();
+ 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
+Slur_proto_engraver::acknowledge_extra_object (Grob_info info)
+{
+ objects_to_acknowledge_.push_back (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_inline_accidental (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_dots (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_fingering (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_tuplet_number (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_script (Grob_info info)
+{
+ if (!info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface")))
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_text_script (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::acknowledge_end_tie (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+void
+Slur_proto_engraver::finalize ()
+{
+ for (vsize i = 0; i < slurs_.size (); i++)
+ {
+ slurs_[i]->warning (_f ("unterminated %s", object_name_));
+ slurs_[i]->suicide ();
+ }
+ slurs_.clear ();
+}
+
+void
+Slur_proto_engraver::create_slur (string spanner_id, Stream_event *ev_cause, Grob *g_cause, Direction dir, bool left_broken)
+{
+ Grob *ccc = unsmob_grob (get_property ("currentCommandColumn"));
+ SCM cause = ev_cause ? ev_cause->self_scm () : g_cause->self_scm ();
+ Spanner *slur = make_spanner (grob_name_, cause);
+ slur->set_property ("spanner-id", ly_string2scm (spanner_id));
+ if (dir)
+ set_grob_direction (slur, dir);
+ if (left_broken)
+ slur->set_bound (LEFT, ccc);
+ slurs_.push_back (slur);
+ if (double_property_name_
+ && to_boolean (get_property (double_property_name_)))
+ {
+ set_grob_direction (slur, DOWN);
+ slur = make_spanner (grob_name_, cause);
+ slur->set_property ("spanner-id", ly_string2scm (spanner_id));
+ set_grob_direction (slur, UP);
+ if (left_broken)
+ slur->set_bound (LEFT, ccc);
+ slurs_.push_back (slur);
+ }
+
+}
+
+bool
+Slur_proto_engraver::can_create_slur (string id, vsize old_slurs, vsize *event_idx, Stream_event *ev)
+{
+ for (vsize j = slurs_.size (); j--;)
+ {
+ Grob *slur = slurs_[j];
+ Direction updown = to_dir (ev->get_property ("direction"));
+
+ // Check if we already have a slur with the same spanner-id.
+ if (id == robust_scm2string (slur->get_property ("spanner-id"), ""))
+ {
+ if (j < old_slurs)
+ {
+ // We already have an old slur, so give a warning
+ // and completely ignore the new slur.
+ ev->origin ()->warning (_f ("already have %s", object_name_));
+ if (event_idx)
+ start_events_.erase (start_events_.begin () + (*event_idx));
+ return false;
+ }
+
+ // If this slur event has no direction, it will not
+ // contribute anything new to the existing slur(s), so
+ // we can ignore it.
+
+ if (!updown)
+ return false;
+
+ Stream_event *c = unsmob_stream_event (slur->get_property ("cause"));
+
+ if (!c)
+ {
+ slur->programming_error (_f ("%s without a cause", object_name_));
+ return true;
+ }
+
+ Direction slur_dir = to_dir (c->get_property ("direction"));
+
+ // If the existing slur does not have a direction yet,
+ // we'd rather take the new one.
+
+ if (!slur_dir)
+ {
+ slur->suicide ();
+ slurs_.erase (slurs_.begin () + j);
+ return true;
+ }
+
+ // If the existing slur has the same direction as ours, drop ours
+
+ if (slur_dir == updown)
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+Slur_proto_engraver::try_to_end (Stream_event *ev)
+{
+ string id = robust_scm2string (ev->get_property ("spanner-id"), "");
+
+ // Find the slurs that are ended with this event (by checking the spanner-id)
+ bool ended = false;
+ for (vsize j = slurs_.size (); j--;)
+ {
+ if (id == robust_scm2string (slurs_[j]->get_property ("spanner-id"), ""))
+ {
+ ended = true;
+ end_slurs_.push_back (slurs_[j]);
+ slurs_.erase (slurs_.begin () + j);
+ }
+ }
+ return ended;
+}
+
+void
+Slur_proto_engraver::process_music ()
+{
+ for (vsize i = 0; i < stop_events_.size (); i++)
+ {
+ string id = robust_scm2string (stop_events_[i]->get_property ("spanner-id"), "");
+ bool ended = try_to_end (stop_events_[i]);
+ if (ended)
+ {
+ // Ignore redundant stop events for this id
+ for (vsize j = stop_events_.size (); --j > i;)
+ {
+ if (id == robust_scm2string (stop_events_[j]->get_property ("spanner-id"), ""))
+ stop_events_.erase (stop_events_.begin () + j);
+ }
+ }
+ else
+ stop_events_[i]->origin ()->warning (_f ("cannot end %s", object_name_));
+ }
+
+ vsize old_slurs = slurs_.size ();
+ for (vsize i = start_events_.size (); i--;)
+ {
+ Stream_event *ev = start_events_[i];
+ string id = robust_scm2string (ev->get_property ("spanner-id"), "");
+ Direction updown = to_dir (ev->get_property ("direction"));
+
+ if (can_create_slur (id, old_slurs, &i, ev))
+ create_slur (id, ev, 0, updown, false);
+ }
+
+ set_melisma (slurs_.size ());
+}
+
+void
+Slur_proto_engraver::set_melisma (bool)
+{
+}
+
+void
+Slur_proto_engraver::stop_translation_timestep ()
+{
+ if (Grob *g = unsmob_grob (get_property ("currentCommandColumn")))
+ {
+ 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 < slurs_.size (); i++)
+ Slur::add_extra_encompass (slurs_[i], g);
+ }
+
+ for (vsize i = 0; i < end_slurs_.size (); i++)
+ {
+ 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], slurs_, end_slurs_);
+
+ objects_to_acknowledge_.clear ();
+ end_slurs_.clear ();
+ start_events_.clear ();
+ stop_events_.clear ();
+}
+
+// no ADD_ACKNOWLEDGER / ADD_TRANSLATOR macro calls
+// since this class is abstract
#include "warn.hh"
#include "slur-scoring.hh"
#include "separation-item.hh"
+#include "unpure-pure-container.hh"
#include "international.hh"
MAKE_SCHEME_CALLBACK (Slur, calc_direction, 1)
{
if (slur)
{
- chain_offset_callback (e, outside_slur_callback_proc, Y_AXIS);
+ chain_offset_callback (e,
+ ly_make_unpure_pure_container (outside_slur_callback_proc,
+ pure_outside_slur_callback_proc),
+ Y_AXIS);
chain_callback (e, outside_slur_cross_staff_proc, ly_symbol2scm ("cross-staff"));
e->set_object ("slur", slur->self_scm ());
}
}
SCM
-Grob::internal_skylines_from_element_stencils (SCM smob, Axis a)
+Grob::internal_skylines_from_element_stencils (Grob *me, Axis a, bool pure, int beg, int end)
{
- Grob *me = unsmob_grob (smob);
extract_grob_set (me, "elements", elts);
vector<Real> x_pos;
for (vsize i = 0; i < elts.size (); i++)
{
x_pos.push_back (elts[i]->relative_coordinate (x_common, X_AXIS));
- y_pos.push_back (elts[i]->relative_coordinate (y_common, Y_AXIS));
+ y_pos.push_back (elts[i]->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end));
}
Real my_x = me->relative_coordinate (x_common, X_AXIS);
- Real my_y = me->relative_coordinate (y_common, Y_AXIS);
+ Real my_y = me->maybe_pure_coordinate (y_common, Y_AXIS, pure, beg, end);
+
Skyline_pair res;
for (vsize i = 0; i < elts.size (); i++)
{
- Skyline_pair *skyp = Skyline_pair::unsmob (elts[i]->get_property (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines"));
+ Skyline_pair *skyp = Skyline_pair::unsmob (elts[i]->get_maybe_pure_property (a == X_AXIS ? "vertical-skylines" : "horizontal-skylines", pure, beg, end));
if (skyp)
{
/*
SCM
Grob::vertical_skylines_from_element_stencils (SCM smob)
{
- return internal_skylines_from_element_stencils (smob, X_AXIS);
+ Grob *me = unsmob_grob (smob);
+ return internal_skylines_from_element_stencils (me, X_AXIS, false, 0, INT_MAX);
}
MAKE_SCHEME_CALLBACK (Grob, horizontal_skylines_from_element_stencils, 1);
SCM
Grob::horizontal_skylines_from_element_stencils (SCM smob)
{
- return internal_skylines_from_element_stencils (smob, Y_AXIS);
+ Grob *me = unsmob_grob (smob);
+ return internal_skylines_from_element_stencils (me, Y_AXIS, false, 0, INT_MAX);
+}
+
+MAKE_SCHEME_CALLBACK (Grob, pure_vertical_skylines_from_element_stencils, 3);
+SCM
+Grob::pure_vertical_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM end_scm)
+{
+ Grob *me = unsmob_grob (smob);
+ int beg = robust_scm2int (beg_scm, 0);
+ int end = robust_scm2int (end_scm, 0);
+ return internal_skylines_from_element_stencils (me, X_AXIS, true, beg, end);
+}
+
+MAKE_SCHEME_CALLBACK (Grob, pure_horizontal_skylines_from_element_stencils, 3);
+SCM
+Grob::pure_horizontal_skylines_from_element_stencils (SCM smob, SCM beg_scm, SCM end_scm)
+{
+ Grob *me = unsmob_grob (smob);
+ int beg = robust_scm2int (beg_scm, 0);
+ int end = robust_scm2int (end_scm, 0);
+ return internal_skylines_from_element_stencils (me, Y_AXIS, true, beg, end);
}
extract_grob_set (me, "elements", elts);
vector<Grob *> relevant_grobs;
- SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
for (vsize i = 0; i < elts.size (); ++i)
{
if (!Axis_group_interface::has_interface (elts[i]))
{
- if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
- relevant_grobs.push_back (elts[i]);
+ relevant_grobs.push_back (elts[i]);
if (Item *it = dynamic_cast<Item *> (elts[i]))
{
for (LEFT_and_RIGHT (d))
{
Item *piece = it->find_prebroken_piece (d);
- if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
+ if (piece && piece->is_live ())
relevant_grobs.push_back (piece);
}
}
if (e.engraver_ == origin)
continue;
- (*e.function_) (e.engraver_, gi);
+ (e.engraver_->*e.function_) (gi);
}
}
#include "grob.hh"
static scm_t_bits unpure_pure_container_tag;
+static scm_t_bits unpure_pure_call_tag;
+// Used for rerouting a function of (grob start end) to one of
+// (grob)
bool
is_unpure_pure_container (SCM s)
unpure_pure_container_unpure_part (SCM smob)
{
LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1);
- return (SCM) SCM_CELL_WORD_1 (smob);
+ return SCM_SMOB_OBJECT (smob);
}
SCM
unpure_pure_container_pure_part (SCM smob)
{
LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1);
- return (SCM) SCM_CELL_WORD_2 (smob);
+ SCM res = SCM_SMOB_OBJECT_2 (smob);
+
+ if (!SCM_UNBNDP (res))
+ return res;
+
+ SCM_NEWSMOB (res, unpure_pure_call_tag,
+ SCM_UNPACK (unpure_pure_container_unpure_part (smob)));
+ return res;
}
LY_DEFINE (ly_unpure_pure_container_p, "ly:unpure-pure-container?",
1, 1, 0, (SCM unpure, SCM pure),
"Make an unpure-pure container. @var{unpure} should be an unpure"
" expression, and @var{pure} should be a pure expression. If @var{pure}"
- " is ommitted, the value of @var{unpure} will be used twice.")
+ " is omitted, the value of @var{unpure} will be used twice,"
+ " except that a callback is given two extra arguments"
+ " that are ignored for the sake of pure calculations.")
{
SCM z;
- if (pure == SCM_UNDEFINED)
+ if (SCM_UNBNDP (pure) && !ly_is_procedure (unpure))
pure = unpure;
SCM_NEWSMOB2 (z, unpure_pure_container_tag, SCM_UNPACK (unpure), SCM_UNPACK (pure));
{
scm_puts ("#<unpure-pure-container ", port);
scm_display (unpure_pure_container_unpure_part (s), port);
- scm_puts (" ", port);
- scm_display (unpure_pure_container_pure_part (s), port);
+ if (!SCM_UNBNDP (SCM_SMOB_OBJECT_2 (s)))
+ {
+ scm_puts (" ", port);
+ scm_display (unpure_pure_container_pure_part (s), port);
+ }
scm_puts (" >", port);
return 1;
}
SCM
-pure_mark (SCM pure)
+pure_mark (SCM smob)
{
- scm_gc_mark (unpure_pure_container_unpure_part (pure));
- scm_gc_mark (unpure_pure_container_pure_part (pure));
- return pure;
+ scm_gc_mark (SCM_SMOB_OBJECT (smob));
+ return SCM_SMOB_OBJECT_2 (smob);
+}
+
+// Function signature has two fixed arguments so that dropping two
+// will always work: if we have fewer to start with, it will trigger
+// wrong-number-of-args in a sensible location rather than making
+// drop-right barf.
+
+SCM
+apply_unpure_pure (SCM clo, SCM arg1, SCM arg2, SCM rest)
+{
+ return scm_apply_0 (SCM_SMOB_OBJECT (clo),
+ scm_call_2 (ly_lily_module_constant ("drop-right"),
+ scm_cons2 (arg1, arg2, rest),
+ scm_from_int (2)));
}
+
void init_unpure_pure_container ()
{
unpure_pure_container_tag = scm_make_smob_type ("unpure-pure-container", 0);
scm_set_smob_mark (unpure_pure_container_tag, pure_mark);
scm_set_smob_print (unpure_pure_container_tag, print_unpure_pure_container);
+ unpure_pure_call_tag = scm_make_smob_type ("unpure-pure-call", 0);
+ scm_set_smob_mark (unpure_pure_call_tag, scm_markcdr);
+ scm_set_smob_apply (unpure_pure_call_tag,
+ (SCM (*)()) apply_unpure_pure, 2, 0, 1);
};
ADD_SCM_INIT_FUNC (unpure_pure_container, init_unpure_pure_container);
\description "Same as @code{Voice} context, except that it is
accommodated for typesetting a piece in Kievan style."
+ \remove "Ligature_bracket_engraver"
+ \consists "Kievan_ligature_engraver"
+
%% Set glyph styles.
\override NoteHead.style = #'kievan
\override Stem.X-offset = #stem::kievan-offset-callback
#{
\set harmonicDots = ##t
\temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (number->string fret))
- \temporary \override NoteHead.Y-extent = #(ly:make-unpure-pure-container ly:grob::stencil-height
- (lambda (grob start end)
- (ly:grob::stencil-height grob)))
+ \temporary \override NoteHead.Y-extent = #grob::always-Y-extent-from-stencil
\temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
(ly:note-head::print grob))
#(make-harmonic
'quoted-context-id "cue"
'quoted-music-name what
'quoted-voice-direction dir
+ ;; following is inverse of instrumentTransposition for
+ ;; historical reasons
'quoted-transposition pitch))
transposition =
(_i "Set instrument transposition")
(context-spec-music
- (make-property-set 'instrumentTransposition
- (ly:pitch-negate pitch))
+ (make-property-set 'instrumentTransposition pitch)
'Staff))
tuplet =
\context {
\name Global
\accepts Score
+ \defaultchild Score
\description "Hard coded entry point for LilyPond. Cannot be tuned."
EventClasses = #all-event-classes
}
\type "Performer_group"
\consists "Staff_performer"
\accepts ChordNameVoice
+ \defaultchild ChordNameVoice
\name ChordNames
}
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: lilypond 2.17.12\n"
+"Project-Id-Version: lilypond 2.17.13\n"
"Report-Msgid-Bugs-To: http://post.gmane.org/post.php?group=gmane.comp.gnu."
"lilypond.bugs\n"
-"POT-Creation-Date: 2013-02-08 17:02+0000\n"
+"POT-Creation-Date: 2013-02-23 16:12+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "alteration not found"
msgstr ""
-#: ligature-bracket-engraver.cc:72 ligature-engraver.cc:104
+#: ligature-bracket-engraver.cc:72 ligature-engraver.cc:109
msgid "cannot find start of ligature"
msgstr ""
-#: ligature-bracket-engraver.cc:85 ligature-engraver.cc:131
+#: ligature-bracket-engraver.cc:85 ligature-engraver.cc:136
msgid "already have a ligature"
msgstr ""
-#: ligature-engraver.cc:109
+#: ligature-engraver.cc:114
msgid "no right bound"
msgstr ""
-#: ligature-engraver.cc:140
+#: ligature-engraver.cc:145
msgid "no left bound"
msgstr ""
-#: ligature-engraver.cc:184
+#: ligature-engraver.cc:189
msgid "unterminated ligature"
msgstr ""
-#: ligature-engraver.cc:211
+#: ligature-engraver.cc:216
msgid "ignoring rest: ligature may not contain rest"
msgstr ""
-#: ligature-engraver.cc:212
+#: ligature-engraver.cc:217
msgid "ligature was started here"
msgstr ""
msgid "type check for `%s' failed; value `%s' must be of type `%s'"
msgstr ""
-#: lily-lexer.cc:246
+#: lily-lexer.cc:249
msgid "include files are not allowed in safe mode"
msgstr ""
-#: lily-lexer.cc:273
+#: lily-lexer.cc:276
#, c-format
msgid "identifier name is a keyword: `%s'"
msgstr ""
-#: lily-lexer.cc:294 lily-lexer.cc:307
+#: lily-lexer.cc:297 lily-lexer.cc:310
#, c-format
msgid "%s:EOF"
msgstr ""
msgid "Processing `%s'"
msgstr ""
-#: lily-parser-scheme.cc:208
+#: lily-parser-scheme.cc:209
msgid ""
"ly:parser-parse-string is only valid with a new parser. Use ly:parser-"
"include-string instead."
msgstr ""
-#: lily-parser-scheme.cc:239
+#: lily-parser-scheme.cc:240
msgid ""
"ly:parse-string-expression is only valid with a new parser. Use ly:parser-"
"include-string instead."
msgstr ""
-#: lily-parser.cc:108
+#: lily-parser.cc:107
msgid "Parsing..."
msgstr ""
msgid "Calculating page breaks..."
msgstr ""
-#: multi-measure-rest.cc:153
+#: multi-measure-rest.cc:152
msgid ""
"usable-duration-logs must be a non-empty list. Falling back to whole rests."
msgstr ""
-#: multi-measure-rest.cc:343
+#: multi-measure-rest.cc:342
msgid "Using naive multi measure rest spacing."
msgstr ""
msgid "Too much lookahead"
msgstr ""
-#: parser.yy:464 parser.yy:732 parser.yy:799
+#: parser.yy:466 parser.yy:734 parser.yy:801
msgid "bad expression type"
msgstr ""
-#: parser.yy:628 parser.yy:1113
+#: parser.yy:630 parser.yy:1115
msgid "not a context mod"
msgstr ""
-#: parser.yy:834
+#: parser.yy:836
msgid "score expected"
msgstr ""
-#: parser.yy:850
+#: parser.yy:852
msgid "\\paper cannot be used in \\score, use \\layout instead"
msgstr ""
-#: parser.yy:874
+#: parser.yy:876
msgid "need \\paper for paper block"
msgstr ""
-#: parser.yy:1022 parser.yy:1033
+#: parser.yy:1024 parser.yy:1035
msgid "unexpected post-event"
msgstr ""
-#: parser.yy:1038
+#: parser.yy:1040
msgid "Ignoring non-music expression"
msgstr ""
-#: parser.yy:1049 parser.yy:2304
+#: parser.yy:1051 parser.yy:2306
msgid "music expected"
msgstr ""
-#: parser.yy:1317
+#: parser.yy:1319
msgid "not a symbol"
msgstr ""
-#: parser.yy:2008 parser.yy:2119 parser.yy:2132 parser.yy:2141
+#: parser.yy:2010 parser.yy:2121 parser.yy:2134 parser.yy:2143
msgid "bad grob property path"
msgstr ""
-#: parser.yy:2099
+#: parser.yy:2101
msgid "only \\consists and \\remove take non-string argument."
msgstr ""
-#: parser.yy:2160
+#: parser.yy:2162
msgid "bad context property path"
msgstr ""
-#: parser.yy:2253 parser.yy:2257 parser.yy:2272
+#: parser.yy:2255 parser.yy:2259 parser.yy:2274
msgid "simple string expected"
msgstr ""
-#: parser.yy:2413
+#: parser.yy:2415
msgid "not a rhythmic event"
msgstr ""
-#: parser.yy:2509 parser.yy:2514 parser.yy:3057
+#: parser.yy:2511 parser.yy:2516 parser.yy:3059
msgid "have to be in Lyric mode for lyrics"
msgstr ""
-#: parser.yy:2629
+#: parser.yy:2631
msgid "expecting string as script definition"
msgstr ""
-#: parser.yy:2724
+#: parser.yy:2726
msgid "not an articulation"
msgstr ""
-#: parser.yy:2796 parser.yy:2842
+#: parser.yy:2798 parser.yy:2844
#, c-format
msgid "not a duration: %d"
msgstr ""
-#: parser.yy:2859
+#: parser.yy:2861
msgid "bass number expected"
msgstr ""
-#: parser.yy:2973
+#: parser.yy:2975
msgid "have to be in Note mode for notes"
msgstr ""
-#: parser.yy:3032
+#: parser.yy:3034
msgid "have to be in Chord mode for chords"
msgstr ""
-#: parser.yy:3256
+#: parser.yy:3258
msgid "not a markup"
msgstr ""
"add-bar-glyph-print-procedure: glyph '~a' has to be a single ASCII character."
msgstr ""
-#: bar-line.scm:808
+#: bar-line.scm:802
#, scheme-format
msgid "No span bar glyph defined for bar glyph '~a'; ignoring."
msgstr ""
msgid "defaulting to ~S pt"
msgstr ""
-#: define-markup-commands.scm:3329
+#: define-markup-commands.scm:3420
#, scheme-format
msgid "not a valid duration string: ~a"
msgstr ""
-#: define-markup-commands.scm:3540
+#: define-markup-commands.scm:3631
#, scheme-format
msgid "not a valid duration string: ~a - ignoring"
msgstr ""
-#: define-music-types.scm:770
+#: define-music-types.scm:772
#, scheme-format
msgid "symbol expected: ~S"
msgstr ""
-#: define-music-types.scm:773
+#: define-music-types.scm:775
#, scheme-format
msgid "cannot find music object: ~S"
msgstr ""
-#: define-music-types.scm:792
+#: define-music-types.scm:794
#, scheme-format
msgid "unknown repeat type `~S'"
msgstr ""
-#: define-music-types.scm:793
+#: define-music-types.scm:795
msgid "See define-music-types.scm for supported repeats"
msgstr ""
msgid "Error in beam quanting. Expected ~S 0, found ~S."
msgstr ""
-#: lily-library.scm:340
+#: lily-library.scm:331
msgid "Music unsuitable for context-mod"
msgstr ""
-#: lily-library.scm:395
+#: lily-library.scm:386
#, scheme-format
msgid "Cannot find context-def \\~a"
msgstr ""
-#: lily-library.scm:411
+#: lily-library.scm:402
msgid "Music unsuitable for output-def"
msgstr ""
-#: lily-library.scm:927
+#: lily-library.scm:901
msgid ""
"Find the index between @var{start} and @var{end} (an integer)\n"
"which produces the closest match to @var{target-val} if\n"
"applied to function @var{getter}."
msgstr ""
-#: lily-library.scm:1001
+#: lily-library.scm:975
#, scheme-format
msgid "unknown unit: ~S"
msgstr ""
-#: lily-library.scm:1026
+#: lily-library.scm:1000
#, scheme-format
msgid "no \\version statement found, please add~afor future compatibility"
msgstr ""
-#: lily-library.scm:1032
+#: lily-library.scm:1006
msgid "old relative compatibility not used"
msgstr ""
msgid "cannot find: ~A"
msgstr ""
-#: lily.scm:794
+#: lily.scm:795
msgid "Success: compilation successfully completed"
msgstr ""
-#: lily.scm:795
+#: lily.scm:796
msgid "Compilation completed with warnings or errors"
msgstr ""
-#: lily.scm:857
+#: lily.scm:858
#, scheme-format
msgid "job ~a terminated with signal: ~a"
msgstr ""
-#: lily.scm:860
+#: lily.scm:861
#, scheme-format
msgid ""
"logfile ~a (exit ~a):\n"
"~a"
msgstr ""
-#: lily.scm:882 lily.scm:971
+#: lily.scm:883 lily.scm:972
#, scheme-format
msgid "failed files: ~S"
msgstr ""
-#: lily.scm:962
+#: lily.scm:963
#, scheme-format
msgid "Redirecting output to ~a..."
msgstr ""
-#: lily.scm:981 ps-to-png.scm:66
+#: lily.scm:982 ps-to-png.scm:66
#, scheme-format
msgid "Invoking `~a'...\n"
msgstr ""
msgid "wrong type for argument ~a. Expecting ~a, found ~s"
msgstr ""
-#: ly-syntax-constructors.scm:188
+#: ly-syntax-constructors.scm:180
#, scheme-format
msgid "Invalid property operation ~a"
msgstr ""
msgid "Must use #(set-paper-size .. ) within \\paper { ... }"
msgstr ""
-#: parser-clef.scm:164 parser-clef.scm:215
+#: parser-clef.scm:164
#, scheme-format
msgid "unknown clef type `~a'"
msgstr ""
-#: parser-clef.scm:165 parser-clef.scm:216
+#: parser-clef.scm:165
#, scheme-format
msgid "supported clefs: ~a"
msgstr ""
-#: parser-ly-from-scheme.scm:73
+#: parser-ly-from-scheme.scm:74
msgid "error in #{ ... #}"
msgstr ""
msgid "assertion failed: ~S"
msgstr ""
-#: translation-functions.scm:374
+#: translation-functions.scm:368
#, scheme-format
msgid "Negative fret for pitch ~a on string ~a"
msgstr ""
-#: translation-functions.scm:377
+#: translation-functions.scm:371
#, scheme-format
msgid "Missing fret for pitch ~a on string ~a"
msgstr ""
-#: translation-functions.scm:420
+#: translation-functions.scm:414
#, scheme-format
msgid "No open string for pitch ~a"
msgstr ""
-#: translation-functions.scm:435 translation-functions.scm:447
+#: translation-functions.scm:429 translation-functions.scm:441
#, scheme-format
msgid "Requested string for pitch requires negative fret: string ~a pitch ~a"
msgstr ""
-#: translation-functions.scm:438
+#: translation-functions.scm:432
msgid "Ignoring string request and recalculating."
msgstr ""
-#: translation-functions.scm:450
+#: translation-functions.scm:444
msgid "Ignoring note in tablature."
msgstr ""
-#: translation-functions.scm:473
+#: translation-functions.scm:467
#, scheme-format
msgid "No string for pitch ~a (given frets ~a)"
msgstr ""
-#: translation-functions.scm:578
+#: translation-functions.scm:572
#, scheme-format
msgid ""
"No label for fret ~a (on string ~a);\n"
"The print routine for span bars."
(let* ((elts-array (ly:grob-object grob 'elements))
(refp (ly:grob-common-refpoint-of-array grob elts-array Y))
- (elts (reverse (sort (ly:grob-array->list elts-array)
- ly:grob-vertical<?)))
+ (elts (sort (ly:grob-array->list elts-array)
+ ly:grob-vertical<?))
;; Elements must be ordered according to their y coordinates
;; relative to their common axis group parent.
;; Otherwise, the computation goes mad.
- (bar-glyph (ly:grob-property grob 'glyph-name))
- (span-bar empty-stencil))
+ (bar-glyph (ly:grob-property grob 'glyph-name)))
(if (string? bar-glyph)
- (let ((extents '())
- (make-span-bars '())
- (model-bar #f))
-
- ;; we compute the extents of each system and store them
- ;; in a list; dito for the 'allow-span-bar property.
- ;; model-bar takes the bar grob, if given.
- (map (lambda (bar)
- (let ((ext (bar-line::bar-y-extent bar refp))
- (staff-symbol (ly:grob-object bar 'staff-symbol)))
-
- (if (ly:grob? staff-symbol)
- (let ((refp-extent (ly:grob-extent staff-symbol refp Y)))
-
- (set! ext (interval-union ext refp-extent))
-
- (if (> (interval-length ext) 0)
- (begin
- (set! extents (append extents (list ext)))
- (set! model-bar bar)
- (set! make-span-bars
- (append make-span-bars
- (list (ly:grob-property
- bar
- 'allow-span-bar
- #t))))))))))
- elts)
- ;; if there is no bar grob, we use the callback argument
- (if (not model-bar)
- (set! model-bar grob))
- ;; we discard the first entry in make-span-bars,
- ;; because its corresponding bar line is the
- ;; uppermost and therefore not connected to
- ;; another bar line
- (if (pair? make-span-bars)
- (set! make-span-bars (cdr make-span-bars)))
- ;; the span bar reaches from the lower end of the upper staff
- ;; to the upper end of the lower staff - when allow-span-bar is #t
- (reduce (lambda (curr prev)
- (let ((span-extent (cons 0 0))
- (allow-span-bar (car make-span-bars)))
-
- (set! make-span-bars (cdr make-span-bars))
- (if (> (interval-length prev) 0)
- (begin
- (set! span-extent (cons (cdr prev)
- (car curr)))
- ;; draw the span bar only when the staff lines
- ;; don't overlap and allow-span-bar is #t:
- (and (> (interval-length span-extent) 0)
- allow-span-bar
- (set! span-bar
- (ly:stencil-add
- span-bar
- (span-bar::compound-bar-line
- model-bar
- bar-glyph
- span-extent))))))
- curr))
- "" extents)
- (set! span-bar (ly:stencil-translate-axis
- span-bar
- (- (ly:grob-relative-coordinate grob refp Y))
- Y))))
- span-bar))
+ (let loop ((extents '())
+ (make-span-bars '())
+ ;; if there is no bar grob, we use the callback
+ ;; argument
+ (model-bar grob)
+ (bar-list elts))
+
+ ;; we compute the extents of each system and store them
+ ;; in a list; dito for the 'allow-span-bar property.
+ ;; model-bar takes the bar grob, if given.
+ (if (pair? bar-list)
+ (let* ((bar (car bar-list))
+ (ext (bar-line::bar-y-extent bar refp))
+ (staff-symbol (ly:grob-object bar 'staff-symbol)))
+ (if (ly:grob? staff-symbol)
+ (if (positive? (interval-length ext))
+ (loop (cons (interval-union
+ ext
+ (ly:grob-extent staff-symbol refp Y))
+ extents)
+ (cons (ly:grob-property
+ bar 'allow-span-bar #t)
+ make-span-bars)
+ bar
+ (cdr bar-list))
+ (loop extents make-span-bars
+ model-bar (cdr bar-list)))))
+ ;; end of loop
+ ;; model-bar is the last bar found in the elts list
+ ;; (former version had the first here).
+
+ ;; the span bar reaches from the lower end of the upper staff
+ ;; to the upper end of the lower staff - when
+ ;; allow-span-bar is #t
+
+ (if (pair? extents)
+ (ly:stencil-translate-axis
+ (fold
+ (lambda (curr prev allow-span-bar span-bar)
+ (if (and allow-span-bar
+ (positive? (interval-length prev)))
+ (let ((span-extent (cons (cdr prev) (car curr))))
+ ;; draw the span bar only when the staff lines
+ ;; don't overlap and allow-span-bar is #t:
+ (if (positive? (interval-length span-extent))
+ (ly:stencil-add
+ span-bar
+ (span-bar::compound-bar-line
+ model-bar
+ bar-glyph
+ span-extent))
+ span-bar))
+ span-bar))
+ empty-stencil
+ ;; we discard the first entry in make-span-bars,
+ ;; because its corresponding bar line is the
+ ;; uppermost and therefore not connected to
+ ;; another bar line
+ (cdr extents) extents (cdr make-span-bars))
+ (- (ly:grob-relative-coordinate grob refp Y)) Y)
+ empty-stencil)))
+ empty-stencil)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; volta bracket functions
(instrumentName ,markup? "The name to print left of a staff. The
@code{instrumentName} property labels the staff in the first system, and
the @code{shortInstrumentName} property labels following lines.")
- ;; the definition is reversed wrt traditional transposition
- ;; otherwise \transpose { \transposition .. } won't work
(instrumentTransposition ,ly:pitch? "Define the transposition of
-the instrument. Its value is the pitch that sounds like middle@tie{}C.
-This is used to transpose the MIDI output, and @code{\\quote}s.")
+the instrument. Its value is the pitch that sounds when the instrument
+plays written middle C. This is used to transpose the MIDI output,
+and @code{\\quote}s.")
(internalBarNumber ,integer? "Contains the current barnumber.
This property is used for internal timekeeping, among others by the
@code{Accidental_engraver}.")
;;
(c0-position ,integer? "An integer indicating the position of
middle@tie{}C.")
+ (chord-dots ,boolean? "If set, remove dots which the
+@code{DotColumn} algorithm would vertically position too far away from
+note heads.")
(circled-tip ,boolean? "Put a circle at start/@/end of
hairpins (al/@/del niente).")
(clip-edges ,boolean? "Allow outward pointing beamlets at the
;; TODO: junk the meta field in favor of something more compact?
+
(define-public all-grob-descriptions
`(
(Accidental
(glyph-name . ,accidental-interface::glyph-name)
(glyph-name-alist . ,standard-alteration-glyph-name-alist)
(stencil . ,ly:accidental-interface::print)
- (horizontal-skylines . ,ly:accidental-interface::horizontal-skylines)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (horizontal-skylines . ,(ly:make-unpure-pure-container ly:accidental-interface::horizontal-skylines))
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(X-extent . ,ly:accidental-interface::width)
- (Y-extent . ,ly:accidental-interface::height)
+ (Y-extent . ,accidental-interface::height)
(meta . ((class . Item)
(interfaces . (accidental-interface
inline-accidental-interface
(glyph-name-alist . ,standard-alteration-glyph-name-alist)
(parenthesized . #t)
(stencil . ,ly:accidental-interface::print)
- (Y-extent . ,ly:accidental-interface::height)
+ (Y-extent . ,accidental-interface::height)
(meta . ((class . Item)
(interfaces . (accidental-interface
inline-accidental-interface
(list ly:self-alignment-interface::centered-on-x-parent))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-extent . ,ly:accidental-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,accidental-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Item)
(interfaces . (accidental-interface
accidental-suggestion-interface
(time-signature . (extra-space . 0.0))
(first-note . (fixed-space . 0.0))))
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,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)))
(side-axis . ,X)
(stencil . ,ly:accidental-interface::print)
(X-offset . ,ly:side-position-interface::x-aligned-side)
- (Y-extent . ,ly:accidental-interface::height)
+ (Y-extent . ,accidental-interface::height)
(meta . ((class . Item)
(interfaces . (accidental-interface
break-aligned-interface
(duration-log . 2)
(glyph-name . ,note-head::calc-glyph-name)
(stencil . ,ly:note-head::print)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (ambitus-interface
font-interface
(staff-position . 0.0)
(stencil . ,ly:arpeggio::print)
(X-extent . ,ly:arpeggio::width)
+ (Y-extent . ,(grob::unpure-Y-extent-from-stencil ly:arpeggio::pure-height))
(X-offset . ,ly:side-position-interface::x-aligned-side)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (arpeggio-interface
font-interface
(next-note . (semi-fixed-space . 0.9))
(right-edge . (extra-space . 0.0))))
(stencil . ,ly:bar-line::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(list ly:break-alignable-interface::self-align-callback))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta .
((class . Item)
(interfaces . (break-alignable-interface
(BassFigure
. (
(stencil . ,ly:text-interface::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (bass-figure-interface
font-interface
(padding . 0.2)
(positioning-done . ,ly:align-interface::align-to-minimum-distances)
(stacking-dir . ,DOWN)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,axis-group-interface::height)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(padding . 0.5)
(side-axis . ,Y)
(staff-padding . 1.0)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(adjacent-pure-heights . ,ly:axis-group-interface::adjacent-pure-heights)
(axes . (,Y))
(vertical-skylines . ,ly:axis-group-interface::calc-skylines)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,axis-group-interface::height)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(quantized-positions . ,ly:beam::set-stem-lengths)
(shorten . ,ly:beam::calc-stem-shorten)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(stencil . ,ly:beam::print)
(meta . ((class . Spanner)
(stencil . ,ly:text-interface::print)
(text . ,(make-musicglyph-markup "scripts.rcomma"))
(Y-offset . ,ly:breathing-sign::offset-callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
breathing-sign-interface
(extra-spacing-height . (0.2 . -0.2))
(extra-spacing-width . (-0.5 . 0.5))
(word-space . 0.0)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (chord-name-interface
font-interface
(next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
;; todo: add X self alignment?
(stencil . ,ly:text-interface::print)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
side-position-interface
(next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(next-note . (extra-space . 1.0))
(right-edge . (extra-space . 0.5))))
(stencil . ,ly:clef::print)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(right-edge . (extra-space . 0.1))))
(stencil . ,ly:custos::print)
(style . vaticana)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
custos-interface
(DotColumn
. (
(axes . (,X))
+ (chord-dots . #t)
(direction . ,RIGHT)
(positioning-done . ,ly:dot-column::calc-positioning-done)
(X-extent . ,ly:axis-group-interface::width)
(dot-count . ,dots::calc-dot-count)
(staff-position . ,dots::calc-staff-position)
(stencil . ,ly:dots::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(extra-spacing-height . (-0.5 . 0.5))
(meta . ((class . Item)
(interfaces . (dots-interface
(slash-negative-kern . 1.6)
(slope . 1.0)
(stencil . ,ly:percent-repeat-item-interface::double-percent)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(thickness . 0.48)
(meta . ((class . Item)
(interfaces . (break-aligned-interface
(list ly:self-alignment-interface::centered-on-y-parent))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
percent-repeat-interface
(slash-negative-kern . 1.6)
(slope . 1.0)
(stencil . ,ly:percent-repeat-item-interface::beat-slash)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(thickness . 0.48)
(meta . ((class . Item)
(interfaces . (font-interface
(side-axis . ,Y)
(slur-padding . 0.3)
(staff-padding . 0.1)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-element-stencils)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(self-alignment-X . ,CENTER)
(self-alignment-Y . ,CENTER)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (Y-offset . ,ly:self-alignment-interface::y-aligned-on-self)
+ (Y-offset . ,self-alignment-interface::y-aligned-on-self)
(meta . ((class . Item)
(interfaces . (dynamic-interface
dynamic-text-interface
(springs-and-rods . ,ly:spanner::set-spacing-rods)
(stencil . ,ly:line-spanner::print)
(style . dashed-line)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(meta . ((class . Spanner)
(interfaces . (dynamic-interface
dynamic-text-spanner-interface
(side-axis . ,Y)
(stencil . ,ly:line-spanner::print)
(style . line)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (episema-interface
font-interface
(staff-padding . 0.5)
(stencil . ,ly:text-interface::print)
(text . ,fingering::calc-text)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (finger-interface
font-interface
(stencil . ,ly:flag::print)
(X-extent . ,ly:flag::width)
(X-offset . ,ly:flag::calc-x-offset)
- (Y-offset . ,ly:flag::calc-y-offset)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-offset . ,(ly:make-unpure-pure-container ly:flag::calc-y-offset ly:flag::pure-calc-y-offset))
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(meta . ((class . Item)
(interfaces . (flag-interface
font-interface))))))
(stencil . ,fret-board::calc-stencil)
(extra-spacing-height . (0.2 . -0.2))
(extra-spacing-width . (-0.5 . 0.5))
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (chord-name-interface
font-interface
(simple-Y . #t)
(stencil . ,ly:line-spanner::print)
(style . line)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(X-extent . #f)
(Y-extent . #f)
(zigzag-width . 0.75)
(stencil . ,ly:hairpin::print)
(thickness . 1.0)
(to-barline . #t)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:self-alignment-interface::y-aligned-on-self)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
+ (Y-extent . ,(grob::unpure-Y-extent-from-stencil ly:hairpin::pure-height))
+ (Y-offset . ,self-alignment-interface::y-aligned-on-self)
(meta . ((class . Spanner)
(interfaces . (dynamic-interface
hairpin-interface
(staff-padding . 0.2)
(stencil . ,ly:horizontal-bracket::print)
(thickness . 1.0)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (horizontal-bracket-interface
line-interface
(side-axis . ,Y)
(staff-padding . 0.5)
(stencil . ,ly:text-interface::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Item)
(interfaces . (font-interface
self-alignment-interface
(right-edge . (extra-space . 0.5))
(first-note . (fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(extra-spacing-width . (0.0 . 1.0))
(extra-spacing-height . ,pure-from-neighbor-interface::extra-spacing-height-including-staff)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(right-edge . (extra-space . 0.5))
(first-note . (fixed-space . 2.5))))
(stencil . ,ly:key-signature-interface::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(extra-spacing-width . (0.0 . 1.0))
(extra-spacing-height . ,pure-from-neighbor-interface::extra-spacing-height-including-staff)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
pure-from-neighbor-interface
staff-symbol-referencer-interface))))))
+ (KievanLigature
+ . (
+ (springs-and-rods . ,ly:spanner::set-spacing-rods)
+ (stencil . ,ly:kievan-ligature::print)
+ (padding . 0.5)
+ (meta . ((class . Spanner)
+ (interfaces . (font-interface
+ kievan-ligature-interface))))))
(LaissezVibrerTie
. (
(stencil . ,laissez-vibrer::print)
(thickness . 1.0)
(extra-spacing-height . (-0.5 . 0.5))
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (semi-tie-interface))))))
(minimum-length-fraction . 0.25)
(springs-and-rods . ,ly:ledger-line-spanner::set-spacing-rods)
(stencil . ,ly:ledger-line-spanner::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(X-extent . #f)
(Y-extent . #f)
(meta . ((class . Spanner)
(padding . 0.07)
(springs-and-rods . ,ly:lyric-hyphen::set-spacing-rods)
(stencil . ,ly:lyric-hyphen::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(thickness . 1.3)
(Y-extent . (0 . 0))
(meta . ((class . Spanner)
(text . ,(grob::calc-property-by-copy 'text))
(word-space . 0.6)
(skyline-horizontal-padding . 0.1)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(X-offset . ,ly:self-alignment-interface::aligned-on-x-parent)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
lyric-syllable-interface
(staff-padding . 3)
(stencil . ,ly:measure-grouping::print)
(thickness . 1)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (measure-grouping-interface
side-position-interface))))))
(padding . 0.8)
(side-axis . ,Y)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(X-offset . ,(ly:make-simple-closure
`(,+
,(ly:make-simple-closure
(self-alignment-X . ,LEFT)
(break-align-symbols . (time-signature))
(non-break-align-symbols . (multi-measure-rest-interface))
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (break-alignable-interface
font-interface
(thick-thickness . 6.6)
;; See Wanske pp. 125
(usable-duration-logs . ,(iota 4 -3))
- (Y-extent . ,ly:multi-measure-rest::height)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:multi-measure-rest::height))
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Spanner)
(interfaces . (font-interface
multi-measure-interface
(list ly:self-alignment-interface::x-aligned-on-self))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-centered-on-y-parent)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Spanner)
(interfaces . (font-interface
multi-measure-interface
(list ly:self-alignment-interface::x-centered-on-y-parent))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Spanner)
(interfaces . (font-interface
multi-measure-interface
(positioning-done . ,ly:note-collision-interface::calc-positioning-done)
(prefer-dotted-right . #t)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,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)))
(horizontal-skylines . ,ly:separation-item::calc-skylines)
(skyline-vertical-padding . 0.15)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,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)))
(stem-attachment . ,ly:note-head::calc-stem-attachment)
(stencil . ,ly:note-head::print)
(X-offset . ,ly:note-head::stem-x-shift)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
gregorian-ligature-interface
(NoteName
. (
(stencil . ,ly:text-interface::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
note-name-interface
(list ly:self-alignment-interface::x-aligned-on-self))
,(ly:make-simple-closure
(list ly:self-alignment-interface::centered-on-x-parent)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
octavate-eight-interface
(staff-padding . 1.0)
(stencil . ,ly:ottava-bracket::print)
(style . dashed-line)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (font-interface
horizontal-bracket-interface
(list ly:self-alignment-interface::x-centered-on-y-parent))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Spanner)
(interfaces . (font-interface
percent-repeat-interface
(springs-and-rods . ,ly:spanner::set-spacing-rods)
(stencil . ,ly:slur::print)
(thickness . 1.1)
- (vertical-skylines . ,ly:slur::vertical-skylines)
- (Y-extent . ,ly:slur::height)
+ (vertical-skylines . ,(ly:make-unpure-pure-container ly:slur::vertical-skylines ly:grob::pure-simple-vertical-skylines-from-extents))
+ (Y-extent . ,slur::height)
(meta . ((class . Spanner)
(interfaces . (slur-interface))))))
(stencil . ,ly:piano-pedal-bracket::print)
(style . line)
(thickness . 1.0)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(meta . ((class . Spanner)
(interfaces . (line-interface
piano-pedal-bracket-interface
(padding . 0.8)
(self-alignment-X . ,CENTER)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(X-offset . ,(ly:make-simple-closure
`(,+
,(ly:make-simple-closure
(list ly:break-alignable-interface::self-align-callback))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (break-alignable-interface
font-interface
(slash-negative-kern . 0.85)
(slope . 1.7)
(stencil . ,ly:percent-repeat-item-interface::beat-slash)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(thickness . 0.48)
(meta . ((class . Item)
(interfaces . (percent-repeat-interface
(stencil . ,ly:tie::print)
(thickness . 1.0)
(extra-spacing-height . (-0.5 . 0.5))
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(meta . ((class . Item)
(interfaces . (semi-tie-interface))))))
(minimum-distance . 0.25)
(stencil . ,ly:rest::print)
(X-extent . ,ly:rest::width)
- (Y-extent . ,ly:rest::height)
- (Y-offset . ,ly:rest::y-offset-callback)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:rest::height ly:rest::pure-height))
+ (Y-offset . ,(ly:make-unpure-pure-container ly:rest::y-offset-callback))
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
rest-interface
(staff-padding . 0.25)
(stencil . ,ly:script-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(X-offset . ,script-interface::calc-x-offset)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Item)
(interfaces . (font-interface
script-interface
(springs-and-rods . ,ly:spanner::set-spacing-rods)
(stencil . ,ly:slur::print)
(thickness . 1.2)
- (vertical-skylines . ,ly:slur::vertical-skylines)
- (Y-extent . ,ly:slur::height)
+ (vertical-skylines . ,(ly:make-unpure-pure-container ly:slur::vertical-skylines ly:grob::pure-simple-vertical-skylines-from-extents))
+ (Y-extent . ,slur::height)
(meta . ((class . Spanner)
(interfaces . (slur-interface))))))
(padding . 0.0) ;; padding relative to SostenutoPedalLineSpanner
(self-alignment-X . ,CENTER)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
piano-pedal-script-interface
(padding . 1.2)
(side-axis . ,Y)
(staff-padding . 1.0)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-element-stencils)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(SpanBar
. (
(allow-span-bar . #t)
- (bar-extent . ,ly:axis-group-interface::height)
+ (bar-extent . ,axis-group-interface::height)
(before-line-breaking . ,ly:span-bar::before-line-breaking)
(break-align-symbol . staff-bar)
(cross-staff . #t)
. (
(X-extent . ,grob::x-parent-width)
(extra-spacing-height . ,pure-from-neighbor-interface::extra-spacing-height)
- (Y-extent . #f)
+ ; we want this to be ignored, so empty, but the extra spacing height
+ ; should preserve the span bar's presence for horizontal spacing
+ (Y-extent . ,pure-from-neighbor-interface::unobtrusive-height)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:pure-from-neighbor-interface::calc-pure-relevant-grobs)))
(ledger-line-thickness . (1.0 . 0.1))
(line-count . 5)
(stencil . ,ly:staff-symbol::print)
- (Y-extent . ,ly:staff-symbol::height)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:staff-symbol::height))
(meta . ((class . Spanner)
(interfaces . (staff-symbol-interface))))))
(side-axis . ,X)
(stencil . ,ly:text-interface::print)
(X-offset . ,ly:side-position-interface::x-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
side-position-interface
(direction . ,ly:stem::calc-direction)
(duration-log . ,stem::calc-duration-log)
- (length . ,ly:stem::calc-length)
+ (length . ,(ly:make-unpure-pure-container ly:stem::calc-length ly:stem::pure-calc-length))
(neutral-direction . ,DOWN)
(positioning-done . ,ly:stem::calc-positioning-done)
(stem-info . ,ly:stem::calc-stem-info)
- (stem-begin-position . ,ly:stem::calc-stem-begin-position)
+ (stem-begin-position . ,(ly:make-unpure-pure-container ly:stem::calc-stem-begin-position ly:stem::pure-calc-stem-begin-position))
(stencil . ,ly:stem::print)
(thickness . 1.3)
(X-extent . ,ly:stem::width)
(X-offset . ,ly:stem::offset-callback)
- (Y-extent . ,ly:stem::height)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:stem::height ly:stem::pure-height))
+ (Y-offset . ,staff-symbol-referencer::callback)
(meta . ((class . Item)
(interfaces . (stem-interface))))))
(stencil . ,ly:stem-tremolo::print)
(style . ,ly:stem-tremolo::calc-style)
(X-extent . ,ly:stem-tremolo::width)
+ (Y-extent . ,(grob::unpure-Y-extent-from-stencil ly:stem-tremolo::pure-height))
(X-offset . ,(ly:make-simple-closure
`(,+
,(ly:make-simple-closure
(list ly:self-alignment-interface::centered-on-x-parent))
,(ly:make-simple-closure
(list ly:self-alignment-interface::x-aligned-on-self)))))
- (Y-offset . ,ly:stem-tremolo::calc-y-offset)
+ (Y-offset . ,(ly:make-unpure-pure-container ly:stem-tremolo::calc-y-offset ly:stem-tremolo::pure-calc-y-offset))
(meta . ((class . Item)
(interfaces . (self-alignment-interface
stem-tremolo-interface))))))
(staff-padding . 0.5)
(stencil . ,print-circled-text-callback)
(text . ,string-number::calc-text)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
self-alignment-interface
(staff-padding . 0.5)
(stencil . ,ly:text-interface::print)
(text . ,stroke-finger::calc-text)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
self-alignment-interface
(padding . 0.0) ;; padding relative to SustainPedalLineSpanner
(self-alignment-X . ,CENTER)
(stencil . ,ly:sustain-pedal::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
piano-pedal-interface
(padding . 1.2)
(side-axis . ,Y)
(staff-padding . 1.2)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-element-stencils)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(skyline-horizontal-padding . 1.0)
(vertical-skylines . ,ly:axis-group-interface::calc-skylines)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:system::height)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:system::height ly:system::calc-pure-height))
(meta . ((class . System)
(object-callbacks . ((footnotes-before-line-breaking . ,ly:system::footnotes-before-line-breaking)
(footnotes-after-line-breaking . ,ly:system::footnotes-after-line-breaking)
(stencil . ,tab-note-head::print)
(whiteout . #t)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
note-head-interface
(slur-padding . 0.5)
(staff-padding . 0.5)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
;; todo: add X self alignment?
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Item)
(interfaces . (font-interface
instrument-specific-markup-interface
(staff-padding . 0.8)
(stencil . ,ly:line-spanner::print)
(style . dashed-line)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (font-interface
(neutral-direction . ,UP)
(springs-and-rods . ,ly:spanner::set-spacing-rods)
(stencil . ,ly:tie::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(thickness . 1.2)
(meta . ((class . Spanner)
(interfaces . (tie-interface))))))
(right-edge . (extra-space . 0.5))
(staff-bar . (minimum-space . 2.0))))
(stencil . ,ly:time-signature::print)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(style . C)
(meta . ((class . Item)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(side-axis . ,X)
(stencil . ,ly:accidental-interface::print)
(X-offset . ,ly:side-position-interface::x-aligned-side)
- (Y-extent . ,ly:accidental-interface::height)
+ (Y-extent . ,accidental-interface::height)
(meta . ((class . Item)
(interfaces . (accidental-interface
font-interface
(stencil . ,parenthesize-elements)
(stencils . ,parentheses-item::calc-parenthesis-stencils)
(X-offset . ,ly:side-position-interface::x-aligned-side)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (axis-group-interface
font-interface
(duration-log . 2)
(font-size . -4)
(stencil . ,ly:note-head::print)
- (Y-offset . ,ly:staff-symbol-referencer::callback)
+ (Y-offset . ,staff-symbol-referencer::callback)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(meta . ((class . Item)
(interfaces . (font-interface
ledgered-interface
(staff-padding . 1.0)
(stencil . ,ly:line-spanner::print)
(style . trill)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(interfaces . (font-interface
line-interface
(staff-padding . 0.25)
(stencil . ,ly:tuplet-bracket::print)
(thickness . 1.6)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
(X-positions . ,ly:tuplet-bracket::calc-x-positions)
(meta . ((class . Spanner)
(padding . 0.0) ;; padding relative to UnaCordaPedalLineSpanner
(self-alignment-X . ,CENTER)
(stencil . ,ly:text-interface::print)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-stencil)
+ (Y-extent . ,grob::always-Y-extent-from-stencil)
(X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
(meta . ((class . Item)
(interfaces . (font-interface
(padding . 1.2)
(side-axis . ,Y)
(staff-padding . 1.2)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-element-stencils)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
(stacking-dir . -1)
(vertical-skylines . ,ly:axis-group-interface::combine-skylines)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
+ (Y-extent . ,axis-group-interface::height)
(meta . ((class . Spanner)
(object-callbacks . ((Y-common . ,ly:axis-group-interface::calc-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)
(padding . 1)))
(nonstaff-unrelatedstaff-spacing . ((padding . 0.5)))
(outside-staff-placement-directive . left-to-right-polite)
- (staff-staff-spacing . ,ly:axis-group-interface::calc-staff-staff-spacing)
+ (staff-staff-spacing . ,(ly:make-unpure-pure-container ly:axis-group-interface::calc-staff-staff-spacing ly:axis-group-interface::calc-pure-staff-staff-spacing))
(stencil . ,ly:axis-group-interface::print)
(skyline-horizontal-padding . 0.1)
(vertical-skylines . ,ly:hara-kiri-group-spanner::calc-skylines)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:hara-kiri-group-spanner::y-extent)
+ (Y-extent . ,(ly:make-unpure-pure-container ly:hara-kiri-group-spanner::y-extent ly:hara-kiri-group-spanner::pure-height))
(Y-offset . ,ly:hara-kiri-group-spanner::force-hara-kiri-callback)
(meta . ((class . Spanner)
(object-callbacks . (
(stencil . ,ly:volta-bracket-interface::print)
(thickness . 1.6) ;; line-thickness
(word-space . 0.6)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-stencil)
+ (vertical-skylines . ,grob::unpure-vertical-skylines-from-stencil)
+ (Y-extent . ,(grob::unpure-Y-extent-from-stencil volta-bracket-interface::pure-height))
(meta . ((class . Spanner)
(interfaces . (font-interface
horizontal-bracket-interface
(outside-staff-priority . 600)
(padding . 1)
(side-axis . ,Y)
- (vertical-skylines . ,ly:grob::vertical-skylines-from-element-stencils)
+ (vertical-skylines . ,grob::always-vertical-skylines-from-element-stencils)
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
+ (Y-extent . ,axis-group-interface::height)
+ (Y-offset . ,side-position-interface::y-aligned-side)
(meta . ((class . Spanner)
(object-callbacks . ((pure-Y-common . ,ly:axis-group-interface::calc-pure-y-common)
(pure-relevant-grobs . ,ly:axis-group-interface::calc-pure-relevant-grobs)))
all-grob-descriptions)
(set! all-grob-descriptions (sort all-grob-descriptions alist<?))
-
-(define (volta-bracket-interface::pure-height grob start end)
- (let ((edge-height (ly:grob-property grob 'edge-height)))
- (if (number-pair? edge-height)
- (let ((smaller (min (car edge-height) (cdr edge-height)))
- (larger (max (car edge-height) (cdr edge-height))))
- (interval-union '(0 . 0) (cons smaller larger)))
- '(0 . 0))))
-
-(define pure-print-callbacks
- (list
- fret-board::calc-stencil
- note-head::brew-ez-stencil
- print-circled-text-callback
- laissez-vibrer::print
- lyric-text::print
- ly:bar-line::print
- ly:mensural-ligature::brew-ligature-primitive
- ly:note-head::print
- ly:dots::print
- ly:clef::print
- ly:flag::print
- ly:time-signature::print
- default-flag
- normal-flag
- mensural-flag
- no-flag
- modern-straight-flag
- old-straight-flag
- ly:key-signature-interface::print
- ly:percent-repeat-item-interface::beat-slash
- ly:text-interface::print
- ly:script-interface::print
- ly:sustain-pedal::print))
-
-;; Sometimes we have grobs with (Y-extent . ,ly:grob::stencil-height)
-;; and the print function is not pure, but there is a easy way to
-;; figure out the Y-extent from the print function.
-(define pure-print-to-height-conversions
- `(
- (,ly:arpeggio::print . ,ly:arpeggio::pure-height)
- (,ly:arpeggio::brew-chord-bracket . ,ly:arpeggio::pure-height)
- (,ly:arpeggio::brew-chord-slur . ,ly:arpeggio::pure-height)
- (,ly:hairpin::print . ,ly:hairpin::pure-height)
- (,ly:stem-tremolo::print . ,ly:stem-tremolo::pure-height)
- (,ly:volta-bracket-interface::print . ,volta-bracket-interface::pure-height)))
-
-;; ly:grob::stencil-extent is safe if the print callback is safe too
-(define (pure-stencil-height grob start stop)
- (let* ((sten (ly:grob-property-data grob 'stencil))
- (pure-height-callback (assoc-get sten pure-print-to-height-conversions)))
- (cond ((or
- (ly:stencil? sten)
- (memq sten pure-print-callbacks))
- (ly:grob::stencil-height grob))
- ((procedure? pure-height-callback)
- (pure-height-callback grob start stop))
- (else
- '(0 . 0)))))
-
-;; Sometimes, a pure callback will be chained to a non-pure callback via
-;; chain_offset_callback, in which case this provides a default by simply
-;; passing through the value from the pure callback.
-(define (pure-chain-offset-callback grob start end prev-offset) prev-offset)
-
-(define pure-conversions-alist
- `(
- (,ly:accidental-interface::height . ,ly:accidental-interface::pure-height)
- (,ly:axis-group-interface::calc-staff-staff-spacing . ,ly:axis-group-interface::calc-pure-staff-staff-spacing)
- (,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
- (,ly:beam::rest-collision-callback . ,ly:beam::pure-rest-collision-callback)
- (,ly:flag::calc-y-offset . ,ly:flag::pure-calc-y-offset)
- (,ly:grob::horizontal-skylines-from-stencil . ,ly:grob::pure-simple-horizontal-skylines-from-extents)
- (,ly:grob::horizontal-skylines-from-element-stencils . ,ly:grob::pure-simple-horizontal-skylines-from-extents)
- (,ly:grob::simple-horizontal-skylines-from-extents . ,ly:grob::pure-simple-horizontal-skylines-from-extents)
- (,ly:grob::simple-vertical-skylines-from-extents . ,ly:grob::pure-simple-vertical-skylines-from-extents)
- (,ly:grob::stencil-height . ,pure-stencil-height)
- (,ly:grob::vertical-skylines-from-stencil . ,ly:grob::pure-simple-vertical-skylines-from-extents)
- (,ly:grob::vertical-skylines-from-element-stencils . ,ly:grob::pure-simple-vertical-skylines-from-extents)
- (,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height)
- (,ly:rest-collision::force-shift-callback-rest . ,pure-chain-offset-callback)
- (,ly:rest::height . ,ly:rest::pure-height)
- (,ly:self-alignment-interface::y-aligned-on-self . ,ly:self-alignment-interface::pure-y-aligned-on-self)
- (,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)
- (,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)
- (,ly:stem::calc-length . ,ly:stem::pure-calc-length)
- (,ly:stem::height . ,ly:stem::pure-height)
- (,ly:stem-tremolo::calc-y-offset . ,ly:stem-tremolo::pure-calc-y-offset)
- (,ly:system::height . ,ly:system::calc-pure-height)))
-
-(define pure-functions
- (list
- ly:accidental-interface::horizontal-skylines
- parenthesize-elements
- laissez-vibrer::print
- ly:multi-measure-rest::height
- ly:rest::y-offset-callback
- ly:staff-symbol-referencer::callback
- ly:staff-symbol::height))
-
-(define-public (pure-relevant? grob)
- (let ((extent-callback (ly:grob-property-data grob 'Y-extent)))
- (not (eq? #f
- (or
- (ly:unpure-pure-container? extent-callback)
- (pair? extent-callback)
- (memq extent-callback pure-functions)
- (and
- (pair? (assq extent-callback pure-conversions-alist))
- (let ((stencil (ly:grob-property-data grob 'stencil)))
- (or
- (not (eq? extent-callback ly:grob::stencil-height))
- (memq stencil pure-print-callbacks)
- (assq stencil pure-print-to-height-conversions)
- (ly:stencil? stencil)))))))))
-
-;; hideous code dup below - to be cleaned up when call pure functino
-;; is eliminated and lilypond works entirely from unpure-pure-containers
-
-(define-public (call-pure-function unpure args start end)
- (if (ly:unpure-pure-container? unpure)
- (let ((unpure (ly:unpure-pure-container-pure-part unpure)))
- (if (ly:simple-closure? unpure)
- (ly:eval-simple-closure (car args) unpure start end)
- (if (not (procedure? unpure))
- unpure
- (apply unpure
- (append
- (list (car args) start end)
- (cdr args))))))
- (if (ly:simple-closure? unpure)
- (ly:eval-simple-closure (car args) unpure start end)
- (if (not (procedure? unpure))
- unpure
- (if (memq unpure pure-functions)
- (apply unpure args)
- (let ((pure (assq unpure pure-conversions-alist)))
- (if pure
- (apply (cdr pure)
- (append
- (list (car args) start end)
- (cdr args))))))))))
X-extent
Y-extent)))
+(define-markup-list-command (score-lines layout props score)
+ (ly:score?)
+ "
+This is the same as the @code{\\score} markup but delivers its
+systems as a list of lines. This is not usually called directly by
+the user. Instead, it is called when the parser encounters
+@code{\\score} in a context where only markup lists are allowed. When
+used as the argument of a toplevel @code{\\markuplist}, the result can
+be split across pages."
+ (let ((output (ly:score-embedded-format score layout)))
+
+ (if (ly:music-output? output)
+ (map
+ (lambda (paper-system)
+ ;; shift such that the refpoint of the bottom staff of
+ ;; the first system is the baseline of the score
+ (ly:stencil-translate-axis
+ (paper-system-stencil paper-system)
+ (- (car (paper-system-staff-extents paper-system)))
+ Y))
+ (vector->list (ly:paper-score-paper-systems output)))
+ (begin
+ (ly:warning (_"no systems found in \\score markup, does it have a \\layout block?"))
+ '()))))
+
(define-markup-command (score layout props score)
(ly:score?)
#:category music
"
@cindex inserting music into text
-Inline an image of music.
+Inline an image of music. The reference point (usually the middle
+staff line) of the lowest staff in the top system is placed on the
+baseline.
@lilypond[verbatim,quote]
\\markup {
}
}
@end lilypond"
- (let ((output (ly:score-embedded-format score layout)))
-
- (if (ly:music-output? output)
- (stack-stencils Y DOWN baseline-skip
- (map paper-system-stencil
- (vector->list
- (ly:paper-score-paper-systems output))))
- (begin
- (ly:warning (_"no systems found in \\score markup, does it have a \\layout block?"))
- empty-stencil))))
+ (stack-stencils Y DOWN baseline-skip
+ (score-lines-markup-list layout props score)))
(define-markup-command (null layout props)
()
(define-public (collect-music-aux score-handler parser music)
(define (music-property symbol)
- (let ((value (ly:music-property music symbol)))
- (if (not (null? value))
- value
- #f)))
+ (ly:music-property music symbol #f))
(cond ((music-property 'page-marker)
;; a page marker: set page break/turn permissions or label
- (begin
- (let ((label (music-property 'page-label)))
- (if (symbol? label)
- (score-handler (ly:make-page-label-marker label))))
- (for-each (lambda (symbol)
- (let ((permission (music-property symbol)))
- (if (symbol? permission)
- (score-handler
- (ly:make-page-permission-marker symbol
- (if (eqv? 'forbid permission)
- '()
- permission))))))
- (list 'line-break-permission 'page-break-permission
- 'page-turn-permission))))
- ((not (music-property 'void))
+ (let ((label (music-property 'page-label)))
+ (if (symbol? label)
+ (score-handler (ly:make-page-label-marker label))))
+ (for-each (lambda (symbol)
+ (let ((permission (music-property symbol)))
+ (if (symbol? permission)
+ (score-handler
+ (ly:make-page-permission-marker symbol
+ (if (eq? 'forbid permission)
+ '()
+ permission))))))
+ '(line-break-permission page-break-permission
+ page-turn-permission)))
+ ((not (music-property 'void))
;; a regular music expression: make a score with this music
;; void music is discarded
(score-handler (scorify-music music parser)))))
(define-public (scorify-music music parser)
"Preprocess @var{music}."
-
- (for-each (lambda (func)
- (set! music (func music parser)))
- toplevel-music-functions)
-
- (ly:make-score music))
-
+ (ly:make-score
+ (fold (lambda (f m) (f m parser))
+ music
+ toplevel-music-functions)))
(define (get-current-filename parser book)
"return any suffix value for output filename allowing for settings by
calls to bookOutputName function"
- (let ((book-filename (paper-variable parser book 'output-filename)))
- (if (not book-filename)
- (ly:parser-output-name parser)
- book-filename)))
+ (or (paper-variable parser book 'output-filename)
+ (ly:parser-output-name parser)))
(define (get-current-suffix parser book)
"return any suffix value for output filename allowing for settings by calls to
"Split LST into two lists at the first element that returns #f for
(PRED previous_element element). Return the two parts as a pair.
Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) . (2 1))"
- (if (null? lst)
- (list lst)
- (let ((i (list-index (lambda (x y) (not (pred x y)))
- lst
- (cdr lst))))
- (if i
- (cons (take lst (1+ i)) (drop lst (1+ i)))
- (list lst)))))
+ (let ((i (and (pair? lst)
+ (list-index (lambda (x y) (not (pred x y)))
+ lst
+ (cdr lst)))))
+ (if i
+ (call-with-values
+ (lambda () (split-at lst (1+ i)))
+ cons)
+ (list lst))))
(define-public (split-list-by-separator lst pred)
"Split @var{lst} at each element that satisfies @var{pred}, and return
the parts (with the separators removed) as a list of lists. For example,
executing @samp{(split-list-by-separator '(a 0 b c 1 d) number?)} returns
@samp{((a) (b c) (d))}."
- (let loop ((result '()) (lst lst))
- (if (and lst (not (null? lst)))
- (loop
- (append result
- (list (take-while (lambda (x) (not (pred x))) lst)))
- (let ((tail (find-tail pred lst)))
- (if tail (cdr tail) #f)))
- result)))
+ (call-with-values (lambda () (break pred lst))
+ (lambda (head tail)
+ (cons head
+ (if (null? tail)
+ tail
+ (split-list-by-separator (cdr tail) pred))))))
(define-public (offset-add a b)
(cons (+ (car a) (car b))
(define-public (reverse-interval iv)
(cons (cdr iv) (car iv)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; boolean
-
-(define (lily-and a b)
- (and a b))
-
-(define (lily-or a b)
- (or a b))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; coordinates
"define-note-names.scm"
"c++.scm"
"chord-entry.scm"
+ "skyline.scm"
"stencil.scm"
"define-markup-commands.scm"
"markup.scm"
(ly:text-interface::interpret-markup layout props text)))
+(define-public (grob::unpure-Y-extent-from-stencil pure-function)
+ "The unpure height will come from a stencil whereas the pure
+ height will come from @code{pure-function}."
+ (ly:make-unpure-pure-container ly:grob::stencil-height pure-function))
+
+(define-public grob::unpure-horizontal-skylines-from-stencil
+ (ly:make-unpure-pure-container
+ ly:grob::horizontal-skylines-from-stencil
+ ly:grob::pure-simple-horizontal-skylines-from-extents))
+
+(define-public grob::always-horizontal-skylines-from-stencil
+ (ly:make-unpure-pure-container
+ ly:grob::horizontal-skylines-from-stencil))
+
+(define-public grob::unpure-vertical-skylines-from-stencil
+ (ly:make-unpure-pure-container
+ ly:grob::vertical-skylines-from-stencil
+ ly:grob::pure-simple-vertical-skylines-from-extents))
+
+(define-public grob::always-vertical-skylines-from-stencil
+ (ly:make-unpure-pure-container
+ ly:grob::vertical-skylines-from-stencil))
+
+(define-public grob::always-vertical-skylines-from-element-stencils
+ (ly:make-unpure-pure-container
+ ly:grob::vertical-skylines-from-element-stencils
+ ly:grob::pure-vertical-skylines-from-element-stencils))
+
+(define-public grob::always-horizontal-skylines-from-element-stencils
+ (ly:make-unpure-pure-container
+ ly:grob::horizontal-skylines-from-element-stencils
+ ly:grob::pure-horizontal-skylines-from-element-stencils))
+
+;; Sometimes, in horizontal spacing, we want grobs to block other grobs.
+;; They thus need to have a non-empty height. We give them a point height
+;; so that, minimally, they block grobs directly to the right of them.
+;; Often this is complimented by an extra-spacing-height.
+;; We don't, however, want these grobs to factor into vertical spacing
+;; decisions, so we make their unpure height #f.
+
+;; Using this as a callback for a grob's Y-extent promises
+;; that the grob's stencil does not depend on line-spacing.
+;; We use this promise to figure the space required by Clefs
+;; and such at the note-spacing stage.
+
+(define-public grob::always-Y-extent-from-stencil
+ (ly:make-unpure-pure-container ly:grob::stencil-height))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; beam slope
;; side-position stuff
(define-public (only-if-beamed g)
- (reduce lily-or
- #f
- (map (lambda (x)
- (ly:grob? (ly:grob-object x 'beam)))
- (ly:grob-array->list (ly:grob-object g
- 'side-support-elements)))))
+ (any (lambda (x) (ly:grob? (ly:grob-object x 'beam)))
+ (ly:grob-array->list (ly:grob-object g 'side-support-elements))))
+
+(define-public side-position-interface::y-aligned-side
+ (ly:make-unpure-pure-container
+ ly:side-position-interface::y-aligned-side
+ ly:side-position-interface::pure-y-aligned-side))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; self-alignment stuff
+
+(define-public self-alignment-interface::y-aligned-on-self
+ (ly:make-unpure-pure-container
+ ly:self-alignment-interface::y-aligned-on-self
+ ly:self-alignment-interface::pure-y-aligned-on-self))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; staff symbol
+
+(define staff-symbol-referencer::callback
+ (ly:make-unpure-pure-container ly:staff-symbol-referencer::callback))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; note heads
10000000))))
(coord-operation - from-neighbors height)))
+;; If there are neighbors, we place the height at their midpoint
+;; to avoid protrusion of this pure height out of the vertical
+;; axis group on either side. This will minimize the impact of the
+;; grob on pure minimum translations.
+
+;; TODO - there is a double call to axis-group-interface::pure-height
+;; here and then in the extra-spacing-height function above. Can/should this
+;; be rolled into one?
+(define-public (pure-from-neighbor-interface::pure-height grob beg end)
+ (let* ((height (ly:axis-group-interface::pure-height
+ grob
+ 0
+ 10000000))
+ (c (interval-center height)))
+ (if (interval-empty? height) empty-interval (cons c c))))
+
+;; Minimizes the impact of the height on vertical spacing while allowing
+;; it to appear in horizontal skylines of paper columns if necessary.
+(define-public pure-from-neighbor-interface::unobtrusive-height
+ (ly:make-unpure-pure-container #f pure-from-neighbor-interface::pure-height))
+
(define-public (pure-from-neighbor-interface::account-for-span-bar grob)
(let* ((esh (pure-from-neighbor-interface::extra-spacing-height grob))
(hsb (ly:grob-property grob 'has-span-bar))
(assoc-get (ly:grob-property grob 'alteration)
standard-alteration-glyph-name-alist))
+(define-public accidental-interface::height
+ (ly:make-unpure-pure-container
+ ly:accidental-interface::height
+ ly:accidental-interface::pure-height))
+
(define-public cancellation-glyph-name-alist
'((0 . "accidentals.natural")))
(- y-center (ly:grob-relative-coordinate me y-ref Y))))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; offset callbacks
+
+(define-public (pure-chain-offset-callback grob start end prev-offset)
+ "Sometimes, a chained offset callback is unpure and there is
+ no way to write a pure function that estimates its behavior.
+ In this case, we use a pure equivalent that will simply pass
+ the previous calculated offset value."
+ prev-offset)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
(ly:grob-property grob 'dot-placement-list))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; slurs
+
+(define-public slur::height
+ (ly:make-unpure-pure-container
+ ly:slur::height
+ ly:slur::pure-height))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; scripts
(interval-center extent))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; axis group interface
+
+(define-public axis-group-interface::height
+ (ly:make-unpure-pure-container
+ ly:axis-group-interface::height
+ ly:axis-group-interface::pure-height))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ambitus
(define-public (laissez-vibrer::print grob)
(ly:tie::print grob))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; volta-bracket
+
+(define-public (volta-bracket-interface::pure-height grob start end)
+ (let ((edge-height (ly:grob-property grob 'edge-height)))
+ (if (number-pair? edge-height)
+ (let ((smaller (min (car edge-height) (cdr edge-height)))
+ (larger (max (car edge-height) (cdr edge-height))))
+ (interval-union '(0 . 0) (cons smaller larger)))
+ '(0 . 0))))
(horizon-padding (and
(ly:grob? grob)
(ly:grob-property grob 'skyline-horizontal-padding 0)))
- (padding-annotation (if next-system
+ (padding-annotation (if (skyline-pair-and-non-empty? next-system)
(annotate-padding
(- system-Y) system-X skyline (paper-system-extent system X)
(- next-system-Y) next-system-X next-skyline (paper-system-extent next-system X)
--- /dev/null
+;;;; This file is part of LilyPond, the GNU music typesetter.
+;;;;
+;;;; Copyright (C) 2013 Mike Solomon <mike@mikesolomon.org>
+;;;;
+;;;; 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/>.
+
+(define-public (skyline-pair::empty? skyp)
+ (and (ly:skyline-empty? (ly:skyline-pair::skyline skyp UP))
+ (ly:skyline-empty? (ly:skyline-pair::skyline skyp DOWN))))
+
+; checks if the pair is not null, and then if not empty
+(define-public (skyline-pair-and-non-empty? skyp)
+ (and (ly:skyline-pair? skyp)
+ (not (skyline-pair::empty? skyp))))