]> git.donarmstrong.com Git - lilypond.git/blob - lily/dot-configuration.cc
make Dot_configuration into class, in new files dot-configuration.{cc,hh}
[lilypond.git] / lily / dot-configuration.cc
1 /*
2   dot-implement.cc -- declare Dot_configuration
3
4   Source file of the GNU LilyPond music typesetter.  Distributed under
5   terms of the GNU General Public License.  LilyPond comes with NO
6   WARRANTY.
7
8   (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 */
10
11 #include "dot-configuration.hh"
12 #include "staff-symbol-referencer.hh"
13
14
15 int
16 Dot_configuration::badness () const
17 {
18   int t = 0;
19   for (Dot_configuration::const_iterator i (begin ());
20        i != end (); i++)
21     {
22       int p = i->first;
23       int demerit = sqr (p - i->second.pos_) * 2;
24
25       int dot_move_dir = sign (p - i->second.pos_);
26       if (i->second.extremal_head_)
27         {
28           if (i->second.dir_
29               && dot_move_dir != i->second.dir_)
30             demerit += 3;
31           else if (dot_move_dir != UP)
32             demerit += 2;
33         }
34       else if (dot_move_dir != UP)
35         demerit += 1;
36
37       t += demerit;
38     }
39
40   return t;
41 }
42
43 void
44 Dot_configuration::print () const
45 {
46   printf ("dotconf { ");
47   for (Dot_configuration::const_iterator i (begin ());
48        i != end (); i++)
49     printf ("%d, ", i->first);
50   printf ("} \n");
51 }
52
53 /*
54   Shift K and following (preceding) entries up (down) as necessary to
55   prevent staffline collisions if D is up (down).
56
57   If K is in CFG, then do nothing.
58 */
59
60 Dot_configuration
61 Dot_configuration::shifted (int k, Direction d) const
62 {
63   Dot_configuration new_cfg;
64   int offset = 0;
65
66   if (d > 0)
67     {
68       for (Dot_configuration::const_iterator i (begin ());
69            i != end (); i++)
70         {
71           int p = i->first;
72           if (p == k)
73             {
74               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
75                 p += d;
76               else
77                 p += 2* d;
78
79               offset = 2*d;
80
81               new_cfg[p] = i->second;
82             }
83           else
84             {
85               if (new_cfg.find (p) == new_cfg.end ())
86                 offset = 0;
87               new_cfg[p + offset] = i->second;
88             }
89         }
90     }
91   else
92     {
93       Dot_configuration::const_iterator i (end ());
94       do
95         {
96           i--;
97
98           int p = i->first;
99           if (p == k)
100             {
101               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
102                 p += d;
103               else
104                 p += 2* d;
105
106               offset = 2*d;
107
108               new_cfg[p] = i->second;
109             }
110           else
111             {
112               if (new_cfg.find (p) == new_cfg.end ())
113                 offset = 0;
114
115               new_cfg[p + offset] = i->second;
116             }
117         }
118       while (i != begin ());
119     }
120
121   return new_cfg;
122 }
123
124 /*
125   Remove the collision in CFG either by shifting up or down, whichever
126   is best.
127 */
128 void
129 Dot_configuration::remove_collision (int p)
130 {
131   bool collide = find (p) != end ();
132
133   if (collide)
134     {
135       Dot_configuration cfg_up = shifted (p, UP);
136       Dot_configuration cfg_down = shifted (p, DOWN);
137
138       int b_up = cfg_up.badness ();
139       int b_down = cfg_down.badness ();
140
141       *this = (b_up < b_down) ? cfg_up : cfg_down;
142     }
143 }