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