*
* - 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
--- /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 */
--- /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
\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
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
. (