release commit
[lilypond.git] / lily / fingering-engraver.cc
blob07df23d08b41b3efb76c422a6b638dd60c52f022
1 /*
2 fingering-engraver.cc -- implement Fingering_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
11 #include "engraver.hh"
12 #include "side-position-interface.hh"
13 #include "item.hh"
14 #include "event.hh"
15 #include "stem.hh"
16 #include "rhythmic-head.hh"
17 #include "self-alignment-interface.hh"
19 class Fingering_engraver : public Engraver
21 Link_array<Music> reqs_;
22 Link_array<Item> fingerings_;
24 public:
25 TRANSLATOR_DECLARATIONS(Fingering_engraver);
26 protected:
27 virtual bool try_music (Music* m);
28 virtual void stop_translation_timestep ();
29 virtual void start_translation_timestep ();
30 virtual void process_music ();
31 virtual void acknowledge_grob (Grob_info);
33 void make_script (Direction, Music*,Axis, int);
36 bool
37 Fingering_engraver::try_music (Music *m)
39 if (m->is_mus_type ("fingering-event"))
41 reqs_.push (m);
42 return true;
44 return false;
47 void
48 Fingering_engraver::acknowledge_grob (Grob_info inf)
50 if (Stem::has_interface (inf.grob_))
52 for (int i=0; i < fingerings_.size (); i++)
54 Side_position_interface::add_support (fingerings_[i],inf.grob_);
57 else if (Rhythmic_head::has_interface (inf.grob_))
59 for (int i=0; i < fingerings_.size (); i++)
61 Grob*t = fingerings_[i];
62 Side_position_interface::add_support (t,inf.grob_);
63 if (!t->get_parent (X_AXIS))
64 t->set_parent (inf.grob_, X_AXIS);
69 void
70 Fingering_engraver::process_music ()
72 for (int i= reqs_.size(); i--;)
74 SCM dir = reqs_[i]->get_mus_property ("direction");
75 make_script (to_dir (dir), reqs_[i], Y_AXIS, i);
79 void
80 Fingering_engraver::make_script (Direction d, Music *r,Axis a, int i)
82 Item *fingering = new Item (get_property ("Fingering"));
84 Axis other = other_axis (a);
86 SCM pitch = r->get_mus_property ("pitch");
87 if (unsmob_pitch (pitch))
88 fingering->set_grob_property ("pitch", pitch);
90 Side_position_interface::set_axis (fingering, a);
92 fingering->add_offset_callback (Self_alignment_interface::aligned_on_self_proc, other);
93 fingering->add_offset_callback (Self_alignment_interface::centered_on_parent_proc, other);
95 // Hmm
96 int priority = 200;
97 SCM s = fingering->get_grob_property ("script-priority");
98 if (gh_number_p (s))
99 priority = gh_scm2int (s);
101 /* See script-engraver.cc */
102 priority += i;
104 fingering->set_grob_property ("script-priority", gh_int2scm (priority));
107 if (!is_direction (fingering->get_grob_property ("direction")))
109 if (d)
110 fingering->set_grob_property ("direction", gh_int2scm (d));
111 else
112 fingering->set_grob_property ("direction", gh_int2scm (RIGHT));
115 SCM dig = r->get_mus_property ("digit");
116 fingering->set_grob_property ("text", scm_number_to_string (dig, gh_int2scm (10)));
118 announce_grob (fingering, r->self_scm());
119 fingerings_.push (fingering);
122 void
123 Fingering_engraver::stop_translation_timestep ()
125 if (!fingerings_.size ())
126 return;
128 for (int i=0; i < fingerings_.size (); i++)
130 Item *ti = fingerings_[i];
131 Side_position_interface::add_staff_support (ti);
132 typeset_grob (ti);
134 fingerings_.clear ();
137 void
138 Fingering_engraver::start_translation_timestep ()
140 reqs_.clear ();
143 Fingering_engraver::Fingering_engraver()
148 ENTER_DESCRIPTION(Fingering_engraver,
149 /* descr */ "Create fingering-scripts",
150 /* creats*/ "Fingering",
151 /* accepts */ "fingering-event",
152 /* acks */ "rhythmic-head-interface stem-interface",
153 /* reads */ "",
154 /* write */ "");