]> git.donarmstrong.com Git - lilypond.git/blob - lily/extender-engraver.cc
release: 1.1.51
[lilypond.git] / lily / extender-engraver.cc
1 /*
2   extender-engraver.cc -- implement Extender_engraver
3
4   (c) 1998--1999 Jan Nieuwenhuizen <janneke@gnu.org>
5 */
6
7 #include "proto.hh"
8 #include "musical-request.hh"
9 #include "extender-engraver.hh"
10 #include "extender-spanner.hh"
11 #include "score-column.hh"
12 #include "text-item.hh"
13
14 ADD_THIS_TRANSLATOR (Extender_engraver);
15
16 Extender_engraver::Extender_engraver ()
17 {
18   extender_spanner_p_ = 0;
19   req_l_ = 0;
20 }
21
22 void
23 Extender_engraver::acknowledge_element (Score_element_info i)
24 {
25   if (Text_item* t = dynamic_cast<Text_item*> (i.elem_l_))
26     {
27       Rhythmic_req * rh = dynamic_cast<Rhythmic_req*>  (i.req_l_);
28       if (!rh)
29         return;
30
31       now_lyrics_.push (Text_lyric_tuple (t, rh, now_mom () + rh->length_mom ()));
32       /*
33         UGH.  What do we do in case of multiple alternatives? 
34        */
35       if (extender_spanner_p_
36           && !extender_spanner_p_->spanned_drul_[RIGHT]
37             )
38           {
39             extender_spanner_p_->set_textitem (RIGHT, t);
40           }
41     }
42 }
43
44
45 bool
46 Extender_engraver::do_try_music (Music* req_l)
47 {
48   if (Extender_req* p = dynamic_cast <Extender_req *> (req_l))
49     {
50       if (req_l_)
51         return false;
52
53       req_l_ = p;
54       return true;
55     }
56   return false;
57 }
58
59 void
60 Extender_engraver::do_removal_processing ()
61 {
62   if (extender_spanner_p_)
63     {
64       req_l_->warning (_ ("unterminated extender"));
65       extender_spanner_p_->set_bounds(RIGHT, get_staff_info ().command_pcol_l ());
66     }
67 }
68
69 void
70 Extender_engraver::do_process_requests ()
71 {
72   Array<Text_lyric_tuple> stopped_texts;
73   Moment now = now_mom ();
74
75   stopped_texts.clear ();
76   while (past_lyrics_pq_.size ()
77          && past_lyrics_pq_.front ().end_ == now)
78     stopped_texts.push (past_lyrics_pq_.get ());
79
80   if (req_l_)
81     {
82       if (!stopped_texts.size ())
83         {
84           req_l_->warning ("Nothing to connect extender to on the left. Ignoring extender request");
85           return;
86         }
87       
88       extender_spanner_p_ = new Extender_spanner;
89       extender_spanner_p_->set_textitem  (LEFT, stopped_texts[0].text_l_);
90       announce_element (Score_element_info (extender_spanner_p_, req_l_));
91     }
92 }
93
94
95 void
96 Extender_engraver::do_pre_move_processing ()
97 {
98   for (int i=0; i < now_lyrics_.size (); i++)
99     {
100       past_lyrics_pq_.insert (now_lyrics_[i]);
101     }
102   now_lyrics_.clear ();
103
104   if (extender_spanner_p_)
105     {
106       typeset_element (extender_spanner_p_);
107       extender_spanner_p_ = 0;
108     }
109 }
110 void
111 Extender_engraver::do_post_move_processing ()
112 {
113   Moment now = now_mom ();
114   while (past_lyrics_pq_.size () && past_lyrics_pq_.front ().end_ < now)
115     past_lyrics_pq_.delmin ();
116
117   req_l_ =0;
118 }
119
120 /**********************************************************************/
121 Text_lyric_tuple::Text_lyric_tuple ()
122 {
123   text_l_ =0;
124   req_l_ =0;
125   end_ = 0;
126 }
127
128 Text_lyric_tuple::Text_lyric_tuple (Text_item *h, Rhythmic_req*m, Moment mom)
129 {
130   text_l_ = h;
131   req_l_ = m;
132   end_ = mom;
133 }
134
135
136 int
137 Text_lyric_tuple::time_compare (Text_lyric_tuple const&h1,
138                              Text_lyric_tuple const &h2)
139 {
140   return (h1.end_ - h2.end_ ).sign ();
141 }