2 slur.cc -- implement Slur
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1998, 1998 Han-Wen Nienhuys <hanwen@stack.nl>
7 Jan Nieuwenhuizen <jan@digicash.com>
12 * begin and end should be treated as a Script.
14 * slur from notehead to stemend: c''()b''
20 #include "paper-def.hh"
21 #include "note-column.hh"
24 #include "molecule.hh"
28 #include "encompass-info.hh"
31 IMPLEMENT_IS_TYPE_B1(Slur,Bow);
38 Slur::add (Note_column*n)
40 encompass_arr_.push (n);
45 Slur::set_default_dir ()
48 for (int i=0; i < encompass_arr_.size (); i ++)
50 if (encompass_arr_[i]->dir_ < 0)
59 Slur::do_add_processing ()
61 set_bounds (LEFT, encompass_arr_[0]);
62 if (encompass_arr_.size () > 1)
63 set_bounds (RIGHT, encompass_arr_.top ());
67 Slur::do_pre_processing ()
69 // don't set directions
73 Slur::do_substitute_dependency (Score_elem*o, Score_elem*n)
76 while ((i = encompass_arr_.find_i ((Note_column*)o->item ())) >=0)
79 encompass_arr_[i] = (Note_column*)n->item ();
81 encompass_arr_.del (i);
86 Note_column_compare (Note_column *const&n1 , Note_column* const&n2)
88 return Item::left_right_compare (n1, n2);
92 Slur::do_post_processing ()
94 encompass_arr_.sort (Note_column_compare);
98 Real interline_f = paper ()->interline_f ();
99 Real internote_f = interline_f / 2;
100 Real notewidth_f = paper ()->note_width ();
101 Real slur_min = paper ()->get_var ("slur_x_minimum");
104 [OSU]: slur and tie placement
107 * x = centre of head (upside-down: inner raakpunt stem) - d * gap
109 * y = length < 5ss : horizontal raakpunt + d * 0.25 ss
110 y = length >= 5ss : y next interline - d * 0.25 ss
111 --> height <= 5 length ?? we use <= 3 length, now...
114 Real gap_f = paper ()->get_var ("slur_x_gap");
116 Drul_array<Note_column*> extrema;
117 extrema[LEFT] = encompass_arr_[0];
118 extrema[RIGHT] = encompass_arr_.top ();
127 if (extrema[d] != spanned_drul_[d])
130 *(spanned_drul_[d]->width ().length () -0.5 * notewidth_f);
135 dx_f_drul_[LEFT] = spanned_drul_[LEFT]->width ().length ();
138 if (encompass_arr_.size () > 1)
139 dx_f_drul_[RIGHT] += notewidth_f;
145 else if (extrema[d]->stem_l_ && !extrema[d]->stem_l_->transparent_b_)
147 dy_f_drul_[d] = (int)rint (extrema[d]->stem_l_->height ()[dir_]);
148 dx_f_drul_[d] += 0.5 * notewidth_f - d * gap_f;
149 if (dir_ == extrema[d]->stem_l_->dir_)
152 dx_f_drul_[d] += 0.5 * (dir_ * d) * d * notewidth_f;
154 dx_f_drul_[d] += 0.25 * (dir_ * d) * d * notewidth_f;
159 dy_f_drul_[d] = (int)rint (extrema[d]->head_positions_interval ()
160 [dir_]) * internote_f;
162 dy_f_drul_[d] += dir_ * interline_f;
164 while (flip(&d) != LEFT);
166 // now that both are set, do dependent
172 if (extrema[d] != spanned_drul_[d])
179 dy_f_drul_[u] += dir_ * internote_f;
181 dy_f_drul_[d] = dy_f_drul_[(Direction)-d];
184 if (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT] < slur_min)
186 dx_f_drul_[d] -= d * slur_min
187 - (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]);
188 dx_f_drul_[d] = dx_f_drul_[(Direction)-d] + d * slur_min;
192 while (flip(&d) != LEFT);
196 Slur::get_encompass_offset_arr () const
198 Offset left = Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]);
199 left.x () += encompass_arr_[0]->stem_l_->hpos_f ();
201 Offset d = Offset (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT],
202 dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]);
203 d.x () += width ().length ();
206 int last = encompass_arr_.size () - 1;
209 if (encompass_arr_[0] != spanned_drul_[LEFT])
213 if (encompass_arr_.top () != spanned_drul_[RIGHT])
220 notes.push (Offset (0,0));
222 for (int i = first; i < last; i++)
224 Encompass_info info (encompass_arr_[i], dir_);
225 notes.push (info.o_ - left);
231 int n = last - first + 2;
232 Array<Offset> notes (n);
233 notes[0] = Offset (0,0);
235 for (int i = first; i < last; i++)
237 Encompass_info info (encompass_arr_[i], dir_);
238 notes[i - first + 1] = info.o_ - left;
240 notes[n - 1] = Offset (d);