X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fline-spanner.cc;h=2ea7b57c64e92cd0195e4ba28def412281a53e67;hb=8438b824fb221159742957c2eeab761effe73be4;hp=5ea4c1a6877f0ce46e5a963d9fe5c58e2286592f;hpb=94189ec2b8da6d7e89dc619c646a927adead9b19;p=lilypond.git diff --git a/lily/line-spanner.cc b/lily/line-spanner.cc index 5ea4c1a687..2ea7b57c64 100644 --- a/lily/line-spanner.cc +++ b/lily/line-spanner.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 2000--2001 Jan Nieuwenhuizen + (c) 2000--2002 Jan Nieuwenhuizen */ #include "molecule.hh" @@ -13,57 +13,131 @@ #include "paper-def.hh" #include "paper-column.hh" #include "staff-symbol-referencer.hh" +#include "font-interface.hh" #include -SCM -Line_spanner::line_atom (Grob* me, Real dx, Real dy) + +/* + slightishly clumsy interface? + + Make a Scheme expression for a line going from (0,0) to (dx,dy). + */ + +static SCM +line_atom (Grob* me, Real thick, Real dx, Real dy) { - SCM list = SCM_EOL; 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"))) - { - Real staff_space = Staff_symbol_referencer::staff_space (me); - Real thick = me->paper_l ()->get_var ("stafflinethickness"); - - SCM s = me->get_grob_property ("line-thickness"); - if (gh_number_p (s)) - thick *= gh_scm2double (s); + Real staff_space = Staff_symbol_referencer::staff_space (me); // maybe these should be in line-thickness? - Real length = staff_space; - 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; + 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 ("dotted-line")) + length = thick; - if (type == ly_symbol2scm ("line")) - length = period + thick; + if (type == ly_symbol2scm ("line")) + length = period + thick; - Real on = length - thick; - Real off = period - on; + Real on = length - thick; + Real off = period - on; - list = gh_list (ly_symbol2scm ("dashed-line"), + 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; } +static SCM +zigzag_atom (Grob* me, Real thick, Real dx, Real dy) +{ + 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; +} + + + +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))) + { + Box b (Interval (-0.5* thick + (0 ? dx)), + Interval (- 0.5* thick + (0? dy))); + mol = Molecule (b, line_atom (me, thick, dx, dy)); + } + else if (gh_symbol_p (type) + && type == ly_symbol2scm ("zigzag")) + { + // TODO: + Box b (Interval (-0.5* thick + (0 ? dx)), + Interval (- 0.5* thick + (0? dy))); + mol = Molecule (b, zigzag_atom (me, thick, dx, dy)); + + } + else if (gh_symbol_p (type) + && type == ly_symbol2scm ("trill")) + { + 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); + 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); + } + return mol; +} + Offset Line_spanner::get_broken_offset (Grob *me, Direction dir) { @@ -73,13 +147,13 @@ Line_spanner::get_broken_offset (Grob *me, Direction dir) if (!bound->break_status_dir ()) { Grob *common[] = { - bound->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me), + bound->common_refpoint (Staff_symbol_referencer::get_staff_symbol (me), X_AXIS), - bound->common_refpoint (Staff_symbol_referencer::staff_symbol_l (me), + bound->common_refpoint (Staff_symbol_referencer::get_staff_symbol (me), Y_AXIS) }; - return Offset ( abs (bound->extent (common[X_AXIS], X_AXIS)[-dir]), + return Offset (abs (bound->extent (common[X_AXIS], X_AXIS)[-dir]), bound->extent (common[Y_AXIS], Y_AXIS).center ()); } return Offset (); @@ -92,22 +166,22 @@ Line_spanner::broken_trend_offset (Grob *me, Direction dir) the unbroken line-spanner would have had. From slur */ Offset o; - if (Spanner *mother = dynamic_cast (me->original_l_)) + if (Spanner *mother = dynamic_cast (me->original_)) { - for (int i = dir == LEFT ? 0 : mother->broken_into_l_arr_.size () - 1; - dir == LEFT ? i < mother->broken_into_l_arr_.size () : i > 0; + 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_into_l_arr_[i - dir] == me) + if (mother->broken_intos_[i - dir] == me) { - Grob *neighbour = mother->broken_into_l_arr_[i]; + 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] + (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])); + (me_o[X_AXIS] + neighbour_o[X_AXIS])); break; } } @@ -119,8 +193,8 @@ Line_spanner::broken_trend_offset (Grob *me, Direction dir) /* Warning: this thing is a cross-staff object, so it should have empty Y-dimensions. - (If not, you risk that this is called from the staff-alignment - routine, via molecule_extent. At this point, the staffs aren't + (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. */ @@ -189,8 +263,8 @@ Line_spanner::brew_molecule (SCM smob) 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); + 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), @@ -202,21 +276,28 @@ Line_spanner::brew_molecule (SCM smob) Y_AXIS)); } - Molecule line; - SCM list = Line_spanner::line_atom (me, dxy[X_AXIS], dxy[Y_AXIS]); - - if (list == SCM_EOL) - return SCM_EOL; - - Box b (Interval (0, dxy[X_AXIS]), Interval (0, dxy[Y_AXIS])); - - line = Molecule (b, list); - line.translate_axis (bound[LEFT]->extent (bound[LEFT], X_AXIS).length ()/2, X_AXIS); - //Offset g (gap, 0); + 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 (); } + +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"); + +