X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fkievan-ligature-engraver.cc;fp=lily%2Fkievan-ligature-engraver.cc;h=92b9848c5b6665f2c52ec37b8a520c58c5b7e886;hb=0ac07f31e0f95fc18e5916ce756b9c746af7cc58;hp=0000000000000000000000000000000000000000;hpb=2f1263e2ccdddcac2eb9f7d8ce2ed92867d3d160;p=lilypond.git diff --git a/lily/kievan-ligature-engraver.cc b/lily/kievan-ligature-engraver.cc new file mode 100644 index 0000000000..92b9848c5b --- /dev/null +++ b/lily/kievan-ligature-engraver.cc @@ -0,0 +1,154 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2013 Aleksandr Andreev + + 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 . +*/ + +#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 const &primitives); + DECLARE_TRANSLATOR_LISTENER (ligature); + +public: + TRANSLATOR_DECLARATIONS (Kievan_ligature_engraver); + +private: + void fold_up_primitives (vector 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 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 (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 (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 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 */ + "" + );