X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftuplet-bracket.cc;h=3228c9f7b6edab7b79b7c7dbea8500b3284fafe0;hb=77267b700c377fd170abcbf4863728937038eb5e;hp=c682b67b48fe99954c19999442dd9aa38a76980b;hpb=0c61221b46addec50e2406e04af44a7d460443d4;p=lilypond.git diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index c682b67b48..3228c9f7b6 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1997--2011 Jan Nieuwenhuizen + Copyright (C) 1997--2015 Jan Nieuwenhuizen Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify @@ -41,6 +41,9 @@ */ #include "tuplet-bracket.hh" + +#include "bracket.hh" +#include "axis-group-interface.hh" #include "line-interface.hh" #include "beam.hh" #include "warn.hh" @@ -63,7 +66,7 @@ get_x_bound_item (Grob *me_grob, Direction hdir, Direction my_dir) { Spanner *me = dynamic_cast (me_grob); Item *g = me->get_bound (hdir); - if (Note_column::has_interface (g) + if (has_interface (g) && Note_column::get_stem (g) && Note_column::dir (g) == my_dir) g = Note_column::get_stem (g); @@ -76,7 +79,7 @@ flatten_number_pair_property (Grob *me, Direction xdir, SCM sym) { Drul_array zero (0, 0); Drul_array pair - = robust_scm2drul (me->internal_get_property (sym), zero); + = robust_scm2drul (me->get_property (sym), zero); pair[xdir] = 0.0; me->set_property (sym, ly_interval2scm (pair)); @@ -91,8 +94,10 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector const &cols, { Spanner *me = dynamic_cast (me_grob); - if (me->get_bound (LEFT)->break_status_dir () - || me->get_bound (RIGHT)->break_status_dir ()) + Item *left = me->get_bound (LEFT); + Item *right = me->get_bound (RIGHT); + if (!left || left->break_status_dir () + || !right || right->break_status_dir ()) return 0; Drul_array stems (Note_column::get_stem (cols[0]), @@ -105,10 +110,8 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector const &cols, return 0; Drul_array beams; - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) beams[d] = stems[d] ? Stem::get_beam (stems[d]) : 0; - while (flip (&d) != LEFT); *equally_long = false; if (! (beams[LEFT] && (beams[LEFT] == beams[RIGHT]) && !me->is_broken ())) @@ -132,15 +135,14 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_connect_to_neighbors, 1); SCM Tuplet_bracket::calc_connect_to_neighbors (SCM smob) { - Spanner *me = unsmob_spanner (smob); + Spanner *me = unsmob (smob); Direction dir = get_grob_direction (me); Drul_array bounds (get_x_bound_item (me, LEFT, dir), get_x_bound_item (me, RIGHT, dir)); Drul_array connect_to_other (false, false); - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) { Direction break_dir = bounds[d]->break_status_dir (); Spanner *orig_spanner = dynamic_cast (me->original ()); @@ -160,7 +162,6 @@ Tuplet_bracket::calc_connect_to_neighbors (SCM smob) && neighbor_idx < orig_spanner->broken_intos_.size () && orig_spanner->broken_intos_[neighbor_idx]->is_live ()); } - while (flip (&d) != LEFT); if (connect_to_other[LEFT] || connect_to_other[RIGHT]) return scm_cons (scm_from_bool (connect_to_other[LEFT]), @@ -185,7 +186,7 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_x_positions, 1) SCM Tuplet_bracket::calc_x_positions (SCM smob) { - Spanner *me = unsmob_spanner (smob); + Spanner *me = unsmob (smob); extract_grob_set (me, "note-columns", columns); Grob *commonx = get_common_x (me); @@ -200,10 +201,9 @@ Tuplet_bracket::calc_x_positions (SCM smob) Drul_array (false, false)); Interval x_span; - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) { - x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[d]; + x_span[d] = Axis_group_interface::generic_bound_extent (bounds[d], commonx, X_AXIS)[d]; if (connect_to_other[d]) { @@ -213,8 +213,9 @@ Tuplet_bracket::calc_x_positions (SCM smob) if (d == RIGHT) x_span[d] += d * overshoot[d]; else - x_span[d] = robust_relative_extent (bounds[d], - commonx, X_AXIS)[RIGHT] + x_span[d] = (bounds[d]->break_status_dir () + ? Axis_group_interface::generic_bound_extent (bounds[d], commonx, X_AXIS)[-d] + : robust_relative_extent (bounds[d], commonx, X_AXIS)[-d]) - overshoot[LEFT]; } @@ -242,7 +243,6 @@ Tuplet_bracket::calc_x_positions (SCM smob) x_span[d] = coord - padding; } } - while (flip (&d) != LEFT); return ly_interval2scm (x_span - me->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS)); } @@ -257,7 +257,7 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, print, 1); SCM Tuplet_bracket::print (SCM smob) { - Spanner *me = unsmob_spanner (smob); + Spanner *me = unsmob (smob); Stencil mol; extract_grob_set (me, "note-columns", columns); @@ -270,7 +270,7 @@ Tuplet_bracket::print (SCM smob) */ SCM bracket_vis_prop = me->get_property ("bracket-visibility"); bool bracket_prop = ly_scm2bool (bracket_vis_prop); // Flag, user has set bracket-visibility prop. - bool bracket = (bracket_vis_prop == ly_symbol2scm ("if-no-beam")); + bool bracket = scm_is_eq (bracket_vis_prop, ly_symbol2scm ("if-no-beam")); if (scm_is_bool (bracket_vis_prop)) bracket_visibility = bracket_prop; else if (bracket) @@ -300,14 +300,12 @@ Tuplet_bracket::print (SCM smob) Interval positions = robust_scm2interval (scm_positions, Interval (0.0, 0.0)); Drul_array points; - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) points[d] = Offset (x_span[d], positions[d]); - while (flip (&d) != LEFT); Output_def *pap = me->layout (); - Grob *number_grob = unsmob_grob (me->get_object ("tuplet-number")); + Grob *number_grob = unsmob (me->get_object ("tuplet-number")); /* Don't print the bracket when it would be smaller than the number. @@ -348,8 +346,7 @@ Tuplet_bracket::print (SCM smob) = robust_scm2booldrul (me->get_property ("connect-to-neighbor"), Drul_array (false, false)); - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) { if (connect_to_other[d]) { @@ -369,7 +366,7 @@ Tuplet_bracket::print (SCM smob) = Text_interface::interpret_markup (pap->self_scm (), properties, text); - Stencil *edge_text = unsmob_stencil (t); + Stencil *edge_text = unsmob (t); edge_text->translate_axis (x_span[d] - x_span[LEFT], X_AXIS); edge_stencils[d] = *edge_text; @@ -377,24 +374,22 @@ Tuplet_bracket::print (SCM smob) } } } - while (flip (&d) != LEFT); - - Stencil brack = make_bracket (me, Y_AXIS, - points[RIGHT] - points[LEFT], - height, - /* - 0.1 = more space at right due to italics - TODO: use italic correction of font. - */ - Interval (-0.5, 0.5) * gap + 0.1, - flare, shorten); - - do + + Stencil brack = + Bracket::make_bracket ( + me, Y_AXIS, points[RIGHT] - points[LEFT], height, + /* + 0.1 = more space at right due to italics + TODO: use italic correction of font. + */ + Interval (-0.5, 0.5) * gap + 0.1, + flare, shorten); + + for (LEFT_and_RIGHT (d)) { if (!edge_stencils[d].is_empty ()) brack.add_stencil (edge_stencils[d]); } - while (flip (&d) != LEFT); mol.add_stencil (brack); } @@ -403,71 +398,6 @@ Tuplet_bracket::print (SCM smob) return mol.smobbed_copy (); } -/* - should move to lookup? - - TODO: this will fail for very short (shorter than the flare) - brackets. -*/ -Stencil -Tuplet_bracket::make_bracket (Grob *me, // for line properties. - Axis protrusion_axis, - Offset dz, - Drul_array height, - Interval gap, - Drul_array flare, - Drul_array shorten) -{ - Drul_array corners (Offset (0, 0), dz); - - Real length = dz.length (); - Drul_array gap_corners; - - Axis bracket_axis = other_axis (protrusion_axis); - - Drul_array straight_corners = corners; - - Direction d = LEFT; - do - straight_corners[d] += -d * shorten[d] / length * dz; - while (flip (&d) != LEFT); - - if (!gap.is_empty ()) - { - do - gap_corners[d] = (dz * 0.5) + gap[d] / length * dz; - while (flip (&d) != LEFT); - } - - Drul_array flare_corners = straight_corners; - do - { - flare_corners[d][bracket_axis] = straight_corners[d][bracket_axis]; - flare_corners[d][protrusion_axis] += height[d]; - straight_corners[d][bracket_axis] += -d * flare[d]; - } - while (flip (&d) != LEFT); - - Stencil m; - do - { - if (!gap.is_empty ()) - m.add_stencil (Line_interface::line (me, straight_corners[d], - gap_corners[d])); - - m.add_stencil (Line_interface::line (me, straight_corners[d], - flare_corners[d])); - } - - while (flip (&d) != LEFT); - - if (gap.is_empty ()) - m.add_stencil (Line_interface::line (me, straight_corners[LEFT], - straight_corners[RIGHT])); - - return m; -} - void Tuplet_bracket::get_bounds (Grob *me, Grob **left, Grob **right) { @@ -536,7 +466,7 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT]; bool follow_beam = par_beam && get_grob_direction (par_beam) == dir - && !to_boolean (par_beam->get_property ("knee")); + && !Beam::is_knee (par_beam); vector points; if (columns.size () @@ -548,16 +478,14 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) Note_column::get_stem (columns.back ())); Interval poss; - Direction side = LEFT; - do + for (LEFT_and_RIGHT (side)) { // Trigger setting of stem lengths if necessary. if (Grob *beam = Stem::get_beam (stems[side])) (void) beam->get_property ("quantized-positions"); poss[side] = stems[side]->extent (stems[side], Y_AXIS)[get_grob_direction (stems[side])] - + stems[side]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS); + + stems[side]->parent_relative (commony, Y_AXIS); } - while (flip (&side) != LEFT); *dy = poss[RIGHT] - poss[LEFT]; points.push_back (Offset (stems[LEFT]->relative_coordinate (commonx, X_AXIS) - x0, poss[LEFT])); @@ -627,14 +555,13 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) if (!tuplets[i]->is_live ()) continue; - Direction d = LEFT; Drul_array positions = robust_scm2interval (tuplets[i]->get_property ("positions"), Interval (0, 0)); Real other_dy = positions[RIGHT] - positions[LEFT]; - do + for (LEFT_and_RIGHT (d)) { Real y = tuplet_y.linear_combination (d * sign (other_dy)); @@ -647,12 +574,41 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) points.push_back (Offset (tuplet_x[d] - x0, y)); } - while (flip (&d) != LEFT); + // Check for number-on-bracket collisions - Grob *number = unsmob_grob (tuplets[i]->get_object ("tuplet-number")); + Grob *number = unsmob (tuplets[i]->get_object ("tuplet-number")); if (number) - points.push_back (Offset (number->extent (commonx, X_AXIS).center () - x0, - number->extent (commony, Y_AXIS)[dir])); + { + Interval x_ext = robust_relative_extent (number, commonx, X_AXIS); + Interval y_ext = robust_relative_extent (number, commony, Y_AXIS); + points.push_back (Offset (x_ext.center () - x0, y_ext[dir])); + } + } + + if (to_boolean (me->get_property ("avoid-scripts")) + && !scm_is_number (me->get_property ("outside-staff-priority"))) + { + extract_grob_set (me, "scripts", scripts); + for (vsize i = 0; i < scripts.size (); i++) + { + if (!scripts[i]->is_live ()) + continue; + if (scm_is_number (scripts[i]->get_property ("outside-staff-priority"))) + continue; + + // assume that if a script is avoiding slurs, it should not get placed + // under a tuplet bracket + if (unsmob (scripts[i]->get_object ("slur"))) + continue; + + Interval script_x + = robust_relative_extent (scripts[i], commonx, X_AXIS); + Interval script_y + = robust_relative_extent (scripts[i], commony, Y_AXIS); + + points.push_back (Offset (script_x.center () - x0, + script_y[dir])); + } } *offset = -dir * infinity_f; @@ -671,21 +627,20 @@ Tuplet_bracket::calc_position_and_height (Grob *me_grob, Real *offset, Real *dy) /* horizontal brackets should not collide with staff lines. - Kind of pointless since we put them outside the staff anyway, but - let's leave code for the future when possibly allow them to move - into the staff once again. - This doesn't seem to support cross-staff tuplets atm. */ - if (*dy == 0 - && fabs (*offset) < ss * Staff_symbol_referencer::staff_radius (me)) + if (*dy == 0) { // quantize, then do collision check. - *offset *= 2 / ss; + *offset /= 0.5 * ss; - *offset = rint (*offset); - if (Staff_symbol_referencer::on_line (me, (int) rint (*offset))) - *offset += dir; + Interval staff_span = Staff_symbol_referencer::staff_span (me); + if (staff_span.contains (*offset)) + { + *offset = rint (*offset); + if (Staff_symbol_referencer::on_line (me, int (*offset))) + *offset += dir; + } *offset *= 0.5 * ss; } @@ -695,7 +650,7 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_direction, 1); SCM Tuplet_bracket::calc_direction (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); Direction dir = Tuplet_bracket::get_default_dir (me); return scm_from_int (dir); } @@ -704,7 +659,7 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_positions, 1); SCM Tuplet_bracket::calc_positions (SCM smob) { - Spanner *me = unsmob_spanner (smob); + Spanner *me = unsmob (smob); Real dy = 0.0; Real offset = 0.0; @@ -749,10 +704,8 @@ Tuplet_bracket::get_default_dir (Grob *me) Direction d = Note_column::dir (columns[i]); extremal_positions[d] = minmax (d, 1.0 * Note_column::head_positions_interval (columns[i])[d], extremal_positions[d]); } - Direction d = LEFT; - do + for (LEFT_and_RIGHT (d)) extremal_positions[d] = -d * (staff_extent[d] - extremal_positions[d]); - while (flip (&d) != LEFT); return extremal_positions[UP] <= extremal_positions[DOWN] ? UP : DOWN; } @@ -767,6 +720,12 @@ Tuplet_bracket::add_column (Grob *me, Item *n) add_bound_item (dynamic_cast (me), n); } +void +Tuplet_bracket::add_script (Grob *me, Item *s) +{ + Pointer_group_interface::add_grob (me, ly_symbol2scm ("scripts"), s); +} + void Tuplet_bracket::add_tuplet_bracket (Grob *me, Grob *bracket) { @@ -777,7 +736,7 @@ MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_cross_staff, 1); SCM Tuplet_bracket::calc_cross_staff (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); extract_grob_set (me, "note-columns", cols); extract_grob_set (me, "tuplets", tuplets); @@ -796,7 +755,7 @@ Tuplet_bracket::calc_cross_staff (SCM smob) for (vsize i = 0; i < cols.size (); i++) { - Grob *stem = unsmob_grob (cols[i]->get_object ("stem")); + Grob *stem = unsmob (cols[i]->get_object ("stem")); if (stem && to_boolean (stem->get_property ("cross-staff"))) return SCM_BOOL_T; } @@ -812,6 +771,7 @@ ADD_INTERFACE (Tuplet_bracket, " @code{edge-text} are printed at the edges.", /* properties */ + "avoid-scripts " "bracket-flare " "bracket-visibility " "break-overshoot " @@ -826,6 +786,7 @@ ADD_INTERFACE (Tuplet_bracket, "note-columns " "padding " "tuplet-number " + "scripts " "shorten-pair " "staff-padding " "thickness "