From d623a43831b22eb89f75b9b8517a7f38d02cb7d4 Mon Sep 17 00:00:00 2001 From: Mike Solomon Date: Thu, 28 Apr 2011 09:10:27 -0400 Subject: [PATCH] Allows for individual glissandi between members of NoteColumns. The property glissandoMap is used to tell the glissando-engraver what note-column members to connect via glissandi. --- input/regression/glissando-chord.ly | 23 +++++++ lily/glissando-engraver.cc | 98 ++++++++++++++++++++++------- scm/define-context-properties.scm | 5 ++ scm/define-grob-interfaces.scm | 2 +- scm/define-grob-properties.scm | 2 + 5 files changed, 105 insertions(+), 25 deletions(-) create mode 100644 input/regression/glissando-chord.ly diff --git a/input/regression/glissando-chord.ly b/input/regression/glissando-chord.ly new file mode 100644 index 0000000000..e140c38d8e --- /dev/null +++ b/input/regression/glissando-chord.ly @@ -0,0 +1,23 @@ +\version "2.15.0" + +\header { + texidoc = "LilyPond typesets glissandi between chords." +} + +\relative c' { + c1 \glissando g' + c,1 \glissando s1 g' + 1 \glissando + 1 \glissando s1 + \set glissandoMap = #'((0 . 1) (1 . 0)) + 1 \glissando s1 + \set glissandoMap = #'((0 . 0) (0 . 1) (0 . 2)) + c1 \glissando s1 + \set glissandoMap = #'((2 . 0) (1 . 0) (0 . 0)) + 1 \glissando s1 c + \unset glissandoMap + \once \override Voice . Glissando #'style = + #(lambda (grob) + (if (eq? 1 (ly:grob-property grob 'glissando-index)) 'zigzag 'default)) + 1 \glissando s1 +} diff --git a/lily/glissando-engraver.cc b/lily/glissando-engraver.cc index 99eb6bc515..08f420c128 100644 --- a/lily/glissando-engraver.cc +++ b/lily/glissando-engraver.cc @@ -20,6 +20,7 @@ #include "engraver.hh" #include "international.hh" +#include "pointer-group-interface.hh" #include "rhythmic-head.hh" #include "spanner.hh" #include "stream-event.hh" @@ -35,21 +36,29 @@ public: protected: DECLARE_TRANSLATOR_LISTENER (glissando); - DECLARE_ACKNOWLEDGER (rhythmic_head); + DECLARE_ACKNOWLEDGER (note_column); virtual void finalize (); void stop_translation_timestep (); void process_music (); + private: - Spanner *line_; - Spanner *last_line_; + vector lines_; + bool start_glissandi; + bool stop_glissandi; + Stream_event *event_; + SCM map; + vector note_column_1; + vector note_column_2; }; Glissando_engraver::Glissando_engraver () { - last_line_ = line_ = 0; event_ = 0; + map = SCM_EOL; + start_glissandi = false; + stop_glissandi = false; } IMPLEMENT_TRANSLATOR_LISTENER (Glissando_engraver, glissando); @@ -63,44 +72,85 @@ void Glissando_engraver::process_music () { if (event_) - line_ = make_spanner ("Glissando", event_->self_scm ()); + start_glissandi = true; } void -Glissando_engraver::acknowledge_rhythmic_head (Grob_info info) +Glissando_engraver::acknowledge_note_column (Grob_info info) { Grob *g = info.grob (); - if (line_) - line_->set_bound (LEFT, g); + if (start_glissandi) + { + extract_grob_set (g, "note-heads", note_heads); + map = get_property ("glissandoMap"); + if (map == SCM_EOL) + for (vsize i = 0; i < note_heads.size (); i++) + { + note_column_1.push_back (i); + note_column_2.push_back (i); + } + else + for (SCM m = map; scm_is_pair (m); m = scm_cdr (m)) + { + SCM candidate = scm_car (m); + if (!scm_is_pair (candidate)) + continue; + int n1 = robust_scm2int (scm_car (candidate), -1); + int n2 = robust_scm2int (scm_cdr (candidate), -1); + if (n1 < 0 || n2 < 0 || n1 >= note_heads.size ()) + continue; + note_column_1.push_back (vsize (n1)); + note_column_2.push_back (vsize (n2)); + } + for (vsize i=0; i < note_column_1.size (); i++) + { + lines_.push_back (make_spanner ("Glissando", event_->self_scm ())); + lines_.back ()->set_bound (LEFT, note_heads[note_column_1[i]]); + } + } - if (last_line_) + if (stop_glissandi) { - last_line_->set_bound (RIGHT, g); - announce_end_grob (last_line_, g->self_scm ()); + extract_grob_set (g, "note-heads", note_heads); + int glissando_index = 0; + for (vsize i=0; i < note_column_1.size (); i++) + { + if (note_column_2[i] >= note_heads.size ()) + lines_[i]->suicide (); + else + { + lines_[i]->set_bound (RIGHT, note_heads[note_column_2[i]]); + lines_[i]->set_property ("glissando-index", scm_from_int (glissando_index)); + glissando_index++; + announce_end_grob (lines_[i], note_heads[note_column_2[i]]->self_scm ()); + } + } + lines_.clear (); + note_column_1.clear (); + note_column_2.clear (); + stop_glissandi = false; } } void Glissando_engraver::stop_translation_timestep () { - if (last_line_ && last_line_->get_bound (RIGHT)) - { - last_line_ = 0; - } - if (line_) + + if (start_glissandi) { - if (last_line_) + if (stop_glissandi) programming_error ("overwriting glissando"); - last_line_ = line_; + stop_glissandi = true; } - line_ = 0; + + start_glissandi = false; event_ = 0; } void Glissando_engraver::finalize () { - if (line_) + if (!lines_.empty ()) { string msg = _ ("unterminated glissando"); @@ -109,12 +159,12 @@ Glissando_engraver::finalize () else warning (msg); - line_->suicide (); - line_ = 0; + for (vsize i=0; i < lines_.size (); i++) + lines_[i]->suicide (); } } -ADD_ACKNOWLEDGER (Glissando_engraver, rhythmic_head); +ADD_ACKNOWLEDGER (Glissando_engraver, note_column); ADD_TRANSLATOR (Glissando_engraver, /* doc */ "Engrave glissandi.", @@ -123,7 +173,7 @@ ADD_TRANSLATOR (Glissando_engraver, "Glissando ", /* read */ - "", + "glissandoMap ", /* write */ "" diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index a813f1421f..e9484ba194 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -257,6 +257,11 @@ containing, in the correct order, the labels to be used for lettered frets in tablature.") + (glissandoMap ,list? "A map in the form of '((source1 . target1) +(source2 . target2) (sourcen . targetn)) showing the glissandi to +be drawn for note columns. The value '() will default to '((0 . 0) +(1 . 1) (n . n)), where n is the minimal number of note-heads in +the two note columns between which the glissandi occur.") (gridInterval ,ly:moment? "Interval for which to generate @code{GridPoint}s.") diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index edc02a7fb3..a7090de032 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -100,7 +100,7 @@ note)." (ly:add-interface 'glissando-interface "A glissando." - '()) + '(glissando-index)) (ly:add-interface 'grace-spacing-interface diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 3381cb9e27..7fd0b13819 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -1003,6 +1003,8 @@ in addition to notes and stems.") (figures ,ly:grob-array? "Figured bass objects for continuation line.") + (glissando-index ,integer? "The index of a glissando in its note +column.") (grace-spacing ,ly:grob? "A run of grace notes.") (heads ,ly:grob-array? "An array of note heads.") -- 2.39.2