X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftie.cc;h=b96a815dfa3b6a4df8b40d7dcc5f3564d0847976;hb=a6193f6f613e0b2ff519b804d28f99fcd6ec9b92;hp=eeaf89fa984794989c00582f6d0fa78476aa82e4;hpb=e4a2733b4c0ab484305dc19fc598d70a9631539b;p=lilypond.git diff --git a/lily/tie.cc b/lily/tie.cc index eeaf89fa98..b96a815dfa 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 "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 () ; } @@ -37,39 +62,52 @@ Tie::Tie() Direction Tie::get_default_dir () const { - int m = (head_l_drul_[LEFT]->position_i () - + head_l_drul_[RIGHT]->position_i ()) /2; + Stem * sl = head(LEFT) ? head (LEFT)->stem_l () :0; + Stem * sr = head(RIGHT) ? head (RIGHT)->stem_l () :0; - /* - If dir is not determined: inverse of stem: down - (see stem::get_default_dir ()) - */ - Direction neutral_dir = (Direction)(int)paper_l ()->get_var ("stem_default_neutral_direction"); - return (m == 0) ? other_dir (neutral_dir) : (m < 0) ? DOWN : UP; + 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() { - 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; + } - Real interline_f = paper_l ()->get_realvar (interline_scm_sym); - Real internote_f = interline_f / 2; + if (!directional_element (this).get ()) + directional_element (this).set (get_default_dir ()); + + Real staff_space = paper_l ()->get_var ("interline"); + Real half_staff_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"); @@ -87,55 +125,13 @@ Tie::do_post_processing() OSU: not different for outer notes, so why all this code? ie, can we drop this, or should it be made switchable. */ -#if 0 - Direction d = LEFT; - do - { - Real head_width_f = head_l_drul_[d] - ? head_l_drul_[d]->extent (X_AXIS).length () - : 0; - /* - side attached to outer (upper or lower) notehead of chord - */ - if (head_l_drul_[d] - /* - && head_l_drul_[d]->remove_elt_property (extremal_scm_sym) != SCM_BOOL_F) - ugh, ugh: - - a~a~a; - - to second tie, middle notehead seems not extremal - - Getting scared a bit by score-element's comment: - // is this a good idea? - */ - && (head_l_drul_[d]->get_elt_property (extremal_scm_sym) - != SCM_BOOL_F)) - { - if (d == LEFT) - dx_f_drul_[d] += head_width_f; - dx_f_drul_[d] += -d * x_gap_f; - } - /* - side attached to inner notehead - */ - else - { - dx_f_drul_[d] += -d * head_width_f; - } - } while (flip (&d) != LEFT); - -#else - - if (head_l_drul_[LEFT]) - dx_f_drul_[LEFT] = head_l_drul_[LEFT]->extent (X_AXIS).length (); + 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; -#endif - /* Slur and tie placement [OSU] -- check this @@ -151,38 +147,31 @@ Tie::do_post_processing() for smal slurs */ - int ypos_i = head_l_drul_[LEFT] ? head_l_drul_[LEFT]->position_i () - : head_l_drul_[RIGHT]->position_i (); - Real y_f = internote_f * ypos_i; + Real ypos = position_f (); + Real y_f = half_staff_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")) { if (abs (ypos_i) % 2) - y_f += dir_ * internote_f; - y_f += dir_ * y_gap_f; + y_f += dir * half_staff_space; + y_f += dir * y_gap_f; } else { if (! (abs (ypos_i) % 2)) - y_f += dir_ * internote_f; - y_f += dir_ * internote_f; - y_f -= dir_ * y_gap_f; + y_f += dir * half_staff_space; + y_f += dir * half_staff_space; + y_f -= dir * y_gap_f; } 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 @@ -195,3 +184,79 @@ Tie::get_rods () const a.push (r); return a; } + + + + +Molecule* +Tie::do_brew_molecule_p () 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 new Molecule (a); +} + + + +Bezier +Tie::get_curve () const +{ + Direction d (directional_element (this).get ()); + Bezier_bow b (get_encompass_offset_arr (), d); + + b.ratio_ = paper_l ()->get_var ("slur_ratio"); + b.height_limit_ = paper_l ()->get_var ("slur_height_limit"); + b.rc_factor_ = paper_l ()->get_var ("slur_rc_factor"); + + b.calculate (); + Bezier c (b.get_curve ()); + + /* 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 space = staff_symbol_referencer (this).staff_space (); + Real y = c.curve_point (horizontal[0])[Y_AXIS]; + + Real ry = rint (y/space) * space; + Real diff = ry - y; + Real newy = y; + if (fabs (diff) < paper_l ()->get_var ("tie_staffline_clearance")) + { + newy = ry - 0.5 * 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; +} + +