]> git.donarmstrong.com Git - lilypond.git/blob - lily/slash-repeat-engraver.cc
* lily/include/translator.icc: new file.
[lilypond.git] / lily / slash-repeat-engraver.cc
1 /*
2   slash-repeat-engraver.cc -- implement Slash_repeat_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "repeated-music.hh"
10 #include "global-context.hh"
11 #include "warn.hh"
12 #include "misc.hh"
13 #include "spanner.hh"
14 #include "item.hh"
15 #include "percent-repeat-iterator.hh"
16 #include "bar-line.hh"
17 #include "score-engraver.hh"
18
19 /**
20    This acknowledges repeated music with "percent" style.  It typesets
21    a % sign.
22
23    TODO:
24
25    - BEAT case: Create items for single beat repeats, i.e. c4 / / /
26
27    - DOUBLE_MEASURE case: attach a % to an appropriate barline.
28 */
29 class Slash_repeat_engraver : public Engraver
30 {
31 public:
32   TRANSLATOR_DECLARATIONS (Slash_repeat_engraver);
33 protected:
34   Music *repeat_;
35
36   /// moment (global time) where beam started.
37   Moment start_mom_;
38   Moment stop_mom_;
39
40   /// location  within measure where beam started.
41   Moment beam_start_location_;
42   Moment next_moment_;
43   Moment body_length_;
44
45   Item *beat_slash_;
46   Item *double_percent_;
47 protected:
48   virtual bool try_music (Music *);
49   PRECOMPUTED_VIRTUAL void stop_translation_timestep ();
50   PRECOMPUTED_VIRTUAL void start_translation_timestep ();
51   PRECOMPUTED_VIRTUAL void process_music ();
52 };
53
54 Slash_repeat_engraver::Slash_repeat_engraver ()
55 {
56   repeat_ = 0;
57   beat_slash_ = 0;
58 }
59
60 bool
61 Slash_repeat_engraver::try_music (Music *m)
62 {
63   if (m->is_mus_type ("repeated-music")
64       && !repeat_
65       && m->get_property ("iterator-ctor")
66       == Percent_repeat_iterator::constructor_proc)
67     {
68       body_length_ = Repeated_music::body_get_length (m);
69       int count = Repeated_music::repeat_count (m);
70
71       Moment now = now_mom ();
72       start_mom_ = now;
73       stop_mom_ = start_mom_ + Moment (count) * body_length_;
74       next_moment_ = start_mom_ + body_length_;
75
76       Moment meas_length
77         = robust_scm2moment (get_property ("measureLength"), Moment (0));
78       if (body_length_ < meas_length)
79         {
80           repeat_ = m;
81         }
82       else
83         return false;
84
85       Global_context *global = get_global_context ();
86       for (int i = 0; i < count; i++)
87         global->add_moment_to_process (next_moment_ + Moment (i) * body_length_);
88
89       return true;
90     }
91
92   return false;
93 }
94
95 void
96 Slash_repeat_engraver::process_music ()
97 {
98   if (repeat_ && now_mom () == next_moment_)
99     {
100       beat_slash_ = make_item ("RepeatSlash", repeat_->self_scm ());
101       next_moment_ = next_moment_ + body_length_;
102
103       get_global_context ()->add_moment_to_process (next_moment_);
104     }
105 }
106
107 void
108 Slash_repeat_engraver::start_translation_timestep ()
109 {
110   if (stop_mom_ == now_mom ())
111     {
112       repeat_ = 0;
113     }
114 }
115
116 void
117 Slash_repeat_engraver::stop_translation_timestep ()
118 {
119   beat_slash_ = 0;
120 }
121
122 #include "translator.icc"
123
124 ADD_TRANSLATOR (Slash_repeat_engraver,
125                 /* descr */ "Make beat repeats.",
126                 /* creats*/ "RepeatSlash",
127                 /* accepts */ "repeated-music",
128                 /* acks  */ "",
129                 /* reads */ "measureLength",
130                 /* write */ "");