X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fottava-bracket.cc;h=3ea133e483570520878b805c5a545bd3c1919244;hb=38d7d319eabc906e82fb42002678c6d42a23b6f7;hp=f72ccf9adcf11ecbede01d48043d8d69f91e36af;hpb=b72fc08ee82eba965f91f2569ab4e43361668641;p=lilypond.git diff --git a/lily/ottava-bracket.cc b/lily/ottava-bracket.cc index f72ccf9adc..3ea133e483 100644 --- a/lily/ottava-bracket.cc +++ b/lily/ottava-bracket.cc @@ -1,48 +1,48 @@ -#include "molecule.hh" -#include "text-item.hh" -#include "text-spanner.hh" -#include "line-spanner.hh" +/* + ottava-bracket.cc -- implement Ottava_bracket + + source file of the GNU LilyPond music typesetter + + (c) 2004--2009 Han-Wen Nienhuys +*/ + +#include "text-interface.hh" #include "spanner.hh" #include "font-interface.hh" #include "dimensions.hh" -#include "paper-def.hh" +#include "output-def.hh" #include "warn.hh" #include "paper-column.hh" #include "staff-symbol-referencer.hh" #include "note-column.hh" #include "directional-element-interface.hh" #include "tuplet-bracket.hh" +#include "rhythmic-head.hh" +#include "pointer-group-interface.hh" struct Ottava_bracket { - DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM)); - static bool has_interface (Grob*); + DECLARE_SCHEME_CALLBACK (print, (SCM)); + DECLARE_GROB_INTERFACE (); }; - /* TODO: the string for ottava shoudl depend on the available space, ie. - Long: 15ma Short: 15ma Empty: 15 - 8va 8va 8 - 8va bassa 8ba 8 - + 8va 8va 8 + 8va bassa 8ba 8 */ - -MAKE_SCHEME_CALLBACK (Ottava_bracket, brew_molecule, 1); +MAKE_SCHEME_CALLBACK (Ottava_bracket, print, 1); SCM -Ottava_bracket::brew_molecule (SCM smob) +Ottava_bracket::print (SCM smob) { - Spanner*me = dynamic_cast (unsmob_grob (smob)); - - + Spanner *me = dynamic_cast (unsmob_grob (smob)); Interval span_points; - + Grob *common = me->get_bound (LEFT)->common_refpoint (me->get_bound (RIGHT), X_AXIS); - Paper_def * paper = me->get_paper(); + Output_def *layout = me->layout (); - Drul_array broken; Direction d = LEFT; do @@ -52,20 +52,33 @@ Ottava_bracket::brew_molecule (SCM smob) if (Note_column::has_interface (b)) { - common = common_refpoint_of_list (b->get_grob_property ("heads"), common, X_AXIS); + extract_grob_set (b, "note-heads", heads); + common = common_refpoint_of_array (heads, common, X_AXIS); + for (vsize i = 0; i < heads.size (); i++) + { + Grob *h = heads[i]; + Grob *dots = Rhythmic_head::get_dots (h); + if (dots) + common = dots->common_refpoint (common, X_AXIS); + } } } while (flip (&d) != LEFT); - SCM properties = Font_interface::font_alist_chain (me); - SCM markup = me->get_grob_property ("text"); - Molecule text; - if (Text_item::markup_p (markup)) - text = *unsmob_molecule (Text_item::interpret_markup (paper->self_scm (), properties, markup)); + SCM properties = Font_interface::text_font_alist_chain (me); + SCM markup = me->get_property ("text"); + Stencil text; + if (Text_interface::is_markup (markup)) + text = *unsmob_stencil (Text_interface::interpret_markup (layout->self_scm (), + properties, markup)); + Drul_array shorten = robust_scm2interval (me->get_property ("shorten-pair"), + Interval (0, 0)); - Drul_array shorten = robust_scm2interval (me->get_grob_property ("shorten-pair"), - Interval (0,0)); + /* + TODO: we should check if there are ledgers, and modify length of + the spanner to that. + */ do { Item *b = me->get_bound (d); @@ -73,68 +86,105 @@ Ottava_bracket::brew_molecule (SCM smob) Interval ext; if (Note_column::has_interface (b)) { - for (SCM s = b->get_grob_property ("note-heads"); gh_pair_p (s); s =gh_cdr (s)) - ext.unite (unsmob_grob (gh_car (s))->extent (common, X_AXIS)); + extract_grob_set (b, "note-heads", heads); + for (vsize i = 0; i < heads.size (); i++) + { + Grob *h = heads[i]; + ext.unite (h->extent (common, X_AXIS)); + Grob *dots = Rhythmic_head::get_dots (h); + + if (dots && d == RIGHT) + ext.unite (dots->extent (common, X_AXIS)); + } } if (ext.is_empty ()) - ext = Interval (0,0); - - span_points[d] = (broken [d]) ? b->extent (common, X_AXIS)[-d] : ext[d]; + ext = robust_relative_extent (b, common, X_AXIS); if (broken[d]) - shorten [d] = 0.0; + { + span_points[d] = b->extent (common, X_AXIS)[RIGHT]; + shorten[d] = 0.; + } + + else + span_points[d] = ext[d]; } while (flip (&d) != LEFT); - /* - 0.3 is ~ italic correction. - */ - Real text_offset = text.extent (X_AXIS).is_empty () - ? 0.0 : text.extent (X_AXIS)[RIGHT] + 0.3; + 0.3 is ~ italic correction. + */ + Real text_size = text.extent (X_AXIS).is_empty () + ? 0.0 : text.extent (X_AXIS)[RIGHT] + 0.3; + + span_points[LEFT] + = min (span_points[LEFT], + (span_points[RIGHT] - text_size + - robust_scm2double (me->get_property ("minimum-length"), -1.0))); Interval bracket_span_points = span_points; - bracket_span_points[LEFT] += text_offset; - - Real thick = paper->get_realvar (ly_symbol2scm ("linethickness")); - thick *= robust_scm2double (me->get_grob_property ("thickness"), 1.0); + bracket_span_points[LEFT] += text_size; - Drul_array edge_height = robust_scm2interval (me->get_grob_property ("edge-height"), + Drul_array edge_height = robust_scm2interval (me->get_property ("edge-height"), Interval (1.0, 1.0)); - - Drul_array flare = robust_scm2interval (me->get_grob_property ("bracket-flare"), - Interval (0,0)); - + Drul_array flare = robust_scm2interval (me->get_property ("bracket-flare"), + Interval (0, 0)); + do + { + edge_height[d] *= -get_grob_direction (me); + if (broken[d]) + edge_height[d] = 0.0; + } + while (flip(&d) != LEFT); - edge_height[LEFT] = 0.0; - edge_height[RIGHT] *= - get_grob_direction (me); - if (broken[RIGHT]) - edge_height[RIGHT] = 0.0; - - Molecule b; - if (!bracket_span_points.is_empty ()) + Stencil b; + Interval empty; + if (!bracket_span_points.is_empty () && bracket_span_points.length () > 0.001) b = Tuplet_bracket::make_bracket (me, Y_AXIS, Offset (bracket_span_points.length (), 0), - thick, edge_height, - 0.0, + edge_height, + empty, flare, shorten); - - + + /* + The vertical lines should not take space, for the following scenario: + + 8 -----+ + o | + | + | + + + Just a small amount, yes. In tight situations, it is even + possible to center the `8' directly below the note, dropping the + ottava line completely... + + */ + + b = Stencil (Box (b.extent (X_AXIS), + Interval (0.1, 0.1)), + b.expr ()); + b.translate_axis (bracket_span_points[LEFT], X_AXIS); text.translate_axis (span_points[LEFT], X_AXIS); text.align_to (Y_AXIS, CENTER); - b.add_molecule (text); - + b.add_stencil (text); + b.translate_axis (- me->relative_coordinate (common, X_AXIS), X_AXIS); - - return b.smobbed_copy (); + + return b.smobbed_copy (); } +ADD_INTERFACE (Ottava_bracket, + "An ottava bracket.", -ADD_INTERFACE (Ottava_bracket, "ottava-bracket-interface", - "An ottava bracket", - "edge-height bracket-flare shorten-pair"); + /* properties */ + "edge-height " + "bracket-flare " + "shorten-pair " + "minimum-length " + );