]> git.donarmstrong.com Git - lilypond.git/blob - lily/chord-name-engraver.cc
release: 1.3.108
[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 "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 Chord_name_engraver : public Engraver 
23 {
24 public:
25   Chord_name_engraver ();
26   VIRTUAL_COPY_CONS (Translator);
27
28 protected:
29   virtual void do_pre_move_processing ();
30   virtual void acknowledge_element (Score_element_info i);
31   virtual void do_process_music ();
32   virtual bool do_try_music (Music* m);
33
34 private:
35   void create_chord_name ();
36   
37   Item* chord_name_p_;
38   Protected_scm pitches_;
39
40   Protected_scm chord_;
41   Protected_scm last_chord_;
42
43   Protected_scm tonic_req_;
44   Protected_scm inversion_req_;
45   Protected_scm bass_req_;
46 };
47
48 ADD_THIS_TRANSLATOR (Chord_name_engraver);
49
50 Chord_name_engraver::Chord_name_engraver ()
51 {
52   chord_name_p_ = 0;
53   pitches_ = SCM_EOL;
54   tonic_req_ = SCM_EOL;
55   inversion_req_ = SCM_EOL;
56   bass_req_ = SCM_EOL;
57   chord_ = SCM_EOL;
58   last_chord_ = SCM_EOL;
59 }
60
61 void
62 Chord_name_engraver::acknowledge_element (Score_element_info i)
63 {
64   if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
65     pitches_ = gh_cons (n->get_mus_property ("pitch"), pitches_);
66 }
67
68 bool
69 Chord_name_engraver::do_try_music (Music* m)
70 {
71   if (Note_req* n = dynamic_cast<Note_req*> (m))
72     {
73       pitches_ = gh_cons (n->get_mus_property ("pitch"), pitches_);
74       return true;
75     }
76   if (Tonic_req* t = dynamic_cast<Tonic_req*> (m))
77     {
78       tonic_req_ = t->get_mus_property ("pitch");
79       return true;
80     }
81   if (Inversion_req* i = dynamic_cast<Inversion_req*> (m))
82     {
83       inversion_req_ = i->get_mus_property ("pitch");
84       return true;
85     }
86   if (Bass_req* b = dynamic_cast<Bass_req*> (m))
87     {
88       bass_req_ = b->get_mus_property ("pitch");
89       return true;
90     }
91   return false;
92 }
93
94 void
95 Chord_name_engraver::do_process_music ()
96 {
97   if (!chord_name_p_ && pitches_ != SCM_EOL)
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_ = Chord::pitches_and_requests_to_chord (pitches_,
105                                                      tonic_req_,
106                                                      inversion_req_,
107                                                      bass_req_,
108                                                      find_inversion_b);
109       
110       create_chord_name ();
111       announce_element (chord_name_p_, 0);
112       SCM s = get_property ("drarnChords"); //FIXME!
113       if (to_boolean (s) && last_chord_ != SCM_EOL &&
114           gh_equal_p (chord_, last_chord_))
115         chord_name_p_->set_elt_property ("begin-of-line-visible", SCM_BOOL_T);
116     }
117 }
118
119 void
120 Chord_name_engraver::create_chord_name ()
121 {
122   chord_name_p_ = new Item (get_property ("ChordName"));
123
124   SCM pitches = gh_car (chord_);
125   SCM modifiers = gh_cdr (chord_);
126   SCM inversion = gh_car (modifiers);
127   SCM bass = gh_cdr (modifiers);
128   /* Hmm, maybe chord-name should use (pitches (inversion . base)) too? */
129   chord_name_p_->set_elt_property ("pitches", pitches);
130   chord_name_p_->set_elt_property ("inversion", inversion);
131   chord_name_p_->set_elt_property ("inversion", bass);
132 }
133
134 void
135 Chord_name_engraver::do_pre_move_processing ()
136 {
137   if (chord_name_p_)
138     {
139       typeset_element (chord_name_p_);
140     }
141   chord_name_p_ = 0;
142
143   pitches_ = SCM_EOL;
144   tonic_req_ = SCM_EOL;
145   inversion_req_ = SCM_EOL;
146   bass_req_ = SCM_EOL;
147   last_chord_ = chord_;
148   chord_ = SCM_EOL;
149 }
150