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