]> git.donarmstrong.com Git - lilypond.git/blob - lily/tie.cc
release: 1.1.58
[lilypond.git] / lily / tie.cc
1 /*
2   tie.cc -- implement Tie
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "paper-def.hh"
10 #include "tie.hh"
11 #include "note-head.hh"
12 #include "paper-column.hh"
13 #include "debug.hh"
14
15
16
17 void
18 Tie::set_head (Direction d, Note_head * head_l)
19 {
20   assert (!head_l_drul_[d]);
21   head_l_drul_[d] = head_l;
22   set_bounds (d, head_l);
23
24   add_dependency (head_l);
25 }
26
27 Tie::Tie()
28 {
29   head_l_drul_[RIGHT] =0;
30   head_l_drul_[LEFT] =0;
31 }
32
33
34 /*
35   ugh: direction of the Tie is more complicated.  See [Ross] p136 and further
36  */
37 Direction
38 Tie::get_default_dir () const
39 {
40   int m = (head_l_drul_[LEFT]->position_i_ 
41           + head_l_drul_[RIGHT]->position_i_) /2;
42   /*
43     If dir is not determined: inverse of stem: down
44     (see stem::get_default_dir ())
45    */
46   return (m <= 0)? DOWN : UP;
47 }
48
49 void
50 Tie::do_add_processing()
51 {
52   if (!(head_l_drul_[LEFT] && head_l_drul_[RIGHT]))
53     warning (_ ("lonely tie"));
54
55   Direction d = LEFT;
56   Drul_array<Note_head *> new_head_drul = head_l_drul_;
57   do {
58     if (!head_l_drul_[d])
59       new_head_drul[d] = head_l_drul_[(Direction)-d];
60   } while (flip(&d) != LEFT);
61   head_l_drul_ = new_head_drul;
62 }
63
64 void
65 Tie::do_post_processing()
66 {
67   assert (head_l_drul_[LEFT] || head_l_drul_[RIGHT]);
68
69   Real interline_f = paper_l ()->get_realvar (interline_scm_sym);
70   Real internote_f = interline_f / 2;
71   Real x_gap_f = paper_l ()->get_var ("tie_x_gap");
72   Real y_gap_f = paper_l ()->get_var ("tie_y_gap");
73
74   /* 
75    Slur and tie placement [OSU]
76
77    Ties:
78
79        * x = inner vertical tangent - d * gap
80
81    */
82
83
84   /*
85     OSU: not different for outer notes, so why all this code?
86     ie,  can we drop this, or should it be made switchable.
87    */
88 #if 0
89   Direction d = LEFT;
90   do
91     {
92       Real head_width_f = head_l_drul_[d]
93         ? head_l_drul_[d]->extent (X_AXIS).length ()
94         : 0;
95       /*
96         side attached to outer (upper or lower) notehead of chord
97       */
98       if (head_l_drul_[d]
99           /*
100             && head_l_drul_[d]->remove_elt_property (extremal_scm_sym) != SCM_BOOL_F)
101             ugh, ugh:
102
103                 a~a~a;
104
105             to second tie, middle notehead seems not extremal
106
107             Getting scared a bit by score-element's comment:
108             // is this a good idea?
109           */
110           && (head_l_drul_[d]->get_elt_property (extremal_scm_sym)
111               != SCM_BOOL_F))
112         {
113         if (d == LEFT)
114             dx_f_drul_[d] += head_width_f;
115           dx_f_drul_[d] += -d * x_gap_f;
116         }
117       /*
118         side attached to inner notehead
119       */
120       else
121         {
122           dx_f_drul_[d] += -d * head_width_f;
123         }
124     } while (flip (&d) != LEFT);
125
126 #else
127
128   if (head_l_drul_[LEFT])
129     dx_f_drul_[LEFT] = head_l_drul_[LEFT]->extent (X_AXIS).length ();
130   dx_f_drul_[LEFT] += x_gap_f;
131   dx_f_drul_[RIGHT] -= x_gap_f;
132
133 #endif
134
135   /* 
136    Slur and tie placement [OSU]  -- check this
137
138    Ties:
139
140        * y = dx <  5ss: horizontal tangent
141          y = dx >= 5ss: y next interline - d * 0.25 ss
142
143          which probably means that OSU assumes that
144
145             dy <= 5 dx
146
147          for smal slurs
148    */
149
150   int ypos_i = head_l_drul_[LEFT] ? head_l_drul_[LEFT]->position_i_
151     : head_l_drul_[RIGHT]->position_i_;
152
153   Real y_f = internote_f * ypos_i; 
154
155   Real dx_f = extent (X_AXIS).length () + dx_f_drul_[RIGHT] - dx_f_drul_[LEFT];
156   if (dx_f < paper_l ()->get_var ("tie_staffspace_length"))
157     {
158       if (abs (ypos_i) % 2)
159         y_f += dir_ * internote_f;
160       y_f += dir_ * y_gap_f;
161     }
162   else
163     {
164       if (! (abs (ypos_i) % 2))
165         y_f += dir_ * internote_f;
166       y_f += dir_ * internote_f;
167       y_f -= dir_ * y_gap_f;
168     }
169   
170   dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = y_f;
171 }
172
173 void
174 Tie::do_substitute_element_pointer (Score_element*o, Score_element*n)
175 {
176   Note_head *new_l = n ? dynamic_cast<Note_head *> (n) : 0;
177   if (dynamic_cast <Item *> (o) == head_l_drul_[LEFT])
178     head_l_drul_[LEFT] = new_l;
179   else if (dynamic_cast <Item *> (o) == head_l_drul_[RIGHT])
180     head_l_drul_[RIGHT] = new_l;
181 }
182
183
184 Array<Rod>
185 Tie::get_rods () const
186 {
187   Array<Rod> a;
188   Rod r;
189   r.item_l_drul_ = spanned_drul_;
190   r.distance_f_ = paper_l ()->get_var ("tie_x_minimum");
191   a.push (r);
192   return a;
193 }