]> git.donarmstrong.com Git - lilypond.git/blob - lily/dot-configuration.cc
Update changelog
[lilypond.git] / lily / dot-configuration.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2015 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.dir_
37           && dot_move_dir != i->second.dir_)
38         demerit += 2;
39       else if (dot_move_dir != UP)
40         demerit += 1;
41
42       t += demerit;
43     }
44
45   return t;
46 }
47
48 void
49 Dot_configuration::print () const
50 {
51   printf ("dotconf { ");
52   for (Dot_configuration::const_iterator i (begin ());
53        i != end (); i++)
54     printf ("%d, ", i->first);
55   printf ("}\n");
56 }
57
58 /*
59   Shift K and following (preceding) entries up (down) as necessary to
60   prevent staffline collisions if D is up (down).
61
62   If K is in CFG, then do nothing.
63 */
64
65 Dot_configuration
66 Dot_configuration::shifted (int k, Direction d) const
67 {
68   Dot_configuration new_cfg (*problem_);
69   int offset = 0;
70
71   if (d > 0)
72     {
73       for (Dot_configuration::const_iterator i (begin ());
74            i != end (); i++)
75         {
76           int p = i->first;
77           if (p == k)
78             {
79               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
80                 p += d;
81               else
82                 p += 2 * d;
83
84               offset = 2 * d;
85
86               new_cfg[p] = i->second;
87             }
88           else
89             {
90               if (new_cfg.find (p) == new_cfg.end ())
91                 offset = 0;
92               new_cfg[p + offset] = i->second;
93             }
94         }
95     }
96   else
97     {
98       Dot_configuration::const_iterator i (end ());
99       do
100         {
101           i--;
102
103           int p = i->first;
104           if (p == k)
105             {
106               if (Staff_symbol_referencer::on_line (i->second.dot_, p))
107                 p += d;
108               else
109                 p += 2 * d;
110
111               offset = 2 * d;
112
113               new_cfg[p] = i->second;
114             }
115           else
116             {
117               if (new_cfg.find (p) == new_cfg.end ())
118                 offset = 0;
119
120               new_cfg[p + offset] = i->second;
121             }
122         }
123       while (i != begin ());
124     }
125
126   return new_cfg;
127 }
128
129 /*
130   Remove the collision in CFG either by shifting up or down, whichever
131   is best.
132 */
133 void
134 Dot_configuration::remove_collision (int p)
135 {
136   bool collide = find (p) != end ();
137
138   if (collide)
139     {
140       Dot_configuration cfg_up = shifted (p, UP);
141       Dot_configuration cfg_down = shifted (p, DOWN);
142
143       int b_up = cfg_up.badness ();
144       int b_down = cfg_down.badness ();
145
146       *this = (b_up < b_down) ? cfg_up : cfg_down;
147     }
148 }
149
150 Dot_configuration::Dot_configuration (Dot_formatting_problem const &problem)
151 {
152   problem_ = &problem;
153 }
154
155 Real
156 Dot_configuration::x_offset () const
157 {
158   Real off = 0.0;
159   for (Dot_configuration::const_iterator i (begin ());
160        i != end (); i++)
161     off = max (off, problem_->head_skyline_.height ((*i).first));
162
163   return off;
164 }