* lily/music-iterator.cc (quit, do_quit): new function: break link
[lilypond.git] / lily / beaming-info.cc
blob35ba768395db13930ea8c0cf68e886fe4377f810
1 /*
2 beaming-info.cc -- implement Beaming_info, Beaming_info_list
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
10 #include "beaming.hh"
12 Beaming_info::Beaming_info ()
14 start_mom_ = 0;
15 beams_i_drul_[LEFT] = 0;
16 beams_i_drul_[RIGHT] = 0;
19 Beaming_info::Beaming_info (Moment m, int i)
21 start_mom_ = m;
22 beams_i_drul_[LEFT] = i;
23 beams_i_drul_[RIGHT] = i;
26 const int infinity_i = INT_MAX; // guh.
27 const int at_beat = 1<<15;
29 int
30 Beaming_info_list::best_splitpoint_index (Moment &beat_length,bool subdivide) const
32 int minden = infinity_i;
33 int minidx = -1;
34 Moment beat_pos;
36 for (int i=1; i < infos_.size (); i++)
38 beat_pos = infos_[i].start_mom_ / beat_length;
39 int den = beat_pos.den ();
40 if (infos_[i].beams_i_drul_[LEFT] == infos_[i-1].beams_i_drul_[RIGHT] && !subdivide)
41 den *= 2;
42 if (den < minden)
44 minidx = i;
45 minden = den;
49 return minidx|(minden==1 && subdivide ? at_beat : 0);
52 int
53 Beaming_info_list::beam_extend_count (Direction d) const
55 if (infos_.size () == 1)
56 return infos_[0].beams_i_drul_[d];
58 Beaming_info thisbeam = infos_.boundary (d, 0);
59 Beaming_info next = infos_.boundary (d, 1);
61 return thisbeam.beams_i_drul_[-d] <? next.beams_i_drul_[d];
64 void
65 Beaming_info_list::beamify (Moment &beat_length,bool subdivide)
67 if (infos_.size () <= 1)
68 return;
70 Drul_array<Beaming_info_list> splits;
71 int m = best_splitpoint_index (beat_length,subdivide);
72 bool split = subdivide && (m & at_beat); m = m & ~at_beat;
73 splits[LEFT].infos_ = infos_.slice (0,m);
74 splits[RIGHT].infos_ = infos_.slice (m, infos_.size ());
76 Direction d = LEFT;
80 splits[d].beamify (beat_length,subdivide);
82 while (flip (&d) != LEFT);
84 int middle_beams = (split ? 1 :
85 splits[RIGHT].beam_extend_count (LEFT) <?
86 splits[LEFT].beam_extend_count (RIGHT));
90 if (splits[d].infos_.size () != 1)
92 splits[d].infos_.boundary (-d, 0).beams_i_drul_[-d] = middle_beams;
95 while (flip (&d) != LEFT);
97 infos_ = splits[LEFT].infos_;
98 infos_.concat (splits[RIGHT].infos_);
101 void
102 Beaming_info_list::add_stem (Moment m, int b)
104 infos_.push (Beaming_info (m, b));