]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-engraver.cc
patch::: 1.3.143.jcn1
[lilypond.git] / lily / piano-pedal-engraver.cc
1 /*   
2   piano-pedal-engraver.cc --  implement Piano_pedal_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2001 Jan Nieuwenhuizen <janneke@gnu.org>
7  */
8
9 #include "engraver.hh"
10 #include "musical-request.hh"
11 #include "grob.hh"
12 #include "item.hh"
13 #include "lily-guile.hh"
14 #include "rhythmic-head.hh"
15 #include "stem.hh"
16 #include "side-position-interface.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "item.hh"
19
20 class Piano_pedal_engraver : public Engraver
21 {
22 public:
23   VIRTUAL_COPY_CONS (Translator);
24   Piano_pedal_engraver ();
25   ~Piano_pedal_engraver ();
26 protected:
27   virtual void initialize ();
28   virtual bool try_music (Music*);
29   virtual void stop_translation_timestep ();
30   virtual void start_translation_timestep ();
31   virtual void acknowledge_grob (Grob_info);
32   virtual void create_grobs ();
33
34 private:
35   struct Pedal_info
36   {
37     char const * name_;
38     Span_req* start_req_l_;
39     Drul_array<Span_req*> req_l_drul_;
40     Item* item_p_;
41   };
42
43
44   Pedal_info *info_list_;
45 };
46
47 ADD_THIS_TRANSLATOR (Piano_pedal_engraver);
48
49 Piano_pedal_engraver::Piano_pedal_engraver ()
50 {
51   info_list_ = 0;
52 }
53 void
54 Piano_pedal_engraver::initialize ()
55 {
56   info_list_ = new Pedal_info[4];
57   Pedal_info *p = info_list_;
58
59
60   char * names [] = { "Sostenuto", "Sustain", "UnaCorda", 0  };
61   char **np = names ;
62   do
63     {
64       p->name_ = *np;
65       p->item_p_ = 0;
66       p->req_l_drul_[START] = 0;
67       p->req_l_drul_[STOP] = 0;
68       p->start_req_l_ = 0;
69
70       p++;
71     }
72   while (* (np ++));
73 }
74
75 Piano_pedal_engraver::~Piano_pedal_engraver ()
76 {
77   delete[] info_list_;
78 }
79
80 /*
81    Urg: Code dup
82    I'm a script
83   */
84 void
85 Piano_pedal_engraver::acknowledge_grob (Grob_info info)
86 {
87   for (Pedal_info*p = info_list_; p && p->name_; p ++)
88     {
89       if (p->item_p_)
90         {
91           if (Rhythmic_head::has_interface (info.elem_l_))
92             {
93               Side_position_interface::add_support (p->item_p_, info.elem_l_);
94
95               if (Side_position_interface::get_axis (p->item_p_) == X_AXIS
96                   && !p->item_p_->parent_l (Y_AXIS))
97                 p->item_p_->set_parent (info.elem_l_, Y_AXIS);
98             }
99           if (Stem::has_interface (info.elem_l_))
100             {
101               Side_position_interface::add_support (p->item_p_,info.elem_l_);
102             }
103         }
104     }
105 }
106
107 bool
108 Piano_pedal_engraver::try_music (Music *m)
109 {
110   if (Span_req * s = dynamic_cast<Span_req*> (m))
111     {
112       for (Pedal_info*p = info_list_; p->name_; p ++)
113         {
114           if (scm_equal_p (s->get_mus_property ("span-type"),
115                            ly_str02scm (p->name_))==SCM_BOOL_T)
116             {
117               p->req_l_drul_[s->get_span_dir ()] = s;
118               return true;
119             }
120         }
121     }
122   return false;
123 }
124
125 void
126 Piano_pedal_engraver::create_grobs ()
127 {
128   for (Pedal_info*p = info_list_; p && p->name_; p ++)
129     {
130       if (p->item_p_ || ! (p->req_l_drul_[STOP] || p->req_l_drul_[START]))
131         continue;
132       
133       SCM s = SCM_EOL;
134       SCM strings = get_property (("pedal" + String (p->name_) + "Strings").ch_C ());
135       if (scm_ilength (strings) < 3)
136         continue;
137       
138       if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
139         {
140           if (!p->start_req_l_)
141             {
142               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s",  p->name_));
143             }
144           else
145             {
146               s = gh_cadr (strings);
147             }
148           p->start_req_l_ = p->req_l_drul_[START];
149         }
150       else if (p->req_l_drul_[STOP])
151         {
152           if (!p->start_req_l_)
153             {
154               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_));
155             }
156           else
157             {
158               s = gh_caddr (strings);
159             }
160           p->start_req_l_ = 0;
161         }
162       else if (p->req_l_drul_[START])
163         {
164           p->start_req_l_ = p->req_l_drul_[START];
165           s = gh_car (strings);
166         }
167
168       if (gh_string_p (s))
169         {
170           String propname = String (p->name_) + "Pedal";
171           p->item_p_ = new Item (get_property (propname.ch_C ()));
172           p->item_p_->set_grob_property ("text", s);
173
174           announce_grob (p->item_p_,
175                             p->req_l_drul_[START]
176                             ? p->req_l_drul_[START]
177                             : p->req_l_drul_[STOP]);
178         }
179       p->req_l_drul_[START] = 0;
180       p->req_l_drul_[STOP] = 0;
181     }
182 }
183
184 void
185 Piano_pedal_engraver::stop_translation_timestep ()
186 {
187   Item * sustain = 0;
188   for (Pedal_info*p = info_list_; p->name_; p ++)
189     {
190       if (p->name_ == String ("Sustain"))
191         sustain = p->item_p_;
192     }
193
194   for (Pedal_info*p = info_list_; p->name_; p ++)
195     {
196       if (p->item_p_)
197         {
198           Side_position_interface::add_staff_support (p->item_p_);
199           
200           /*
201             Hmm.
202           */
203           if (p->name_ != String ("Sustain"))
204             {
205               if (sustain)
206                 {
207                   Side_position_interface::add_support (p->item_p_,sustain);
208                 }
209             }
210           typeset_grob (p->item_p_);
211         }
212       p->item_p_ = 0;
213     }
214 }
215
216 void
217 Piano_pedal_engraver::start_translation_timestep ()
218 {
219   for (Pedal_info*p = info_list_; p->name_; p ++)
220     {
221       p->req_l_drul_[STOP] = 0;
222       p->req_l_drul_[START] = 0;
223     }
224 }