]> git.donarmstrong.com Git - lilypond.git/blob - lily/trill-spanner-engraver.cc
Fix #670: Chained trills
[lilypond.git] / lily / trill-spanner-engraver.cc
1 /*
2   trill-spanner-engraver.cc -- implement Trill_spanner_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2009 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 /*
10   C&P from text-spanner.cc
11
12   - todo: ending should be detected automatically? a new note
13   automatically is the end of the trill?
14 */
15
16 #include "engraver.hh"
17
18 #include "international.hh"
19 #include "note-column.hh"
20 #include "pointer-group-interface.hh"
21 #include "side-position-interface.hh"
22 #include "stream-event.hh"
23 #include "spanner.hh"
24
25 #include "translator.icc"
26
27 class Trill_spanner_engraver : public Engraver
28 {
29 public:
30   TRANSLATOR_DECLARATIONS (Trill_spanner_engraver);
31 protected:
32   virtual void finalize ();
33   DECLARE_TRANSLATOR_LISTENER (trill_span);
34   DECLARE_ACKNOWLEDGER (note_column);
35
36   void stop_translation_timestep ();
37   void process_music ();
38
39 private:
40   Spanner *span_;
41   Spanner *finished_;
42   Stream_event *current_event_;
43   Drul_array<Stream_event *> event_drul_;
44   void typeset_all ();
45 };
46
47 Trill_spanner_engraver::Trill_spanner_engraver ()
48 {
49   finished_ = 0;
50   current_event_ = 0;
51   span_ = 0;
52   event_drul_.set (0, 0);
53 }
54
55 IMPLEMENT_TRANSLATOR_LISTENER (Trill_spanner_engraver, trill_span);
56 void
57 Trill_spanner_engraver::listen_trill_span (Stream_event *ev)
58 {
59   Direction d = to_dir (ev->get_property ("span-direction"));
60   ASSIGN_EVENT_ONCE (event_drul_[d], ev);
61 }
62
63 void
64 Trill_spanner_engraver::acknowledge_note_column (Grob_info info)
65 {
66   if (span_)
67     {
68       Pointer_group_interface::add_grob (span_,
69                                          ly_symbol2scm ("note-columns"),
70                                          info.grob());
71       if (!span_->get_bound (LEFT))
72         add_bound_item (span_, info.grob ());
73     }
74   else if (finished_)
75     {
76       Pointer_group_interface::add_grob (finished_, ly_symbol2scm ("note-columns"),
77                                          info.grob());
78       if (!finished_->get_bound (RIGHT))
79         add_bound_item (finished_, info.grob ());
80     }
81 }
82
83 void
84 Trill_spanner_engraver::process_music ()
85 {
86   if (span_
87       && (event_drul_[STOP] || event_drul_[START]))
88     {
89       Stream_event *ender = event_drul_[STOP];
90       if (!ender)
91         ender = event_drul_[START];
92       finished_ = span_;
93       announce_end_grob (finished_, ender->self_scm ());
94       span_ = 0;
95       current_event_ = 0;
96     }
97
98   if (event_drul_[START])
99     {
100       current_event_ = event_drul_[START];
101       span_ = make_spanner ("TrillSpanner", event_drul_[START]->self_scm ());
102       Side_position_interface::set_axis (span_, Y_AXIS);
103     }
104 }
105
106 void
107 Trill_spanner_engraver::typeset_all ()
108 {
109   if (finished_)
110     {
111       if (!finished_->get_bound (RIGHT))
112         {
113           Grob *e = unsmob_grob (get_property ("currentMusicalColumn"));
114           finished_->set_bound (RIGHT, e);
115         }
116       finished_ = 0;
117     }
118 }
119
120 void
121 Trill_spanner_engraver::stop_translation_timestep ()
122 {
123   if (span_ && !span_->get_bound (LEFT))
124     {
125       Grob *e = unsmob_grob (get_property ("currentMusicalColumn"));
126       span_->set_bound (LEFT, e);
127     }
128
129   typeset_all ();
130   event_drul_.set (0, 0);
131 }
132
133 void
134 Trill_spanner_engraver::finalize ()
135 {
136   typeset_all ();
137   if (span_)
138     {
139       Grob *e = unsmob_grob (get_property ("currentCommandColumn"));
140       span_->set_bound (RIGHT, e);
141     }
142 }
143
144 ADD_ACKNOWLEDGER (Trill_spanner_engraver, note_column);
145
146 ADD_TRANSLATOR (Trill_spanner_engraver,
147                 /* doc */
148                 "Create trill spanner from an event.",
149
150                 /* create */
151                 "TrillSpanner ",
152
153                 /* read */
154                 "currentCommandColumn "
155                 "currentMusicalColumn ",
156
157                 /* write */
158                 ""
159                 );