X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fspan-bar.cc;h=60ef61de0b6487224f433896d4662318acb392e2;hb=28976d28a04cfb9abe97af7214d7dce11f732604;hp=b564cf17909326ff82ea1184eb4e505485db374b;hpb=4995fea559cd5399b4f462de546a15195d76f4c3;p=lilypond.git diff --git a/lily/span-bar.cc b/lily/span-bar.cc index b564cf1790..60ef61de0b 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -3,91 +3,108 @@ source file of the GNU LilyPond music typesetter - (c) 1997--2001 Han-Wen Nienhuys + (c) 1997--2004 Han-Wen Nienhuys */ #include "span-bar.hh" #include "font-interface.hh" #include "dimensions.hh" #include "paper-def.hh" -#include "molecule.hh" +#include "stencil.hh" #include "warn.hh" #include "axis-group-interface.hh" #include "group-interface.hh" #include "grob.hh" -#include "bar.hh" +#include "bar-line.hh" void Span_bar::add_bar (Grob*me, Grob*b) { - Pointer_group_interface::add_element (me,"elements", b); + Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), b); me->add_dependency (b); } -MAKE_SCHEME_CALLBACK (Span_bar,brew_molecule,1); - -/** - * Limitations/Bugs: - * - * (1) Elements from 'me->get_grob_property ("elements")' must be - * ordered according to their y coordinates relative to their common - * axis group parent. Otherwise, the computation goes mad. (TODO: - * apply a sort algorithm that ensures this precondition.) However, - * until now, I have seen no case where lily has not fulfilled this - * precondition. - * - * (2) This method depends on bar_engraver not being removed from - * staff context. If bar_engraver is removed, the size of the staff - * lines is evaluated as 0, which results in a solid span bar line - * with faulty y coordinate. - */ +MAKE_SCHEME_CALLBACK (Span_bar,print,1); -/* - This routine was originally by Juergen Reuter, but it was a on the - bulky side. Rewritten by Han-Wen. - */ +/* Limitations/Bugs: + + (1) Elements from 'me->get_property ("elements")' must be + ordered according to their y coordinates relative to their common + axis group parent. Otherwise, the computation goes mad. + + (TODO: + apply a sort algorithm that ensures this precondition.) However, + until now, I have seen no case where lily has not fulfilled this + precondition. + + (2) This method depends on bar_engraver not being removed from + staff context. If bar_engraver is removed, the size of the staff + lines is evaluated as 0, which results in a solid span bar line + with faulty y coordinate. */ + +/* This routine was originally by Juergen Reuter, but it was a on the + bulky side. Rewritten by Han-Wen. */ SCM -Span_bar::brew_molecule (SCM smobbed_me) +Span_bar::print (SCM smobbed_me) { Grob *me = unsmob_grob (smobbed_me); - SCM first_elt = me->get_grob_property ("elements"); + SCM first_elt = me->get_property ("elements"); - // compute common refpoint of elements + /* compute common refpoint of elements */ Grob *refp = me; - for (SCM elts = first_elt; gh_pair_p (elts); elts = gh_cdr (elts)) + for (SCM elts = first_elt; is_pair (elts); elts = ly_cdr (elts)) { - SCM smobbed_staff_bar = gh_car (elts); + SCM smobbed_staff_bar = ly_car (elts); Grob *staff_bar = unsmob_grob (smobbed_staff_bar); refp = staff_bar->common_refpoint (refp, Y_AXIS); } - // evaluate glyph - Span_bar::evaluate_glyph(me); - SCM glyph = me->get_grob_property (ly_symbol2scm ("glyph")); - String glyph_str = ly_scm2string (glyph); + Span_bar::evaluate_glyph (me); + SCM glyph = me->get_property ("glyph"); + + /* glyph may not be a string, when ME is killed by Hara Kiri in + between. */ + if (!is_string (glyph)) + return SCM_EOL; + + String glyph_string = ly_scm2string (glyph); + + /* compose span_bar_mol */ + Stencil span_bar_mol; - // compose span_bar_mol - Molecule span_bar_mol; - Grob *prev_staff_bar = 0; - for (SCM elts = first_elt; gh_pair_p (elts); elts = gh_cdr (elts)) + Interval prev_extent; + for (SCM elts = first_elt; is_pair (elts); elts = ly_cdr (elts)) { - SCM smobbed_staff_bar = gh_car (elts); + SCM smobbed_staff_bar = ly_car (elts); Grob *staff_bar = unsmob_grob (smobbed_staff_bar); - if (prev_staff_bar) + Interval ext = staff_bar->extent (refp, Y_AXIS); + if (ext.is_empty ()) + continue; + + if (!prev_extent.is_empty ()) { - Interval l(prev_staff_bar->extent (refp, Y_AXIS)[UP], - staff_bar->extent (refp, Y_AXIS)[DOWN]); - - Molecule interbar - = Bar::compound_barline (staff_bar, glyph_str, l.length()); - interbar.translate_axis (l.center (), Y_AXIS); - span_bar_mol.add_molecule (interbar); + Interval l (prev_extent [UP], + ext[DOWN]); + + if (l.is_empty ()) + { + /* There is overlap between the bar lines. Do nothing. */ + } + else + { + Stencil interbar = Bar_line::compound_barline (staff_bar, + glyph_string, + l.length ()); + interbar.translate_axis (l.center (), Y_AXIS); + span_bar_mol.add_stencil (interbar); + } } - prev_staff_bar = staff_bar; + prev_extent = ext; } - span_bar_mol.translate_axis (- me->relative_coordinate (refp, Y_AXIS), Y_AXIS); + span_bar_mol.translate_axis (- me->relative_coordinate (refp, Y_AXIS), + Y_AXIS); return span_bar_mol.smobbed_copy (); } @@ -97,14 +114,14 @@ SCM Span_bar::width_callback (SCM element_smob, SCM scm_axis) { Grob *se = unsmob_grob (element_smob); - Axis a = (Axis) gh_scm2int (scm_axis); + Axis a = (Axis) ly_scm2int (scm_axis); assert (a == X_AXIS); - String gl = ly_scm2string (se->get_grob_property ("glyph")); + String gl = ly_scm2string (se->get_property ("glyph")); /* urg. */ - Molecule m = Bar::compound_barline (se, gl, 40 PT); + Stencil m = Bar_line::compound_barline (se, gl, 40 PT); return ly_interval2scm (m.extent (X_AXIS)); } @@ -116,10 +133,9 @@ Span_bar::before_line_breaking (SCM smob) evaluate_empty (unsmob_grob (smob)); evaluate_glyph (unsmob_grob (smob)); - /* - no need to call Bar::before_line_breaking (), because the info - in ELEMENTS already has been procced by Bar::before_line_breaking (). - */ + /* No need to call Bar_line::before_line_breaking (), because the info + in ELEMENTS already has been procced by + Bar_line::before_line_breaking (). */ return SCM_UNSPECIFIED; } @@ -129,33 +145,29 @@ SCM Span_bar::center_on_spanned_callback (SCM element_smob, SCM axis) { Grob *me = unsmob_grob (element_smob); - Axis a = (Axis) gh_scm2int (axis); + Axis a = (Axis) ly_scm2int (axis); assert (a == Y_AXIS); Interval i (get_spanned_interval (me)); - /* - Bar::brew_molecule delivers a barline of y-extent (-h/2,h/2), so - we have to translate ourselves to be in the center of the - interval that we span. */ - if (i.empty_b ()) + /* Bar_line::print delivers a barline of y-extent (-h/2,h/2), so + we have to translate ourselves to be in the center of the + interval that we span. */ + if (i.is_empty ()) { me->suicide (); - return gh_double2scm (0.0); + return scm_make_real (0.0); } - return gh_double2scm (i.center ()); + return scm_make_real (i.center ()); } void Span_bar::evaluate_empty (Grob*me) { - /* - TODO: filter all hara-kiried out of ELEMENS list, and then - optionally do suicide. Call this cleanage function from - center_on_spanned_callback () as well. - - */ - if (!gh_pair_p (me->get_grob_property ("elements"))) + /* TODO: filter all hara-kiried out of ELEMENS list, and then + optionally do suicide. Call this cleanage function from + center_on_spanned_callback () as well. */ + if (!is_pair (me->get_property ("elements"))) { me->suicide (); } @@ -164,18 +176,25 @@ Span_bar::evaluate_empty (Grob*me) void Span_bar::evaluate_glyph (Grob*me) { - SCM elts = me->get_grob_property ("elements"); - Grob * b = unsmob_grob (gh_car (elts)); - SCM glsym =ly_symbol2scm ("glyph"); - SCM gl =b ->get_grob_property (glsym); - if (!gh_string_p (gl)) + SCM gl = me->get_property ("glyph"); + + if (is_string (gl)) + return ; + + for (SCM s = me->get_property ("elements"); + !is_string (gl) && is_pair (s); s = ly_cdr (s)) { - me->suicide (); - return ; + gl = unsmob_grob (ly_car (s)) + ->get_property ("glyph"); } - String type = ly_scm2string (gl); + if (!is_string (gl)) + { + me->suicide (); + return; + } + String type = ly_scm2string (gl); if (type == "|:") { type = ".|"; @@ -189,15 +208,17 @@ Span_bar::evaluate_glyph (Grob*me) type = ".|."; } - gl = ly_str02scm (type.ch_C ()); - if (scm_equal_p (me->get_grob_property (glsym), gl) != SCM_BOOL_T) - me->set_grob_property (glsym, gl); + gl = scm_makfrom0str (type.to_str0 ()); + if (scm_equal_p (me->get_property ("glyph"), gl) + != SCM_BOOL_T) + me->set_property ("glyph", gl); } Interval Span_bar::get_spanned_interval (Grob*me) { - return ly_scm2interval (Axis_group_interface::group_extent_callback (me->self_scm (), gh_int2scm (Y_AXIS))); + return ly_scm2interval (Axis_group_interface::group_extent_callback + (me->self_scm (), scm_int2num (Y_AXIS))); } @@ -207,28 +228,20 @@ Span_bar::get_bar_size (SCM smob) { Grob* me = unsmob_grob (smob); Interval iv (get_spanned_interval (me)); - if (iv.empty_b ()) + if (iv.is_empty ()) { - /* - This happens if the bars are hara-kiried from under us. - */ + /* This happens if the bars are hara-kiried from under us. */ me->suicide (); - return gh_double2scm (-1); + return scm_make_real (-1); } - return gh_double2scm (iv.length ()); + return scm_make_real (iv.length ()); } -void -Span_bar::set_interface (Grob *me) -{ - Bar::set_interface (me); - - me->set_interface (ly_symbol2scm ("span-bar-interface")); - me->set_extent_callback (SCM_EOL, Y_AXIS); -} -bool -Span_bar::has_interface (Grob*m) -{ - return m && m->has_interface (ly_symbol2scm ("span-bar-interface")); -} + +ADD_INTERFACE (Span_bar,"span-bar-interface", + "A bar line that spanned between other barlines. This interface is " + " used for bar lines that connect different staves.", + "elements"); + +