]> git.donarmstrong.com Git - lilypond.git/blob - lily/dot-configuration.cc
Merge commit 'origin' into includes
[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--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 */
10
11 #include <cstdio>
12 #include "dot-configuration.hh"
13 #include "dot-formatting-problem.hh"
14 #include "staff-symbol-referencer.hh"
15
16
17 int
18 Dot_configuration::badness () const
19 {
20   int t = 0;
21   for (Dot_configuration::const_iterator i (begin ());
22        i != end (); i++)
23     {
24       int p = i->first;
25       int demerit = sqr (p - i->second.pos_) * 2;
26
27       int dot_move_dir = sign (p - i->second.pos_);
28       if (i->second.extremal_head_)
29         {
30           if (i->second.dir_
31               && dot_move_dir != i->second.dir_)
32             demerit += 3;
33           else if (dot_move_dir != UP)
34             demerit += 2;
35         }
36       else if (dot_move_dir != UP)
37         demerit += 1;
38
39       t += demerit;
40     }
41
42   return t;
43 }
44
45 void
46 Dot_configuration::print () const
47 {
48   printf ("dotconf { ");
49   for (Dot_configuration::const_iterator i (begin ());
50        i != end (); i++)
51     printf ("%d, ", i->first);
52   printf ("}\n");
53 }
54
55 /*
56   Shift K and following (preceding) entries up (down) as necessary to
57   prevent staffline collisions if D is up (down).
58
59   If K is in CFG, then do nothing.
60 */
61
62 Dot_configuration
63 Dot_configuration::shifted (int k, Direction d) const
64 {
65   Dot_configuration new_cfg (*problem_);
66   int offset = 0;
67
68   if (d > 0)
69     {
70       for (Dot_configuration::const_iterator i (begin ());
71            i != end (); i++)
72         {
73           int p = i->first;
74           if (p == k)
75             {
76               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
77                 p += d;
78               else
79                 p += 2* d;
80
81               offset = 2*d;
82
83               new_cfg[p] = i->second;
84             }
85           else
86             {
87               if (new_cfg.find (p) == new_cfg.end ())
88                 offset = 0;
89               new_cfg[p + offset] = i->second;
90             }
91         }
92     }
93   else
94     {
95       Dot_configuration::const_iterator i (end ());
96       do
97         {
98           i--;
99
100           int p = i->first;
101           if (p == k)
102             {
103               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
104                 p += d;
105               else
106                 p += 2* d;
107
108               offset = 2*d;
109
110               new_cfg[p] = i->second;
111             }
112           else
113             {
114               if (new_cfg.find (p) == new_cfg.end ())
115                 offset = 0;
116
117               new_cfg[p + offset] = i->second;
118             }
119         }
120       while (i != begin ());
121     }
122
123   return new_cfg;
124 }
125
126 /*
127   Remove the collision in CFG either by shifting up or down, whichever
128   is best.
129 */
130 void
131 Dot_configuration::remove_collision (int p)
132 {
133   bool collide = find (p) != end ();
134
135   if (collide)
136     {
137       Dot_configuration cfg_up = shifted (p, UP);
138       Dot_configuration cfg_down = shifted (p, DOWN);
139
140       int b_up = cfg_up.badness ();
141       int b_down = cfg_down.badness ();
142
143       *this = (b_up < b_down) ? cfg_up : cfg_down;
144     }
145 }
146
147 Dot_configuration::Dot_configuration (Dot_formatting_problem const &problem)
148 {
149   problem_ = &problem;
150 }
151
152 Real
153 Dot_configuration::x_offset () const
154 {
155   Real off = 0.0;
156   for (Dot_configuration::const_iterator i (begin ());
157        i != end (); i++)
158     off = max (off, problem_->head_skyline_.height ((*i).first));
159
160   return off;
161 }