]> git.donarmstrong.com Git - lilypond.git/blob - lily/text-spanner-engraver.cc
8e26e7d5019f1ecfd1e67ecb22baf0c369f4b925
[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_acknowledged_grobs ();
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_acknowledged_grobs ()
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           assert (!finished_);
97           Grob* e = unsmob_grob (get_property ("currentMusicalColumn"));
98           span_->set_bound (RIGHT, e);
99
100           finished_ = span_;
101           span_ = 0;
102           current_req_ = 0;
103           req_drul_[STOP] = 0;
104         }
105     }
106
107   if (req_drul_[START])
108     {
109       if (current_req_)
110         {
111           req_drul_[START]->origin ()->warning
112  (_ ("already have a text spanner"));
113         }
114       else
115         {
116           current_req_ = req_drul_[START];
117           span_  = new Spanner (get_property ("TextSpanner"));
118
119           /* Ugh.  Reset (de)cresc. specific properties */
120           span_->set_grob_property ("outer", SCM_BOOL_T);
121           span_->set_grob_property ("if-text-padding", gh_double2scm (0));
122           span_->set_grob_property ("width-correct", gh_double2scm (0));
123                     
124           Side_position_interface::set_axis (span_, Y_AXIS);
125           Grob *e = unsmob_grob (get_property ("currentMusicalColumn"));
126           span_->set_bound (LEFT, e);
127           
128           announce_grob (span_, req_drul_[START]->self_scm());
129           req_drul_[START] = 0;
130         }
131     }
132 }
133
134 void
135 Text_spanner_engraver::acknowledge_grob (Grob_info info)
136 {
137   if (span_ && Note_column::has_interface (info.grob_))
138     {
139       Side_position_interface::add_support (span_, info.grob_);
140       add_bound_item (span_, dynamic_cast<Item*> (info.grob_));
141     }
142 }
143
144 void
145 Text_spanner_engraver::typeset_all ()
146 {  
147   if (finished_)
148     {
149       Side_position_interface::add_staff_support (finished_);
150       typeset_grob (finished_);
151       finished_ = 0;
152     }
153 }
154
155 void
156 Text_spanner_engraver::stop_translation_timestep ()
157 {
158   typeset_all ();
159 }
160
161 void
162 Text_spanner_engraver::finalize ()
163 {
164   typeset_all ();
165   if (span_)
166     {
167       current_req_->origin ()->warning (_ ("unterminated text spanner"));
168       span_->suicide ();
169       span_ = 0;
170     }
171 }
172
173 ENTER_DESCRIPTION(Text_spanner_engraver,
174 /* descr */       "Create text spanner from a  Span_req ",
175 /* creats*/       "TextSpanner",
176 /* acks  */       "note-column-interface",
177 /* reads */       "",
178 /* write */       "");