X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fstem.cc;h=e83ffd9893226a95672f70ebf284d7cd8d926733;hb=b430c32d29caa72a7ae3f679f1f62066c1ebfa95;hp=5b1a3d5041423e488e9cdc40eba25f4f7bf7a34a;hpb=9a7759a2afdfa3e0d5b88cf02576d8fcb7fcaab7;p=lilypond.git diff --git a/lily/stem.cc b/lily/stem.cc index 5b1a3d5041..e83ffd9893 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -27,7 +27,7 @@ #include "stem.hh" #include "spanner.hh" -#include // rint +#include // rint using namespace std; #include "beam.hh" @@ -65,7 +65,7 @@ Stem::set_beaming (Grob *me, int beam_count, Direction d) lst = scm_cons (scm_from_int (i), lst); else lst = SCM_BOOL_F; - + index_set_cell (pair, d, lst); } @@ -89,7 +89,7 @@ Stem::head_positions (Grob *me) { Drul_array e (extremal_heads (me)); return Interval (Staff_symbol_referencer::get_position (e[DOWN]), - Staff_symbol_referencer::get_position (e[UP])); + Staff_symbol_referencer::get_position (e[UP])); } return Interval (); } @@ -100,12 +100,10 @@ Stem::chord_start_y (Grob *me) Interval hp = head_positions (me); if (!hp.is_empty ()) return hp[get_grob_direction (me)] * Staff_symbol_referencer::staff_space (me) - * 0.5; + * 0.5; return 0; } - - void Stem::set_stemend (Grob *me, Real se) { @@ -180,13 +178,13 @@ Stem::extremal_heads (Grob *me) Direction d = LEFT; do - { - if (d * p > d * extpos[d]) - { - exthead[d] = n; - extpos[d] = p; - } - } + { + if (d * p > d * extpos[d]) + { + exthead[d] = n; + extpos[d] = p; + } + } while (flip (&d) != DOWN); } return exthead; @@ -226,23 +224,21 @@ bool Stem::is_invisible (Grob *me) { return !is_normal_stem (me) - && (robust_scm2double (me->get_property ("stemlet-length"), - 0.0) == 0.0); + && (robust_scm2double (me->get_property ("stemlet-length"), + 0.0) == 0.0); } - bool Stem::is_normal_stem (Grob *me) { return head_count (me) && scm_to_int (me->get_property ("duration-log")) >= 1; } - MAKE_SCHEME_CALLBACK (Stem, pure_height, 3) SCM Stem::pure_height (SCM smob, - SCM /* start */, - SCM /* end */) + SCM /* start */, + SCM /* end */) { Grob *me = unsmob_grob (smob); Interval iv; @@ -258,29 +254,29 @@ Stem::pure_height (SCM smob, Real len_in_halfspaces; SCM user_set_len_scm = me->get_property_data ("length"); if (scm_is_number (user_set_len_scm)) - len_in_halfspaces = scm_to_double (user_set_len_scm); + len_in_halfspaces = scm_to_double (user_set_len_scm); else - len_in_halfspaces = scm_to_double (calc_length (smob)); + len_in_halfspaces = scm_to_double (calc_length (smob)); Real len = len_in_halfspaces * ss / 2; Direction dir = get_grob_direction (me); Interval hp = head_positions (me); if (dir == UP) - iv = Interval (0, len); + iv = Interval (0, len); else - iv = Interval (-len, 0); + iv = Interval (-len, 0); if (!hp.is_empty ()) - { - iv.translate (hp[dir] * ss / 2); - iv.add_point (hp[-dir] * ss / 2); - } + { + iv.translate (hp[dir] * ss / 2); + iv.add_point (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); + iv[UP] = max (iv[UP], rad * ss); else - iv[DOWN] = min (iv[DOWN], -rad * ss); + iv[DOWN] = min (iv[DOWN], -rad * ss); } else iv = Interval (-rad * ss, rad * ss); @@ -302,7 +298,7 @@ Stem::calc_stem_end_position (SCM smob) (void) beam->get_property ("quantized-positions"); return me->get_property ("stem-end-position"); } - + vector a; /* WARNING: IN HALF SPACES */ @@ -326,7 +322,7 @@ SCM Stem::calc_length (SCM smob) { Grob *me = unsmob_grob (smob); - + SCM details = me->get_property ("details"); int durlog = duration_log (me); @@ -346,7 +342,7 @@ Stem::calc_length (SCM smob) { 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; + ? robust_list_ref (max (duration_log (me) - 2, 0), sshorten) : SCM_EOL; Real shorten_property = 2 * robust_scm2double (scm_shorten, 0); /* change in length between full-size and shortened stems is executed gradually. "transition area" = stems between full-sized and fully-shortened. @@ -364,7 +360,7 @@ Stem::calc_length (SCM smob) Shortening of flagged stems begins in the same moment as unflagged ones, but not earlier than on the middle line note. */ - Real which_step = (min (1.0, quarter_stem_length - (2 * staff_rad) - 2.0)) + abs(hp[dir]); + Real which_step = (min (1.0, quarter_stem_length - (2 * staff_rad) - 2.0)) + abs (hp[dir]); Real shorten = min (max (0.0, (shortening_step * which_step)), shorten_property); length -= shorten; @@ -382,7 +378,7 @@ Stem::calc_length (SCM smob) (Stem_tremolo::raw_stencil () looks at the beam.) --hwn */ Real minlen = 1.0 - + 2 * Stem_tremolo::vertical_length (t_flag) / ss; + + 2 * Stem_tremolo::vertical_length (t_flag) / ss; /* We don't want to add the whole extent of the flag because the trem and the flag can overlap partly. beam_translation gives a good @@ -401,7 +397,7 @@ Stem::calc_length (SCM smob) } length = max (length, minlen + 1.0); } - + return scm_from_double (length); } /* The log of the duration (Number of hooks on the flag minus two) */ @@ -416,14 +412,14 @@ MAKE_SCHEME_CALLBACK (Stem, calc_positioning_done, 1); SCM Stem::calc_positioning_done (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob_grob (smob); if (!head_count (me)) return SCM_BOOL_T; me->set_property ("positioning-done", SCM_BOOL_T); - + extract_grob_set (me, "note-heads", ro_heads); - vector heads (ro_heads); + vector heads (ro_heads); vector_sort (heads, position_less); Direction dir = get_grob_direction (me); @@ -442,8 +438,8 @@ Stem::calc_positioning_done (SCM smob) bool is_harmonic_centered = false; for (vsize i = 0; i < heads.size (); i++) - is_harmonic_centered = is_harmonic_centered - || heads[i]->get_property ("style") == ly_symbol2scm ("harmonic"); + is_harmonic_centered = is_harmonic_centered + || heads[i]->get_property ("style") == ly_symbol2scm ("harmonic"); is_harmonic_centered = is_harmonic_centered && is_invisible (me); Real w = hed->extent (hed, X_AXIS)[dir]; @@ -452,10 +448,10 @@ Stem::calc_positioning_done (SCM smob) Real amount = w - heads[i]->extent (heads[i], X_AXIS)[dir]; if (is_harmonic_centered) - amount = - hed->extent (hed, X_AXIS).linear_combination (CENTER) - - heads[i]->extent (heads[i], X_AXIS).linear_combination (CENTER); - + amount + = hed->extent (hed, X_AXIS).linear_combination (CENTER) + - heads[i]->extent (heads[i], X_AXIS).linear_combination (CENTER); + heads[i]->translate_axis (amount, X_AXIS); } bool parity = true; @@ -463,54 +459,54 @@ Stem::calc_positioning_done (SCM smob) for (vsize i = 1; i < heads.size (); i++) { Real p = Staff_symbol_referencer::get_position (heads[i]); - Real dy = fabs (lastpos- p); + Real dy = fabs (lastpos - p); /* - dy should always be 0.5, 0.0, 1.0, but provide safety margin - for rounding errors. + dy should always be 0.5, 0.0, 1.0, but provide safety margin + for rounding errors. */ if (dy < 1.1) - { - if (parity) - { - Real ell = heads[i]->extent (heads[i], X_AXIS).length (); + { + if (parity) + { + Real ell = heads[i]->extent (heads[i], X_AXIS).length (); - Direction d = get_grob_direction (me); - /* - Reversed head should be shifted ell-thickness, but this - looks too crowded, so we only shift ell-0.5*thickness. + Direction d = get_grob_direction (me); + /* + Reversed head should be shifted ell-thickness, but this + looks too crowded, so we only shift ell-0.5*thickness. - This leads to assymetry: Normal heads overlap the - stem 100% whereas reversed heads only overlaps the - stem 50% - */ + This leads to assymetry: Normal heads overlap the + stem 100% whereas reversed heads only overlaps the + stem 50% + */ - Real reverse_overlap = 0.5; - heads[i]->translate_axis ((ell - thick * reverse_overlap) * d, - X_AXIS); + Real reverse_overlap = 0.5; + heads[i]->translate_axis ((ell - thick * reverse_overlap) * d, + X_AXIS); - if (is_invisible (me)) - heads[i]->translate_axis (-thick * (2 - reverse_overlap) * d, - X_AXIS); + if (is_invisible (me)) + heads[i]->translate_axis (-thick * (2 - reverse_overlap) * d, + X_AXIS); - /* TODO: + /* TODO: - For some cases we should kern some more: when the - distance between the next or prev note is too large, we'd - get large white gaps, eg. + For some cases we should kern some more: when the + distance between the next or prev note is too large, we'd + get large white gaps, eg. - | + | X| - |X <- kern this. - | - X - - */ - } - parity = !parity; - } + |X <- kern this. + | + X + + */ + } + parity = !parity; + } else - parity = true; + parity = true; lastpos = int (p); } @@ -535,9 +531,9 @@ Stem::calc_direction (SCM smob) SCM dd = me->get_property ("default-direction"); dir = to_dir (dd); if (!dir) - return me->get_property ("neutral-direction"); + return me->get_property ("neutral-direction"); } - + return scm_from_int (dir); } @@ -554,14 +550,13 @@ Stem::calc_default_direction (SCM smob) { int udistance = (int) (UP * hp[UP] - staff_center); int ddistance = (int) (DOWN * hp[DOWN] - staff_center); - + dir = Direction (sign (ddistance - udistance)); } - + return scm_from_int (dir); } - MAKE_SCHEME_CALLBACK (Stem, height, 1); SCM Stem::height (SCM smob) @@ -569,9 +564,9 @@ Stem::height (SCM smob) Grob *me = unsmob_grob (smob); if (!is_normal_stem (me)) return ly_interval2scm (Interval ()); - + Direction dir = get_grob_direction (me); - + Grob *beam = get_beam (me); if (beam) { @@ -588,10 +583,10 @@ Stem::height (SCM smob) if (beam) { if (dir == CENTER) - { - programming_error ("no stem direction"); - dir = UP; - } + { + programming_error ("no stem direction"); + dir = UP; + } iv[dir] += dir * Beam::get_beam_thickness (beam) * 0.5; } @@ -617,7 +612,7 @@ Stem::calc_flag (SCM smob) '() 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); @@ -644,13 +639,13 @@ Stem::calc_flag (SCM smob) } else staffline_offs = "2"; - } + } else staffline_offs = ""; char dir = (get_grob_direction (me) == UP) ? 'u' : 'd'; string font_char = flag_style - + to_string (dir) + staffline_offs + to_string (log); + + to_string (dir) + staffline_offs + to_string (log); Font_metric *fm = Font_interface::get_default_font (me); Stencil flag = fm->find_by_name ("flags." + font_char); if (flag.is_empty ()) @@ -674,12 +669,11 @@ Stem::calc_flag (SCM smob) else flag.add_stencil (stroke); } - } + } return flag.smobbed_copy (); } - Stencil Stem::flag (Grob *me) { @@ -695,11 +689,14 @@ Stem::flag (Grob *me) // 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 (); - } + if (Stencil *flag = unsmob_stencil (flag_style_scm)) + { + return *flag; + } + else + { + return Stencil (); + } } MAKE_SCHEME_CALLBACK (Stem, width, 1); @@ -713,7 +710,7 @@ Stem::width (SCM e) if (is_invisible (me)) r.set_empty (); else if (unsmob_grob (me->get_object ("beam")) - || abs (duration_log (me)) <= 2) + || abs (duration_log (me)) <= 2) { r = Interval (-1, 1); r *= thickness (me) / 2; @@ -730,7 +727,7 @@ Real Stem::thickness (Grob *me) { return scm_to_double (me->get_property ("thickness")) - * Staff_symbol_referencer::line_thickness (me); + * Staff_symbol_referencer::line_thickness (me); } MAKE_SCHEME_CALLBACK (Stem, calc_stem_begin_position, 1); @@ -742,8 +739,8 @@ Stem::calc_stem_begin_position (SCM smob) Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; Grob *lh = to_boolean (me->get_property ("avoid-note-head")) - ? last_head (me) - : first_head (me); + ? last_head (me) + : first_head (me); Real pos = Staff_symbol_referencer::get_position (lh); @@ -765,20 +762,20 @@ Stem::print (SCM smob) { Grob *me = unsmob_grob (smob); Grob *beam = get_beam (me); - + Stencil mol; Direction d = get_grob_direction (me); Real stemlet_length = robust_scm2double (me->get_property ("stemlet-length"), - 0.0); + 0.0); bool stemlet = stemlet_length > 0.0; /* TODO: make the stem start a direction ? This is required to avoid stems passing in tablature chords. */ Grob *lh = to_boolean (me->get_property ("avoid-note-head")) - ? last_head (me) - : first_head (me); + ? last_head (me) + : first_head (me); if (!lh && !stemlet) return SCM_EOL; @@ -786,7 +783,7 @@ Stem::print (SCM smob) if (!lh && stemlet && !beam) return SCM_EOL; - if (lh && robust_scm2int (lh->get_property ("duration-log"), 0) < 1) + if (lh && robust_scm2int (lh->get_property ("duration-log"), 0) < 1) return SCM_EOL; if (is_invisible (me)) @@ -805,9 +802,9 @@ Stem::print (SCM smob) int beam_count = beam_multiplicity (me).length () + 1; y2 -= d - * (0.5 * beam_thickness - + beam_translation * max (0, (beam_count - 1)) - + stemlet_length) / half_space; + * (0.5 * beam_thickness + + beam_translation * max (0, (beam_count - 1)) + + stemlet_length) / half_space; } Interval stem_y (min (y1, y2), max (y2, y1)); @@ -818,7 +815,7 @@ Stem::print (SCM smob) = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); Box b = Box (Interval (-stem_width / 2, stem_width / 2), - Interval (stem_y[DOWN] * half_space, stem_y[UP] * half_space)); + Interval (stem_y[DOWN] * half_space, stem_y[UP] * half_space)); Stencil ss = Lookup::round_filled_box (b, blot); mol.add_stencil (ss); @@ -836,7 +833,7 @@ Stem::get_translated_flag (Grob *me) { Direction d = get_grob_direction (me); Real blot - = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); + = me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter")); Real stem_width = thickness (me); Real half_space = Staff_symbol_referencer::staff_space (me) * 0.5; Real y2 = robust_scm2double (me->get_property ("stem-end-position"), 0.0); @@ -846,7 +843,6 @@ Stem::get_translated_flag (Grob *me) return fl; } - /* move the stem to right of the notehead if it is up. */ @@ -864,16 +860,15 @@ Stem::offset_callback (SCM smob) return scm_from_double (r); } - if (Grob *f = first_head (me)) { Interval head_wid = f->extent (f, X_AXIS); Real attach = 0.0; if (is_invisible (me)) - attach = 0.0; + attach = 0.0; else - attach = Note_head::stem_attachment_coordinate (f, X_AXIS); + attach = Note_head::stem_attachment_coordinate (f, X_AXIS); Direction d = get_grob_direction (me); Real real_attach = head_wid.linear_combination (d * attach); @@ -881,10 +876,10 @@ Stem::offset_callback (SCM smob) /* If not centered: correct for stem thickness. */ if (attach) - { - Real rule_thick = thickness (me); - r += -d * rule_thick * 0.5; - } + { + Real rule_thick = thickness (me); + r += -d * rule_thick * 0.5; + } return scm_from_double (r); } @@ -904,7 +899,7 @@ Stem::get_stem_info (Grob *me) { Stem_info si; si.dir_ = get_grob_direction (me); - + SCM scm_info = me->get_property ("stem-info"); si.ideal_y_ = scm_to_double (scm_car (scm_info)); si.shortest_y_ = scm_to_double (scm_cadr (scm_info)); @@ -931,7 +926,7 @@ Stem::calc_stem_info (SCM smob) { (void) beam->get_property ("beaming"); } - + Real beam_translation = Beam::get_beam_translation (beam); Real beam_thickness = Beam::get_beam_thickness (beam); int beam_count = Beam::get_direction_beam_count (beam, my_dir); @@ -941,27 +936,27 @@ Stem::calc_stem_info (SCM smob) /* Simple standard stem length */ SCM details = me->get_property ("details"); SCM lengths = ly_assoc_get (ly_symbol2scm ("beamed-lengths"), details, SCM_EOL); - + Real ideal_length = (scm_is_pair (lengths) ? (scm_to_double (robust_list_ref (beam_count - 1, lengths)) - * staff_space - * length_fraction - /* - stem only extends to center of beam - */ - - 0.5 * beam_thickness) + * staff_space + * length_fraction + /* + stem only extends to center of beam + */ + - 0.5 * beam_thickness) : 0.0); /* Condition: sane minimum free stem length (chord to beams) */ lengths = ly_assoc_get (ly_symbol2scm ("beamed-minimum-free-lengths"), - details, SCM_EOL); + details, SCM_EOL); Real ideal_minimum_free = (scm_is_pair (lengths) ? (scm_to_double (robust_list_ref (beam_count - 1, lengths)) - * staff_space - * length_fraction) + * staff_space + * length_fraction) : 0.0); Real height_of_my_trem = 0.0; @@ -969,12 +964,11 @@ Stem::calc_stem_info (SCM smob) if (trem) { height_of_my_trem - = Stem_tremolo::vertical_length (trem) - /* hack a bit of space around the trem. */ - + beam_translation; + = Stem_tremolo::vertical_length (trem) + /* hack a bit of space around the trem. */ + + beam_translation; } - /* UGH It seems that also for ideal minimum length, we must use the maximum beam count (for this direction): @@ -983,21 +977,21 @@ Stem::calc_stem_info (SCM smob) must be horizontal. */ Real height_of_my_beams = beam_thickness - + (beam_count - 1) * beam_translation; + + (beam_count - 1) * beam_translation; Real ideal_minimum_length = ideal_minimum_free - + height_of_my_beams - + height_of_my_trem - /* stem only extends to center of beam */ - - 0.5 * beam_thickness; + + height_of_my_beams + + height_of_my_trem + /* stem only extends to center of beam */ + - 0.5 * beam_thickness; ideal_length = max (ideal_length, ideal_minimum_length); /* Convert to Y position, calculate for dir == UP */ Real note_start = /* staff positions */ - head_positions (me)[my_dir] * 0.5 - * my_dir * staff_space; + head_positions (me)[my_dir] * 0.5 + * my_dir * staff_space; Real ideal_y = note_start + ideal_length; /* Conditions for Y position */ @@ -1020,36 +1014,36 @@ Stem::calc_stem_info (SCM smob) if (!no_extend && !is_knee) { /* Highest beam of (UP) beam must never be lower than middle - staffline */ + staffline */ ideal_y = max (ideal_y, 0.0); /* Lowest beam of (UP) beam must never be lower than second staffline */ ideal_y = max (ideal_y, (-staff_space - - beam_thickness + height_of_my_beams)); + - beam_thickness + height_of_my_beams)); } ideal_y -= robust_scm2double (beam->get_property ("shorten"), 0); SCM bemfl = ly_assoc_get (ly_symbol2scm ("beamed-extreme-minimum-free-lengths"), - details, SCM_EOL); - + details, SCM_EOL); + Real minimum_free = (scm_is_pair (bemfl) ? (scm_to_double (robust_list_ref (beam_count - 1, bemfl)) - * staff_space - * length_fraction) + * staff_space + * length_fraction) : 0.0); Real minimum_length = max (minimum_free, height_of_my_trem) - + height_of_my_beams - /* stem only extends to center of beam */ - - 0.5 * beam_thickness; + + height_of_my_beams + /* stem only extends to center of beam */ + - 0.5 * beam_thickness; ideal_y *= my_dir; Real minimum_y = note_start + minimum_length; Real shortest_y = minimum_y * my_dir; return scm_list_2 (scm_from_double (ideal_y), - scm_from_double (shortest_y)); + scm_from_double (shortest_y)); } Slice @@ -1078,60 +1072,60 @@ Stem::calc_cross_staff (SCM smob) /* FIXME: Too many properties */ ADD_INTERFACE (Stem, - "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-extreme-minimum-free-lengths\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" - "@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" - " and beams.\n" - "@end table\n", - - /* properties */ - "avoid-note-head " - "beam " - "beaming " - "beamlet-default-length " - "beamlet-max-length-proportion " - "default-direction " - "details " - "direction " - "duration-log " - "flag " - "flag-style " - "french-beaming " - "length " - "length-fraction " - "max-beam-connect " - "neutral-direction " - "no-stem-extend " - "note-heads " - "positioning-done " - "rests " - "stem-begin-position " - "stem-end-position " - "stem-info " - "stemlet-length " - "stroke-style " - "thickness " - "tremolo-flag " - ); + "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-extreme-minimum-free-lengths\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" + "@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" + " and beams.\n" + "@end table\n", + + /* properties */ + "avoid-note-head " + "beam " + "beaming " + "beamlet-default-length " + "beamlet-max-length-proportion " + "default-direction " + "details " + "direction " + "duration-log " + "flag " + "flag-style " + "french-beaming " + "length " + "length-fraction " + "max-beam-connect " + "neutral-direction " + "no-stem-extend " + "note-heads " + "positioning-done " + "rests " + "stem-begin-position " + "stem-end-position " + "stem-info " + "stemlet-length " + "stroke-style " + "thickness " + "tremolo-flag " + ); /****************************************************************/