2 slur.cc -- implement Slur
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
12 think about crossing stems.
13 Begin and end should be treated as a Script.
18 #include "paper-def.hh"
19 #include "note-column.hh"
22 #include "molecule.hh"
27 Slur::add (Note_column
*n
)
29 encompass_arr_
.push (n
);
34 Slur::set_default_dir ()
37 for (int i
=0; i
< encompass_arr_
.size (); i
++)
39 if (encompass_arr_
[i
]->dir_
< 0)
48 Slur::do_add_processing ()
50 set_bounds (LEFT
, encompass_arr_
[0]);
51 if (encompass_arr_
.size () > 1)
52 set_bounds (RIGHT
, encompass_arr_
.top ());
56 Slur::do_pre_processing ()
58 // don't set directions
62 Slur::do_substitute_dependency (Score_elem
*o
, Score_elem
*n
)
65 while ((i
= encompass_arr_
.find_i ((Note_column
*)o
->item ())) >=0)
68 encompass_arr_
[i
] = (Note_column
*)n
->item ();
70 encompass_arr_
.del (i
);
75 Note_column_compare (Note_column
*const&n1
, Note_column
* const&n2
)
77 return Item::left_right_compare (n1
, n2
);
81 Slur::do_post_processing ()
83 encompass_arr_
.sort (Note_column_compare
);
86 Real interline_f
= paper ()->interline_f ();
87 Real inter_f
= interline_f
/ 2;
90 [OSU]: slur and tie placement
93 * x = centre of head (upside-down: inner raakpunt stem) - d * gap
95 * y = length < 5ss : horizontal raakpunt + d * 0.25 ss
96 y = length >= 5ss : y next interline - d * 0.25 ss
97 --> height <= 5 length ?? we use <= 3 length, now...
99 * suggested gap = ss / 5;
101 // jcn: 1/5 seems so small?
102 Real gap_f
= interline_f
/ 2; // 5;
104 Drul_array
<Note_column
*> extrema
;
105 extrema
[LEFT
] = encompass_arr_
[0];
106 extrema
[RIGHT
] = encompass_arr_
.top ();
109 Real nw_f
= paper ()->note_width ();
113 if (extrema
[d
] != spanned_drul_
[d
])
116 *(spanned_drul_
[d
]->width ().length () -0.5*nw_f
);
118 else if (extrema
[d
]->stem_l_
&& !extrema
[d
]->stem_l_
->transparent_b_
)
120 dy_f_drul_
[d
] = (int)rint (extrema
[d
]->stem_l_
->height ()[dir_
]);
121 /* normal slur from notehead centre to notehead centre, minus gap */
122 dx_f_drul_
[d
] += -d
* gap_f
;
126 dy_f_drul_
[d
] = (int)rint (extrema
[d
]->head_positions_interval ()[dir_
])* inter_f
;
128 dy_f_drul_
[d
] += dir_
* interline_f
;
130 while ((d
*= -1) != LEFT
);
134 Slur::height_f () const
137 rather braindead way that of adjusting slur height
138 for heads/stems that extend beyond default slur
142 Real interline_f
= paper ()->interline_f ();
143 Real nh_f
= interline_f
/ 2;
145 Real dx
= width ().length ();
146 Real dy
= dy_f_drul_
[RIGHT
] - dy_f_drul_
[LEFT
];
147 Stem
* stem
= encompass_arr_
[0]->stem_l_
;
148 Real lx
= stem
->hpos_f ();
149 Real centre
= (width ().min () + width ().max ()) / 2;
150 Real ly
= stem
->dir_
== dir_
? stem
->stem_end_f () : stem
->stem_begin_f ()
152 for (int i
= 0; i
< encompass_arr_
.size (); i
++)
154 Stem
* stem
= encompass_arr_
[i
]->stem_l_
;
155 Real sx
= abs (centre
- stem
->hpos_f ());
156 Real sy
= stem
->dir_
== dir_
? stem
->stem_end_f ()
157 : stem
->stem_begin_f () + dir_
* nh_f
/ 2;
158 sy
= dir_
* (sy
- (ly
+ ((stem
->hpos_f () - lx
) / dx
) * dy
));
160 uhm, correct for guess bezier curve (more if further from centre)
161 forget the cos alpha...
164 h
= h
>? sy
* (1 + 2 * sx
/ dx
);
166 Real ratio
= 1.0/3; // duh
168 correct h for slur ratio
170 Real staffheight
= paper ()->get_var ("barsize");
172 h
*= ((h
* interline_f
) / dx
) / ratio
;
176 IMPLEMENT_IS_TYPE_B1(Slur
,Spanner
);