]> git.donarmstrong.com Git - lilypond.git/blob - lily/beaming-info.cc
* stepmake/aclocal.m4 (STEPMAKE_PANGO_FT2): Define HAVE_PANGO16 too.
[lilypond.git] / lily / beaming-info.cc
1 /*
2   beaming-info.cc -- implement Beaming_info, Beaming_info_list
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "beaming.hh"
10
11 Beaming_info::Beaming_info ()
12 {
13   start_mom_ = 0;
14   beams_i_drul_[LEFT] = 0;
15   beams_i_drul_[RIGHT] = 0;
16 }
17
18 Beaming_info::Beaming_info (Moment m, int i)
19 {
20   start_mom_ = m;
21   beams_i_drul_[LEFT] = i;
22   beams_i_drul_[RIGHT] = i;
23 }
24
25 const int infinity_i = INT_MAX; // guh.
26 const int at_beat = 1<<15;
27
28 int
29 Beaming_info_list::best_splitpoint_index (Moment &beat_length, bool subdivide) const
30 {
31   int minden = infinity_i;
32   int minidx = -1;
33   Moment beat_pos;
34
35   for (int i = 1; i < infos_.size (); i++)
36     {
37       beat_pos = infos_[i].start_mom_ / beat_length;
38       int den = beat_pos.den ();
39       if (infos_[i].beams_i_drul_[LEFT] == infos_[i - 1].beams_i_drul_[RIGHT] && !subdivide)
40         den *= 2;
41       if (den < minden)
42         {
43           minidx = i;
44           minden = den;
45         }
46     }
47
48   return minidx | (minden == 1 && subdivide ? at_beat : 0);
49 }
50
51 int
52 Beaming_info_list::beam_extend_count (Direction d) const
53 {
54   if (infos_.size () == 1)
55     return infos_[0].beams_i_drul_[d];
56
57   Beaming_info thisbeam = infos_.boundary (d, 0);
58   Beaming_info next = infos_.boundary (d, 1);
59
60   return thisbeam.beams_i_drul_[-d] <? next.beams_i_drul_[d];
61 }
62
63 void
64 Beaming_info_list::beamify (Moment &beat_length, bool subdivide)
65 {
66   if (infos_.size () <= 1)
67     return;
68
69   Drul_array<Beaming_info_list> splits;
70   int m = best_splitpoint_index (beat_length, subdivide);
71   bool split = subdivide && (m & at_beat); m = m & ~at_beat;
72   splits[LEFT].infos_ = infos_.slice (0, m);
73   splits[RIGHT].infos_ = infos_.slice (m, infos_.size ());
74
75   Direction d = LEFT;
76
77   do
78     {
79       splits[d].beamify (beat_length, subdivide);
80     }
81   while (flip (&d) != LEFT);
82
83   int middle_beams = (split ? 1
84                       : splits[RIGHT].beam_extend_count (LEFT) <?
85                       splits[LEFT].beam_extend_count (RIGHT));
86
87   do
88     {
89       if (splits[d].infos_.size () != 1)
90         splits[d].infos_.boundary (-d, 0).beams_i_drul_[-d] = middle_beams;
91     }
92   while (flip (&d) != LEFT);
93
94   infos_ = splits[LEFT].infos_;
95   infos_.concat (splits[RIGHT].infos_);
96 }
97
98 void
99 Beaming_info_list::add_stem (Moment m, int b)
100 {
101   infos_.push (Beaming_info (m, b));
102 }