]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-column.cc
release: 1.3.102
[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-interface"));
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-interface"));
31 }
32
33
34 /*
35   tie dir depends on what Tie_column does.
36 */
37
38 void
39 Tie_column::add_tie (Score_element*me,Score_element *s)
40 {
41   if (!  Pointer_group_interface ::count (me, "ties"))
42     {
43       dynamic_cast<Spanner*> (me)->set_bound (LEFT, Tie::head (s,LEFT));
44       dynamic_cast<Spanner*> (me)->set_bound (RIGHT, Tie::head (s,RIGHT));
45     }
46   
47   Pointer_group_interface::add_element (me, "ties",s);
48   s->add_dependency (me);
49 }
50
51
52 int
53 tie_compare (Score_element* const & s1,
54              Score_element* const & s2)
55 {
56   return sign (Tie::position_f (s1) - Tie::position_f(s2));
57 }
58
59 /*
60   See [Ross p. 138].
61
62
63   In normal chord cases, the outer ties point outwards, and the
64   direction of the rest is determined by their staff position.
65
66   Ross forgets about the tie that is *on* the middle staff line. We
67   assume it goes UP. (TODO: make me settable) */
68 void
69 Tie_column::set_directions (Score_element*me)
70 {
71   Link_array<Score_element> ties =
72     Pointer_group_interface__extract_elements (me, (Score_element*)0, "ties");
73
74   for (int i = ties.size (); i--; )
75     if (Directional_element_interface::get (ties[i]))
76       ties.del (i);
77   
78
79   Direction d = Directional_element_interface::get (me);
80   if (d)
81     {
82       for (int i = ties.size (); i--;)
83         {
84           Score_element *  t = ties[i];
85           Directional_element_interface::set (t, d);
86         }
87       return;
88     }
89   
90   if (ties.size () == 1)
91     {
92       Score_element *  t = ties[0];      
93       Directional_element_interface::set (t,Tie::get_default_dir (t));
94       return;
95     }
96   
97   ties.sort (tie_compare);
98   Directional_element_interface::set( ties[0], DOWN);
99   ties.del (0);
100   
101   Directional_element_interface ::set(ties.pop (), UP);
102   for (int i=ties.size(); i--; )
103     {
104       Score_element *  t = ties[i];
105       Real p = Tie::position_f (t);
106       Direction d = (Direction) sign (p);
107       if (!d)
108         d = UP;
109       Directional_element_interface::set (t, d);
110     }
111   
112 }
113
114 MAKE_SCHEME_CALLBACK(Tie_column,after_line_breaking,1);
115 SCM
116 Tie_column::after_line_breaking (SCM smob)
117 {
118   set_directions (unsmob_element (smob));
119   return SCM_UNSPECIFIED;
120 }