]> git.donarmstrong.com Git - lilypond.git/blob - lily/fingering-engraver.cc
f469df8139484e59fa2619ee8ac38bcf5ab8e4f2
[lilypond.git] / lily / fingering-engraver.cc
1 /*
2   fingering-engraver.cc -- implement Fingering_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver.hh"
10 #include "pitch.hh"
11 #include "rhythmic-head.hh"
12 #include "self-alignment-interface.hh"
13 #include "side-position-interface.hh"
14 #include "stem.hh"
15 #include "stream-event.hh"
16
17 #include "translator.icc"
18
19 class Fingering_engraver : public Engraver
20 {
21   vector<Stream_event*> events_;
22   vector<Item*> fingerings_;
23
24 public:
25   TRANSLATOR_DECLARATIONS (Fingering_engraver);
26 protected:
27   void stop_translation_timestep ();
28   void process_music ();
29   DECLARE_TRANSLATOR_LISTENER (fingering);
30   DECLARE_ACKNOWLEDGER (rhythmic_head);
31   DECLARE_ACKNOWLEDGER (stem);
32
33 private:
34   void make_script (Direction, Stream_event *, int);
35 };
36
37 IMPLEMENT_TRANSLATOR_LISTENER (Fingering_engraver, fingering);
38 void
39 Fingering_engraver::listen_fingering (Stream_event *ev)
40 {
41   events_.push_back (ev);
42 }
43
44 void
45 Fingering_engraver::acknowledge_stem (Grob_info inf)
46 {
47   for (vsize i = 0; i < fingerings_.size (); i++)
48     Side_position_interface::add_support (fingerings_[i], inf.grob ());
49 }
50
51 void
52 Fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
53 {
54   for (vsize i = 0; i < fingerings_.size (); i++)
55     {
56       Grob *t = fingerings_[i];
57       Side_position_interface::add_support (t, inf.grob ());
58       if (!t->get_parent (X_AXIS))
59         t->set_parent (inf.grob (), X_AXIS);
60     }
61 }
62
63 void
64 Fingering_engraver::process_music ()
65 {
66   for (vsize i = events_.size (); i--;)
67     {
68       SCM dir = events_[i]->get_property ("direction");
69       make_script (to_dir (dir), events_[i], i);
70     }
71 }
72
73 void
74 Fingering_engraver::make_script (Direction d, Stream_event *r, int i)
75 {
76   Item *fingering = make_item ("Fingering", r->self_scm ());
77
78   /*
79     Huh, what's this for? --hwn.
80
81     junkme.
82   */
83   SCM pitch = r->get_property ("pitch");
84   if (unsmob_pitch (pitch))
85     fingering->set_property ("pitch", pitch);
86
87   /*
88     We can't fold these definitions into define-grobs since
89     fingerings for chords need different settings.
90   */
91   Side_position_interface::set_axis (fingering, Y_AXIS);
92   Self_alignment_interface::set_align_self (fingering, X_AXIS);
93   Self_alignment_interface::set_center_parent (fingering, X_AXIS);
94
95   // Hmm
96   int priority = 200;
97   SCM s = fingering->get_property ("script-priority");
98   if (scm_is_number (s))
99     priority = scm_to_int (s);
100
101   /* See script-engraver.cc */
102   priority += i;
103
104   fingering->set_property ("script-priority", scm_from_int (priority));
105
106   if (!is_direction (fingering->get_property_data (ly_symbol2scm ("direction"))))
107     {
108       if (d)
109         fingering->set_property ("direction", scm_from_int (d));
110       else
111         fingering->set_property ("direction", scm_from_int (RIGHT));
112     }
113
114   fingerings_.push_back (fingering);
115 }
116
117 void
118 Fingering_engraver::stop_translation_timestep ()
119 {
120   if (!fingerings_.size ())
121     return;
122
123   fingerings_.clear ();
124   events_.clear ();
125 }
126
127 Fingering_engraver::Fingering_engraver ()
128 {
129 }
130
131 ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head);
132 ADD_ACKNOWLEDGER (Fingering_engraver, stem);
133 ADD_TRANSLATOR (Fingering_engraver,
134                 /* doc */ "Create fingering-scripts",
135                 /* create */ "Fingering",
136                 /* accept */ "fingering-event",
137                 /* read */ "",
138                 /* write */ "");