]> git.donarmstrong.com Git - lilypond.git/blob - lily/slash-repeat-engraver.cc
(Paper_column): copy rank_. This fixes
[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 "repeated-music.hh"
11 #include "global-context.hh"
12 #include "warn.hh"
13 #include "misc.hh"
14 #include "spanner.hh"
15 #include "item.hh"
16 #include "percent-repeat-iterator.hh"
17 #include "bar-line.hh"
18 #include "score-engraver.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 Slash_repeat_engraver : public Engraver
32 {
33 public:
34   TRANSLATOR_DECLARATIONS (Slash_repeat_engraver);
35 protected:
36   Repeated_music * repeat_;
37
38   /// moment (global time) where beam started.
39   Moment start_mom_;
40   Moment stop_mom_;
41
42   /// location  within measure where beam started.
43   Moment beam_start_location_;
44   Moment next_moment_;
45   Moment body_length_;
46
47   Item * beat_slash_;
48   Item * double_percent_;
49 protected:
50   virtual bool try_music (Music*);
51   virtual void stop_translation_timestep ();
52   virtual void start_translation_timestep ();
53   virtual void process_music ();
54 };
55
56 Slash_repeat_engraver::Slash_repeat_engraver ()
57 {
58   repeat_ = 0;
59   beat_slash_ = 0;
60 }
61
62 bool
63 Slash_repeat_engraver::try_music (Music * m)
64 {
65   Repeated_music * rp = dynamic_cast<Repeated_music*> (m);
66   if (rp
67       && !repeat_
68       && rp->get_property ("iterator-ctor")
69       == Percent_repeat_iterator::constructor_proc)
70     {
71       body_length_ = rp->body_get_length ();
72       int count =   rp->repeat_count ();
73       
74       Moment now = now_mom ();
75       start_mom_ = now;
76       stop_mom_ = start_mom_ + Moment (count) * body_length_;
77       next_moment_ = start_mom_ + body_length_;
78
79       SCM m = get_property ("measureLength");
80       Moment meas_len;
81       if (Moment *mp = unsmob_moment (m))
82         meas_len = *mp;
83
84       if (body_length_ < meas_len 
85           && meas_len.main_part_.mod_rat (body_length_.main_part_)
86           == Moment (Rational (0,0)))
87         {
88           repeat_ = rp;
89         }
90       else
91         return false;
92       
93       Global_context *global =get_global_context ();
94       for (int i = 0; i < count; i++)  
95         global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
96   
97       return true;
98     }
99
100   return false;
101 }
102
103 void
104 Slash_repeat_engraver::process_music ()
105 {
106   if (repeat_ && now_mom () == next_moment_)
107     {
108       beat_slash_ = make_item ("RepeatSlash", repeat_->self_scm ());
109       next_moment_ = next_moment_ + body_length_;
110
111       get_global_context ()->add_moment_to_process (next_moment_);
112     }
113 }
114
115
116 void
117 Slash_repeat_engraver::start_translation_timestep ()
118 {
119   if (stop_mom_ == now_mom ())
120     {
121       repeat_ = 0;
122     }
123 }
124
125 void
126 Slash_repeat_engraver::stop_translation_timestep ()
127 {
128   beat_slash_ = 0;
129 }
130
131
132
133
134 ENTER_DESCRIPTION (Slash_repeat_engraver,
135 /* descr */       "Make beat repeats.",
136 /* creats*/       "RepeatSlash",
137 /* accepts */     "repeated-music",
138 /* acks  */      "",
139 /* reads */       "measureLength",
140 /* write */       "");