Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / dot-configuration.cc
blobb72bd54ef7d7c842cbf59b11948cd83a98abbe0c
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
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.
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.
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/>.
20 #include <cstdio>
21 #include "dot-configuration.hh"
22 #include "dot-formatting-problem.hh"
23 #include "staff-symbol-referencer.hh"
26 int
27 Dot_configuration::badness () const
29 int t = 0;
30 for (Dot_configuration::const_iterator i (begin ());
31 i != end (); i++)
33 int p = i->first;
34 int demerit = sqr (p - i->second.pos_) * 2;
36 int dot_move_dir = sign (p - i->second.pos_);
37 if (i->second.extremal_head_)
39 if (i->second.dir_
40 && dot_move_dir != i->second.dir_)
41 demerit += 3;
42 else if (dot_move_dir != UP)
43 demerit += 2;
45 else if (dot_move_dir != UP)
46 demerit += 1;
48 t += demerit;
51 return t;
54 void
55 Dot_configuration::print () const
57 printf ("dotconf { ");
58 for (Dot_configuration::const_iterator i (begin ());
59 i != end (); i++)
60 printf ("%d, ", i->first);
61 printf ("}\n");
65 Shift K and following (preceding) entries up (down) as necessary to
66 prevent staffline collisions if D is up (down).
68 If K is in CFG, then do nothing.
71 Dot_configuration
72 Dot_configuration::shifted (int k, Direction d) const
74 Dot_configuration new_cfg (*problem_);
75 int offset = 0;
77 if (d > 0)
79 for (Dot_configuration::const_iterator i (begin ());
80 i != end (); i++)
82 int p = i->first;
83 if (p == k)
85 if (Staff_symbol_referencer::on_line (i->second.dot_, p))
86 p += d;
87 else
88 p += 2* d;
90 offset = 2*d;
92 new_cfg[p] = i->second;
94 else
96 if (new_cfg.find (p) == new_cfg.end ())
97 offset = 0;
98 new_cfg[p + offset] = i->second;
102 else
104 Dot_configuration::const_iterator i (end ());
107 i--;
109 int p = i->first;
110 if (p == k)
112 if (Staff_symbol_referencer::on_line (i->second.dot_, p))
113 p += d;
114 else
115 p += 2* d;
117 offset = 2*d;
119 new_cfg[p] = i->second;
121 else
123 if (new_cfg.find (p) == new_cfg.end ())
124 offset = 0;
126 new_cfg[p + offset] = i->second;
129 while (i != begin ());
132 return new_cfg;
136 Remove the collision in CFG either by shifting up or down, whichever
137 is best.
139 void
140 Dot_configuration::remove_collision (int p)
142 bool collide = find (p) != end ();
144 if (collide)
146 Dot_configuration cfg_up = shifted (p, UP);
147 Dot_configuration cfg_down = shifted (p, DOWN);
149 int b_up = cfg_up.badness ();
150 int b_down = cfg_down.badness ();
152 *this = (b_up < b_down) ? cfg_up : cfg_down;
156 Dot_configuration::Dot_configuration (Dot_formatting_problem const &problem)
158 problem_ = &problem;
161 Real
162 Dot_configuration::x_offset () const
164 Real off = 0.0;
165 for (Dot_configuration::const_iterator i (begin ());
166 i != end (); i++)
167 off = max (off, problem_->head_skyline_.height ((*i).first));
169 return off;