X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fline-spanner.cc;h=a1fe664c16275205e973c1eeb82f1987456dccbe;hb=05b3ddf4bb419c41da16b4be853d823ee0d3a0ec;hp=fad5b352513cb5f3d71048f3af2c2525caa5f1b6;hpb=d7be2ca7f331d94c9525bb0658f7e767c5e39230;p=lilypond.git diff --git a/lily/line-spanner.cc b/lily/line-spanner.cc index fad5b35251..f42628820e 100644 --- a/lily/line-spanner.cc +++ b/lily/line-spanner.cc @@ -1,303 +1,395 @@ /* - line-spanner.cc -- implement Line_spanner + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2000--2012 Jan Nieuwenhuizen - (c) 2000--2002 Jan Nieuwenhuizen + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ -#include "molecule.hh" +#include "align-interface.hh" +#include "axis-group-interface.hh" +#include "font-interface.hh" +#include "grob-interface.hh" +#include "international.hh" #include "item.hh" -#include "spanner.hh" -#include "line-spanner.hh" -#include "paper-def.hh" +#include "lily-proto.hh" +#include "line-interface.hh" +#include "note-column.hh" +#include "output-def.hh" #include "paper-column.hh" +#include "pointer-group-interface.hh" +#include "spanner.hh" #include "staff-symbol-referencer.hh" -#include "font-interface.hh" - -#include - - -/* - slightishly clumsy interface? - - Make a Scheme expression for a line going from (0,0) to (dx,dy). - */ +#include "system.hh" +#include "text-interface.hh" +#include "warn.hh" -static SCM -line_atom (Grob* me, Real thick, Real dx, Real dy) +class Line_spanner +{ +public: + DECLARE_SCHEME_CALLBACK (print, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_left_bound_info, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_left_bound_info_and_text, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_right_bound_info, (SCM)); + DECLARE_SCHEME_CALLBACK (calc_bound_info, (SCM, Direction)); + DECLARE_GROB_INTERFACE (); +}; + +Spanner *parent_spanner (Grob *g) { - SCM type = me->get_grob_property ("type"); - Real staff_space = Staff_symbol_referencer::staff_space (me); - - // maybe these should be in line-thickness? - Real length = staff_space; - SCM s = me->get_grob_property ("dash-length"); - if (gh_number_p (s)) - length = gh_scm2double (s) * staff_space; - - Real period = 2 * length + thick; - s = me->get_grob_property ("dash-period"); - if (gh_number_p (s)) - period = gh_scm2double (s) * staff_space; - - if (type == ly_symbol2scm ("dotted-line")) - length = thick; - - if (type == ly_symbol2scm ("line")) - length = period + thick; - - Real on = length - thick; - Real off = period - on; - - SCM list = scm_list_n (ly_symbol2scm ("dashed-line"), - gh_double2scm (thick), - gh_double2scm (on), - gh_double2scm (off), - gh_double2scm (dx), - gh_double2scm (dy), - SCM_UNDEFINED); - - return list; + if (Spanner::has_interface (g)) + return dynamic_cast (g); + return parent_spanner (g->get_parent (Y_AXIS)); } -static SCM -zigzag_atom (Grob* me, Real thick, Real dx, Real dy) +SCM +Line_spanner::calc_bound_info (SCM smob, Direction dir) { - Real staff_space = Staff_symbol_referencer::staff_space (me); - SCM ws = me->get_grob_property ("zigzag-width"); - SCM ls = me->get_grob_property ("zigzag-length"); - double w = (gh_number_p(ws) ? gh_scm2double(ws) : 1)*staff_space; - double l = (gh_number_p(ls) ? gh_scm2double(ls) : 1)*w; - double h = l>w/2 ? sqrt(l*l-w*w/4) : 0; - - SCM list = scm_list_n (ly_symbol2scm ("zigzag-line"), - gh_bool2scm (true), - gh_double2scm (w), - gh_double2scm (h), - gh_double2scm (thick), - gh_double2scm (dx), - gh_double2scm (dy), - SCM_UNDEFINED); - - return list; -} + Spanner *me = unsmob_spanner (smob); + Grob *commonx = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS); + commonx = me->common_refpoint (commonx, X_AXIS); + SCM bound_details = me->get_property ("bound-details"); -Molecule -Line_spanner::line_molecule (Grob* me, Real thick, Real dx, Real dy) -{ - Molecule mol; - SCM type = me->get_grob_property ("type"); - if (gh_symbol_p (type) - && (type == ly_symbol2scm ("line") - || type == ly_symbol2scm ("dashed-line") - || type == ly_symbol2scm ("dotted-line") - || (type == ly_symbol2scm ("trill") && dy != 0))) + SCM details = SCM_BOOL_F; + if (details == SCM_BOOL_F) + details = ly_assoc_get ((dir == LEFT) + ? ly_symbol2scm ("left") + : ly_symbol2scm ("right"), bound_details, SCM_BOOL_F); + + if (me->get_bound (dir)->break_status_dir ()) { - Box b (Interval (-0.5* thick + (0 ? dx)), - Interval (- 0.5* thick + (0? dy))); - mol = Molecule (b, line_atom (me, thick, dx, dy)); + SCM extra = ly_assoc_get ((dir == LEFT) + ? ly_symbol2scm ("left-broken") + : ly_symbol2scm ("right-broken"), bound_details, SCM_EOL); + + details = scm_append (scm_list_2 (extra, details)); } - else if (gh_symbol_p (type) - && type == ly_symbol2scm ("zigzag")) + + if (details == SCM_BOOL_F) + details = ly_assoc_get (ly_symbol2scm ("default"), bound_details, SCM_EOL); + + SCM text = ly_assoc_get (ly_symbol2scm ("text"), details, SCM_BOOL_F); + if (Text_interface::is_markup (text)) { - // TODO: - Box b (Interval (-0.5* thick + (0 ? dx)), - Interval (- 0.5* thick + (0? dy))); - mol = Molecule (b, zigzag_atom (me, thick, dx, dy)); + Output_def *layout = me->layout (); + SCM properties = Font_interface::text_font_alist_chain (me); + details = scm_acons (ly_symbol2scm ("stencil"), + Text_interface::interpret_markup (layout->self_scm (), + properties, text), + details); + } + if (!scm_is_number (ly_assoc_get (ly_symbol2scm ("X"), details, SCM_BOOL_F))) + { + Direction attach = (Direction) + robust_scm2int (ly_assoc_get (ly_symbol2scm ("attach-dir"), + details, SCM_BOOL_F), + CENTER); + + Item *bound_item = me->get_bound (dir); + Grob *bound_grob = bound_item; + if (to_boolean (ly_assoc_get (ly_symbol2scm ("end-on-note"), details, SCM_BOOL_F)) + && bound_item->break_status_dir ()) + { + extract_grob_set (me, "note-columns", columns); + if (columns.size ()) + bound_grob = (dir == LEFT) + ? columns[0] : columns.back (); + } + + Real x_coord = (Paper_column::has_interface (bound_grob) + ? Axis_group_interface::generic_bound_extent (bound_grob, commonx, X_AXIS) + : robust_relative_extent (bound_grob, commonx, X_AXIS)).linear_combination (attach); + + Grob *acc = Note_column::accidentals (bound_grob->get_parent (X_AXIS)); + if (acc && to_boolean (ly_assoc_get (ly_symbol2scm ("end-on-accidental"), details, SCM_BOOL_F))) + x_coord = robust_relative_extent (acc, commonx, X_AXIS).linear_combination (attach); + + details = scm_acons (ly_symbol2scm ("X"), + scm_from_double (x_coord), + details); } - else if (gh_symbol_p (type) - && type == ly_symbol2scm ("trill")) + + if (!scm_is_number (ly_assoc_get (ly_symbol2scm ("Y"), details, SCM_BOOL_F))) { - SCM alist_chain = Font_interface::font_alist_chain (me); - SCM style_chain = scm_list_n (gh_cons (ly_symbol2scm ("font-family"), - ly_symbol2scm ("music")), - SCM_UNDEFINED); - - Font_metric *fm = Font_interface::get_font (me, - scm_list_n (style_chain, - alist_chain, - SCM_UNDEFINED)); - Molecule m = fm->find_by_name ("scripts-trill-element"); - do - mol.add_at_edge (X_AXIS, RIGHT, m, 0,0); - while (m.extent (X_AXIS).length () - && mol.extent (X_AXIS).length () - + m.extent (X_AXIS).length () < dx); - - /* - FIXME: should center element on x/y - */ - mol.translate_axis (m.extent (X_AXIS).length () / 2, X_AXIS); - mol.translate_axis (-(mol.extent (Y_AXIS)[DOWN] - + mol.extent (Y_AXIS).length ())/2, Y_AXIS); + Real y = 0.0; + + Real extra_dy = robust_scm2double (me->get_property ("extra-dy"), + 0.0); + + Grob *common_y = me->common_refpoint (me->get_bound (dir), Y_AXIS); + if (me->get_bound (dir)->break_status_dir ()) + { + if (to_boolean (me->get_property ("simple-Y"))) + { + Spanner *orig = dynamic_cast(me->original ()); + Spanner *extreme = dir == LEFT ? orig->broken_intos_.front () : orig->broken_intos_.back (); + Grob *e_bound = extreme->get_bound (dir); + Grob *e_common_y = extreme->common_refpoint (e_bound, Y_AXIS); + y = e_bound->extent (e_common_y, Y_AXIS).center (); + } + else + { + Spanner *next_sp = me->broken_neighbor (dir); + Item *next_bound = next_sp->get_bound (dir); + + if (next_bound->break_status_dir ()) + { + programming_error ("no note heads for the line spanner on neighbor line?" + " Confused."); + me->suicide (); + return SCM_EOL; + } + + Spanner *next_bound_parent = parent_spanner (next_bound); + Interval next_ext = next_bound->extent (next_bound_parent, Y_AXIS); + + /* + We want to know what would be the y-position of the next + bound (relative to my y-parent) if it belonged to the + same system as this bound. We rely on the fact that the + y-parent of the next bound is a spanner (probably the + VerticalAxisGroup of a staff) that extends over the break. + */ + Spanner *next_bound_parent_on_this_line + = next_bound_parent->broken_neighbor (other_dir (dir)); + + if (next_bound_parent_on_this_line) + { + Grob *common = me->common_refpoint (next_bound_parent_on_this_line, Y_AXIS); + Real bound_offset = next_bound_parent_on_this_line->relative_coordinate (common, Y_AXIS); + y = next_ext.center () + bound_offset - me->relative_coordinate (common, Y_AXIS); + } + else + { + /* + We fall back to assuming that the distance between + staves doesn't change over line breaks. + */ + programming_error ("next-bound's parent doesn't extend to this line"); + Grob *next_system = next_bound->get_system (); + Grob *this_system = me->get_system (); + y = next_ext.center () + next_bound_parent->relative_coordinate (next_system, Y_AXIS) + - me->relative_coordinate (this_system, Y_AXIS); + } + } + } + else + { + y = me->get_bound (dir)->extent (common_y, Y_AXIS).center (); + details = scm_acons (ly_symbol2scm ("common-Y"), common_y->self_scm (), details); + } + + y += dir * extra_dy / 2; + details = scm_acons (ly_symbol2scm ("Y"), scm_from_double (y), details); } - return mol; + + return details; +} + +MAKE_SCHEME_CALLBACK (Line_spanner, calc_cross_staff, 1); +SCM +Line_spanner::calc_cross_staff (SCM smob) +{ + Spanner *me = unsmob_spanner (smob); + if (!me) + return SCM_BOOL_F; + + if (to_boolean (me->get_bound (LEFT)->get_property ("non-musical")) + || to_boolean (me->get_bound (RIGHT)->get_property ("non-musical"))) + return SCM_BOOL_F; + + return scm_from_bool (Staff_symbol_referencer::get_staff_symbol (me->get_bound (LEFT)) + != Staff_symbol_referencer::get_staff_symbol (me->get_bound (RIGHT))); } -Offset -Line_spanner::get_broken_offset (Grob *me, Direction dir) +MAKE_SCHEME_CALLBACK (Line_spanner, calc_right_bound_info, 1); +SCM +Line_spanner::calc_right_bound_info (SCM smob) { - Spanner *spanner = dynamic_cast (me); - Item* bound = spanner->get_bound (dir); - - if (!bound->break_status_dir ()) + return Line_spanner::calc_bound_info (smob, RIGHT); +} + +MAKE_SCHEME_CALLBACK (Line_spanner, calc_left_bound_info, 1); +SCM +Line_spanner::calc_left_bound_info (SCM smob) +{ + return Line_spanner::calc_bound_info (smob, LEFT); +} + +MAKE_SCHEME_CALLBACK (Line_spanner, calc_left_bound_info_and_text, 1); +SCM +Line_spanner::calc_left_bound_info_and_text (SCM smob) +{ + SCM alist = Line_spanner::calc_bound_info (smob, LEFT); + Spanner *me = unsmob_spanner (smob); + + SCM text = me->get_property ("text"); + if (Text_interface::is_markup (text) + && me->get_bound (LEFT)->break_status_dir () == CENTER + && ly_assoc_get (ly_symbol2scm ("stencil"), alist, SCM_BOOL_F) == SCM_BOOL_F) { - Grob *common[] = { - bound->common_refpoint (Staff_symbol_referencer::get_staff_symbol (me), - X_AXIS), - bound->common_refpoint (Staff_symbol_referencer::get_staff_symbol (me), - Y_AXIS) - }; - - return Offset (abs (bound->extent (common[X_AXIS], X_AXIS)[-dir]), - bound->extent (common[Y_AXIS], Y_AXIS).center ()); + Output_def *layout = me->layout (); + SCM properties = Font_interface::text_font_alist_chain (me); + alist = scm_acons (ly_symbol2scm ("stencil"), + Text_interface::interpret_markup (layout->self_scm (), + properties, text), + alist); } - return Offset (); + + return alist; } -Offset -Line_spanner::broken_trend_offset (Grob *me, Direction dir) +MAKE_SCHEME_CALLBACK (Line_spanner, print, 1); +SCM +Line_spanner::print (SCM smob) { - /* A broken line-spaner should maintain the same vertical trend - the unbroken line-spanner would have had. - From slur */ - Offset o; - if (Spanner *mother = dynamic_cast (me->original_)) + Spanner *me = dynamic_cast (unsmob_grob (smob)); + + // Triggers simple-Y calculations + bool simple_y = to_boolean (me->get_property ("simple-Y")) && !to_boolean (me->get_property ("cross-staff")); + + Drul_array bounds (me->get_property ("left-bound-info"), + me->get_property ("right-bound-info")); + + Grob *commonx = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS); + commonx = me->common_refpoint (commonx, X_AXIS); + + Drul_array span_points; + + for (LEFT_and_RIGHT (d)) { - for (int i = dir == LEFT ? 0 : mother->broken_intos_.size () - 1; - dir == LEFT ? i < mother->broken_intos_.size () : i > 0; - dir == LEFT ? i++ : i--) - { - if (mother->broken_intos_[i - dir] == me) - { - Grob *neighbour = mother->broken_intos_[i]; - Offset neighbour_o = get_broken_offset (neighbour, dir); - Offset me_o = get_broken_offset (me, -dir); - // Hmm, why not return me_o[X], but recalc in brew_mol? - o = Offset (0, - (neighbour_o[Y_AXIS]*me_o[X_AXIS] - - me_o[Y_AXIS]*neighbour_o[X_AXIS]) * dir / - (me_o[X_AXIS] + neighbour_o[X_AXIS])); - break; - } - } + Offset z (robust_scm2double (ly_assoc_get (ly_symbol2scm ("X"), + bounds[d], SCM_BOOL_F), 0.0), + robust_scm2double (ly_assoc_get (ly_symbol2scm ("Y"), + bounds[d], SCM_BOOL_F), 0.0)); + + span_points[d] = z; } - return o; -} + Drul_array gaps (0, 0); + Drul_array arrows (0, 0); + Drul_array stencils (0, 0); + Drul_array common_y (0, 0); -/* - Warning: this thing is a cross-staff object, so it should have empty Y-dimensions. + // For scaling of 'padding and 'stencil-offset + Real magstep + = pow (2, robust_scm2double (me->get_property ("font-size"), 0.0) / 6); - (If not, you risk that this is called from the staff-alignment - routine, via molecule_extent. At this point, the staves aren't - separated yet, so it doesn't work cross-staff. + for (LEFT_and_RIGHT (d)) + { + gaps[d] = robust_scm2double (ly_assoc_get (ly_symbol2scm ("padding"), + bounds[d], SCM_BOOL_F), 0.0); + arrows[d] = to_boolean (ly_assoc_get (ly_symbol2scm ("arrow"), + bounds[d], SCM_BOOL_F)); + stencils[d] = unsmob_stencil (ly_assoc_get (ly_symbol2scm ("stencil"), + bounds[d], SCM_BOOL_F)); + common_y[d] = unsmob_grob (ly_assoc_get (ly_symbol2scm ("common-Y"), + bounds[d], SCM_BOOL_F)); + if (!common_y[d]) + common_y[d] = me; + } -*/ + Grob *my_common_y = common_y[LEFT]->common_refpoint (common_y[RIGHT], Y_AXIS); -MAKE_SCHEME_CALLBACK (Line_spanner, brew_molecule, 1); -SCM -Line_spanner::brew_molecule (SCM smob) -{ - Grob *me= unsmob_grob (smob); - - Spanner *spanner = dynamic_cast (me); - Item* bound_drul[] = { - spanner->get_bound (LEFT), - 0, - spanner->get_bound (RIGHT) - }; - - Item** bound = bound_drul + 1; - - Grob *common[] = { 0, 0 }; - for (Axis a = X_AXIS; a < NO_AXES; a = Axis (a + 1)) + if (!simple_y) { - common[a] = bound[LEFT]->common_refpoint (bound[RIGHT], a); - - if (!common[a]) - return SCM_EOL; + for (LEFT_and_RIGHT (d)) + span_points[d][Y_AXIS] += common_y[d]->relative_coordinate (my_common_y, Y_AXIS); } - - Real gap = gh_scm2double (me->get_grob_property ("gap")); - Real dist; /*distance between points */ - - Offset ofxy (gap, 0); /*offset from start point to start of line*/ - Offset dxy ; - Offset my_off; - Offset his_off; - - - if (bound[LEFT]->break_status_dir () || bound[RIGHT]->break_status_dir ()) - /* across line break */ + + Interval normalized_endpoints = robust_scm2interval (me->get_property ("normalized-endpoints"), Interval (0, 1)); + Real y_length = span_points[RIGHT][Y_AXIS] - span_points[LEFT][Y_AXIS]; + + span_points[LEFT][Y_AXIS] += normalized_endpoints[LEFT] * y_length; + span_points[RIGHT][Y_AXIS] -= (1 - normalized_endpoints[RIGHT]) * y_length; + + Offset dz = (span_points[RIGHT] - span_points[LEFT]); + Offset dz_dir = dz.direction (); + if (gaps[LEFT] + gaps[RIGHT] > dz.length ()) { - Direction broken = bound[LEFT]->break_status_dir () ? LEFT : RIGHT; + return SCM_EOL; + } - dxy[X_AXIS] = bound[RIGHT]->extent (common[X_AXIS], X_AXIS)[LEFT] - - bound[LEFT]->extent (common[X_AXIS], X_AXIS)[RIGHT]; - - dxy += broken_trend_offset (me, broken); - dxy[X_AXIS] -= 1 * gap; + Stencil line; + for (LEFT_and_RIGHT (d)) + { + span_points[d] += -d * gaps[d] * magstep * dz.direction (); - my_off = Offset (0, - me->relative_coordinate (common[Y_AXIS], Y_AXIS)); + if (stencils[d]) + { + Stencil s = stencils[d]->translated (span_points[d]); + SCM align = ly_assoc_get (ly_symbol2scm ("stencil-align-dir-y"), + bounds[d], SCM_BOOL_F); + SCM off = ly_assoc_get (ly_symbol2scm ("stencil-offset"), + bounds[d], SCM_BOOL_F); - his_off = Offset (0, - bound[-broken]->relative_coordinate (common[Y_AXIS], - Y_AXIS)); + if (scm_is_number (align)) + s.align_to (Y_AXIS, scm_to_double (align)); - if (broken == LEFT) - { - my_off[Y_AXIS] += dxy[Y_AXIS]; - } + if (is_number_pair (off)) + s.translate (ly_scm2offset (off) * magstep); + + line.add_stencil (s); + } } - else + + for (LEFT_and_RIGHT (d)) { - Real off = gap + ((bound[LEFT]->extent (bound[LEFT], X_AXIS).length ()*3)/4); // distance from center to start of line - dxy[X_AXIS] = bound[RIGHT]->extent (common[X_AXIS], X_AXIS).center () - - bound[LEFT]->extent (common[X_AXIS], X_AXIS).center (); - dxy[Y_AXIS] = bound[RIGHT]->extent (common[Y_AXIS], Y_AXIS).center () - - bound[LEFT]->extent (common[Y_AXIS], Y_AXIS).center (); - - dist = sqrt (dxy[X_AXIS]*dxy[X_AXIS]+dxy[Y_AXIS]*dxy[Y_AXIS]); - ofxy = dxy* (off/dist); - dxy -= 2*ofxy; - - my_off = Offset (me->relative_coordinate (common[X_AXIS], X_AXIS), - me->relative_coordinate (common[Y_AXIS], Y_AXIS)); - - his_off = Offset (bound[LEFT]->relative_coordinate (common[X_AXIS], - X_AXIS), - bound[LEFT]->relative_coordinate (common[Y_AXIS], - Y_AXIS)); - - } - - Real thick = me->get_paper ()->get_var ("linethickness"); - - SCM s = me->get_grob_property ("thickness"); - if (gh_number_p (s)) - thick *= gh_scm2double (s); - - - Molecule line = line_molecule (me, thick, dxy[X_AXIS], dxy[Y_AXIS]); - line.translate_axis (bound[LEFT]->extent (bound[LEFT], - X_AXIS).length ()/2, X_AXIS); - line.translate (ofxy - my_off + his_off); - return line.smobbed_copy (); -} + if (stencils[d]) + span_points[d] += dz_dir * + (stencils[d]->extent (X_AXIS)[-d] / dz_dir[X_AXIS]); + } + Offset adjust = dz.direction () * Staff_symbol_referencer::staff_space (me); + + Offset line_left = span_points[LEFT] + (arrows[LEFT] ? adjust * 1.4 : Offset (0, 0)); + Offset line_right = span_points[RIGHT] - (arrows[RIGHT] ? adjust * 0.55 : Offset (0, 0)); + if (line_right[X_AXIS] > line_left[X_AXIS]) + { + line.add_stencil (Line_interface::line (me, line_left, line_right)); + line.add_stencil (Line_interface::arrows (me, + span_points[LEFT], + span_points[RIGHT], + arrows[LEFT], + arrows[RIGHT])); + } + else + me->warning (_ ("Line spanner's left point is to the right of its right point.")); -ADD_INTERFACE (Line_spanner, "line-spanner-interface", - "Generic line drawn between two objects, eg. for use with glissandi.\n" -"gap is measured in staff-spaces.\n" -"The property 'type is one of: line, dashed-line, trill, dotted-line or zigzag.\n" -"\n", - "gap dash-period dash-length zigzag-width zigzag-length thickness type"); + line.translate (Offset (-me->relative_coordinate (commonx, X_AXIS), + simple_y ? 0.0 : -me->relative_coordinate (my_common_y, Y_AXIS))); + return line.smobbed_copy (); +} +ADD_INTERFACE (Line_spanner, + "Generic line drawn between two objects, e.g., for use with" + " glissandi.", + + /* properties */ + "bound-details " + "extra-dy " + "gap " + "left-bound-info " + "note-columns " + "right-bound-info " + "simple-Y " + "thickness " + "to-barline " + );