]> git.donarmstrong.com Git - lilypond.git/blob - lily/slash-repeat-engraver.cc
2003 -> 2004
[lilypond.git] / lily / slash-repeat-engraver.cc
1 /*   
2      slash-repeat-engraver.cc --  implement Chord_tremolo_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2004 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 #include "bar-line.hh"
20
21 #include "score-engraver.hh"
22 #include "translator-group.hh"
23
24 /**
25   This acknowledges repeated music with "percent" style.  It typesets
26   a % sign.  
27
28   TODO:
29
30   - BEAT case: Create items for single beat repeats, i.e. c4 / / /
31
32   - DOUBLE_MEASURE case: attach a % to an appropriate barline.
33   
34 */
35 class Slash_repeat_engraver : public Engraver
36 {
37 public:
38   TRANSLATOR_DECLARATIONS(Slash_repeat_engraver);
39 protected:
40   Repeated_music * repeat_;
41
42   /// moment (global time) where beam started.
43   Moment start_mom_;
44   Moment stop_mom_;
45
46   /// location  within measure where beam started.
47   Moment beam_start_location_;
48   Moment next_moment_;
49   Moment body_length_;
50
51   Item * beat_slash_;
52   Item * double_percent_;
53 protected:
54   virtual bool try_music (Music*);
55   virtual void stop_translation_timestep ();
56   virtual void start_translation_timestep ();
57   virtual void process_music ();
58 };
59
60 Slash_repeat_engraver::Slash_repeat_engraver ()
61 {
62   repeat_ =0;
63   beat_slash_ = 0;
64 }
65
66 bool
67 Slash_repeat_engraver::try_music (Music * m)
68 {
69   Repeated_music * rp = dynamic_cast<Repeated_music*> (m);
70   if (rp
71       && !repeat_
72       && rp->get_mus_property ("iterator-ctor")
73       == Percent_repeat_iterator::constructor_proc)
74     {
75       body_length_ = rp->body_get_length ();
76       int count =   rp->repeat_count ();
77       
78       Moment now = now_mom ();
79       start_mom_ = now;
80       stop_mom_ = start_mom_ + Moment (count) * body_length_;
81       next_moment_ = start_mom_ + body_length_;
82
83       SCM m = get_property ("measureLength");
84       Moment meas_len;
85       if (Moment *mp = unsmob_moment (m))
86         meas_len = *mp;
87
88       if (body_length_ < meas_len 
89           && meas_len.main_part_.mod_rat (body_length_.main_part_)
90           == Moment (Rational (0,0)))
91         {
92           repeat_ = rp;
93         }
94       else
95         return false;
96       
97       Global_translator *global =top_engraver();
98       for (int i = 0; i < count; i++)  
99         global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
100   
101       return true;
102     }
103
104   return false;
105 }
106
107 void
108 Slash_repeat_engraver::process_music ()
109 {
110   if (repeat_ && now_mom () == next_moment_)
111     {
112       beat_slash_ = make_item ("RepeatSlash");
113       announce_grob(beat_slash_, repeat_->self_scm());
114       next_moment_ = next_moment_ + body_length_;
115
116       top_engraver()->add_moment_to_process (next_moment_);
117     }
118 }
119
120
121 void
122 Slash_repeat_engraver::start_translation_timestep ()
123 {
124   if (stop_mom_ == now_mom ())
125     {
126       repeat_ = 0;
127     }
128 }
129
130 void
131 Slash_repeat_engraver::stop_translation_timestep ()
132 {
133  if (beat_slash_)
134     {
135       typeset_grob (beat_slash_);
136       beat_slash_ = 0;
137     }
138 }
139
140
141
142
143 ENTER_DESCRIPTION(Slash_repeat_engraver,
144 /* descr */       "Make beat repeats.",
145 /* creats*/       "RepeatSlash",
146 /* accepts */     "repeated-music",
147 /* acks  */      "",
148 /* reads */       "measureLength",
149 /* write */       "");