]> git.donarmstrong.com Git - lilypond.git/blob - lily/dot-configuration.cc
Grand fixcc.py run on all .hh .cc files.
[lilypond.git] / lily / dot-configuration.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <cstdio>
21 #include "dot-configuration.hh"
22 #include "dot-formatting-problem.hh"
23 #include "staff-symbol-referencer.hh"
24
25 int
26 Dot_configuration::badness () const
27 {
28   int t = 0;
29   for (Dot_configuration::const_iterator i (begin ());
30        i != end (); i++)
31     {
32       int p = i->first;
33       int demerit = sqr (p - i->second.pos_) * 2;
34
35       int dot_move_dir = sign (p - i->second.pos_);
36       if (i->second.extremal_head_)
37         {
38           if (i->second.dir_
39               && dot_move_dir != i->second.dir_)
40             demerit += 3;
41           else if (dot_move_dir != UP)
42             demerit += 2;
43         }
44       else if (dot_move_dir != UP)
45         demerit += 1;
46
47       t += demerit;
48     }
49
50   return t;
51 }
52
53 void
54 Dot_configuration::print () const
55 {
56   printf ("dotconf { ");
57   for (Dot_configuration::const_iterator i (begin ());
58        i != end (); i++)
59     printf ("%d, ", i->first);
60   printf ("}\n");
61 }
62
63 /*
64   Shift K and following (preceding) entries up (down) as necessary to
65   prevent staffline collisions if D is up (down).
66
67   If K is in CFG, then do nothing.
68 */
69
70 Dot_configuration
71 Dot_configuration::shifted (int k, Direction d) const
72 {
73   Dot_configuration new_cfg (*problem_);
74   int offset = 0;
75
76   if (d > 0)
77     {
78       for (Dot_configuration::const_iterator i (begin ());
79            i != end (); i++)
80         {
81           int p = i->first;
82           if (p == k)
83             {
84               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
85                 p += d;
86               else
87                 p += 2 * d;
88
89               offset = 2 * d;
90
91               new_cfg[p] = i->second;
92             }
93           else
94             {
95               if (new_cfg.find (p) == new_cfg.end ())
96                 offset = 0;
97               new_cfg[p + offset] = i->second;
98             }
99         }
100     }
101   else
102     {
103       Dot_configuration::const_iterator i (end ());
104       do
105         {
106           i--;
107
108           int p = i->first;
109           if (p == k)
110             {
111               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
112                 p += d;
113               else
114                 p += 2 * d;
115
116               offset = 2 * d;
117
118               new_cfg[p] = i->second;
119             }
120           else
121             {
122               if (new_cfg.find (p) == new_cfg.end ())
123                 offset = 0;
124
125               new_cfg[p + offset] = i->second;
126             }
127         }
128       while (i != begin ());
129     }
130
131   return new_cfg;
132 }
133
134 /*
135   Remove the collision in CFG either by shifting up or down, whichever
136   is best.
137 */
138 void
139 Dot_configuration::remove_collision (int p)
140 {
141   bool collide = find (p) != end ();
142
143   if (collide)
144     {
145       Dot_configuration cfg_up = shifted (p, UP);
146       Dot_configuration cfg_down = shifted (p, DOWN);
147
148       int b_up = cfg_up.badness ();
149       int b_down = cfg_down.badness ();
150
151       *this = (b_up < b_down) ? cfg_up : cfg_down;
152     }
153 }
154
155 Dot_configuration::Dot_configuration (Dot_formatting_problem const &problem)
156 {
157   problem_ = &problem;
158 }
159
160 Real
161 Dot_configuration::x_offset () const
162 {
163   Real off = 0.0;
164   for (Dot_configuration::const_iterator i (begin ());
165        i != end (); i++)
166     off = max (off, problem_->head_skyline_.height ((*i).first));
167
168   return off;
169 }