]> git.donarmstrong.com Git - lilypond.git/blob - lily/text-spanner-engraver.cc
* scm/define-grobs.scm: uniform naming for definitions and output
[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--2003 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "note-column.hh"
10 #include "item.hh"
11 #include "side-position-interface.hh"
12 #include "engraver.hh"
13
14 class Text_spanner_engraver : public Engraver
15 {
16 public:
17   TRANSLATOR_DECLARATIONS(Text_spanner_engraver);  
18 protected:
19   virtual void finalize ();
20   virtual void acknowledge_grob (Grob_info);
21   virtual bool try_music (Music *);
22   virtual void stop_translation_timestep ();
23   virtual void start_translation_timestep ();
24   virtual void process_music ();
25
26 private:
27   Spanner *span_;
28   Spanner *finished_;
29   Music *current_req_;
30   Drul_array<Music*> req_drul_;
31   void typeset_all ();
32 };
33
34
35 Text_spanner_engraver::Text_spanner_engraver ()
36 {
37   finished_ = 0;
38   current_req_ = 0;
39   span_ =0;
40   req_drul_[START] = 0;
41   req_drul_[STOP] = 0;
42 }
43
44 void
45 Text_spanner_engraver::start_translation_timestep ()
46 {
47   req_drul_[START] = 0;
48   req_drul_[STOP] = 0;
49 }
50
51 bool
52 Text_spanner_engraver::try_music (Music *m)
53 {
54   if (m->is_mus_type ("text-span-event"))
55     {
56
57       Direction d = to_dir (m->get_mus_property ("span-direction"));
58       req_drul_[d] = m;
59       return true;
60     }
61   else if (m->is_mus_type ("abort-event"))
62     {
63       req_drul_[LEFT] = 0;
64       req_drul_[RIGHT] = 0;
65       if (span_)
66         span_->suicide ();
67       span_ = 0;
68     }
69
70   return false;
71 }
72
73 void
74 Text_spanner_engraver::process_music ()
75 {
76   if (req_drul_[STOP])
77     {
78       if (!span_)
79         {
80           req_drul_[STOP]->origin ()->warning
81  (_ ("can't find start of text spanner"));
82         }
83       else
84         {
85           finished_ = span_;
86           span_ = 0;
87           current_req_ = 0;
88         }
89     }
90
91   if (req_drul_[START])
92     {
93       if (current_req_)
94         {
95           req_drul_[START]->origin ()->warning(_ ("already have a text spanner"));
96         }
97       else
98         {
99           current_req_ = req_drul_[START];
100           span_  = new Spanner (get_property ("TextSpanner"));
101
102 #if 0
103           /* Ugh.  Reset (de)cresc. specific properties */
104           span_->set_grob_property ("enclose-bounds", SCM_BOOL_T);
105           span_->set_grob_property ("if-text-padding", gh_double2scm (0));
106           span_->set_grob_property ("width-correct", gh_double2scm (0));
107 #endif
108           
109           Side_position_interface::set_axis (span_, Y_AXIS);
110           announce_grob (span_, req_drul_[START]->self_scm());
111           req_drul_[START] = 0;
112         }
113     }
114 }
115
116 void
117 Text_spanner_engraver::acknowledge_grob (Grob_info info)
118 {
119   Spanner * spans[2] ={span_, finished_};
120   for (int i = 0;  i < 2 ; i++)
121     {
122       if (spans[i] && Note_column::has_interface (info.grob_))
123         {
124           Side_position_interface::add_support (spans[i], info.grob_);
125           add_bound_item (spans[i], dynamic_cast<Item*> (info.grob_));
126         }
127     }
128 }
129
130 void
131 Text_spanner_engraver::typeset_all ()
132 {  
133   if (finished_)
134     {
135       Side_position_interface::add_staff_support (finished_);
136       if (!finished_->get_bound (RIGHT))
137         {
138           Grob* e = unsmob_grob (get_property ("currentMusicalColumn"));
139           finished_->set_bound (RIGHT, e);
140         }
141       typeset_grob (finished_);
142       finished_ = 0;
143     }
144 }
145
146 void
147 Text_spanner_engraver::stop_translation_timestep ()
148 {
149   if (span_ && !span_->get_bound (LEFT))
150     {
151       Grob* e = unsmob_grob (get_property ("currentMusicalColumn"));
152       span_->set_bound (LEFT, e);
153     }
154
155   typeset_all ();
156 }
157
158 void
159 Text_spanner_engraver::finalize ()
160 {
161   typeset_all ();
162   if (span_)
163     {
164       current_req_->origin ()->warning (_ ("unterminated text spanner"));
165       span_->suicide ();
166       span_ = 0;
167     }
168 }
169
170 ENTER_DESCRIPTION(Text_spanner_engraver,
171 /* descr */       "Create text spanner from a Music.",
172 /* creats*/       "TextSpanner",
173 /* accepts */     "text-span-event",
174 /* acks  */      "note-column-interface",
175 /* reads */       "",
176 /* write */       "");