]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie-column.cc
release: 1.3.65
[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 "tie-column.hh"
11 #include "group-interface.hh"
12 #include "tie.hh"
13 #include "directional-element-interface.hh"
14 #include "note-head.hh"
15
16 Tie_column::Tie_column (SCM s)
17   : Spanner (s)
18 {
19   set_elt_pointer ("ties", SCM_EOL);
20   set_extent_callback (0, X_AXIS);
21   set_extent_callback (0, Y_AXIS);  
22 }
23
24 void
25 Tie_column::add_tie (Tie *s)
26 {
27   Pointer_group_interface g (this, "ties");
28   if (!g.count ())
29     {
30       set_bound (LEFT, s->head (LEFT));
31       set_bound (RIGHT, s->head (RIGHT));
32     }
33   
34   Pointer_group_interface (this, "ties").add_element (s);
35   s->add_dependency (this);
36 }
37
38
39 int
40 tie_compare (Tie* const & s1,
41              Tie* const & s2)
42 {
43   return sign (s1->position_f () - s2->position_f());
44 }
45
46 /*
47   See [Ross p. 138].
48
49
50   In normal chord cases, the outer ties point outwards, and the
51   direction of the rest is determined by their staff position.
52
53   Ross forgets about the tie that is *on* the middle staff line. We
54   assume it goes UP. (TODO: make this settable) */
55 void
56 Tie_column::set_directions ()
57 {
58   Link_array<Tie> ties =
59     Pointer_group_interface__extract_elements (this, (Tie*)0, "ties");
60
61
62   Direction d = Directional_element_interface (this).get ();
63
64   if (d)
65     {
66       for (int i = ties.size (); i--;)
67         {
68           Tie * t = ties[i];
69           Directional_element_interface (t).set (d);
70         }
71       return;
72     }
73   
74   if (ties.size () == 1)
75     {
76       Tie * t = ties[0];      
77       Directional_element_interface (t).set (t->get_default_dir ());
78       return;
79     }
80   
81   ties.sort (tie_compare);
82   Directional_element_interface tie0(ties[0]);
83   tie0.set (DOWN);
84   ties.del (0);
85   
86   Directional_element_interface tietop(ties.pop ());
87   tietop.set (UP);
88
89   for (int i=ties.size(); i--; )
90     {
91       Tie * t = ties[i];
92       Real p = t->position_f ();
93       Direction d = (Direction) sign (p);
94       if (!d)
95         d = UP;
96       Directional_element_interface (t).set (d);
97     }
98   
99 }
100
101 GLUE_SCORE_ELEMENT(Tie_column,after_line_breaking);
102 SCM
103 Tie_column::member_after_line_breaking ()
104 {
105   set_directions ();
106   return SCM_UNDEFINED;
107 }