+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_connect_to_neighbors, 1);
+SCM
+Tuplet_bracket::calc_connect_to_neighbors (SCM smob)
+{
+ Spanner *me = unsmob_spanner (smob);
+
+ Direction dir = get_grob_direction (me);
+ Drul_array<Item *> bounds (get_x_bound_item (me, LEFT, dir),
+ get_x_bound_item (me, RIGHT, dir));
+
+ Drul_array<bool> connect_to_other (false, false);
+ Direction d = LEFT;
+ do
+ {
+ Direction break_dir = bounds[d]->break_status_dir ();
+ Spanner *orig_spanner = dynamic_cast<Spanner *> (me->original ());
+ vsize neighbor_idx = me->get_break_index () - break_dir;
+ if (break_dir
+ && d == RIGHT
+ && neighbor_idx < orig_spanner->broken_intos_.size ())
+ {
+ Grob *neighbor = orig_spanner->broken_intos_[neighbor_idx];
+
+ /* trigger possible suicide*/
+ (void) neighbor->get_property ("positions");
+ }
+
+ connect_to_other[d]
+ = (break_dir
+ && 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]),
+ scm_from_bool (connect_to_other[RIGHT]));
+
+ return SCM_EOL;
+}
+
+Grob *
+Tuplet_bracket::get_common_x (Spanner *me)
+{
+ extract_grob_set (me, "note-columns", columns);
+
+ Grob *commonx = common_refpoint_of_array (columns, me, X_AXIS);
+ commonx = commonx->common_refpoint (me->get_bound (LEFT), X_AXIS);
+ commonx = commonx->common_refpoint (me->get_bound (RIGHT), X_AXIS);
+
+ return commonx;
+}
+
+MAKE_SCHEME_CALLBACK (Tuplet_bracket, calc_control_points, 1)
+SCM
+Tuplet_bracket::calc_control_points (SCM smob)
+{
+ Spanner *me = unsmob_spanner (smob);
+
+ extract_grob_set (me, "note-columns", columns);
+
+ SCM scm_positions = me->get_property ("positions");
+ if (!me->is_live ())
+ return SCM_EOL;
+
+ if (!scm_is_pair (scm_positions))
+ programming_error ("Positions should be number pair");
+
+ Drul_array<Real> positions
+ = robust_scm2drul (scm_positions, Drul_array<Real> (0, 0));
+
+ Grob *commonx = get_common_x (me);
+ Direction dir = get_grob_direction (me);
+
+ Drul_array<Item *> bounds;
+ bounds[LEFT] = get_x_bound_item (me, LEFT, dir);
+ bounds[RIGHT] = get_x_bound_item (me, RIGHT, dir);
+
+ Drul_array<bool> connect_to_other
+ = robust_scm2booldrul (me->get_property ("connect-to-neighbor"),
+ Drul_array<bool> (false, false));
+
+ Interval x_span;
+ Direction d = LEFT;
+ do
+ {
+ x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[d];
+
+ if (connect_to_other[d])
+ {
+ Interval overshoot (robust_scm2drul (me->get_property ("break-overshoot"),
+ Interval (-0.5, 0.0)));
+
+ if (d == RIGHT)
+ x_span[d] += d * overshoot[d];
+ else
+ x_span[d] = robust_relative_extent (bounds[d],
+ commonx, X_AXIS)[RIGHT]
+ - overshoot[LEFT];
+ }
+
+ else if (d == RIGHT
+ && (columns.empty ()
+ || (bounds[d]->get_column ()
+ != dynamic_cast<Item *> (columns.back ())->get_column ())))
+ {
+ /*
+ We're connecting to a column, for the last bit of a broken
+ fullLength bracket.
+ */
+ Real padding
+ = robust_scm2double (me->get_property ("full-length-padding"), 1.0);
+
+ if (bounds[d]->break_status_dir ())
+ padding = 0.0;
+
+ Real coord = bounds[d]->relative_coordinate (commonx, X_AXIS);
+ if (to_boolean (me->get_property ("full-length-to-extent")))
+ coord = robust_relative_extent (bounds[d], commonx, X_AXIS)[LEFT];
+
+ coord = max (coord, x_span[LEFT]);
+
+ x_span[d] = coord - padding;
+ }
+ }
+ while (flip (&d) != LEFT);
+
+ x_span -= me->get_bound (LEFT)->relative_coordinate (commonx, X_AXIS);
+ return scm_list_2 (ly_offset2scm (Offset (x_span[LEFT], positions[LEFT])),
+ ly_offset2scm (Offset (x_span[RIGHT], positions[RIGHT])));
+}