]> git.donarmstrong.com Git - lilypond.git/blob - lily/clef-engraver.cc
patch::: 1.3.9.hwn2
[lilypond.git] / lily / clef-engraver.cc
1 /*
2   clef.cc -- implement Clef_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>,
7
8   Mats Bengtsson <matsb@s3.kth.se>
9 */
10
11 /*
12   CLEAN ME UP.
13  */
14
15 #include <ctype.h>
16 #include "bar.hh"
17 #include "clef-engraver.hh"
18 #include "clef-item.hh"
19 #include "debug.hh"
20 #include "command-request.hh"
21 #include "timing-translator.hh"
22 #include "note-head.hh"
23 #include "key-item.hh"
24 #include "local-key-item.hh"
25
26 Clef_engraver::Clef_engraver()
27 {
28   clef_p_ = 0;
29   clef_req_l_ = 0;
30   clef_type_str_ = "";
31   c0_position_i_ = 0;
32   clef_position_i_ = 0;
33   octave_dir_ = CENTER;
34   create_default_b_ = true;
35 }
36
37 bool
38 Clef_engraver::set_type (String s)
39 {
40   if (s.right_str(2) == "_8") // Down one octave
41     {
42       octave_dir_ = DOWN;
43       s = s.left_str(s.length_i() - 2);
44     }
45   else if (s.right_str(2) == "^8") // Up one octave
46     {
47       octave_dir_ = UP;
48       s = s.left_str(s.length_i() - 2);
49     }
50   else
51     octave_dir_ = CENTER;
52
53   bool found = false;
54   SCM c = get_property ("supportedClefTypes",0);
55   for (; gh_pair_p(c); c = gh_cdr (c))
56     {
57       SCM entry = gh_car (c);
58       SCM name  = gh_car (entry);
59
60       if (ly_scm2string (name) != s)
61         continue;
62       
63       SCM glyph  = gh_cadr (entry);
64       SCM pos  = gh_caddr (entry);
65       
66       clef_type_str_ = ly_scm2string (glyph);
67       clef_position_i_ = gh_scm2int (pos);
68       found = true;
69       break;
70     }
71     
72   if (!found)
73     {
74       switch(toupper (s[0]))
75         {
76         case 'F': 
77           clef_type_str_ = "bass";
78           break;
79         case  'G':
80           clef_type_str_ = "treble";
81           break;
82         case 'C': 
83           clef_type_str_ = "alto";
84           break;
85         default:
86           return false;
87         }
88       clef_position_i_ = 2 * (s[1] - '0') - 6;
89     }
90
91   if (clef_type_str_ == "treble")
92     c0_position_i_ = clef_position_i_ - 4;
93   else if (clef_type_str_ == "alto")
94     c0_position_i_ = clef_position_i_;
95   else if (clef_type_str_ == "bass")
96     c0_position_i_ = clef_position_i_ + 4;
97   else
98     assert (false);
99       
100   c0_position_i_ -= (int) octave_dir_ * 7;
101   
102   return true;
103 }
104
105
106 /** 
107   Generate a clef at the start of a measure. (when you see a Bar,
108   ie. a breakpoint) 
109   */
110 void
111 Clef_engraver::acknowledge_element (Score_element_info info)
112 {
113   if (dynamic_cast<Bar*>(info.elem_l_)
114       && clef_type_str_.length_i())
115     {
116       bool default_clef = !clef_p_;
117       create_clef();
118       if(!default_clef)
119         clef_p_->set_elt_property("visibility-lambda",
120                                   ly_eval_str ("all-visibility"));
121     }
122
123   /* ugh; should make Clef_referenced baseclass */
124   Item * it_l =dynamic_cast <Item *> (info.elem_l_);
125   if (it_l)
126     {
127       if (Note_head * h = dynamic_cast<Note_head*>(it_l))
128         {
129           h->set_position (int (h->position_f ()) + c0_position_i_);
130         }
131       else if (Local_key_item *i = dynamic_cast<Local_key_item*> (it_l))
132         {
133           i->c0_position_i_ =c0_position_i_;
134         }
135       else if (Key_item *k = dynamic_cast<Key_item*>(it_l))
136         {
137           k-> set_c_position (c0_position_i_);
138         }
139     } 
140 }
141
142 void
143 Clef_engraver::do_creation_processing()
144 {
145   create_default_b_ = true;     // should read property.
146   SCM def = get_property ("createInitdefaultClef", 0);
147   if (gh_string_p (def))
148     set_type (ly_scm2string (def));
149   
150   if (clef_type_str_.length_i ())
151     { 
152       create_clef();
153       clef_p_->set_elt_property ("non-default", SCM_BOOL_T);
154     }
155 }
156
157 bool
158 Clef_engraver::do_try_music (Music * r_l)
159 {
160   if (Clef_change_req *cl = dynamic_cast <Clef_change_req *> (r_l))
161     {
162       clef_req_l_ = cl;
163       if (!set_type (cl->clef_str_))
164         cl->error (_ ("unknown clef type"));
165
166       return true;
167     }
168   else
169     return false;
170
171 }
172
173 void
174 Clef_engraver::create_clef()
175 {
176   if (!clef_p_)
177     {
178       Clef_item *c= new Clef_item;
179       c->set_elt_property ("break-aligned", SCM_BOOL_T);
180       announce_element (Score_element_info (c, clef_req_l_));
181       clef_p_ = c;
182     }
183   
184   clef_p_->symbol_ = clef_type_str_;
185   clef_p_->set_position(clef_position_i_);
186   if (octave_dir_)
187     {
188       clef_p_->set_elt_property ("octave-dir", gh_int2scm (octave_dir_));
189     }
190 }
191
192
193 void
194 Clef_engraver::do_process_requests()
195 {
196   if (clef_req_l_)
197     {
198       create_clef();
199     }
200   else if (create_default_b_)
201     {
202       SCM type = get_property ("defaultClef", 0);
203       if (gh_string_p (type))
204         set_type (ly_scm2string (type));
205       else
206         set_type ( "treble");
207       create_clef ();
208       create_default_b_ = false;
209     }
210 }
211
212 void
213 Clef_engraver::do_pre_move_processing()
214 {
215   if (clef_p_)
216     {
217       typeset_element (clef_p_);
218       clef_p_ =0;
219     }
220   create_default_b_ = false;
221 }
222
223 void
224 Clef_engraver::do_post_move_processing()
225 {
226   clef_req_l_ = 0;
227 }
228
229 void
230 Clef_engraver::do_removal_processing()
231 {
232   assert (!clef_p_);
233 }
234
235
236
237 ADD_THIS_TRANSLATOR(Clef_engraver);
238