]> git.donarmstrong.com Git - lilypond.git/blob - lily/new-chord-name-engraver.cc
* input/regression/ambitus.ly: move file.
[lilypond.git] / lily / new-chord-name-engraver.cc
1 /*
2   chord-name-engraver.cc -- implement New_chord_name_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--2003 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "engraver.hh"
10 #include "chord-name.hh"
11 #include "chord.hh"
12 #include "event.hh"
13 #include "paper-def.hh"
14 #include "font-interface.hh"
15 #include "paper-def.hh"
16 #include "main.hh"
17 #include "dimensions.hh"
18 #include "item.hh"
19 #include "pitch.hh"
20 #include "protected-scm.hh"
21
22 class New_chord_name_engraver : public Engraver 
23 {
24   TRANSLATOR_DECLARATIONS( New_chord_name_engraver);
25 protected:
26   virtual void stop_translation_timestep ();
27   virtual void process_music ();
28   virtual bool try_music (Music *);
29
30 private:
31   void add_note (Music *);
32   
33   Item* chord_name_;
34   Link_array<Music> notes_;
35   
36   Protected_scm last_chord_;
37 };
38
39
40
41 New_chord_name_engraver::New_chord_name_engraver ()
42 {
43   chord_name_ = 0;
44   last_chord_ = SCM_EOL;
45 }
46
47 void
48 New_chord_name_engraver::add_note (Music * n)
49 {
50   notes_.push (n);
51 }
52
53 void
54 New_chord_name_engraver::process_music ()
55 {
56   if (!notes_.size() )
57     return;
58   
59   SCM bass = SCM_EOL;
60   SCM inversion = SCM_EOL;
61   SCM pitches = SCM_EOL;
62
63   for (int i =0 ; i < notes_.size (); i++)
64     {
65       Music *n = notes_[i];
66       SCM p = n->get_mus_property ("pitch");;
67       if (n->get_mus_property ("inversion") == SCM_BOOL_T)
68         inversion = p;
69       else if (n->get_mus_property ("bass") == SCM_BOOL_T)
70         bass = p;
71       else
72         pitches = gh_cons (p, pitches);
73     }
74
75   pitches = scm_sort_list (pitches, Pitch::less_p_proc);
76
77
78   SCM name_proc = get_property ("chordNameFunction");
79   SCM exceptions = get_property ("chordNameExceptions");
80   SCM markup = scm_call_4 (name_proc, pitches, bass, inversion, exceptions);
81
82   /*
83     Ugh. 
84    */
85   SCM chord_as_scm = gh_cons (pitches, gh_cons (bass, inversion));
86   
87   chord_name_ = new Item (get_property ("ChordName"));
88   chord_name_->set_grob_property("text", markup);
89   announce_grob(chord_name_, SCM_EOL);
90   SCM s = get_property ("chordChanges");
91   if (to_boolean (s) && gh_pair_p (last_chord_) 
92       && gh_equal_p (chord_as_scm, last_chord_))
93     chord_name_->set_grob_property ("begin-of-line-visible", SCM_BOOL_T);
94
95   last_chord_ = chord_as_scm;
96 }
97
98 bool
99 New_chord_name_engraver::try_music (Music* m)
100 {
101   /*
102     hmm. Should check? 
103    */
104   if (m->is_mus_type ("note-event"))
105     {
106       add_note (m);
107       return true;
108     }
109   return false;
110 }
111
112 void
113 New_chord_name_engraver::stop_translation_timestep ()
114 {
115   if (chord_name_)
116     {
117       typeset_grob (chord_name_);
118     }
119   chord_name_ = 0;
120   notes_.clear ();
121 }
122
123 ENTER_DESCRIPTION(New_chord_name_engraver,
124 /* descr */       "Catch note-events "
125 "and generate the appropriate chordname.",
126 /* creats*/       "ChordName",
127 /* accepts */     "note-event",
128 /* acks  */      "",
129 /* reads */       "chordChanges chordNameExceptions chordNameFunction",
130 /* write */       "");