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