Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / tie-column.cc
blob6e0eaecec0e09fa987aeb4b73bf70f57fea38eca
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2000--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 "tie-column.hh"
22 #include <cmath>
24 #include "output-def.hh"
25 #include "skyline.hh"
26 #include "warn.hh"
27 #include "paper-column.hh"
28 #include "spanner.hh"
29 #include "pointer-group-interface.hh"
30 #include "tie.hh"
31 #include "directional-element-interface.hh"
32 #include "tie-column-format.hh"
33 #include "tie-formatting-problem.hh"
34 #include "tie-configuration.hh"
36 using namespace std;
38 void
39 Tie_column::add_tie (Grob *tc, Grob *tie)
41 Spanner *me = dynamic_cast<Spanner *> (tc);
43 if (tie->get_parent (Y_AXIS)
44 && Tie_column::has_interface (tie->get_parent (Y_AXIS)))
45 return;
47 if (!me->get_bound (LEFT)
48 || (Paper_column::get_rank (me->get_bound (LEFT)->get_column ())
49 > Paper_column::get_rank (dynamic_cast<Spanner*> (tie)->get_bound (LEFT)->get_column ())))
51 me->set_bound (LEFT, Tie::head (tie, LEFT));
52 me->set_bound (RIGHT, Tie::head (tie, RIGHT));
55 tie->set_parent (me, Y_AXIS);
56 Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), tie);
60 Extend the spanner over its Tie constituents.
62 MAKE_SCHEME_CALLBACK (Tie_column, before_line_breaking, 1);
63 SCM
64 Tie_column::before_line_breaking (SCM smob)
66 Spanner *me = dynamic_cast<Spanner *> (unsmob_grob (smob));
67 for (SCM s = me->get_property ("ties"); scm_is_pair (s); s = scm_cdr (s))
69 Spanner *tie = dynamic_cast<Spanner *> (unsmob_grob (scm_car (s)));
70 Direction dir = LEFT;
73 if (dir * tie->get_bound (dir)->get_column ()->get_rank ()
74 > dir * me->get_bound (dir)->get_column ()->get_rank ())
75 me->set_bound (dir, Tie::head (tie, dir));
77 while (flip (&dir) != LEFT);
80 return SCM_UNSPECIFIED;
83 MAKE_SCHEME_CALLBACK (Tie_column, calc_positioning_done, 1)
84 SCM
85 Tie_column::calc_positioning_done (SCM smob)
87 Grob *me = unsmob_grob (smob);
88 extract_grob_set (me, "ties", ro_ties);
89 vector<Grob*> ties (ro_ties);
90 if (!ties.size ())
91 return SCM_BOOL_T;
93 me->set_property ("positioning-done", SCM_BOOL_T);
94 vector_sort (ties, Tie::less);
96 Tie_formatting_problem problem;
97 problem.from_ties (ties);
99 SCM manual_configs = me->get_property ("tie-configuration");
100 problem.set_manual_tie_configuration (manual_configs);
102 Ties_configuration base = problem.generate_optimal_configuration ();
103 for (vsize i = 0; i < base.size (); i++)
105 SCM cp = Tie::get_control_points (ties[i], problem.common_x_refpoint (),
106 base[i],
107 problem.details_);
109 ties[i]->set_property ("control-points", cp);
110 set_grob_direction (ties[i],
111 base[i].dir_);
113 problem.set_debug_scoring (base);
115 return SCM_BOOL_T;
120 ADD_INTERFACE (Tie_column,
121 "Object that sets directions of multiple ties in a tied"
122 " chord.",
124 /* properties */
125 "positioning-done "
126 "tie-configuration "