]> git.donarmstrong.com Git - lilypond.git/blob - lily/text-spanner-engraver.cc
* VERSION (MY_PATCH_LEVEL): make 1.7.0
[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
44
45 Text_spanner_engraver::Text_spanner_engraver ()
46 {
47   finished_ = 0;
48   current_req_ = 0;
49   span_ =0;
50   req_drul_[START] = 0;
51   req_drul_[STOP] = 0;
52 }
53
54 void
55 Text_spanner_engraver::start_translation_timestep ()
56 {
57   req_drul_[START] = 0;
58   req_drul_[STOP] = 0;
59 }
60
61 bool
62 Text_spanner_engraver::try_music (Music *m)
63 {
64   if (Span_req *s =  dynamic_cast <Span_req*> (m))
65     {
66       String t =  ly_scm2string (s->get_mus_property ("span-type"));            
67       if (t == "abort")
68         {
69           req_drul_[LEFT] = 0;
70           req_drul_[RIGHT] = 0;
71           if (span_)
72             span_->suicide ();
73           span_ = 0;
74         }
75       else if (t == "text")
76         {
77           req_drul_[s->get_span_dir ()] = s;
78           return true;
79         }
80     }
81   return false;
82 }
83
84 void
85 Text_spanner_engraver::process_music ()
86 {
87   if (req_drul_[STOP])
88     {
89       if (!span_)
90         {
91           req_drul_[STOP]->origin ()->warning
92  (_ ("can't find start of text spanner"));
93         }
94       else
95         {
96           finished_ = span_;
97           span_ = 0;
98           current_req_ = 0;
99         }
100     }
101
102   if (req_drul_[START])
103     {
104       if (current_req_)
105         {
106           req_drul_[START]->origin ()->warning(_ ("already have a text spanner"));
107         }
108       else
109         {
110           current_req_ = req_drul_[START];
111           span_  = new Spanner (get_property ("TextSpanner"));
112
113           /* Ugh.  Reset (de)cresc. specific properties */
114           span_->set_grob_property ("outer", SCM_BOOL_T);
115           span_->set_grob_property ("if-text-padding", gh_double2scm (0));
116           span_->set_grob_property ("width-correct", gh_double2scm (0));
117                     
118           Side_position_interface::set_axis (span_, Y_AXIS);
119           announce_grob (span_, req_drul_[START]->self_scm());
120           req_drul_[START] = 0;
121         }
122     }
123 }
124
125 void
126 Text_spanner_engraver::acknowledge_grob (Grob_info info)
127 {
128   Spanner * spans[2] ={span_, finished_};
129   for (int i = 0;  i < 2 ; i++)
130     {
131       if (spans[i] && Note_column::has_interface (info.grob_))
132         {
133           Side_position_interface::add_support (spans[i], info.grob_);
134           add_bound_item (spans[i], dynamic_cast<Item*> (info.grob_));
135         }
136     }
137 }
138
139 void
140 Text_spanner_engraver::typeset_all ()
141 {  
142   if (finished_)
143     {
144       Side_position_interface::add_staff_support (finished_);
145
146       if (!finished_->get_bound (RIGHT))
147         {
148           Grob* e = unsmob_grob (get_property ("currentMusicalColumn"));
149           span_->set_bound (RIGHT, e);
150         }
151       typeset_grob (finished_);
152       finished_ = 0;
153     }
154 }
155
156 void
157 Text_spanner_engraver::stop_translation_timestep ()
158 {
159   if (span_ && !span_->get_bound (LEFT))
160     {
161       Grob* e = unsmob_grob (get_property ("currentMusicalColumn"));
162       span_->set_bound (LEFT, e);
163     }
164
165   typeset_all ();
166 }
167
168 void
169 Text_spanner_engraver::finalize ()
170 {
171   typeset_all ();
172   if (span_)
173     {
174       current_req_->origin ()->warning (_ ("unterminated text spanner"));
175       span_->suicide ();
176       span_ = 0;
177     }
178 }
179
180 ENTER_DESCRIPTION(Text_spanner_engraver,
181 /* descr */       "Create text spanner from a Span_req.",
182 /* creats*/       "TextSpanner",
183 /* acks  */       "note-column-interface",
184 /* reads */       "",
185 /* write */       "");