X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie.cc;h=87de462d7391656f316118bf2c377c9faebb76b6;hb=f798a4c8737f0d279fcf54ba4f0951074565fa76;hp=dc7ac39b9ce60072f60674c0693000b76f4b0260;hpb=4fabc68182cab7149d2a4b52502e180f57199831;p=lilypond.git diff --git a/lily/tie.cc b/lily/tie.cc index dc7ac39b9c..87de462d73 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -3,31 +3,56 @@ source file of the GNU LilyPond music typesetter - (c) 1997--1999 Han-Wen Nienhuys + (c) 1997--2000 Han-Wen Nienhuys */ +#include +#include "lookup.hh" #include "paper-def.hh" #include "tie.hh" #include "note-head.hh" -#include "p-col.hh" +#include "bezier.hh" +#include "paper-column.hh" #include "debug.hh" - - +#include "staff-symbol-referencer.hh" +#include "directional-element-interface.hh" +#include "molecule.hh" +#include "bezier-bow.hh" +#include "stem.hh" void -Tie::set_head (Direction d, Note_head * head_l) +Tie::set_head (Direction d, Item * head_l) { - assert (!head_l_drul_[d]); - head_l_drul_[d] = head_l; + assert (!head (d)); + index_set_cell (get_elt_property ("heads"), d, head_l->self_scm_); + set_bounds (d, head_l); - add_dependency (head_l); } Tie::Tie() { - head_l_drul_[RIGHT] =0; - head_l_drul_[LEFT] =0; + set_elt_property ("heads", gh_cons (SCM_EOL, SCM_EOL)); + dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = 0.0; + dx_f_drul_[LEFT] = dx_f_drul_[RIGHT] = 0.0; + +} + +Note_head* +Tie::head (Direction d) const +{ + SCM c = get_elt_property ("heads"); + c = index_cell (c, d); + + return dynamic_cast (unsmob_element (c)); +} + +Real +Tie::position_f () const +{ + return head (LEFT) + ? staff_symbol_referencer (head (LEFT)).position_f () + : staff_symbol_referencer (head (RIGHT)).position_f () ; } @@ -35,121 +60,118 @@ Tie::Tie() ugh: direction of the Tie is more complicated. See [Ross] p136 and further */ Direction -Tie::get_default_dir() const +Tie::get_default_dir () const { - int m= (head_l_drul_[LEFT]->position_i_ - + head_l_drul_[RIGHT]->position_i_) /2; - return(m < 0)? DOWN : UP; + Stem * sl = head(LEFT) ? head (LEFT)->stem_l () :0; + Stem * sr = head(RIGHT) ? head (RIGHT)->stem_l () :0; + + if (sl && directional_element (sl).get () == UP + && sr && directional_element (sr).get () == UP) + return DOWN; + else + return UP; } void Tie::do_add_processing() { - if (!(head_l_drul_[LEFT] && head_l_drul_[RIGHT])) + if (!(head (LEFT) && head (RIGHT))) warning (_ ("lonely tie")); Direction d = LEFT; - Drul_array new_head_drul = head_l_drul_; + Drul_array new_head_drul; + new_head_drul[LEFT] = head(LEFT); + new_head_drul[RIGHT] = head(RIGHT); do { - if (!head_l_drul_[d]) - new_head_drul[d] = head_l_drul_[(Direction)-d]; + if (!head (d)) + new_head_drul[d] = head((Direction)-d); } while (flip(&d) != LEFT); - head_l_drul_ = new_head_drul; + + index_set_cell (get_elt_property ("heads"), LEFT, new_head_drul[LEFT]->self_scm_ ); + index_set_cell (get_elt_property ("heads"), RIGHT, new_head_drul[RIGHT]->self_scm_ ); } void Tie::do_post_processing() { - // URG: share code with slur! - assert (head_l_drul_[LEFT] || head_l_drul_[RIGHT]); + if (!head (LEFT) && !head (RIGHT)) + { + programming_error ("Tie without heads."); + set_elt_property ("transparent", SCM_BOOL_T); + set_empty (X_AXIS); + set_empty (Y_AXIS); + return; + } - // URG - Real notewidth = paper_l ()->note_width () * 0.8; - Real interline_f = paper_l ()->get_realvar (interline_scm_sym); + if (!directional_element (this).get ()) + directional_element (this).set (get_default_dir ()); + + Real staff_space = staff_symbol_referencer (this).staff_space (); + Real half_space = staff_space / 2; + Real x_gap_f = paper_l ()->get_var ("tie_x_gap"); + Real y_gap_f = paper_l ()->get_var ("tie_y_gap"); /* - [OSU]: slur and tie placement + Slur and tie placement [OSU] - ties: - * x = inner raakpunt - d * gap + Ties: + + * x = inner vertical tangent - d * gap - * y = length < 5ss : horizontal raakpunt - y = length >= 5ss : y next interline - d * 0.25 ss - --> height <= 5 length ?? we use <= 3 length, now... */ - Real gap_f = paper_l ()->get_var ("slur_x_gap"); - Direction d = LEFT; - do - { - dy_f_drul_[d] = .5 * interline_f * (head_l_drul_[d] - ? head_l_drul_[d]->position_i_ - : head_l_drul_[(Direction)-d]->position_i_); - } - while (flip(&d) != LEFT); + /* + OSU: not different for outer notes, so why all this code? + ie, can we drop this, or should it be made switchable. + */ + if (head (LEFT)) + dx_f_drul_[LEFT] = head (LEFT)->extent (X_AXIS).length (); + else + dx_f_drul_[LEFT] = get_broken_left_end_align (); + dx_f_drul_[LEFT] += x_gap_f; + dx_f_drul_[RIGHT] -= x_gap_f; + + /* + Slur and tie placement [OSU] -- check this + + Ties: + + * y = dx < 5ss: horizontal tangent + y = dx >= 5ss: y next interline - d * 0.25 ss + + which probably means that OSU assumes that + + dy <= 5 dx + + for smal slurs + */ + + + Real ypos = position_f (); - do + Real y_f = half_space * ypos; + int ypos_i = int (ypos); + + Real dx_f = extent (X_AXIS).length () + dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]; + Direction dir = directional_element (this).get(); + if (dx_f < paper_l ()->get_var ("tie_staffspace_length")) { - // tie attached to outer notehead - if (head_l_drul_[d] - && head_l_drul_[d]->remove_elt_property (extremal_scm_sym) != SCM_BOOL_F) - { - if (d == LEFT) - dx_f_drul_[d] += notewidth; - dx_f_drul_[d] += -d * gap_f; - /* attach to outer 3/4 end of head */ - dy_f_drul_[d] += dir_ * 0.25 * interline_f; - } - // tie attached to inner notehead - else if (head_l_drul_[d] && d == LEFT) - { - dx_f_drul_[d] += -d * notewidth; - } - // uhm? loose end of tie // tie attached to stem - else - { - dx_f_drul_[d] = -d * (spanned_drul_[d]->extent (X_AXIS).length () - -0.5 * notewidth); - } + if (abs (ypos_i) % 2) + y_f += dir * half_space; + y_f += dir * y_gap_f; } - while (flip(&d) != LEFT); - - // now that both are set, do dependent - do + else { - // tie attached to outer notehead - if (!head_l_drul_[d]) - { - dy_f_drul_[d] = dy_f_drul_[(Direction) -d]; - } + if (! (abs (ypos_i) % 2)) + y_f += dir * half_space; + y_f += dir * half_space; + y_f -= dir * y_gap_f; } - while (flip(&d) != LEFT); - - /* - Avoid too steep ties - * slur from notehead to stemend: c''()b'' - */ - Real damp_f = paper_l ()->get_var ("tie_slope_damping"); - Offset d_off = Offset (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT], - dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]); - d_off.x () += extent (X_AXIS).length (); - - Real ratio_f = abs (d_off.y () / d_off.x ()); - if (ratio_f > damp_f) - dy_f_drul_[(Direction)(- dir_ * sign (d_off.y ()))] += - dir_ * (ratio_f - damp_f) * d_off.x (); + + dy_f_drul_[LEFT] = dy_f_drul_[RIGHT] = y_f; } -void -Tie::do_substitute_element_pointer (Score_element*o, Score_element*n) -{ - Note_head *new_l =n?dynamic_cast (n):0; - if (dynamic_cast (o) == head_l_drul_[LEFT]) - head_l_drul_[LEFT] = new_l; - else if (dynamic_cast (o) == head_l_drul_[RIGHT]) - head_l_drul_[RIGHT] = new_l; -} Array @@ -162,3 +184,79 @@ Tie::get_rods () const a.push (r); return a; } + + + + +Molecule +Tie::do_brew_molecule () const +{ + Real thick = paper_l ()->get_var ("tie_thickness"); + Bezier one = get_curve (); + + Molecule a; + SCM d = get_elt_property ("dashed"); + if (gh_number_p (d)) + a = lookup_l ()->dashed_slur (one, thick, gh_scm2int (d)); + else + a = lookup_l ()->slur (one, directional_element (this).get () * thick, thick); + + return a; +} + + + +Bezier +Tie::get_curve () const +{ + Direction d (directional_element (this).get ()); + Bezier_bow b (get_encompass_offset_arr (), d); + + Real staff_space = staff_symbol_referencer (this).staff_space (); + Real h_inf = paper_l ()->get_var ("tie_height_limit_factor") * staff_space; + Real r_0 = paper_l ()->get_var ("tie_ratio"); + + b.set_default_bezier (h_inf, r_0); + Bezier c = b.get_bezier (); + + /* should do this for slurs as well. */ + Array horizontal (c.solve_derivative (Offset (1,0))); + + if (horizontal.size ()) + { + /* + ugh. Doesnt work for non-horizontal curves. + */ + Real y = c.curve_point (horizontal[0])[Y_AXIS]; + + Real ry = rint (y/staff_space) * staff_space; + Real diff = ry - y; + Real newy = y; + if (fabs (y) <= 2.0 + && fabs (diff) < paper_l ()->get_var ("tie_staffline_clearance")) + { + newy = ry - 0.5 * staff_space * sign (diff) ; + } + + Real y0 = c.control_ [0][Y_AXIS]; + c.control_[2][Y_AXIS] = + c.control_[1][Y_AXIS] = + (c.control_[1][Y_AXIS] - y0) * ((newy - y0) / (y - y0)) + y0; + } + else + programming_error ("Tie is nowhere horizontal"); + return c; +} + +Array +Tie::get_encompass_offset_arr () const +{ + Array offset_arr; + offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); + offset_arr.push (Offset (spanner_length () + dx_f_drul_[RIGHT], + dy_f_drul_[RIGHT])); + + return offset_arr; +} + +