From: David Kastrup Date: Tue, 24 Jun 2014 15:54:03 +0000 (+0200) Subject: Issue 3966/2: Allows the user to override the text property of ChordName X-Git-Tag: release/2.19.9-1^2~6 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=6445987a6cc30312ce81e6e007e54e697b1f6702;p=lilypond.git Issue 3966/2: Allows the user to override the text property of ChordName This is a reimplementation of issue 2813. --- diff --git a/input/regression/chord-name-override-text.ly b/input/regression/chord-name-override-text.ly new file mode 100644 index 0000000000..36b4795dbd --- /dev/null +++ b/input/regression/chord-name-override-text.ly @@ -0,0 +1,13 @@ +\version "2.17.6" + +\header { + texidoc = "Users can override the @code{text} property of +@code{ChordName}. +" +} + +\new ChordNames \chordmode { + a b c:7 + \once \override ChordName.text = #"foo" + d +} diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 86d977cabe..0ca322716f 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -42,7 +42,6 @@ protected: DECLARE_TRANSLATOR_LISTENER (note); DECLARE_TRANSLATOR_LISTENER (rest); private: - Item *chord_name_; vector notes_; Stream_event *rest_event_; @@ -55,86 +54,99 @@ Chord_name_engraver::finalize () Chord_name_engraver::Chord_name_engraver () { - chord_name_ = 0; rest_event_ = 0; } void Chord_name_engraver::process_music () { + if (!rest_event_ && notes_.empty ()) + return; + SCM markup; SCM bass = SCM_EOL; SCM inversion = SCM_EOL; SCM pitches = SCM_EOL; + Item *chord_name = 0; + // rest events present a hen-and-egg problem with regard to + // overriding the text property of the ChordName grob since we + // cannot create a ChordName grob, look at its text property and, if + // not set, use noChordSymbol to decide whether we should not have + // created the grob in the first place. if (rest_event_) { SCM no_chord_markup = get_property ("noChordSymbol"); if (!Text_interface::is_markup (no_chord_markup)) return; markup = no_chord_markup; + chord_name = make_item ("ChordName", rest_event_->self_scm ()); + chord_name->set_property ("text", markup); } else { - if (!notes_.size ()) - return; - - Stream_event *inversion_event = 0; - for (vsize i = 0; i < notes_.size (); i++) + chord_name = make_item ("ChordName", notes_[0]->self_scm ()); + // We cannot actually delay fetching the text property in case + // it is a callback since we need to compare the generated + // markups for the sake of chordChanges + markup = chord_name->get_property ("text"); + if (!Text_interface::is_markup (markup)) { - Stream_event *n = notes_[i]; - SCM p = n->get_property ("pitch"); - if (!unsmob_pitch (p)) - continue; - - if (n->get_property ("inversion") == SCM_BOOL_T) + Stream_event *inversion_event = 0; + for (vsize i = 0; i < notes_.size (); i++) { - inversion_event = n; - inversion = p; + Stream_event *n = notes_[i]; + SCM p = n->get_property ("pitch"); + if (!unsmob_pitch (p)) + continue; + + if (n->get_property ("inversion") == SCM_BOOL_T) + { + inversion_event = n; + inversion = p; + } + else if (n->get_property ("bass") == SCM_BOOL_T) + bass = p; + else + pitches = scm_cons (p, pitches); } - else if (n->get_property ("bass") == SCM_BOOL_T) - bass = p; - else - pitches = scm_cons (p, pitches); - } - if (inversion_event) - { - SCM oct = inversion_event->get_property ("octavation"); - if (scm_is_number (oct)) + if (inversion_event) { - Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch")); - int octavation = scm_to_int (oct); - Pitch orig = p->transposed (Pitch (-octavation, 0, 0)); - - pitches = scm_cons (orig.smobbed_copy (), pitches); + SCM oct = inversion_event->get_property ("octavation"); + if (scm_is_number (oct)) + { + Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch")); + int octavation = scm_to_int (oct); + Pitch orig = p->transposed (Pitch (-octavation, 0, 0)); + + pitches = scm_cons (orig.smobbed_copy (), pitches); + } + else + programming_error ("inversion does not have original pitch"); } - else - programming_error ("inversion does not have original pitch"); - } - pitches = scm_sort_list (pitches, Pitch::less_p_proc); + pitches = scm_sort_list (pitches, Pitch::less_p_proc); - SCM name_proc = get_property ("chordNameFunction"); - markup = scm_call_4 (name_proc, pitches, bass, inversion, - context ()->self_scm ()); + SCM name_proc = get_property ("chordNameFunction"); + markup = scm_call_4 (name_proc, pitches, bass, inversion, + context ()->self_scm ()); + if (!Text_interface::is_markup (markup)) + { + // Ugh, we created a grob, now we better populate it. + // Use an empty string. + markup = scm_string (SCM_EOL); + } + chord_name->set_property ("text", markup); + } } - /* - Ugh. - */ - SCM chord_as_scm = scm_cons (pitches, scm_cons (bass, inversion)); - - chord_name_ = make_item ("ChordName", - rest_event_ ? rest_event_->self_scm () : notes_[0]->self_scm ()); - chord_name_->set_property ("text", markup); SCM chord_changes = get_property ("chordChanges"); SCM last_chord = get_property ("lastChord"); - if (to_boolean (chord_changes) && scm_is_pair (last_chord) - && ly_is_equal (chord_as_scm, last_chord)) - chord_name_->set_property ("begin-of-line-visible", SCM_BOOL_T); + if (to_boolean (chord_changes) && ly_is_equal (markup, last_chord)) + chord_name->set_property ("begin-of-line-visible", SCM_BOOL_T); - context ()->set_property ("lastChord", chord_as_scm); + context ()->set_property ("lastChord", markup); } IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note); @@ -154,7 +166,6 @@ Chord_name_engraver::listen_rest (Stream_event *ev) void Chord_name_engraver::stop_translation_timestep () { - chord_name_ = 0; notes_.clear (); rest_event_ = 0; } diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 66100915b4..2d38188d29 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -709,7 +709,7 @@ in an axis group.") @code{CommandColumn} contains items that will affect spacing.") - (lastChord ,list? "Last chord, used for detecting chord changes.") + (lastChord ,markup? "Last chord, used for detecting chord changes.") (lastKeyAlterations ,list? "Last key signature before a key signature change.") (localAlterations ,list? "The key signature at this point in the