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