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