]> git.donarmstrong.com Git - lilypond.git/blob - lily/chord-name-engraver.cc
release: 1.3.68
[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   Array<Musical_pitch> pitch_arr_;
35   Item* chord_name_p_;
36   Tonic_req* tonic_req_;
37   Inversion_req* inversion_req_;
38   Bass_req* bass_req_;
39 };
40
41 ADD_THIS_TRANSLATOR (Chord_name_engraver);
42
43 Chord_name_engraver::Chord_name_engraver ()
44 {
45   chord_name_p_ = 0;
46   tonic_req_ = 0;
47   inversion_req_ = 0;
48   bass_req_ = 0;
49 }
50
51 void
52 Chord_name_engraver::acknowledge_element (Score_element_info i)
53 {
54   if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
55     pitch_arr_.push (n->pitch_);
56 }
57
58 bool
59 Chord_name_engraver::do_try_music (Music* m)
60 {
61   if (Note_req* n = dynamic_cast<Note_req*> (m))
62     {
63       pitch_arr_.push (n->pitch_);
64       return true;
65     }
66   if (Tonic_req* t = dynamic_cast<Tonic_req*> (m))
67     {
68       tonic_req_ = t;
69       return true;
70     }
71   if (Inversion_req* i = dynamic_cast<Inversion_req*> (m))
72     {
73       inversion_req_ = i;
74       return true;
75     }
76   if (Bass_req* b = dynamic_cast<Bass_req*> (m))
77     {
78       bass_req_ = b;
79       return true;
80     }
81   return false;
82 }
83
84 void
85 Chord_name_engraver::do_process_music ()
86 {
87   if (chord_name_p_)
88     return;
89   if (!pitch_arr_.size ())
90     return;
91
92   bool find_inversion_b = false;
93   SCM chord_inversion = get_property ("chordInversion");
94   if (gh_boolean_p (chord_inversion))
95     find_inversion_b = gh_scm2bool (chord_inversion);
96
97   chord_name_p_ = new Item (get_property ("basicChordNameProperties"));
98   Chord chord = to_chord (pitch_arr_, tonic_req_, inversion_req_, bass_req_,
99                           find_inversion_b);
100
101   /*
102     Hmm, why not represent complete chord as list?
103     ((tonic third fifth) (inversion bass))
104   */
105   SCM plist = SCM_EOL;
106   for (int i= chord.pitch_arr_.size (); i--; )
107     plist = gh_cons (chord.pitch_arr_[i].to_scm (), plist);
108   
109   chord_name_p_->set_elt_property ("pitches", plist);
110   if (chord.inversion_b_)
111     chord_name_p_->set_elt_property ("inversion",
112                                      chord.inversion_pitch_.to_scm ());
113   if (chord.bass_b_)
114     chord_name_p_->set_elt_property ("bass", chord.bass_pitch_.to_scm ());
115
116   announce_element (Score_element_info (chord_name_p_, 0));
117 }
118
119 void
120 Chord_name_engraver::do_pre_move_processing ()
121 {
122   if (chord_name_p_)
123     {
124       typeset_element (chord_name_p_);
125     }
126   pitch_arr_.clear ();
127   chord_name_p_ = 0;
128   tonic_req_ = 0;
129   inversion_req_ = 0;
130   bass_req_ = 0;
131 }
132