]> git.donarmstrong.com Git - lilypond.git/blob - lily/percent-repeat-engraver.cc
patch::: 1.3.136.jcn3
[lilypond.git] / lily / percent-repeat-engraver.cc
1 /*   
2   new-chord-tremolo-engraver.cc --  implement Chord_tremolo_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "engraver.hh"
11 #include "repeated-music.hh"
12 #include "engraver-group-engraver.hh"
13 #include "global-translator.hh"
14 #include "warn.hh"
15 #include "misc.hh"
16 #include "spanner.hh"
17 #include "item.hh"
18 #include "percent-repeat-iterator.hh"
19
20 /**
21   This acknowledges repeated music with "percent" style.  It typesets
22   a % sign.  
23
24   TODO:
25
26   - BEAT case: Create items for single beat repeats, i.e. c4 / / /
27
28   - DOUBLE_MEASURE case: attach a % to an appropriate barline.
29   
30 */
31 class Percent_repeat_engraver : public Engraver
32 {
33   void typeset_perc ();
34 public:
35   VIRTUAL_COPY_CONS (Translator);
36   Percent_repeat_engraver ();
37 protected:
38   Repeated_music * repeat_;
39
40   /// moment (global time) where beam started.
41   Moment start_mom_;
42   Moment stop_mom_;
43
44   /// location  within measure where beam started.
45   Moment beam_start_location_;
46   Moment next_moment_;
47   Moment body_length_;
48
49   enum {
50     UNKNOWN,
51     BEAT,
52     MEASURE,
53     DOUBLE_MEASURE,
54   } repeat_sign_type_ ;
55   
56   Spanner * perc_p_;
57   Spanner * finished_perc_p_;
58   Item * stem_tremolo_;
59 protected:
60   virtual void finalize ();
61   virtual bool try_music (Music*);
62   virtual void acknowledge_grob (Grob_info);
63   virtual void stop_translation_timestep ();
64   virtual void start_translation_timestep ();
65   virtual void process_music ();
66 };
67
68 Percent_repeat_engraver::Percent_repeat_engraver ()
69 {
70   perc_p_  = finished_perc_p_ = 0;
71   repeat_ =0;
72   stem_tremolo_ = 0;
73 }
74
75 bool
76 Percent_repeat_engraver::try_music (Music * m)
77 {
78   Repeated_music * rp = dynamic_cast<Repeated_music*> (m);
79   if (rp
80       && rp->get_mus_property ("iterator-ctor")
81          == Percent_repeat_iterator::constructor_cxx_function
82       && !repeat_)
83     {
84       body_length_ = rp->body_length_mom ();
85       int count =   rp->repeat_count ();
86       
87       Moment now = now_mom ();
88       start_mom_ = now;
89       stop_mom_ = start_mom_ + Moment (count) * body_length_;
90       next_moment_ = start_mom_ + body_length_;
91
92       SCM m = get_property ("timeSignatureFraction");
93       Moment mlen (1,
94                   gh_scm2int (gh_cdr (m)));
95
96       if (mlen == body_length_)
97         repeat_sign_type_ = BEAT;
98       else
99         {
100           mlen *= gh_scm2int (gh_car (m));
101           if (mlen == body_length_)
102             repeat_sign_type_ = MEASURE;
103           else if (Moment (2)* mlen == body_length_)
104             repeat_sign_type_ = DOUBLE_MEASURE;
105
106           if (repeat_sign_type_ != MEASURE)
107             {
108               warning (_ ("Don't know yet how to handle this percent repeat."));
109               return false;
110             }
111         }
112
113       repeat_ = rp;
114
115       
116       Global_translator *global_l =0;
117       Translator *t = this;
118       do
119         {
120           t = t->daddy_trans_l_ ;
121           global_l = dynamic_cast<Global_translator*> (t);
122         }
123       while (!global_l);
124
125       for (int i = 0; i < count; i++)  
126         global_l->add_moment_to_process (now + Moment (1+i) * body_length_);
127   
128       return true;
129     }
130
131   return false;
132 }
133
134 void
135 Percent_repeat_engraver::process_music ()
136 {
137   if (repeat_ && now_mom () == next_moment_)
138     {
139       if (repeat_sign_type_ == BEAT)
140         {
141           ;
142         }
143       else if (repeat_sign_type_ == MEASURE)
144         {
145           finished_perc_p_ = perc_p_;
146           typeset_perc ();
147           perc_p_ = new Spanner (get_property ("PercentRepeat"));
148           SCM col =get_property ("currentCommandColumn");
149           perc_p_->set_bound (LEFT, unsmob_grob (col));
150           announce_grob (perc_p_, repeat_);
151         }
152
153       next_moment_ = next_moment_ + body_length_;
154     }
155 }
156 void
157 Percent_repeat_engraver::finalize ()
158 {
159   typeset_perc ();
160   if (perc_p_)
161     {
162       repeat_->origin ()->warning (_ ("unterminated chord tremolo"));
163       perc_p_->suicide ();
164     }
165 }
166
167 void
168 Percent_repeat_engraver::typeset_perc ()
169 {
170   if (finished_perc_p_)
171     {
172       SCM col =get_property ("currentCommandColumn");
173       finished_perc_p_->set_bound (RIGHT, unsmob_grob (col));
174       typeset_grob (finished_perc_p_);
175       finished_perc_p_ = 0;
176     }
177 }
178
179
180 void
181 Percent_repeat_engraver::acknowledge_grob (Grob_info info)
182 {
183 }
184
185
186 void
187 Percent_repeat_engraver::start_translation_timestep ()
188 {
189   if (perc_p_ && stop_mom_ == now_mom ())
190     {
191       finished_perc_p_ = perc_p_;
192       typeset_perc ();
193       repeat_ = 0;
194       perc_p_ = 0;
195       repeat_sign_type_ = UNKNOWN;
196     }
197 }
198
199
200 void
201 Percent_repeat_engraver::stop_translation_timestep ()
202 {
203   typeset_perc ();
204 }
205
206 ADD_THIS_TRANSLATOR (Percent_repeat_engraver);
207
208