From: David Nalesnik Date: Thu, 23 Feb 2017 15:57:44 +0000 (-0600) Subject: Issue 5084: Create Bracket class X-Git-Url: https://git.donarmstrong.com/?p=lilypond.git;a=commitdiff_plain;h=9e877e5aea3fb6cf6e7873d1e8797672cda450f5 Issue 5084: Create Bracket class Code involving brackets suffers from two confusing organizational issues: (1) Tuplet_bracket::make_bracket is used to create brackets for a number of grobs: BassFigureBracket, HorizontalBracket, OttavaBracket, PianoPedalBracket, VoltaBracket, along with TupletBracket (2) Methods belonging to Horizontal_bracket are used to draw both horizonal brackets (HorizontalBracket) and vertical brackets (BassFigureBracket) To remedy this, a new Bracket class is created. This new class contains the old Tuplet_bracket::make_bracket, Horizontal_bracket::make_bracket, and Horizontal_bracket::make_enclosing_bracket. These methods have been renamed to clarify their purpose. --- diff --git a/lily/bracket.cc b/lily/bracket.cc new file mode 100644 index 0000000000..8d95b696dd --- /dev/null +++ b/lily/bracket.cc @@ -0,0 +1,151 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 1997--2015 Jan Nieuwenhuizen + Han-Wen Nienhuys + + 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 "bracket.hh" + + #include "axis-group-interface.hh" + #include "directional-element-interface.hh" + #include "grob.hh" + #include "lookup.hh" + #include "output-def.hh" + #include "staff-symbol-referencer.hh" + #include "spanner.hh" + #include "item.hh" + #include "line-interface.hh" + +/* + should move to lookup? + + TODO: this will fail for very short (shorter than the flare) + brackets. +*/ +Stencil +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; + + for (LEFT_and_RIGHT (d)) + straight_corners[d] += -d * shorten[d] / length * dz; + + if (!gap.is_empty ()) + { + for (LEFT_and_RIGHT (d)) + gap_corners[d] = (dz * 0.5) + gap[d] / length * dz; + } + + Drul_array flare_corners = straight_corners; + for (LEFT_and_RIGHT (d)) + { + 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]; + } + + Stencil m; + if (!gap.is_empty ()) + for (LEFT_and_RIGHT (d)) + m.add_stencil (Line_interface::line (me, straight_corners[d], + gap_corners[d])); + else + m.add_stencil (Line_interface::line (me, straight_corners[LEFT], + straight_corners[RIGHT])); + + if (scm_is_number (me->get_property ("dash-fraction"))) + me->set_property ("dash-fraction", scm_from_double (1.0)); + for (LEFT_and_RIGHT (d)) + m.add_stencil (Line_interface::line (me, straight_corners[d], + flare_corners[d])); + return m; +} + +/* + Return an ungapped bracket along either the X- or Y-axis. +*/ +Stencil +Bracket::make_axis_constrained_bracket (Grob *me, Real length, Axis a, + Direction dir) +{ + Drul_array edge_height = robust_scm2interval (me->get_property ("edge-height"), + Interval (1.0, 1.0)); + Drul_array flare = robust_scm2interval (me->get_property ("bracket-flare"), + Interval (0, 0)); + Drul_array shorten = robust_scm2interval (me->get_property ("shorten-pair"), + Interval (0, 0)); + + // Make sure that it points in the correct direction: + scale_drul (&edge_height, Real (-dir)); + + Offset start; + start[a] = length; + + Drul_array connect_to_other + = robust_scm2booldrul (me->get_property ("connect-to-neighbor"), + Drul_array (false, false)); + + for (LEFT_and_RIGHT (d)) + { + if (connect_to_other[d]) + { + edge_height[d] = 0.0; + flare[d] = 0.0; + shorten[d] = 0.0; + } + } + + return make_bracket (me, other_axis (a), start, edge_height, + Interval (), flare, shorten); +} + +/* + Return an axis-constrained, ungapped bracket which encloses a group of + grobs. Used for analysis brackets (HorizontalBracket) and + figured bass (BassFigureBracket). +*/ +Stencil +Bracket::make_enclosing_bracket (Grob *me, Grob *refpoint, + vector grobs, Axis a, + Direction dir) +{ + Grob *common = common_refpoint_of_array (grobs, refpoint, a); + Interval ext = Axis_group_interface::relative_group_extent (grobs, common, a); + + if (ext.is_empty ()) + { + me->programming_error ("Can't enclose empty extents with bracket"); + return Stencil (); + } + else + { + Stencil b = make_axis_constrained_bracket (me, ext.length (), a, dir); + b.translate_axis (ext[LEFT] - refpoint->relative_coordinate (common, a), a); + + return b; + } +} diff --git a/lily/enclosing-bracket.cc b/lily/enclosing-bracket.cc index dd551e3841..3ccc62b668 100644 --- a/lily/enclosing-bracket.cc +++ b/lily/enclosing-bracket.cc @@ -19,7 +19,7 @@ */ #include "stencil.hh" -#include "horizontal-bracket.hh" +#include "bracket.hh" #include "grob.hh" #include "axis-group-interface.hh" #include "pointer-group-interface.hh" @@ -64,8 +64,10 @@ Enclosing_bracket::width (SCM grob) Grob *common_x = common_refpoint_of_array (elements, me, X_AXIS); Interval xext = Axis_group_interface::relative_group_extent (elements, common_x, X_AXIS); - Stencil left_br = Horizontal_bracket::make_bracket (me, 10.0, Y_AXIS, LEFT); - Stencil right_br = Horizontal_bracket::make_bracket (me, 10.0, Y_AXIS, LEFT); + Stencil left_br = + Bracket::make_axis_constrained_bracket (me, 10.0, Y_AXIS, LEFT); + Stencil right_br = + Bracket::make_axis_constrained_bracket (me, 10.0, Y_AXIS, LEFT); xext.widen (robust_scm2double (me->get_property ("padding"), 0.25)); left_br.translate_axis (xext[LEFT], X_AXIS); @@ -97,10 +99,10 @@ Enclosing_bracket::print (SCM grob) xext = Interval (0, 0); } - Stencil left_br = Horizontal_bracket::make_enclosing_bracket (me, me, elements, - Y_AXIS, LEFT); - Stencil right_br = Horizontal_bracket::make_enclosing_bracket (me, me, elements, - Y_AXIS, RIGHT); + Stencil left_br = + Bracket::make_enclosing_bracket (me, me, elements, Y_AXIS, LEFT); + Stencil right_br = + Bracket::make_enclosing_bracket (me, me, elements, Y_AXIS, RIGHT); xext.widen (robust_scm2double (me->get_property ("padding"), 0.25)); left_br.translate_axis (xext[LEFT], X_AXIS); diff --git a/lily/horizontal-bracket.cc b/lily/horizontal-bracket.cc index cf37516d5c..b453985b09 100644 --- a/lily/horizontal-bracket.cc +++ b/lily/horizontal-bracket.cc @@ -19,79 +19,13 @@ #include "horizontal-bracket.hh" -#include "lookup.hh" -#include "side-position-interface.hh" +#include "bracket.hh" +#include "stencil.hh" #include "pointer-group-interface.hh" #include "directional-element-interface.hh" -#include "output-def.hh" -#include "staff-symbol-referencer.hh" -#include "tuplet-bracket.hh" -#include "axis-group-interface.hh" #include "spanner.hh" #include "item.hh" -Stencil -Horizontal_bracket::make_bracket (Grob *me, - Real length, - Axis a, Direction dir) -{ - Drul_array edge_height = robust_scm2interval (me->get_property ("edge-height"), - Interval (1.0, 1.0)); - Drul_array flare = robust_scm2interval (me->get_property ("bracket-flare"), - Interval (0, 0)); - Drul_array shorten = robust_scm2interval (me->get_property ("shorten-pair"), - Interval (0, 0)); - - // Make sure that it points in the correct direction: - scale_drul (&edge_height, Real (-dir)); - - Interval empty; - Offset start; - start[a] = length; - - Drul_array connect_to_other - = robust_scm2booldrul (me->get_property ("connect-to-neighbor"), - Drul_array (false, false)); - - for (LEFT_and_RIGHT (d)) - { - if (connect_to_other[d]) - { - edge_height[d] = 0.0; - flare[d] = 0.0; - shorten[d] = 0.0; - } - } - - /* - ugh, Tuplet_bracket should use Horizontal_bracket, not the other way around. - */ - return Tuplet_bracket::make_bracket (me, other_axis (a), start, - edge_height, empty, flare, shorten); -} - -Stencil -Horizontal_bracket::make_enclosing_bracket (Grob *me, Grob *refpoint, - vector grobs, - Axis a, Direction dir) -{ - Grob *common = common_refpoint_of_array (grobs, refpoint, a); - Interval ext = Axis_group_interface::relative_group_extent (grobs, common, a); - - if (ext.is_empty ()) - { - me->programming_error ("Can't enclose empty extents with bracket"); - return Stencil (); - } - else - { - Stencil b = make_bracket (me, ext.length (), a, dir); - b.translate_axis (ext[LEFT] - refpoint->relative_coordinate (common, a), a); - - return b; - } -} - MAKE_SCHEME_CALLBACK (Horizontal_bracket, print, 1); SCM Horizontal_bracket::print (SCM smob) @@ -113,7 +47,8 @@ Horizontal_bracket::print (SCM smob) enclosed.push_back (b); } - Stencil b = make_enclosing_bracket (me, me, enclosed, X_AXIS, get_grob_direction (me)); + Stencil b = Bracket::make_enclosing_bracket (me, me, enclosed, X_AXIS, + get_grob_direction (me)); return b.smobbed_copy (); } diff --git a/lily/include/bracket.hh b/lily/include/bracket.hh new file mode 100644 index 0000000000..c58ebfc3f9 --- /dev/null +++ b/lily/include/bracket.hh @@ -0,0 +1,40 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 1997--2015 Han-Wen Nienhuys + + 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 . +*/ + +#ifndef BRACKET_HH +#define BRACKET_HH + +#include "lily-proto.hh" +#include "grob-interface.hh" +#include "std-vector.hh" + +struct Bracket +{ + static Stencil make_bracket (Grob *me, Axis protrusion_axis, + Offset dz, Drul_array height, + Interval gap, Drul_array flare, + Drul_array shorten); + static Stencil make_axis_constrained_bracket (Grob *me, Real length, + Axis a, Direction dir); + static Stencil make_enclosing_bracket (Grob *me, Grob *refpoint, + vector grobs, + Axis a, Direction dir); +}; + +#endif /* BRACKET_HH */ diff --git a/lily/include/horizontal-bracket.hh b/lily/include/horizontal-bracket.hh index 3a1692fc11..bfc76b7a0d 100644 --- a/lily/include/horizontal-bracket.hh +++ b/lily/include/horizontal-bracket.hh @@ -21,16 +21,11 @@ #define HORIZONTAL_BRACKET_HH #include "lily-proto.hh" -#include "std-vector.hh" #include "grob-interface.hh" struct Horizontal_bracket { DECLARE_SCHEME_CALLBACK (print, (SCM)); - static Stencil make_bracket (Grob *, Real, Axis, Direction); - static Stencil make_enclosing_bracket (Grob *me, Grob *refpoint, - vector grobs, - Axis a, Direction dir); }; #endif /* HORIZONTAL_BRACKET_HH */ diff --git a/lily/include/tuplet-bracket.hh b/lily/include/tuplet-bracket.hh index 1e41154fbf..cfe1ca1481 100644 --- a/lily/include/tuplet-bracket.hh +++ b/lily/include/tuplet-bracket.hh @@ -43,10 +43,6 @@ public: static Grob *parallel_beam (Grob *me, vector const &cols, bool *equally_long); static void calc_position_and_height (Grob *, Real *, Real *dy); - static Stencil make_bracket (Grob *me, Axis protrusion_axis, - Offset dz, Drul_array height, - Interval gap, Drul_array widen, - Drul_array shorten); static Direction get_default_dir (Grob *); }; diff --git a/lily/ottava-bracket.cc b/lily/ottava-bracket.cc index 63a9d3ebca..cc33d8b152 100644 --- a/lily/ottava-bracket.cc +++ b/lily/ottava-bracket.cc @@ -28,7 +28,7 @@ #include "staff-symbol-referencer.hh" #include "note-column.hh" #include "directional-element-interface.hh" -#include "tuplet-bracket.hh" +#include "bracket.hh" #include "rhythmic-head.hh" #include "pointer-group-interface.hh" @@ -151,12 +151,11 @@ Ottava_bracket::print (SCM smob) 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), - edge_height, - empty, - flare, Drul_array (0, 0)); + b = Bracket::make_bracket ( + me, Y_AXIS, Offset (bracket_span_points.length (), 0), + edge_height, empty, flare, Drul_array (0, 0)); /* * The vertical lines should not take space, for the following scenario: diff --git a/lily/piano-pedal-bracket.cc b/lily/piano-pedal-bracket.cc index b47e5e3b6d..d13f56414f 100644 --- a/lily/piano-pedal-bracket.cc +++ b/lily/piano-pedal-bracket.cc @@ -20,7 +20,7 @@ #include "stencil.hh" #include "spanner.hh" #include "item.hh" -#include "tuplet-bracket.hh" +#include "bracket.hh" #include "axis-group-interface.hh" struct Piano_pedal_bracket @@ -89,11 +89,9 @@ Piano_pedal_bracket::print (SCM smob) if (!span_points.is_empty () && span_points.length () > 0.001) { - m = Tuplet_bracket::make_bracket (me, Y_AXIS, - Offset (span_points.length (), 0), - height, - Interval (), - flare, shorten); + m = Bracket::make_bracket ( + me, Y_AXIS, Offset (span_points.length (), 0), height, + Interval (), flare, shorten); } m.translate_axis (span_points[LEFT] - me->relative_coordinate (common, X_AXIS), X_AXIS); diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index 340b017723..3228c9f7b6 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -41,6 +41,8 @@ */ #include "tuplet-bracket.hh" + +#include "bracket.hh" #include "axis-group-interface.hh" #include "line-interface.hh" #include "beam.hh" @@ -373,15 +375,15 @@ Tuplet_bracket::print (SCM smob) } } - 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); + 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)) { @@ -396,64 +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; - - for (LEFT_and_RIGHT (d)) - straight_corners[d] += -d * shorten[d] / length * dz; - - if (!gap.is_empty ()) - { - for (LEFT_and_RIGHT (d)) - gap_corners[d] = (dz * 0.5) + gap[d] / length * dz; - } - - Drul_array flare_corners = straight_corners; - for (LEFT_and_RIGHT (d)) - { - 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]; - } - - Stencil m; - if (!gap.is_empty ()) - for (LEFT_and_RIGHT (d)) - m.add_stencil (Line_interface::line (me, straight_corners[d], - gap_corners[d])); - else - m.add_stencil (Line_interface::line (me, straight_corners[LEFT], - straight_corners[RIGHT])); - - if (scm_is_number (me->get_property ("dash-fraction"))) - me->set_property ("dash-fraction", scm_from_double (1.0)); - for (LEFT_and_RIGHT (d)) - m.add_stencil (Line_interface::line (me, straight_corners[d], - flare_corners[d])); - return m; -} - void Tuplet_bracket::get_bounds (Grob *me, Grob **left, Grob **right) { diff --git a/lily/volta-bracket.cc b/lily/volta-bracket.cc index 9ac2b44637..e337a34b34 100644 --- a/lily/volta-bracket.cc +++ b/lily/volta-bracket.cc @@ -31,7 +31,7 @@ using namespace std; #include "side-position-interface.hh" #include "directional-element-interface.hh" #include "lookup.hh" -#include "tuplet-bracket.hh" +#include "bracket.hh" #include "lily-imports.hh" /* @@ -94,12 +94,9 @@ Volta_bracket_interface::print (SCM smob) Offset start; start[X_AXIS] = me->spanner_length () - left; - /* - ugh, Tuplet_bracket should use Horizontal_bracket, not the other way around. - */ Stencil total - = Tuplet_bracket::make_bracket (me, Y_AXIS, start, - edge_height, empty, flare, shorten); + = Bracket::make_bracket (me, Y_AXIS, start, edge_height, empty, + flare, shorten); if (!orig_span || broken_first_bracket) {