X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ffretboard-engraver.cc;h=f6c7601dfa551e64fde09f230993ee674ce5f520;hb=e2c7a2ab964d7ab2b4d993634303327adf5e39f2;hp=056b826588f69fc8bcce8fa9c9c65dc6333b1725;hpb=ac6c83f047635535d0481a15654c13e776334dc6;p=lilypond.git diff --git a/lily/fretboard-engraver.cc b/lily/fretboard-engraver.cc index 056b826588..f6c7601dfa 100644 --- a/lily/fretboard-engraver.cc +++ b/lily/fretboard-engraver.cc @@ -1,7 +1,20 @@ /* - fretboard-engraver.cc -- part of GNU LilyPond + This file is part of LilyPond, the GNU music typesetter. - (c) 2006 Han-Wen Nienhuys + Copyright (C) 2006--2010 Han-Wen Nienhuys + + 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 @@ -23,23 +36,34 @@ using namespace std; class Fretboard_engraver : public Engraver { Item *fret_board_; - + vector note_events_; vector tabstring_events_; public: TRANSLATOR_DECLARATIONS (Fretboard_engraver); protected: + void stop_translation_timestep (); + void process_music (); + virtual void derived_mark() const; DECLARE_TRANSLATOR_LISTENER (note); DECLARE_TRANSLATOR_LISTENER (string_number); - void process_music (); - void stop_translation_timestep (); +private: + SCM last_fret_notes_; }; + +void +Fretboard_engraver::derived_mark () const +{ + scm_gc_mark (last_fret_notes_); +} + Fretboard_engraver::Fretboard_engraver () { fret_board_ = 0; + last_fret_notes_ = SCM_EOL; } IMPLEMENT_TRANSLATOR_LISTENER (Fretboard_engraver, note); @@ -62,18 +86,64 @@ Fretboard_engraver::process_music () if (!note_events_.size ()) return ; - fret_board_ = make_item ("FretBoard", note_events_[0]->self_scm ()); + // Ugh -- copied from tab-note-heads-engraver; need to resolve + vsize j = 0; - SCM proc = get_property ("noteToFretFunction"); - if (ly_is_procedure (proc)) + vector string_events; + + for (vsize i = 0; i < note_events_.size (); i++) { - scm_call_4 (proc, - context ()->self_scm (), - fret_board_->self_scm (), - - ly_cxx_vector_to_list (note_events_), - ly_cxx_vector_to_list (tabstring_events_)); + + Stream_event *event = note_events_[i]; + + Stream_event *tabstring_event = 0; + + /* + For notes inside a chord construct, string indications are + stored as articulations on the note, so we check through + the notes + */ + for (SCM s = event->get_property ("articulations"); + !tabstring_event && scm_is_pair (s); s = scm_cdr (s)) + { + Stream_event *art = unsmob_stream_event (scm_car (s)); + + if (art->in_event_class ("string-number-event")) + tabstring_event = art; + } + + /* + For string indications listed outside a chord construct, + a string_number_event is generated, so if there was no string + in the articulations, we check for string events outside + the chord construct + */ + if (!tabstring_event && j < tabstring_events_.size ()) + { + tabstring_event = tabstring_events_[j]; + if (j + 1 < tabstring_events_.size ()) + j++; + } + if (tabstring_event) + string_events.push_back (tabstring_event); } + // end of copied code + + fret_board_ = make_item ("FretBoard", note_events_[0]->self_scm ()); + SCM fret_notes = ly_cxx_vector_to_list (note_events_); + SCM proc = get_property ("noteToFretFunction"); + if (ly_is_procedure (proc)) + scm_call_4 (proc, + context ()->self_scm (), + fret_notes, + ly_cxx_vector_to_list (string_events), + fret_board_->self_scm ()); + SCM changes = get_property ("chordChanges"); + if (to_boolean (changes) && scm_is_pair (last_fret_notes_) + && ly_is_equal (last_fret_notes_, fret_notes)) + fret_board_->set_property ("begin-of-line-visible", SCM_BOOL_T); + + last_fret_notes_ = fret_notes; } void @@ -86,17 +156,21 @@ Fretboard_engraver::stop_translation_timestep () ADD_TRANSLATOR (Fretboard_engraver, /* doc */ - "Generate one or more tablature noteheads from event of type" + "Generate fret diagram from one or more events of type" " @code{NoteEvent}.", /* create */ "FretBoard ", /* read */ - "stringTunings " + "chordChanges " + "highStringOne " + "maximumFretStretch " "minimumFret " - "tablatureFormat " - "highStringOne ", + "noteToFretFunction " + "predefinedDiagramTable " + "stringTunings " + "tablatureFormat ", /* write */ ""