]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-column.cc
release: 1.3.131
[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--2001 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 (Grob*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 (Grob*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 (Grob*me,Grob *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 (Grob* const & s1,
54              Grob* 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 (Grob*me)
70 {
71   Link_array<Grob> ties =
72     Pointer_group_interface__extract_elements (me, (Grob*)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   if(!ties.size())
80     return ;
81   
82
83   Direction d = Directional_element_interface::get (me);
84   if (d)
85     {
86       for (int i = ties.size (); i--;)
87         {
88           Grob *  t = ties[i];
89           Directional_element_interface::set (t, d);
90         }
91       return;
92     }
93   
94   if (ties.size () == 1)
95     {
96       Grob *  t = ties[0];      
97       Directional_element_interface::set (t,Tie::get_default_dir (t));
98       return;
99     }
100   
101   ties.sort (tie_compare);
102   Directional_element_interface::set( ties[0], DOWN);
103   ties.del (0);
104   
105   Directional_element_interface ::set(ties.pop (), UP);
106   for (int i=ties.size(); i--; )
107     {
108       Grob *  t = ties[i];
109       Real p = Tie::position_f (t);
110       Direction d = (Direction) sign (p);
111       if (!d)
112         d = UP;
113       Directional_element_interface::set (t, d);
114     }
115   
116 }
117
118 MAKE_SCHEME_CALLBACK(Tie_column,after_line_breaking,1);
119 SCM
120 Tie_column::after_line_breaking (SCM smob)
121 {
122   set_directions (unsmob_grob (smob));
123   return SCM_UNSPECIFIED;
124 }