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