]> git.donarmstrong.com Git - lilypond.git/blob - lily/glissando-engraver.cc
Fix #223.
[lilypond.git] / lily / glissando-engraver.cc
1 /*
2   note-head-line-engraver.cc -- implement Note_head_line_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "engraver.hh"
10
11 #include "international.hh"
12 #include "rhythmic-head.hh"
13 #include "spanner.hh"
14 #include "stream-event.hh"
15 #include "warn.hh"
16
17 #include "translator.icc"
18
19 /**
20    Create line-spanner grobs for glissandi lines that connect note
21    heads.
22 */
23 class Glissando_engraver : public Engraver
24 {
25 public:
26   TRANSLATOR_DECLARATIONS (Glissando_engraver);
27
28 protected:
29   DECLARE_TRANSLATOR_LISTENER (glissando);
30   DECLARE_ACKNOWLEDGER (rhythmic_head);
31   virtual void finalize ();
32
33   void stop_translation_timestep ();
34   void process_music ();
35 private:
36   Spanner *line_;
37   Spanner *last_line_;
38   Stream_event *event_;
39 };
40
41 Glissando_engraver::Glissando_engraver ()
42 {
43   last_line_ = line_ = 0;
44   event_ = 0;
45 }
46
47 IMPLEMENT_TRANSLATOR_LISTENER (Glissando_engraver, glissando);
48 void
49 Glissando_engraver::listen_glissando (Stream_event *ev)
50 {
51   ASSIGN_EVENT_ONCE (event_, ev);
52 }
53
54 void
55 Glissando_engraver::process_music ()
56 {
57   if (event_)
58     line_ = make_spanner ("Glissando", event_->self_scm ());
59 }
60
61 void
62 Glissando_engraver::acknowledge_rhythmic_head (Grob_info info)
63 {
64   Grob *g = info.grob ();
65   if (line_)
66     line_->set_bound (LEFT, g);
67
68   if (last_line_)
69     last_line_->set_bound (RIGHT, g);
70 }
71
72 void
73 Glissando_engraver::stop_translation_timestep ()
74 {
75   if (last_line_ && last_line_->get_bound (RIGHT))
76     last_line_ = 0;
77
78   if (line_)
79     {
80       if (last_line_)
81         programming_error ("overwriting glissando");
82       last_line_ = line_;
83     }
84   line_ = 0;
85   event_ = 0;
86 }
87
88 void
89 Glissando_engraver::finalize ()
90 {
91   if (line_)
92     {
93       string msg = _ ("unterminated glissando");
94
95       if (event_)
96         event_->origin ()->warning (msg);
97       else
98         warning (msg);
99
100       line_->suicide ();
101       line_ = 0;
102     }
103 }
104
105 ADD_ACKNOWLEDGER (Glissando_engraver, rhythmic_head);
106 ADD_TRANSLATOR (Glissando_engraver,
107                 /* doc */ "Engrave a glissandi",
108                 /* create */ "Glissando",
109                 /* read */ "followVoice",
110                 /* write */ "");