X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fslur.cc;h=ca200b2b243ca80fd342b74e70794c9e1cf9d0d1;hb=105fd7580334c8f42838ac62504c5f290f3428c5;hp=ccad52d81cd9172fdc879cacb1180f2923cbcaf2;hpb=9c8bcb9a2a1fedb5459e593b18a8c550318e6800;p=lilypond.git diff --git a/lily/slur.cc b/lily/slur.cc index ccad52d81c..ca200b2b24 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -67,9 +67,12 @@ Slur::de_uglyfy (Score_element*me, Slur_bezier_bow* bb, Real default_height) Real h = bb->curve_.control_[i][Y_AXIS] * ff / length; Real f = default_height / length; - Real c1 = me->paper_l ()->get_var ("bezier_control1"); - Real c2 = me->paper_l ()->get_var ("bezier_control2"); - Real c3 = me->paper_l ()->get_var ("bezier_control3"); + SCM up = me->get_elt_property ("de-uglify-parameters"); + + Real c1 = gh_scm2double (gh_car (up)); + Real c2 = gh_scm2double (gh_cadr (up)); + Real c3 = gh_scm2double (gh_caddr (up)); + if (h > c1 * f) { h = c1 * f; @@ -104,58 +107,16 @@ Slur::get_default_dir (Score_element*me) } - - - -Offset -Slur::encompass_offset (Score_element*me, - Score_element* col, - Score_element **common) -{ - Offset o; - Score_element* stem_l = unsmob_element (col->get_elt_property ("stem")); - - Direction dir = Directional_element_interface (me).get (); - - if (!stem_l) - { - warning (_ ("Slur over rest?")); - o[X_AXIS] = col->relative_coordinate (common[X_AXIS], X_AXIS); - o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS); - return o; - } - Direction stem_dir = Directional_element_interface (stem_l).get (); - o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS); - - /* - Simply set x to middle of notehead - */ - - o[X_AXIS] -= 0.5 * stem_dir * col->extent (X_AXIS).length (); - - if ((stem_dir == dir) - && !stem_l->extent (Y_AXIS).empty_b ()) - { - o[Y_AXIS] = stem_l->relative_coordinate (common[Y_AXIS], Y_AXIS); // iuhg - } - else - { - o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS); // ugh - } - - /* - leave a gap: slur mustn't touch head/stem - */ - o[Y_AXIS] += dir * me->paper_l ()->get_var ("slur_y_free"); - return o; -} - -MAKE_SCHEME_CALLBACK(Slur,after_line_breaking); - +MAKE_SCHEME_CALLBACK (Slur, after_line_breaking); SCM Slur::after_line_breaking (SCM smob) { Score_element *me = unsmob_element (smob); + if (!scm_ilength (me->get_elt_property ("note-columns"))) + { + me->suicide (); + return SCM_UNSPECIFIED; + } set_extremities (me); set_control_points (me); return SCM_UNSPECIFIED; @@ -164,8 +125,8 @@ Slur::after_line_breaking (SCM smob) void Slur::set_extremities (Score_element*me) { - if (!Directional_element_interface (me).get ()) - Directional_element_interface (me).set (get_default_dir (me)); + if (!Directional_element_interface::get (me)) + Directional_element_interface ::set (me,get_default_dir (me)); Direction dir = LEFT; do @@ -174,7 +135,8 @@ Slur::set_extremities (Score_element*me) { // for (SCM s = get_elt_property ("slur-extremity-rules"); s != SCM_EOL; s = gh_cdr (s)) - for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules")); + for (SCM s = scm_eval2 (ly_symbol2scm ("slur-extremity-rules"), + SCM_EOL); s != SCM_EOL; s = gh_cdr (s)) { SCM r = gh_call2 (gh_caar (s), me->self_scm (), @@ -191,80 +153,151 @@ Slur::set_extremities (Score_element*me) while (flip (&dir) != LEFT); } +Real +Slur::get_first_notecolumn_y (Score_element *me, Direction dir) +{ + Score_element *col = dir == LEFT + ? unsmob_element (gh_car (scm_reverse (me->get_elt_property + ("note-columns")))) + : unsmob_element + (gh_car (me->get_elt_property ("note-columns"))); + + Score_element *common[] = + { + 0, + me->common_refpoint (col, Y_AXIS) + }; + Real y; + if (col == ((Spanner*)me)->get_bound (dir)) + { + y = get_attachment (me, dir, common)[Y_AXIS]; + } + else + { + y = encompass_offset (me, col, common)[Y_AXIS] + - me->relative_coordinate (common[Y_AXIS], Y_AXIS); + } + return y; +} + +Offset +Slur::broken_trend_offset (Score_element *me, Direction dir) +{ + /* + A broken slur should maintain the same vertical trend + the unbroken slur would have had. + */ + Offset o; + if (Spanner *mother = dynamic_cast (me->original_l_)) + { + for (int i = dir == LEFT ? 0 : mother->broken_into_l_arr_.size (); + dir == LEFT ? i < mother->broken_into_l_arr_.size () : i; + dir == LEFT ? i++ : --i) + { + if (mother->broken_into_l_arr_[i - dir] == me) + { + Score_element *neighbour = mother->broken_into_l_arr_[i]; + if (dir == RIGHT) + neighbour->set_elt_property ("direction", + me->get_elt_property ("direction")); + Real neighbour_y = get_first_notecolumn_y (neighbour, dir); + Real y = get_first_notecolumn_y (me, -dir); + o = Offset (0, (y + neighbour_y) / 2); + break; + } + } + } + return o; +} + Offset Slur::get_attachment (Score_element*me,Direction dir, Score_element **common) { - Spanner*sp = dynamic_cast(me); SCM s = me->get_elt_property ("attachment"); + if (!gh_symbol_p (index_cell (s, dir))) + { + set_extremities (me); + s = me->get_elt_property ("attachment"); + } SCM a = dir == LEFT ? gh_car (s) : gh_cdr (s); + Spanner*sp = dynamic_cast(me); String str = ly_symbol2string (a); Real ss = Staff_symbol_referencer::staff_space ((Score_element*)me); Real hs = ss / 2.0; Offset o; - - + + Score_element *stem = 0; if (Note_column::has_interface (sp->get_bound (dir))) { Score_element * n =sp->get_bound (dir); - if (Score_element*st = Note_column::stem_l (n)) + if (Score_element *stem = Note_column::stem_l (n)) { if (str == "head") { - o = Offset (0, Stem::chord_start_f (st )); + o = Offset (0, Stem::head_positions (stem) + [Directional_element_interface::get (me)] * hs); /* Default position is centered in X, on outer side of head Y */ o += Offset (0.5 * n->extent (X_AXIS).length (), - 0.5 * ss * Directional_element_interface (me).get ()); + 0.5 * ss * Directional_element_interface::get (me)); } else if (str == "alongside-stem") { - o = Offset (0, Stem::chord_start_f (st )); + o = Offset (0, Stem::chord_start_f (stem)); /* Default position is on stem X, on outer side of head Y */ o += Offset (n->extent (X_AXIS).length () - * (1 + Stem::get_direction (st )), - 0.5 * ss * Directional_element_interface (me).get ()); + * (1 + Stem::get_direction (stem)), + 0.5 * ss * Directional_element_interface::get (me)); } else if (str == "stem") { - o = Offset (0, Stem::stem_end_position (st ) * hs); + o = Offset (0, Stem::stem_end_position (stem) * hs); /* Default position is on stem X, at stem end Y */ o += Offset (0.5 * (n->extent (X_AXIS).length () - - st->extent (X_AXIS).length ()) - * (1 + Stem::get_direction (st )), + - stem->extent (X_AXIS).length ()) + * (1 + Stem::get_direction (stem)), 0); } - else if (str == "loose-end") - { - SCM other_a = dir == LEFT ? gh_cdr (s) : gh_car (s); - if (ly_symbol2string (other_a) != "loose-end") - { - o = Offset (0, get_attachment (me, -dir, common)[Y_AXIS]); - } - } + } + } + else if (str == "loose-end") + { + SCM other_a = dir == LEFT ? gh_cdr (s) : gh_car (s); + if (ly_symbol2string (other_a) != "loose-end") + { +#if 0 + /* + The braindead way: horizontal + */ + o = Offset (0, get_attachment (me, -dir, common)[Y_AXIS]); +#else + o = broken_trend_offset (me, dir); +#endif - SCM l = scm_assoc - (scm_listify (a, - gh_int2scm (Stem::get_direction (st ) * dir), - gh_int2scm (Directional_element_interface (me).get () * dir), - SCM_UNDEFINED), - scm_eval (ly_symbol2scm ("slur-extremity-offset-alist"))); - - if (l != SCM_BOOL_F) - { - o += ly_scm2offset (gh_cdr (l)) * ss * dir; - } } + + } + + SCM l = scm_assoc + (scm_listify (a, + gh_int2scm (stem ? Stem::get_direction (stem) : 1 * dir), + gh_int2scm (Directional_element_interface::get (me) * dir), + SCM_UNDEFINED), + scm_eval2 (ly_symbol2scm ("slur-extremity-offset-alist"), SCM_EOL)); + + if (l != SCM_BOOL_F) + { + o += ly_scm2offset (gh_cdr (l)) * ss * dir; } - /* What if get_bound () is not a note-column? @@ -275,13 +308,59 @@ Slur::get_attachment (Score_element*me,Direction dir, o[Y_AXIS] += sp->get_bound (dir)->relative_coordinate (common[Y_AXIS], Y_AXIS) - me->relative_coordinate (common[Y_AXIS], Y_AXIS); } + + return o; +} + +Offset +Slur::encompass_offset (Score_element*me, + Score_element* col, + Score_element **common) +{ + Offset o; + Score_element* stem_l = unsmob_element (col->get_elt_property ("stem")); + + Direction dir = Directional_element_interface::get (me); + + if (!stem_l) + { + warning (_ ("Slur over rest?")); + o[X_AXIS] = col->relative_coordinate (common[X_AXIS], X_AXIS); + o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS); + return o; + } + Direction stem_dir = Directional_element_interface::get (stem_l); + o[X_AXIS] = stem_l->relative_coordinate (0, X_AXIS); + + /* + Simply set x to middle of notehead + */ + + o[X_AXIS] -= 0.5 * stem_dir * col->extent (X_AXIS).length (); + + if ((stem_dir == dir) + && !stem_l->extent (Y_AXIS).empty_b ()) + { + o[Y_AXIS] = stem_l->relative_coordinate (common[Y_AXIS], Y_AXIS); // iuhg + o[Y_AXIS] += stem_l->extent (Y_AXIS)[dir]; + } + else + { + o[Y_AXIS] = col->relative_coordinate (common[Y_AXIS], Y_AXIS); // ugh + o[Y_AXIS] += col->extent (Y_AXIS)[dir]; + } + + /* + leave a gap: slur mustn't touch head/stem + */ + o[Y_AXIS] += dir * me->paper_l ()->get_var ("slur_y_free"); return o; } Array Slur::get_encompass_offset_arr (Score_element*me) { - Spanner*sp = dynamic_cast(me); + Spanner*sp = dynamic_cast(me); SCM eltlist = me->get_elt_property ("note-columns"); Score_element *common[] = {me->common_refpoint (eltlist,X_AXIS), me->common_refpoint (eltlist,Y_AXIS)}; @@ -371,11 +450,17 @@ Slur::set_spacing_rods (SCM smob) /* Ugh should have dash-length + dash-period */ -MAKE_SCHEME_CALLBACK(Slur,brew_molecule); +MAKE_SCHEME_CALLBACK (Slur, brew_molecule); SCM Slur::brew_molecule (SCM smob) { Score_element * me = unsmob_element (smob); + if (!scm_ilength (me->get_elt_property ("note-columns"))) + { + me->suicide (); + return SCM_EOL; + } + Real thick = me->paper_l ()->get_var ("stafflinethickness") * gh_scm2double (me->get_elt_property ("thickness")); Bezier one = get_curve (me); @@ -385,7 +470,7 @@ Slur::brew_molecule (SCM smob) if (gh_number_p (d)) a = me->lookup_l ()->dashed_slur (one, thick, thick * gh_scm2double (d)); else - a = me->lookup_l ()->slur (one, Directional_element_interface (me).get () * thick, thick); + a = me->lookup_l ()->slur (one, Directional_element_interface::get (me) * thick, thick); return a.create_scheme(); } @@ -399,7 +484,7 @@ Slur::set_control_points (Score_element*me) Real r_0 = me->paper_l ()->get_var ("slur_ratio"); Slur_bezier_bow bb (get_encompass_offset_arr (me), - Directional_element_interface (me).get (), + Directional_element_interface::get (me), h_inf, r_0); if (bb.fit_factor () > 1.0) @@ -429,38 +514,44 @@ Slur::set_control_points (Score_element*me) SCM controls = SCM_EOL; for (int i= 4; i--;) - controls = gh_cons ( ly_offset2scm (b.control_[i]), controls); + { + controls = gh_cons ( ly_offset2scm (b.control_[i]), controls); + /* + BRRR WHURG. + All these null control-points, where do they all come from? + */ + if (i && b.control_[i][X_AXIS] == 0) + me->suicide (); + } me->set_elt_property ("control-points", controls); } - Bezier Slur::get_curve (Score_element*me) { Bezier b; int i = 0; - if (!Directional_element_interface (me).get () + if (!Directional_element_interface::get (me) || ! gh_symbol_p (index_cell (me->get_elt_property ("attachment"), LEFT))) set_extremities (me); if (!gh_pair_p (me->get_elt_property ("control-points"))) set_control_points (me); - - + for (SCM s= me->get_elt_property ("control-points"); s != SCM_EOL; s = gh_cdr (s)) { b.control_[i] = ly_scm2offset (gh_car (s)); i++; } - + Array enc (get_encompass_offset_arr (me)); - Direction dir = Directional_element_interface (me).get (); + Direction dir = Directional_element_interface::get (me); Real x1 = enc[0][X_AXIS]; Real x2 = enc.top ()[X_AXIS]; - + Real off = 0.0; for (int i=1; i < enc.size ()-1; i++) {