Fixes Issue 1504, allowing feather beam line breaking.
[lilypond/patrick.git] / lily / spaceable-grob.cc
blob268259b0882b4976c3d51bba77c07ea4c39b1483
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 "spaceable-grob.hh"
22 #include <cstdio>
24 #include "warn.hh"
25 #include "spring.hh"
26 #include "pointer-group-interface.hh"
27 #include "grob.hh"
28 #include "paper-column.hh"
29 #include "international.hh"
31 SCM
32 Spaceable_grob::get_minimum_distances (Grob *me)
34 return me->get_object ("minimum-distances");
37 /*todo: merge code of spring & rod?
39 void
40 Spaceable_grob::add_rod (Grob *me, Grob *p, Real d)
42 // printf ("rod %lf\n", d);
43 if (d < 0)
44 return;
46 if (isinf (d))
47 programming_error ("infinite rod");
49 SCM mins = get_minimum_distances (me);
50 SCM newdist = scm_from_double (d);
51 for (SCM s = mins; scm_is_pair (s); s = scm_cdr (s))
53 SCM dist = scm_car (s);
54 if (scm_car (dist) == p->self_scm ())
56 scm_set_cdr_x (dist, scm_max (scm_cdr (dist),
57 newdist));
58 return;
62 if (Paper_column::get_rank (p) < Paper_column::get_rank (me))
63 programming_error ("Adding reverse rod");
65 mins = scm_cons (scm_cons (p->self_scm (), newdist), mins);
66 me->set_object ("minimum-distances", mins);
69 void
70 Spaceable_grob::add_spring (Grob *me, Grob *other, Spring sp)
72 SCM ideal = me->get_object ("ideal-distances");
74 ideal = scm_cons (scm_cons (sp.smobbed_copy (), other->self_scm ()), ideal);
75 me->set_object ("ideal-distances", ideal);
78 Spring
79 Spaceable_grob::get_spring (Grob *this_col, Grob *next_col)
81 Spring *spring = 0;
83 for (SCM s = this_col->get_object ("ideal-distances");
84 !spring && scm_is_pair (s);
85 s = scm_cdr (s))
87 if (scm_is_pair (scm_car (s))
88 && unsmob_grob (scm_cdar (s)) == next_col
89 && unsmob_spring (scm_caar (s)))
90 spring = unsmob_spring (scm_caar (s));
93 if (!spring)
94 programming_error (_f ("No spring between column %d and next one",
95 Paper_column::get_rank (this_col)));
97 return spring ? *spring : Spring ();
102 ADD_INTERFACE (Spaceable_grob,
103 "A layout object that takes part in the spacing problem.",
105 /* properties */
106 "allow-loose-spacing "
107 "ideal-distances "
108 "keep-inside-line "
109 "left-neighbor "
110 "measure-length "
111 "minimum-distances "
112 "right-neighbor "
113 "spacing-wishes "