]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-column.cc
release: 1.3.72
[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 (0, X_AXIS);
24   me->set_extent_callback (0, 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   Pointer_group_interface g (me, "ties");
37   if (!g.count ())
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 (me, "ties").add_element (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 (me).get ();
72
73   if (d)
74     {
75       for (int i = ties.size (); i--;)
76         {
77           Score_element *  t = ties[i];
78           Directional_element_interface (t).set (d);
79         }
80       return;
81     }
82   
83   if (ties.size () == 1)
84     {
85       Score_element *  t = ties[0];      
86       Directional_element_interface (t).set (Tie::get_default_dir (t));
87       return;
88     }
89   
90   ties.sort (tie_compare);
91   Directional_element_interface tie0(ties[0]);
92   tie0.set (DOWN);
93   ties.del (0);
94   
95   Directional_element_interface tietop(ties.pop ());
96   tietop.set (UP);
97
98   for (int i=ties.size(); i--; )
99     {
100       Score_element *  t = ties[i];
101       Real p = Tie::position_f (t);
102       Direction d = (Direction) sign (p);
103       if (!d)
104         d = UP;
105       Directional_element_interface (t).set (d);
106     }
107   
108 }
109
110 MAKE_SCHEME_CALLBACK(Tie_column,after_line_breaking);
111 SCM
112 Tie_column::after_line_breaking (SCM smob)
113 {
114   set_directions (unsmob_element (smob));
115   return SCM_UNSPECIFIED;
116 }