]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-column.cc
4d68c240747982d982756037a5c306f6135b2f79
[lilypond.git] / lily / tie-column.cc
1 /*   
2   tie-column.cc --  implement Tie_column
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "spanner.hh"
11 #include "tie-column.hh"
12 #include "group-interface.hh"
13 #include "tie.hh"
14 #include "directional-element-interface.hh"
15 #include "rhythmic-head.hh"
16
17
18
19 void
20 Tie_column::set_interface (Score_element*me)
21 {
22   me->set_interface (ly_symbol2scm ("tie-column"));
23   me->set_extent_callback (SCM_EOL, X_AXIS);
24   me->set_extent_callback (SCM_EOL, Y_AXIS) ; 
25 }
26
27 bool
28 Tie_column::has_interface (Score_element*me)
29 {
30   return  me->has_interface (ly_symbol2scm ("tie-column"));
31 }
32
33 void
34 Tie_column::add_tie (Score_element*me,Score_element *s)
35 {
36
37   if (!  Pointer_group_interface ::count (me, "ties"))
38     {
39       dynamic_cast<Spanner*> (me)->set_bound (LEFT, Tie::head (s,LEFT));
40       dynamic_cast<Spanner*> (me)->set_bound (RIGHT, Tie::head (s,RIGHT));
41     }
42   
43   Pointer_group_interface::add_element (me, "ties",s);
44   s->add_dependency (me);
45 }
46
47
48 int
49 tie_compare (Score_element* const & s1,
50              Score_element* const & s2)
51 {
52   return sign (Tie::position_f (s1) - Tie::position_f(s2));
53 }
54
55 /*
56   See [Ross p. 138].
57
58
59   In normal chord cases, the outer ties point outwards, and the
60   direction of the rest is determined by their staff position.
61
62   Ross forgets about the tie that is *on* the middle staff line. We
63   assume it goes UP. (TODO: make me settable) */
64 void
65 Tie_column::set_directions (Score_element*me)
66 {
67   Link_array<Score_element> ties =
68     Pointer_group_interface__extract_elements (me, (Score_element*)0, "ties");
69
70
71   Direction d = Directional_element_interface::get (me);
72
73   if (d)
74     {
75       for (int i = ties.size (); i--;)
76         {
77           Score_element *  t = ties[i];
78           Directional_element_interface::set (t, d);
79         }
80       return;
81     }
82   
83   if (ties.size () == 1)
84     {
85       Score_element *  t = ties[0];      
86       Directional_element_interface::set (t,Tie::get_default_dir (t));
87       return;
88     }
89   
90   ties.sort (tie_compare);
91   Directional_element_interface::set( ties[0], DOWN);
92   ties.del (0);
93   
94   Directional_element_interface ::set(ties.pop (), UP);
95   for (int i=ties.size(); i--; )
96     {
97       Score_element *  t = ties[i];
98       Real p = Tie::position_f (t);
99       Direction d = (Direction) sign (p);
100       if (!d)
101         d = UP;
102       Directional_element_interface::set (t, d);
103     }
104   
105 }
106
107 MAKE_SCHEME_CALLBACK(Tie_column,after_line_breaking,1);
108 SCM
109 Tie_column::after_line_breaking (SCM smob)
110 {
111   set_directions (unsmob_element (smob));
112   return SCM_UNSPECIFIED;
113 }