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