* flower/include/std-vector.hh
[lilypond/patrick.git] / lily / beaming-info.cc
blob11c6dde0c6ade6947db7f4144a6c78b71fd258cf
1 /*
2 beaming-info.cc -- implement Beaming_info, Beaming_info_list
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
9 #include "beaming.hh"
11 Beaming_info::Beaming_info ()
13 start_mom_ = 0;
14 beams_i_drul_[LEFT] = 0;
15 beams_i_drul_[RIGHT] = 0;
18 Beaming_info::Beaming_info (Moment m, int i)
20 start_mom_ = m;
21 beams_i_drul_[LEFT] = i;
22 beams_i_drul_[RIGHT] = i;
25 const int at_beat = 1 << 15;
27 int
28 Beaming_info_list::best_splitpoint_index (Moment &beat_length, bool subdivide) const
30 int minden = INT_MAX;
31 int minidx = -1;
32 Moment beat_pos;
34 for (vsize i = 1; i < infos_.size (); i++)
36 beat_pos = infos_[i].start_mom_ / beat_length;
37 int den = beat_pos.den ();
38 if (infos_[i].beams_i_drul_[LEFT] == infos_[i - 1].beams_i_drul_[RIGHT] && !subdivide)
39 den *= 2;
40 if (den < minden)
42 minidx = i;
43 minden = den;
47 return minidx | (minden == 1 && subdivide ? at_beat : 0);
50 int
51 Beaming_info_list::beam_extend_count (Direction d) const
53 if (infos_.size () == 1)
54 return infos_[0].beams_i_drul_[d];
56 Beaming_info thisbeam = infos_.boundary (d, 0);
57 Beaming_info next = infos_.boundary (d, 1);
59 return min (thisbeam.beams_i_drul_[-d], next.beams_i_drul_[d]);
62 void
63 Beaming_info_list::beamify (Moment &beat_length, bool subdivide)
65 if (infos_.size () <= 1)
66 return;
68 Drul_array<Beaming_info_list> splits;
69 int m = best_splitpoint_index (beat_length, subdivide);
70 bool split = subdivide && (m & at_beat); m = m & ~at_beat;
71 splits[LEFT].infos_ = std::vector<Beaming_info> (infos_.begin (),
72 infos_.begin () + m);
73 splits[RIGHT].infos_ = std::vector<Beaming_info> (infos_.begin () + m,
74 infos_.end ());
76 Direction d = LEFT;
79 splits[d].beamify (beat_length, subdivide);
80 while (flip (&d) != LEFT)
83 int middle_beams = (split ? 1
84 : min (splits[RIGHT].beam_extend_count (LEFT),
85 splits[LEFT].beam_extend_count (RIGHT)));
89 if (splits[d].infos_.size () != 1)
90 splits[d].infos_.boundary (-d, 0).beams_i_drul_[-d] = middle_beams;
92 while (flip (&d) != LEFT);
94 infos_ = splits[LEFT].infos_;
95 infos_.insert (infos_.end (), splits[RIGHT].infos_.begin (), splits[RIGHT].infos_.end ());
97 clip_edges ();
100 void
101 Beaming_info_list::add_stem (Moment m, int b)
103 infos_.push_back (Beaming_info (m, b));
106 void
107 Beaming_info_list::clip_edges ()
109 if (infos_.size ())
111 infos_[0].beams_i_drul_[LEFT] = 0;
112 infos_.back ().beams_i_drul_[RIGHT] = 0;