Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / repeated-music.cc
blob581b1ac17a850f1b62f471fbf2d4f46fce45fb33
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1999--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "repeated-music.hh"
21 #include "music-sequence.hh"
22 #include "pitch.hh"
23 #include "warn.hh"
24 #include "program-option.hh"
26 Music *
27 Repeated_music::body (Music *me)
29 return unsmob_music (me->get_property ("element"));
32 SCM
33 Repeated_music::alternatives (Music *me)
35 return me->get_property ("elements");
38 MAKE_SCHEME_CALLBACK (Repeated_music, relative_callback, 2);
39 SCM
40 Repeated_music::relative_callback (SCM music, SCM pitch)
42 Pitch p = *unsmob_pitch (pitch);
43 Music *me = unsmob_music (music);
44 if (lily_1_8_relative)
46 Music *body = unsmob_music (me->get_property ("element"));
47 if (body)
48 p = body->to_relative_octave (p);
50 Pitch last = p;
51 SCM alternatives = me->get_property ("elements");
53 for (SCM s = alternatives; scm_is_pair (s); s = scm_cdr (s))
55 lily_1_8_compatibility_used = true;
56 unsmob_music (scm_car (s))->to_relative_octave (p);
59 return last.smobbed_copy ();
61 else
62 return me->generic_to_relative_octave (p).smobbed_copy ();
65 Moment
66 Repeated_music::alternatives_get_length (Music *me, bool fold)
68 SCM alternative_list = alternatives (me);
69 int len = scm_ilength (alternative_list);
70 if (len <= 0)
71 return 0;
73 if (fold)
74 return Music_sequence::maximum_length (alternative_list);
76 Moment m = 0;
77 int done = 0;
78 int count = robust_scm2int (me->get_property ("repeat-count"), 0);
80 SCM p = alternative_list;
81 while (scm_is_pair (p) && done < count)
83 m = m + unsmob_music (scm_car (p))->get_length ();
84 done++;
85 if (count - done < len)
86 p = scm_cdr (p);
88 return m;
92 Sum all duration of all available alternatives. This is for the case
93 of volta repeats, where the alternatives are iterated just as they
94 were entered. */
95 Moment
96 Repeated_music::alternatives_volta_get_length (Music *me)
98 return Music_sequence::cumulative_length (alternatives (me));
102 Length of the body in THIS. Disregards REPEAT-COUNT.
104 Moment
105 Repeated_music::body_get_length (Music *me)
107 Moment m = 0;
108 if (Music *body = unsmob_music (me->get_property ("element")))
109 m = body->get_length ();
110 return m;
113 MAKE_SCHEME_CALLBACK (Repeated_music, unfolded_music_length, 1);
116 Repeated_music::unfolded_music_length (SCM m)
118 Music *me = unsmob_music (m);
120 Moment l = Moment (repeat_count (me)) * body_get_length (me) + alternatives_get_length (me, false);
121 return l.smobbed_copy ();
124 MAKE_SCHEME_CALLBACK (Repeated_music, folded_music_length, 1);
126 Repeated_music::folded_music_length (SCM m)
128 Music *me = unsmob_music (m);
130 Moment l = body_get_length (me) + alternatives_get_length (me, true);
131 return l.smobbed_copy ();
135 Repeated_music::repeat_count (Music *me)
137 return scm_to_int (me->get_property ("repeat-count"));
140 MAKE_SCHEME_CALLBACK (Repeated_music, volta_music_length, 1);
142 Repeated_music::volta_music_length (SCM m)
144 Music *me = unsmob_music (m);
145 Moment l = body_get_length (me) + alternatives_volta_get_length (me);
146 return l.smobbed_copy ();
149 MAKE_SCHEME_CALLBACK (Repeated_music, minimum_start, 1);
151 Repeated_music::minimum_start (SCM m)
153 Music *me = unsmob_music (m);
154 Music *body = unsmob_music (me->get_property ("element"));
156 if (body)
157 return body->start_mom ().smobbed_copy ();
158 else
159 return Music_sequence::minimum_start (me->get_property ("elements")).smobbed_copy ();
162 MAKE_SCHEME_CALLBACK (Repeated_music, first_start, 1);
164 Repeated_music::first_start (SCM m)
166 Music *me = unsmob_music (m);
167 Music *body = unsmob_music (me->get_property ("element"));
169 Moment rv = (body) ? body->start_mom ()
170 : Music_sequence::first_start (me->get_property ("elements"));
172 return rv.smobbed_copy ();