2 piano-pedal-engraver.cc -- implement Piano_pedal_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "musical-request.hh"
11 #include "score-element.hh"
14 #include "lily-guile.hh"
15 #include "note-head.hh"
17 #include "side-position-interface.hh"
18 #include "staff-symbol-referencer.hh"
19 #include "dictionary.hh"
20 #include "dictionary-iter.hh"
21 #include "text-item.hh"
28 * symbols are at wrong place in font
31 class Sustain_pedal : public Item
34 VIRTUAL_COPY_CONS (Score_element);
37 virtual Molecule do_brew_molecule () const;
38 virtual void after_line_breaking ();
42 Sustain_pedal::after_line_breaking ()
44 Side_position_interface i (this);
45 Direction d = i.get_direction ();
50 Sustain_pedal::do_brew_molecule () const
53 SCM glyph = get_elt_property ("glyph");
54 if (glyph == SCM_UNDEFINED)
56 String text = ly_scm2string (glyph);
58 for (int i = 0; i < text.length_i (); i++)
60 // leuke koor dump door tiepo, snapnie helemaal:
61 //String idx = ("pedal-") + text[i];
63 // braak: waarom vindt String het zo moeilijk om
64 // String + char te doen?
65 //String idx = "pedal-" + String (&text.byte_C ()[i], 1);
66 String idx = String ("pedal-") + String (&text.byte_C ()[i], 1);
67 Molecule m = lookup_l ()->afm_find (idx);
73 SCM s = scm_eval (gh_list (ly_symbol2scm ("pedal-kerning"),
74 ly_str02scm (String (&text.byte_C ()[i - 1], 1).ch_C ()),
75 ly_str02scm (String (&text.byte_C ()[i], 1).ch_C ()),
79 Staff_symbol_referencer_interface st (this);
80 Real staff_space = st.staff_space ();
81 kern = gh_scm2double (s) * staff_space;
84 mol.add_at_edge (X_AXIS, RIGHT, m, kern);
94 * it would be real cool if an engraver could be initialised with a
97 Piano_pedal_engraver::"sostenuto"
98 Piano_pedal_engraver::"sustain"
99 Piano_pedal_engraver::"una-chorda"
105 class Piano_pedal_engraver : public Engraver
109 Span_req* start_req_l_;
110 Drul_array<Span_req*> req_l_drul_;
115 VIRTUAL_COPY_CONS (Translator);
116 Piano_pedal_engraver ();
119 virtual bool do_try_music (Music*);
120 virtual void do_process_music ();
121 virtual void do_pre_move_processing ();
122 virtual void do_post_move_processing ();
123 virtual void acknowledge_element (Score_element_info);
126 Dictionary<Pedal_info> info_dict_;
129 ADD_THIS_TRANSLATOR (Piano_pedal_engraver);
131 Piano_pedal_engraver::Piano_pedal_engraver ()
133 (void)info_dict_["Sostenuto"];
134 (void)info_dict_["Sustain"];
135 (void)info_dict_["UnaChorda"];
136 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
138 Pedal_info& p = i.val_ref ();
140 p.req_l_drul_[START] = 0;
141 p.req_l_drul_[STOP] = 0;
151 Piano_pedal_engraver::acknowledge_element (Score_element_info info)
153 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
155 Pedal_info& p = i.val_ref ();
158 if (Note_head* n = dynamic_cast<Note_head*> (info.elem_l_))
160 Side_position_interface st (p.item_p_);
162 if (st.get_axis( ) == X_AXIS
163 && !p.item_p_->parent_l (Y_AXIS))
164 p.item_p_->set_parent (n, Y_AXIS);
166 if (Stem* s = dynamic_cast<Stem*> (info.elem_l_))
168 Side_position_interface st (p.item_p_);
176 Piano_pedal_engraver::do_try_music (Music *m)
178 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
180 Pedal_info& p = i.val_ref ();
181 if (Span_req * s = dynamic_cast<Span_req*>(m))
183 if (s->span_type_str_ == i.key ())
185 p.req_l_drul_[s->span_dir_] = s;
194 Piano_pedal_engraver::do_process_music ()
196 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
198 Pedal_info& p = i.val_ref ();
199 SCM s = SCM_UNDEFINED;
200 if (p.req_l_drul_[STOP] && p.req_l_drul_[START])
204 p.req_l_drul_[STOP]->warning (_f ("can't find start of piano pedal: %s", i.key ()));
208 s = get_property ("stopStart" + i.key ());
210 p.start_req_l_ = p.req_l_drul_[START];
212 else if (p.req_l_drul_[STOP])
216 p.req_l_drul_[STOP]->warning (_f ("can't find start of piano pedal: %s", i.key ()));
220 s = get_property ("stop" + i.key ());
224 else if (p.req_l_drul_[START])
226 p.start_req_l_ = p.req_l_drul_[START];
227 s = get_property ("start" + i.key ());
230 if (s != SCM_UNDEFINED)
232 if (i.key () == "Sustain")
234 p.item_p_ = new Sustain_pedal;
235 p.item_p_->set_elt_property ("glyph", s);
239 p.item_p_ = new Text_item;
240 p.item_p_->set_elt_property ("text", s);
242 p.item_p_->set_elt_property ("style", ly_str02scm ("italic"));
245 Side_position_interface si (p.item_p_);
246 si.set_axis (Y_AXIS);
249 If set to empty, it can't be centred
250 Howto centre non-fat text?
251 p.item_p_->set_empty (X_AXIS);
253 p.item_p_->set_elt_property ("self-alignment-X", gh_int2scm (0));
254 p.item_p_->add_offset_callback (Side_position_interface::aligned_on_self, X_AXIS);
255 p.item_p_->add_offset_callback (Side_position_interface::centered_on_parent, X_AXIS);
256 announce_element (Score_element_info (p.item_p_,
258 ? p.req_l_drul_[START]
259 : p.req_l_drul_[STOP]));
265 Piano_pedal_engraver::do_pre_move_processing ()
267 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
269 Pedal_info& p = i.val_ref ();
272 side_position (p.item_p_).add_staff_support ();
273 typeset_element (p.item_p_);
280 Piano_pedal_engraver::do_post_move_processing ()
282 for (Dictionary_iter <Pedal_info> i (info_dict_); i.ok (); i++)
284 Pedal_info& p = i.val_ref ();
285 p.req_l_drul_[STOP] = 0;
286 p.req_l_drul_[START] = 0;