X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fstem.cc;h=1f8b21e85f51fec72fa86c818b24417dcde43298;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=9ef07652e33bff3df8fc314e793fbed3a4e51c11;hpb=9cf485743fe1f5f6e2de3d2c5e070b67055edeb7;p=lilypond.git diff --git a/lily/stem.cc b/lily/stem.cc index 9ef07652e3..1f8b21e85f 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1996--2007 Han-Wen Nienhuys + (c) 1996--2008 Han-Wen Nienhuys Jan Nieuwenhuizen TODO: This is way too hairy @@ -240,22 +240,31 @@ Stem::pure_height (SCM smob, SCM start, SCM end) if (!is_normal_stem (me)) return ly_interval2scm (iv); - /* if we are part of a cross-staff beam, return empty */ - if (get_beam (me) && Beam::is_cross_staff (get_beam (me))) - return ly_interval2scm (iv); - Real ss = Staff_symbol_referencer::staff_space (me); - Real len = scm_to_double (calc_length (smob)) * ss / 2; - Direction dir = get_grob_direction (me); + Real rad = Staff_symbol_referencer::staff_radius (me); - Interval hp = head_positions (me); - if (dir == UP) - iv = Interval (0, len); - else - iv = Interval (-len, 0); + if (!to_boolean (me->get_property ("cross-staff"))) + { + Real len = scm_to_double (calc_length (smob)) * ss / 2; + Direction dir = get_grob_direction (me); - if (!hp.is_empty ()) - iv.translate (hp[dir] * ss / 2); + Interval hp = head_positions (me); + if (dir == UP) + iv = Interval (0, len); + else + iv = Interval (-len, 0); + + if (!hp.is_empty ()) + iv.translate (hp[dir] * ss / 2); + + /* extend the stem (away from the head) to cover the staff */ + if (dir == UP) + iv[UP] = max (iv[UP], rad * ss); + else + iv[DOWN] = min (iv[DOWN], -rad * ss); + } + else + iv = Interval (-rad * ss, rad * ss); return ly_interval2scm (iv); } @@ -285,8 +294,8 @@ Stem::calc_stem_end_position (SCM smob) Real stem_end = dir ? hp[dir] + dir * length : 0; /* TODO: change name to extend-stems to staff/center/'() */ - bool no_extend_b = to_boolean (me->get_property ("no-stem-extend")); - if (!no_extend_b && dir * stem_end < 0) + bool no_extend = to_boolean (me->get_property ("no-stem-extend")); + if (!no_extend && dir * stem_end < 0) stem_end = 0.0; return scm_from_double (stem_end); @@ -304,7 +313,7 @@ Stem::calc_length (SCM smob) Real ss = Staff_symbol_referencer::staff_space (me); Real length = 7; - SCM s = scm_cdr (scm_assq (ly_symbol2scm ("lengths"), details)); + SCM s = ly_assoc_get (ly_symbol2scm ("lengths"), details, SCM_EOL); if (scm_is_pair (s)) length = 2 * scm_to_double (robust_list_ref (durlog - 2, s)); @@ -315,7 +324,7 @@ Stem::calc_length (SCM smob) Interval hp = head_positions (me); if (dir && dir * hp[dir] >= 0) { - SCM sshorten = scm_cdr (scm_assq (ly_symbol2scm ("stem-shorten"), details)); + SCM sshorten = ly_assoc_get (ly_symbol2scm ("stem-shorten"), details, SCM_EOL); SCM scm_shorten = scm_is_pair (sshorten) ? robust_list_ref (max (duration_log (me) - 2, 0), sshorten) : SCM_EOL; Real shorten = 2* robust_scm2double (scm_shorten, 0); @@ -561,29 +570,25 @@ Stem::stem_end_position (Grob *me) return robust_scm2double (me->get_property ("stem-end-position"), 0); } -Stencil -Stem::flag (Grob *me) +MAKE_SCHEME_CALLBACK (Stem, calc_flag, 1); +SCM +Stem::calc_flag (SCM smob) { - int log = duration_log (me); - if (log < 3 - || unsmob_grob (me->get_object ("beam"))) - return Stencil (); + Grob *me = unsmob_grob (smob); - if (!is_normal_stem (me)) - return Stencil (); - + int log = duration_log (me); /* TODO: maybe property stroke-style should take different values, e.g. "" (i.e. no stroke), "single" and "double" (currently, it's '() or "grace"). */ string flag_style; - SCM flag_style_scm = me->get_property ("flag-style"); + SCM flag_style_scm = me->get_property ("flag-style"); if (scm_is_symbol (flag_style_scm)) flag_style = ly_symbol2string (flag_style_scm); if (flag_style == "no-flag") - return Stencil (); + return Stencil ().smobbed_copy (); bool adjust = true; @@ -598,14 +603,14 @@ Stem::flag (Grob *me) */ { if (adjust) - { - int p = (int) (rint (stem_end_position (me))); - staffline_offs - = Staff_symbol_referencer::on_line (me, p) ? "0" : "1"; - } + { + int p = (int) (rint (stem_end_position (me))); + staffline_offs + = Staff_symbol_referencer::on_line (me, p) ? "0" : "1"; + } else - staffline_offs = "2"; - } + staffline_offs = "2"; + } else staffline_offs = ""; @@ -622,17 +627,45 @@ Stem::flag (Grob *me) { string stroke_style = ly_scm2string (stroke_style_scm); if (!stroke_style.empty ()) - { - string font_char = to_string (dir) + stroke_style; - Stencil stroke = fm->find_by_name ("flags." + font_char); - if (stroke.is_empty ()) - me->warning (_f ("flag stroke `%s' not found", font_char)); - else - flag.add_stencil (stroke); - } - } + { + string font_char = flag_style + to_string (dir) + stroke_style; + Stencil stroke = fm->find_by_name ("flags." + font_char); + if (stroke.is_empty ()) + { + font_char = to_string (dir) + stroke_style; + stroke = fm->find_by_name ("flags." + font_char); + } + if (stroke.is_empty ()) + me->warning (_f ("flag stroke `%s' not found", font_char)); + else + flag.add_stencil (stroke); + } + } - return flag; + return flag.smobbed_copy (); +} + + +Stencil +Stem::flag (Grob *me) +{ + int log = duration_log (me); + if (log < 3 + || unsmob_grob (me->get_object ("beam"))) + return Stencil (); + + if (!is_normal_stem (me)) + return Stencil (); + + // This get_property call already evaluates the scheme function with + // the grob passed as argument! Thus, we only have to check if a valid + // stencil is returned. + SCM flag_style_scm = me->get_property ("flag"); + if (Stencil *flag = unsmob_stencil (flag_style_scm)) { + return *flag; + } else { + return Stencil (); + } } MAKE_SCHEME_CALLBACK (Stem, width, 1); @@ -693,6 +726,9 @@ Stem::print (SCM smob) if (!lh && stemlet && !beam) return SCM_EOL; + if (lh && robust_scm2int (lh->get_property ("duration-log"), 0) < 1) + return SCM_EOL; + if (is_invisible (me)) return SCM_EOL; @@ -856,7 +892,7 @@ Stem::calc_stem_info (SCM smob) /* Simple standard stem length */ SCM details = me->get_property ("details"); - SCM lengths = scm_cdr (scm_assq (ly_symbol2scm ("beamed-lengths"), details)); + SCM lengths = ly_assoc_get (ly_symbol2scm ("beamed-lengths"), details, SCM_EOL); Real ideal_length = scm_to_double (robust_list_ref (beam_count - 1, lengths)) @@ -868,7 +904,7 @@ Stem::calc_stem_info (SCM smob) - 0.5 * beam_thickness; /* Condition: sane minimum free stem length (chord to beams) */ - lengths = scm_cdr (scm_assq (ly_symbol2scm ("beamed-minimum-free-lengths"), details)); + lengths = ly_assoc_get (ly_symbol2scm ("beamed-minimum-free-lengths"), details, SCM_EOL); Real ideal_minimum_free = scm_to_double (robust_list_ref (beam_count - 1, lengths)) @@ -926,9 +962,9 @@ Stem::calc_stem_info (SCM smob) Obviously not for grace beams. Also, not for knees. Seems to be a good thing. */ - bool no_extend_b = to_boolean (me->get_property ("no-stem-extend")); + bool no_extend = to_boolean (me->get_property ("no-stem-extend")); bool is_knee = to_boolean (beam->get_property ("knee")); - if (!no_extend_b && !is_knee) + if (!no_extend && !is_knee) { /* Highest beam of (UP) beam must never be lower than middle staffline */ @@ -940,8 +976,8 @@ Stem::calc_stem_info (SCM smob) ideal_y -= robust_scm2double (beam->get_property ("shorten"), 0); - SCM bemfl = scm_cdr (scm_assq (ly_symbol2scm ("beamed-extreme-minimum-free-lengths"), - details)); + SCM bemfl = ly_assoc_get (ly_symbol2scm ("beamed-extreme-minimum-free-lengths"), + details, SCM_EOL); Real minimum_free = scm_to_double (robust_list_ref (beam_count - 1, bemfl)) @@ -987,27 +1023,30 @@ Stem::calc_cross_staff (SCM smob) /* FIXME: Too many properties */ ADD_INTERFACE (Stem, - "The stem represent the graphical stem. " - "In addition, it internally connects note heads, beams and" - "tremolos. " - "Rests and whole notes have invisible stems." - - "\n\nThe following properties may be set in the details list." + "The stem represents the graphical stem. In addition, it" + " internally connects note heads, beams, and tremolos. Rests" + " and whole notes have invisible stems.\n" + "\n" + "The following properties may be set in the @code{details}" + " list.\n" + "\n" "@table @code\n" - "@item beamed-lengths \n" - "list of stem lengths given beam multiplicity. \n" - "@item beamed-minimum-free-lengths \n" - "list of normal minimum free stem lengths (chord to beams) given beam multiplicity.\n" + "@item beamed-lengths\n" + "List of stem lengths given beam multiplicity.\n" + "@item beamed-minimum-free-lengths\n" + "List of normal minimum free stem lengths (chord to beams)" + " given beam multiplicity.\n" "@item beamed-extreme-minimum-free-lengths\n" - "list of extreme minimum free stem lengths (chord to beams) given beam multiplicity.\n" + "List of extreme minimum free stem lengths (chord to beams)" + " given beam multiplicity.\n" "@item lengths\n" - "Default stem lengths. The list gives a length for each flag-count.\n" + "Default stem lengths. The list gives a length for each" + " flag count.\n" "@item stem-shorten\n" - "How much a stem in a forced direction " - "should be shortened. The list gives an amount depending on the number " - "of flags/beams." - "@end table\n" - , + "How much a stem in a forced direction should be shortened." + " The list gives an amount depending on the number of flags" + " and beams.\n" + "@end table\n", /* properties */ "avoid-note-head " @@ -1017,6 +1056,7 @@ ADD_INTERFACE (Stem, "details " "direction " "duration-log " + "flag " "flag-style " "french-beaming " "length "