]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-configuration.cc
19bcbd822c250df3a3a9862d30a5010c58dad213
[lilypond.git] / lily / tie-configuration.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2005--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6
7   LilyPond is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   LilyPond is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "tie-configuration.hh"
22
23 #include "warn.hh"
24 #include "tie-formatting-problem.hh"
25 #include "bezier.hh"
26
27 int
28 Tie_configuration::compare (Tie_configuration const &a,
29                             Tie_configuration const &b)
30 {
31   if (a.position_ - b.position_)
32     return sign (a.position_ - b.position_);
33   return sign (a.dir_ - b.dir_);
34 }
35
36 Tie_configuration::Tie_configuration ()
37 {
38   dir_ = CENTER;
39   position_ = 0;
40   delta_y_ = 0.0;
41   score_ = 0.0;
42   scored_ = false;
43   column_ranks_ = Drul_array<int> (0, 0);
44 }
45
46 void
47 Tie_configuration::center_tie_vertically (Tie_details const &details)
48 {
49   Bezier b = get_untransformed_bezier (details);
50   Offset middle = b.curve_point (0.5);
51   Offset edge = b.curve_point (0.0);
52   Real center = (edge[Y_AXIS] + middle[Y_AXIS]) / 2.0;
53
54   delta_y_ = - dir_ * center;
55 }
56
57 Bezier
58 Tie_configuration::get_transformed_bezier (Tie_details const &details) const
59 {
60   Bezier b (get_untransformed_bezier (details));
61
62   b.scale (1, dir_);
63   b.translate (Offset (attachment_x_[LEFT],
64                        delta_y_ + details.staff_space_ * 0.5 * position_));
65
66   return b;
67 }
68
69 /*
70   Get bezier with left control at (0,0)
71  */
72 Bezier
73 Tie_configuration::get_untransformed_bezier (Tie_details const &details) const
74 {
75   Real l = attachment_x_.length ();
76   if (isinf (l) || isnan (l))
77     {
78       programming_error ("Inf or NaN encountered");
79       l = 1.0;
80     }
81   return slur_shape (l,
82                      details.height_limit_,
83                      details.ratio_);
84 }
85
86 int
87 Tie_configuration::column_span_length () const
88 {
89   return column_ranks_[RIGHT] - column_ranks_[LEFT];
90 }
91
92 Real
93 Tie_configuration::distance (Tie_configuration const &a,
94                              Tie_configuration const &b)
95 {
96
97   Real d = 3 * (a.position_ - b.position_);
98   if (d < 0)
99     return d + (2 + (b.dir_ - a.dir_));
100   else
101     return d + (2 + (a.dir_ - b.dir_));
102 }
103
104 void
105 Tie_configuration::add_score (Real s, const string &desc)
106 {
107   assert (!scored_);
108   score_ += s;
109   if (s)
110     score_card_ += to_string ("%s=%.2f ", desc.c_str (), s);
111 }
112
113 Real
114 Tie_configuration::height (Tie_details const &details) const
115 {
116   Real l = attachment_x_.length ();
117
118   return slur_shape (l,
119                      details.height_limit_,
120                      details.ratio_).curve_point (0.5)[Y_AXIS];
121 }
122
123 Ties_configuration::Ties_configuration ()
124 {
125   score_ = 0.0;
126   scored_ = false;
127 }
128
129 void
130 Ties_configuration::reset_score ()
131 {
132   score_ = 0.0;
133   scored_ = false;
134   score_card_ = "";
135   tie_score_cards_.clear ();
136 }
137
138 void
139 Ties_configuration::add_tie_score (Real s, int i, const string &desc)
140 {
141   assert (!scored_);
142   score_ += s;
143   if (s)
144     {
145       while (tie_score_cards_.size () < size ())
146         tie_score_cards_.push_back ("");
147
148       tie_score_cards_[i] += to_string ("%s=%.2f ", desc.c_str (), s);
149     }
150 }
151
152 void
153 Ties_configuration::add_score (Real s, const string &desc)
154 {
155   assert (!scored_);
156   score_ += s;
157   if (s)
158     score_card_ += to_string ("%s=%.2f ", desc.c_str (), s);
159 }
160
161 Real
162 Ties_configuration::score () const
163 {
164   return score_;
165 }
166
167 string
168 Ties_configuration::complete_tie_card (vsize i) const
169 {
170   string s;
171   s += to_string ("%d (%.2f) %c: ", (*this)[i].position_, (*this)[i].delta_y_,
172                   ((*this)[i].dir_ == UP ? 'u' : 'd'))
173        + (*this)[i].card () + (*this).tie_card (i);
174
175   /*
176     this is a little awkward, but we must decide where to put
177     aggregrates.
178    */
179   if (i == 0)
180     s += card ();
181
182   if (i + 1 == size ())
183     s += to_string ("TOTAL=%.2f", score ());
184
185   return s;
186 }
187
188 /* for use inside GDB */
189 string
190 Ties_configuration::complete_score_card () const
191 {
192   string s;
193   for (vsize i = 0; i < size (); i++)
194     {
195       s += complete_tie_card (i);
196     }
197
198   return s;
199 }
200
201 string
202 Ties_configuration::card () const
203 {
204   return score_card_;
205 }
206