]> git.donarmstrong.com Git - lilypond.git/blob - lily/chord-name-engraver.cc
release: 1.3.94
[lilypond.git] / lily / chord-name-engraver.cc
1 /*
2   chord-name-engraver.cc -- implement Chord_name_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "engraver.hh"
10 #include "chord-name.hh"
11 #include "chord.hh"
12 #include "musical-request.hh"
13 #include "paper-def.hh"
14 #include "lookup.hh"
15 #include "paper-def.hh"
16 #include "main.hh"
17 #include "dimensions.hh"
18 #include "item.hh"
19 #include "musical-pitch.hh"
20
21 class Chord_name_engraver : public Engraver 
22 {
23 public:
24   Chord_name_engraver ();
25   VIRTUAL_COPY_CONS (Translator);
26
27 protected:
28   virtual void do_pre_move_processing ();
29   virtual void acknowledge_element (Score_element_info i);
30   virtual void do_process_music ();
31   virtual bool do_try_music (Music* m);
32
33 private:
34   void create_chord_name ();
35
36   Array<Musical_pitch> pitch_arr_;
37   Item* chord_name_p_;
38   Chord* chord_p_;
39   Chord* last_chord_p_;
40   Tonic_req* tonic_req_;
41   Inversion_req* inversion_req_;
42   Bass_req* bass_req_;
43 };
44
45 ADD_THIS_TRANSLATOR (Chord_name_engraver);
46
47 Chord_name_engraver::Chord_name_engraver ()
48 {
49   chord_name_p_ = 0;
50   tonic_req_ = 0;
51   inversion_req_ = 0;
52   bass_req_ = 0;
53   chord_p_ = 0;
54   last_chord_p_ = 0;
55 }
56
57 void
58 Chord_name_engraver::acknowledge_element (Score_element_info i)
59 {
60   if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
61     pitch_arr_.push (n->pitch_);
62 }
63
64 bool
65 Chord_name_engraver::do_try_music (Music* m)
66 {
67   if (Note_req* n = dynamic_cast<Note_req*> (m))
68     {
69       pitch_arr_.push (n->pitch_);
70       return true;
71     }
72   if (Tonic_req* t = dynamic_cast<Tonic_req*> (m))
73     {
74       tonic_req_ = t;
75       return true;
76     }
77   if (Inversion_req* i = dynamic_cast<Inversion_req*> (m))
78     {
79       inversion_req_ = i;
80       return true;
81     }
82   if (Bass_req* b = dynamic_cast<Bass_req*> (m))
83     {
84       bass_req_ = b;
85       return true;
86     }
87   return false;
88 }
89
90 void
91 Chord_name_engraver::do_process_music ()
92 {
93   if (chord_name_p_)
94     return;
95
96   if (!pitch_arr_.size ())
97     return;
98
99   bool find_inversion_b = false;
100   SCM chord_inversion = get_property ("chordInversion");
101   if (gh_boolean_p (chord_inversion))
102     find_inversion_b = gh_scm2bool (chord_inversion);
103
104   chord_p_ = new Chord (to_chord (pitch_arr_,
105                                   tonic_req_, inversion_req_, bass_req_,
106                                   find_inversion_b));
107   
108   create_chord_name ();
109   announce_element (chord_name_p_, 0);
110   SCM s = get_property ("drarnChords"); //FIXME!
111   if (to_boolean (s) && last_chord_p_ && !compare (chord_p_, last_chord_p_))
112     chord_name_p_->set_elt_property ("begin-of-line-visible", SCM_BOOL_T);
113 }
114
115 void
116 Chord_name_engraver::create_chord_name ()
117 {
118   assert (chord_p_);
119   chord_name_p_ = new Item (get_property ("ChordName"));
120   /*
121     Hmm, why not represent complete chord as list?
122     ((tonic third fifth) (inversion bass))
123   */
124   SCM plist = SCM_EOL;
125   for (int i= chord_p_->pitch_arr_.size (); i--; )
126     plist = gh_cons (chord_p_->pitch_arr_[i].to_scm (), plist);
127   
128   chord_name_p_->set_elt_property ("pitches", plist);
129   if (chord_p_->inversion_b_)
130     chord_name_p_->set_elt_property ("inversion",
131                                      chord_p_->inversion_pitch_.to_scm ());
132   if (chord_p_->bass_b_)
133     chord_name_p_->set_elt_property ("bass", chord_p_->bass_pitch_.to_scm ());
134 }
135
136 void
137 Chord_name_engraver::do_pre_move_processing ()
138 {
139   if (chord_name_p_)
140     {
141       typeset_element (chord_name_p_);
142     }
143   pitch_arr_.clear ();
144   chord_name_p_ = 0;
145   tonic_req_ = 0;
146   inversion_req_ = 0;
147   bass_req_ = 0;
148   delete last_chord_p_;
149   last_chord_p_ = chord_p_;
150   chord_p_ = 0;
151 }
152