X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam.cc;h=f744b4fff6bbdf75b2e7836a47e15d33060faba7;hb=46340a068e743b3b35175c80b811c0b3860512ea;hp=f7c2f126ebfe88643961837a5c8af422a272fc29;hpb=04e1bc1c75af8f56a15013837ecd881ae4e4e319;p=lilypond.git diff --git a/lily/beam.cc b/lily/beam.cc index f7c2f126eb..f744b4fff6 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2000 Han-Wen Nienhuys + (c) 1997--2001 Han-Wen Nienhuys Jan Nieuwenhuizen */ @@ -11,14 +11,12 @@ /* [TODO] - * remove *-hs variables, and do all y-position stuff in staff-space. - This is not trivial, as Stem, and Stem_info both use point dimensions - (indicated by _f suffix) in several places too. - - * shorter! (now +- 1000 lines) - * less hairy code - * move paper vars to scm + -* shorter! (now +- 1000 lines) + + -* less hairy code + -* Remove #'direction from beam. The beam has no direction per se. + It may only set directions for stems. */ @@ -42,7 +40,7 @@ void Beam::add_stem (Grob*me, Grob*s) { - Pointer_group_interface:: add_element(me, "stems", s); + Pointer_group_interface:: add_element (me, "stems", s); s->add_dependency (me); @@ -56,9 +54,9 @@ int Beam::get_multiplicity (Grob*me) { int m = 0; - for (SCM s = me->get_grob_property ("stems"); gh_pair_p (s); s = gh_cdr (s)) + for (SCM s = me->get_grob_property ("stems"); gh_pair_p (s); s = ly_cdr (s)) { - Grob * sc = unsmob_grob (gh_car (s)); + Grob * sc = unsmob_grob (ly_car (s)); if (Stem::has_interface (sc)) m = m >? Stem::beam_count (sc,LEFT) >? Stem::beam_count (sc,RIGHT); @@ -74,7 +72,7 @@ Beam::get_multiplicity (Grob*me) [Alternatively, stems could set its own directions, according to their beam, during 'final-pre-processing'.] */ -MAKE_SCHEME_CALLBACK(Beam,before_line_breaking,1); +MAKE_SCHEME_CALLBACK (Beam,before_line_breaking,1); SCM Beam::before_line_breaking (SCM smob) { @@ -126,7 +124,7 @@ Beam::get_default_dir (Grob*me) count[d] ++; } - } while (flip(&d) != DOWN); + } while (flip (&d) != DOWN); SCM func = me->get_grob_property ("dir-function"); SCM s = gh_call2 (func, @@ -141,7 +139,7 @@ Beam::get_default_dir (Grob*me) /* If dir is not determined: get default */ - return to_dir (me->get_grob_property ("default-neutral-direction")); + return to_dir (me->get_grob_property ("neutral-direction")); } @@ -154,7 +152,7 @@ void Beam::set_stem_directions (Grob*me) { Link_array stems - =Pointer_group_interface__extract_elements (me, (Item*) 0, "stems"); + =Pointer_group_interface__extract_elements (me, (Item*) 0, "stems"); Direction d = Directional_element_interface::get (me); for (int i=0; i set_grob_property ("dy", gh_double2scm (0)); /* Hmm, callbacks should be called by, a eh, callback mechanism - somewhere(?), I guess, not by looping here. */ + somewhere (?), I guess, not by looping here. */ SCM list = me->get_grob_property ("y-dy-callbacks"); - for (SCM i = list; gh_pair_p (i); i = gh_cdr (i)) - gh_call1 (gh_car (i), smob); + for (SCM i = list; gh_pair_p (i); i = ly_cdr (i)) + gh_call1 (ly_car (i), smob); // UGH. Y is not in staff position unit? // Ik dacht datwe daar juist van weg wilden? @@ -331,6 +329,7 @@ Beam::least_squares (SCM smob) Real y = 0; Real dy = 0; + /* Stem_info, and thus y,dy in this function are corrected for beam-dir */ Real first_ideal = Stem::calc_stem_info (first_visible_stem (me)).idealy_f_; if (first_ideal == Stem::calc_stem_info (last_visible_stem (me)).idealy_f_) { @@ -361,8 +360,10 @@ Beam::least_squares (SCM smob) dy = dydx * dx; } - me->set_grob_property ("y", gh_double2scm (y)); - me->set_grob_property ("dy", gh_double2scm (dy)); + /* Store true, not dir-corrected values */ + Direction dir = Directional_element_interface::get (me); + me->set_grob_property ("y", gh_double2scm (y * dir)); + me->set_grob_property ("dy", gh_double2scm (dy * dir)); return SCM_UNSPECIFIED; } @@ -375,9 +376,11 @@ Beam::cancel_suspect_slope (SCM smob) if (visible_stem_count (me) <= 1) return SCM_UNSPECIFIED; - Real y = gh_scm2double (me->get_grob_property ("y")); - Real dy = gh_scm2double (me->get_grob_property ("dy")); - + /* Stem_info, and thus y,dy in this function are corrected for beam-dir */ + Direction dir = Directional_element_interface::get (me); + Real y = gh_scm2double (me->get_grob_property ("y")) * dir; + Real dy = gh_scm2double (me->get_grob_property ("dy")) * dir; + /* steep slope running against lengthened stem is suspect */ Real first_ideal = Stem::calc_stem_info (first_visible_stem (me)).idealy_f_; Real last_ideal = Stem::calc_stem_info (last_visible_stem (me)).idealy_f_; @@ -388,11 +391,12 @@ Beam::cancel_suspect_slope (SCM smob) Real dx = last_visible_stem (me)->relative_coordinate (0, X_AXIS) - first_visible_stem (me)->relative_coordinate (0, X_AXIS); Real dydx = dy && dx ? dy/dx : 0; - if (((y - first_ideal > lengthened) && (dydx > steep)) + if (( (y - first_ideal > lengthened) && (dydx > steep)) || ((y + dy - last_ideal > lengthened) && (dydx < -steep))) { Real adjusted_y = y + dy / 2; - me->set_grob_property ("y", gh_double2scm (adjusted_y)); + /* Store true, not dir-corrected values */ + me->set_grob_property ("y", gh_double2scm (adjusted_y * dir)); me->set_grob_property ("dy", gh_double2scm (0)); } return SCM_UNSPECIFIED; @@ -417,8 +421,10 @@ Beam::slope_damping (SCM smob) if (damping) { - Real y = gh_scm2double (me->get_grob_property ("y")); - Real dy = gh_scm2double (me->get_grob_property ("dy")); + /* y,dy in this function are corrected for beam-dir */ + Direction dir = Directional_element_interface::get (me); + Real y = gh_scm2double (me->get_grob_property ("y")) * dir; + Real dy = gh_scm2double (me->get_grob_property ("dy")) * dir; // ugh -> use commonx Real dx = last_visible_stem (me)->relative_coordinate (0, X_AXIS) @@ -428,8 +434,9 @@ Beam::slope_damping (SCM smob) Real damped_dy = dydx * dx; Real adjusted_y = y + (dy - damped_dy) / 2; - me->set_grob_property ("y", gh_double2scm (adjusted_y)); - me->set_grob_property ("dy", gh_double2scm (damped_dy)); + /* Store true, not dir-corrected values */ + me->set_grob_property ("y", gh_double2scm (adjusted_y * dir)); + me->set_grob_property ("dy", gh_double2scm (damped_dy * dir)); } return SCM_UNSPECIFIED; } @@ -453,13 +460,15 @@ Beam::quantise_dy (SCM smob) gh_double2scm (me->paper_l ()->get_var ("stafflinethickness") / 1.0)); - for (SCM s = quants; gh_pair_p (s); s = gh_cdr (s)) - a.push (gh_scm2double (gh_car (s))); + for (SCM s = quants; gh_pair_p (s); s = ly_cdr (s)) + a.push (gh_scm2double (ly_car (s))); if (a.size () > 1) { - Real y = gh_scm2double (me->get_grob_property ("y")); - Real dy = gh_scm2double (me->get_grob_property ("dy")); + /* y,dy in this function are corrected for beam-dir */ + Direction dir = Directional_element_interface::get (me); + Real y = gh_scm2double (me->get_grob_property ("y")) * dir; + Real dy = gh_scm2double (me->get_grob_property ("dy")) * dir; Real staff_space = Staff_symbol_referencer::staff_space (me); @@ -470,58 +479,37 @@ Beam::quantise_dy (SCM smob) Real quantised_dy = q * sign (dy); Real adjusted_y = y + (dy - quantised_dy) / 2; - me->set_grob_property ("y", gh_double2scm (adjusted_y)); - me->set_grob_property ("dy", gh_double2scm (quantised_dy)); + /* Store true, not dir-corrected values */ + me->set_grob_property ("y", gh_double2scm (adjusted_y * dir)); + me->set_grob_property ("dy", gh_double2scm (quantised_dy * dir)); } return SCM_UNSPECIFIED; } - -/* - What to do? Why do we have two dimensions (staff-position and - staff-space)? Do other grobs export staff-position to the user, - should we junk that? - - height-hs -> staff-position-height - y-position-hs -> staff-position - - or - - height-hs -> height / 2 - y-postion-hs -> y-position / 2 - - - UGHUGH. IF this callback is omitted, we hang. - FIXME: until here, we used only stem_info, which acts as if dir=up. -*/ +/* It's tricky to have the user override y,dy directly, so we use this + translation func. Also, if our staff_space != 1 (smaller staff, eg), + user will expect staff-position to be discrete values. */ MAKE_SCHEME_CALLBACK (Beam, user_override, 1); SCM Beam::user_override (SCM smob) { Grob *me = unsmob_grob (smob); - Real half_space = Staff_symbol_referencer::staff_space (me) / 2; - - Real y = gh_scm2double (me->get_grob_property ("y")); - Real dy = gh_scm2double (me->get_grob_property ("dy")); + Real staff_space = Staff_symbol_referencer::staff_space (me); - - SCM s = me->get_grob_property ("y-position-hs"); + SCM s = me->get_grob_property ("staff-position"); if (gh_number_p (s)) - y = gh_scm2double (s) * half_space; - else - // ughugh - y *= Directional_element_interface::get (me); + { + Real y = gh_scm2double (s) * staff_space * 0.5; + me->set_grob_property ("y", gh_double2scm (y)); + } - s = me->get_grob_property ("height-hs"); + /* Name suggestions? Tilt, slope, vertical-* ? */ + s = me->get_grob_property ("height"); if (gh_number_p (s)) - dy = gh_scm2double (s) * half_space; - else - // ughugh - dy *= Directional_element_interface::get (me); - - - me->set_grob_property ("y", gh_double2scm (y)); - me->set_grob_property ("dy", gh_double2scm (dy)); + { + Real dy = gh_scm2double (s) * staff_space * 0.5; + me->set_grob_property ("dy", gh_double2scm (dy)); + } return SCM_UNSPECIFIED; } @@ -630,7 +618,7 @@ Beam::check_stem_length_f (Grob*me,Real y, Real dy) Link_array stems= Pointer_group_interface__extract_elements (me, (Item*)0, "stems"); - for (int i=0; i < stems.size(); i++) + for (int i=0; i < stems.size (); i++) { Item* s = stems[i]; if (Stem::invisible_b (s)) @@ -684,6 +672,13 @@ Beam::set_stem_lengths (Grob *me) Real stem_y = calc_stem_y_f (me, s, y, dy); + // doesn't play well with dvips + if (scm_definedp (ly_symbol2scm ("ps-testing"), SCM_UNDEFINED) + == SCM_BOOL_T) + if (Stem::get_direction (s) == Directional_element_interface::get (me)) + stem_y += Stem::get_direction (s) + * gh_scm2double (me->get_grob_property ("thickness")) / 2; + /* caution: stem measures in staff-positions */ Real id = me->relative_coordinate (common, Y_AXIS) - stems[i]->relative_coordinate (common, Y_AXIS); @@ -710,15 +705,15 @@ Beam::quantise_y_f (Grob*me,Real y, Real dy, int quant_dir) SCM proc = me->get_grob_property ("vertical-position-quant-function"); SCM quants = scm_apply (proc, me->self_scm (), - gh_list (gh_int2scm (multiplicity), + scm_list_n (gh_int2scm (multiplicity), gh_double2scm (dy/staff_space), gh_double2scm (thick/staff_space), SCM_EOL, SCM_UNDEFINED)); Array a; - for (; gh_pair_p (quants); quants = gh_cdr (quants)) - a.push (gh_scm2double (gh_car (quants))); + for (; gh_pair_p (quants); quants = ly_cdr (quants)) + a.push (gh_scm2double (ly_car (quants))); if (a.size () <= 1) return y; @@ -729,7 +724,7 @@ Beam::quantise_y_f (Grob*me,Real y, Real dy, int quant_dir) Real q = up_y - iv[SMALLER] <= iv[BIGGER] - up_y ? iv[SMALLER] : iv[BIGGER]; if (quant_dir) - q = iv[(Direction)quant_dir]; + q = iv[ (Direction)quant_dir]; return q * Directional_element_interface::get (me); } @@ -741,7 +736,7 @@ Beam::set_beaming (Grob*me,Beaming_info_list *beaming) Pointer_group_interface__extract_elements (me, (Grob*)0, "stems"); Direction d = LEFT; - for (int i=0; i < stems.size(); i++) + for (int i=0; i < stems.size (); i++) { do { @@ -767,14 +762,15 @@ Beam::set_beaming (Grob*me,Beaming_info_list *beaming) FIXME: clean me up. */ Molecule -Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) +Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev, + Real /* dy */ , Real dydx + ) { // ugh -> use commonx - if ((next && !(next->relative_coordinate (0, X_AXIS) > here->relative_coordinate (0, X_AXIS))) || - (prev && !(prev->relative_coordinate (0, X_AXIS) < here->relative_coordinate (0, X_AXIS)))) + if ((next && ! (next->relative_coordinate (0, X_AXIS) > here->relative_coordinate (0, X_AXIS))) || + (prev && ! (prev->relative_coordinate (0, X_AXIS) < here->relative_coordinate (0, X_AXIS)))) programming_error ("Beams are not left-to-right"); - Real staffline_f = me->paper_l ()->get_var ("stafflinethickness"); int multiplicity = get_multiplicity (me); SCM space_proc = me->get_grob_property ("space-function"); @@ -784,15 +780,14 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) Real interbeam_f = gh_scm2double (space) ; Real bdy = interbeam_f; - Real stemdx = staffline_f; - + +#if 0 // ugh -> use commonx Real dx = visible_stem_count (me) ? last_visible_stem (me)->relative_coordinate (0, X_AXIS) - first_visible_stem (me)->relative_coordinate (0, X_AXIS) : 0.0; - Real dy = gh_scm2double (me->get_grob_property ("dy")); - Real dydx = dy && dx ? dy/dx : 0; - +#endif + Molecule leftbeams; Molecule rightbeams; @@ -809,7 +804,12 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) Direction dir = Directional_element_interface::get (me); - + + /* [Tremolo] beams on whole notes may not have direction set? */ + if (dir == CENTER) + dir = Directional_element_interface::get (here); + + /* half beams extending to the left. */ if (prev) { @@ -819,12 +819,20 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) Half beam should be one note-width, but let's make sure two half-beams never touch */ - Real w = here->relative_coordinate (0, X_AXIS) - prev->relative_coordinate (0, X_AXIS); + + // FIXME: TODO (check) stem width / sloped beams + Real w = here->relative_coordinate (0, X_AXIS) + - prev->relative_coordinate (0, X_AXIS); + Real stem_w = gh_scm2double (prev->get_grob_property ("thickness")) + // URG + * me->paper_l ()->get_var ("stafflinethickness"); + w = w/2 relative_coordinate (0, X_AXIS) - here->relative_coordinate (0, X_AXIS); - Molecule a = Lookup::beam (dydx, w + stemdx, thick); - a.translate_axis( - stemdx/2, X_AXIS); + Real w = next->relative_coordinate (0, X_AXIS) + - here->relative_coordinate (0, X_AXIS); + + Real stem_w = gh_scm2double (next->get_grob_property ("thickness")) + // URG + * me->paper_l ()->get_var ("stafflinethickness"); + + Molecule a = Lookup::beam (dydx, w + stem_w, thick); + a.translate_axis (- stem_w/2, X_AXIS); int j = 0; Real gap_f = 0; - + SCM gap = me->get_grob_property ("gap"); if (gh_number_p (gap)) { - int gap_i = gh_scm2int ( (gap)); + int gap_i = gh_scm2int ((gap)); int nogap = rwholebeams - gap_i; for (; j < nogap; j++) @@ -856,16 +872,24 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) b.translate_axis (-dir * bdy * j, Y_AXIS); rightbeams.add_molecule (b); } - // TODO: notehead widths differ for different types - gap_f = nw_f / 2; + if (Stem::invisible_b (here)) + gap_f = nw_f; + else + gap_f = nw_f / 2; w -= 2 * gap_f; - a = Lookup::beam (dydx, w + stemdx, thick); + a = Lookup::beam (dydx, w + stem_w, thick); } for (; j < rwholebeams; j++) { Molecule b (a); - b.translate (Offset (Stem::invisible_b (here) ? 0 : gap_f, -dir * bdy * j)); + Real tx = 0; + if (Stem::invisible_b (here)) + // ugh, see chord-tremolo.ly + tx = (-dir + 1) / 2 * nw_f * 1.5 + gap_f/4; + else + tx = gap_f; + b.translate (Offset (tx, -dir * bdy * j)); rightbeams.add_molecule (b); } @@ -890,7 +914,7 @@ Beam::stem_beams (Grob*me,Item *here, Item *next, Item *prev) return leftbeams; } -MAKE_SCHEME_CALLBACK(Beam,brew_molecule,1); +MAKE_SCHEME_CALLBACK (Beam,brew_molecule,1); SCM Beam::brew_molecule (SCM smob) { @@ -911,22 +935,30 @@ Beam::brew_molecule (SCM smob) else { x0 = stems[0]->relative_coordinate (0, X_AXIS); - dx = stems.top()->relative_coordinate (0, X_AXIS) - x0; + dx = stems.top ()->relative_coordinate (0, X_AXIS) - x0; } + + + /* + TODO: the naming of the grob properties sucks. + */ + SCM dy_s = me->get_grob_property ("dy"); + SCM y_s = me->get_grob_property ("y"); + - Real dy = gh_scm2double (me->get_grob_property ("dy")); + Real dy = gh_number_p (dy_s) ? gh_scm2double (dy_s) : 0.0; Real dydx = dy && dx ? dy/dx : 0; - Real y = gh_scm2double (me->get_grob_property ("y")); + Real y = gh_number_p (y_s) ? gh_scm2double (y_s) : 0.0; - for (int j=0; j 0)? stems[j-1] : 0; - Item * next = (j < stems.size()-1) ? stems[j+1] :0; + Item * next = (j < stems.size ()-1) ? stems[j+1] :0; - Molecule sb = stem_beams (me, i, next, prev); + Molecule sb = stem_beams (me, i, next, prev, dy, dydx); Real x = i->relative_coordinate (0, X_AXIS)-x0; sb.translate (Offset (x, x * dydx + y)); mol.add_molecule (sb); @@ -941,7 +973,7 @@ int Beam::forced_stem_count (Grob*me) { Link_arraystems = - Pointer_group_interface__extract_elements ( me, (Item*) 0, "stems"); + Pointer_group_interface__extract_elements (me, (Item*) 0, "stems"); int f = 0; for (int i=0; i < stems.size (); i++) { @@ -950,8 +982,8 @@ Beam::forced_stem_count (Grob*me) if (Stem::invisible_b (s)) continue; - if (((int)Stem::chord_start_f (s)) - && (Stem::get_direction (s ) != Stem::get_default_dir (s ))) + if (( (int)Stem::chord_start_f (s)) + && (Stem::get_direction (s) != Stem::get_default_dir (s))) f++; } return f; @@ -978,10 +1010,10 @@ Beam::visible_stem_count (Grob*me) } Item* -Beam::first_visible_stem(Grob*me) +Beam::first_visible_stem (Grob*me) { Link_arraystems = - Pointer_group_interface__extract_elements ( me, (Item*) 0, "stems"); + Pointer_group_interface__extract_elements (me, (Item*) 0, "stems"); for (int i = 0; i < stems.size (); i++) { @@ -992,10 +1024,10 @@ Beam::first_visible_stem(Grob*me) } Item* -Beam::last_visible_stem(Grob*me) +Beam::last_visible_stem (Grob*me) { Link_arraystems = - Pointer_group_interface__extract_elements ( me, (Item*) 0, "stems"); + Pointer_group_interface__extract_elements (me, (Item*) 0, "stems"); for (int i = stems.size (); i--;) { if (!Stem::invisible_b (stems[i])) @@ -1014,7 +1046,7 @@ Beam::last_visible_stem(Grob*me) rest -> stem -> beam -> interpolate_y_position () */ -MAKE_SCHEME_CALLBACK(Beam,rest_collision_callback,2); +MAKE_SCHEME_CALLBACK (Beam,rest_collision_callback,2); SCM Beam::rest_collision_callback (SCM element_smob, SCM axis) { @@ -1046,8 +1078,8 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) beam_y = gh_scm2double (s); // ugh -> use commonx - Real x0 = first_visible_stem(beam)->relative_coordinate (0, X_AXIS); - Real dx = last_visible_stem(beam)->relative_coordinate (0, X_AXIS) - x0; + Real x0 = first_visible_stem (beam)->relative_coordinate (0, X_AXIS); + Real dx = last_visible_stem (beam)->relative_coordinate (0, X_AXIS) - x0; Real dydx = beam_dy && dx ? beam_dy/dx : 0; Direction d = Stem::get_direction (stem); @@ -1072,7 +1104,7 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) if (discrete_dist < stafflines+1) discrete_dist = int (ceil (discrete_dist / 2.0)* 2.0); - return gh_double2scm (-d * discrete_dist); + return gh_double2scm (-d * discrete_dist); } @@ -1082,15 +1114,3 @@ Beam::has_interface (Grob*me) return me->has_interface (ly_symbol2scm ("beam-interface")); } -void -Beam::set_interface (Grob*me) -{ -#if 0 - /* - why the init? No way to tell difference between default and user - override. */ - me->set_grob_property ("y" ,gh_double2scm (0)); - me->set_grob_property ("dy", gh_double2scm (0)); - me->set_interface (ly_symbol2scm("beam-interface")); -#endif -}