]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-configuration.cc
968bfd65ad95c8c445052b9ee9ff51d5e1ef3f31
[lilypond.git] / lily / tie-configuration.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2005--2015 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 using std::string;
28
29 int
30 Tie_configuration::compare (Tie_configuration const &a,
31                             Tie_configuration const &b)
32 {
33   if (a.position_ - b.position_)
34     return sign (a.position_ - b.position_);
35   return sign (a.dir_ - b.dir_);
36 }
37
38 Tie_configuration::Tie_configuration ()
39 {
40   dir_ = CENTER;
41   position_ = 0;
42   delta_y_ = 0.0;
43   score_ = 0.0;
44   scored_ = false;
45   column_ranks_ = Drul_array<int> (0, 0);
46 }
47
48 void
49 Tie_configuration::center_tie_vertically (Tie_details const &details)
50 {
51   Bezier b = get_untransformed_bezier (details);
52   Offset middle = b.curve_point (0.5);
53   Offset edge = b.curve_point (0.0);
54   Real center = (edge[Y_AXIS] + middle[Y_AXIS]) / 2.0;
55
56   delta_y_ = - dir_ * center;
57 }
58
59 Bezier
60 Tie_configuration::get_transformed_bezier (Tie_details const &details) const
61 {
62   Bezier b (get_untransformed_bezier (details));
63
64   b.scale (1, dir_);
65   b.translate (Offset (attachment_x_[LEFT],
66                        delta_y_ + details.staff_space_ * 0.5 * position_));
67
68   return b;
69 }
70
71 /*
72   Get bezier with left control at (0,0)
73  */
74 Bezier
75 Tie_configuration::get_untransformed_bezier (Tie_details const &details) const
76 {
77   Real l = attachment_x_.length ();
78   if (isinf (l) || isnan (l))
79     {
80       programming_error ("Inf or NaN encountered");
81       l = 1.0;
82     }
83   return slur_shape (l,
84                      details.height_limit_,
85                      details.ratio_);
86 }
87
88 int
89 Tie_configuration::column_span_length () const
90 {
91   return column_ranks_[RIGHT] - column_ranks_[LEFT];
92 }
93
94 Real
95 Tie_configuration::distance (Tie_configuration const &a,
96                              Tie_configuration const &b)
97 {
98
99   Real d = 3 * (a.position_ - b.position_);
100   if (d < 0)
101     return d + (2 + (b.dir_ - a.dir_));
102   else
103     return d + (2 + (a.dir_ - b.dir_));
104 }
105
106 void
107 Tie_configuration::add_score (Real s, const string &desc)
108 {
109   assert (!scored_);
110   score_ += s;
111   if (s)
112     score_card_ += to_string ("%s=%.2f ", desc.c_str (), s);
113 }
114
115 Real
116 Tie_configuration::height (Tie_details const &details) const
117 {
118   Real l = attachment_x_.length ();
119
120   return slur_shape (l,
121                      details.height_limit_,
122                      details.ratio_).curve_point (0.5)[Y_AXIS];
123 }
124
125 Ties_configuration::Ties_configuration ()
126 {
127   score_ = 0.0;
128   scored_ = false;
129 }
130
131 void
132 Ties_configuration::reset_score ()
133 {
134   score_ = 0.0;
135   scored_ = false;
136   score_card_ = "";
137   tie_score_cards_.clear ();
138 }
139
140 void
141 Ties_configuration::add_tie_score (Real s, int i, const string &desc)
142 {
143   assert (!scored_);
144   score_ += s;
145   if (s)
146     {
147       while (tie_score_cards_.size () < size ())
148         tie_score_cards_.push_back ("");
149
150       tie_score_cards_[i] += to_string ("%s=%.2f ", desc.c_str (), s);
151     }
152 }
153
154 void
155 Ties_configuration::add_score (Real s, const string &desc)
156 {
157   assert (!scored_);
158   score_ += s;
159   if (s)
160     score_card_ += to_string ("%s=%.2f ", desc.c_str (), s);
161 }
162
163 Real
164 Ties_configuration::score () const
165 {
166   return score_;
167 }
168
169 string
170 Ties_configuration::complete_tie_card (vsize i) const
171 {
172   string s;
173   s += to_string ("%d (%.2f) %c: ", (*this)[i].position_, (*this)[i].delta_y_,
174                   ((*this)[i].dir_ == UP ? 'u' : 'd'))
175        + (*this)[i].card () + tie_card (i);
176
177   /*
178     this is a little awkward, but we must decide where to put
179     aggregrates.
180    */
181   if (i == 0)
182     s += card ();
183
184   if (i + 1 == size ())
185     s += to_string ("TOTAL=%.2f", score ());
186
187   return s;
188 }
189
190 /* for use inside GDB */
191 string
192 Ties_configuration::complete_score_card () const
193 {
194   string s;
195   for (vsize i = 0; i < size (); i++)
196     {
197       s += complete_tie_card (i);
198     }
199
200   return s;
201 }
202
203 string
204 Ties_configuration::card () const
205 {
206   return score_card_;
207 }
208