/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org>
+ Copyright (C) 1997--2011 Jan Nieuwenhuizen <janneke@gnu.org>
Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
todo: handle breaking elegantly.
*/
-
#include "tuplet-bracket.hh"
#include "line-interface.hh"
#include "beam.hh"
return g;
}
-
void
flatten_number_pair_property (Grob *me, Direction xdir, SCM sym)
{
me->set_property (sym, ly_interval2scm (pair));
}
-
/*
Return beam that encompasses the span of the tuplet bracket.
*/
Grob *
-Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols,
+Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob *> const &cols,
bool *equally_long)
{
Spanner *me = dynamic_cast<Spanner *> (me_grob);
return 0;
Drul_array<Grob *> stems (Note_column::get_stem (cols[0]),
- Note_column::get_stem (cols.back ()));
+ Note_column::get_stem (cols.back ()));
if (!stems[RIGHT]
|| !stems[LEFT]
- || (dynamic_cast<Item*> (stems[RIGHT])->get_column ()
+ || (dynamic_cast<Item *> (stems[RIGHT])->get_column ()
!= me->get_bound (RIGHT)->get_column ()))
return 0;
Drul_array<Grob *> beams;
Direction d = LEFT;
- do {
+ do
beams[d] = stems[d] ? Stem::get_beam (stems[d]) : 0;
- } while (flip (&d) != LEFT);
+ while (flip (&d) != LEFT);
*equally_long = false;
- if (!(beams[LEFT] && (beams[LEFT] == beams[RIGHT]) && !me->is_broken ()))
+ if (! (beams[LEFT] && (beams[LEFT] == beams[RIGHT]) && !me->is_broken ()))
return 0;
extract_grob_set (beams[LEFT], "stems", beam_stems);
return 0;
}
- *equally_long =
- (beam_stems[0] == stems[LEFT]
- && beam_stems.back () == stems[RIGHT]);
+ *equally_long
+ = (beam_stems[0] == stems[LEFT]
+ && beam_stems.back () == stems[RIGHT]);
return beams[LEFT];
}
-
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);
+ 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
}
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 *
+Grob *
Tuplet_bracket::get_common_x (Spanner *me)
{
extract_grob_set (me, "note-columns", columns);
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));
+ 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;
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);
+ 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);
+ 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 = robust_relative_extent (bounds[d], commonx, X_AXIS)[LEFT];
coord = max (coord, x_span[LEFT]);
}
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])));
bool equally_long = false;
Grob *par_beam = parallel_beam (me, columns, &equally_long);
- bool bracket_visibility = !(par_beam && equally_long);
+ bool bracket_visibility = !(par_beam && equally_long); // Flag, print/don't print tuplet bracket.
/*
- Fixme: the type of this prop is sucky.
+ FIXME: The type of this prop is sucky.
*/
- SCM bracket = me->get_property ("bracket-visibility");
- if (scm_is_bool (bracket))
- bracket_visibility = ly_scm2bool (bracket);
- else if (bracket == ly_symbol2scm ("if-no-beam"))
+ 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"));
+ if (scm_is_bool (bracket_vis_prop))
+ bracket_visibility = bracket_prop;
+ else if (bracket)
bracket_visibility = !par_beam;
-
+
/*
Don't print a tuplet bracket and number if
no control-points were calculated
return SCM_EOL;
}
/* if the tuplet does not span any time, i.e. a single-note tuplet, hide
- the bracket, but still let the number be displayed */
- if (robust_scm2moment (me->get_bound (LEFT)->get_column ()->get_property ("when"), Moment (0))
- == robust_scm2moment (me->get_bound (RIGHT)->get_column ()->get_property ("when"), Moment (0)))
- {
- bracket_visibility = false;
- }
+ the bracket, but still let the number be displayed.
+ Only do this if the user has not explicitly specified bracket-visibility = #t.
+ */
+ if (!to_boolean (bracket_vis_prop)
+ && (robust_scm2moment (me->get_bound (LEFT)->get_column ()->get_property ("when"), Moment (0))
+ == robust_scm2moment (me->get_bound (RIGHT)->get_column ()->get_property ("when"), Moment (0))))
+ bracket_visibility = false;
Drul_array<Offset> points;
points[LEFT] = ly_scm2offset (scm_car (cpoints));
Grob *number_grob = unsmob_grob (me->get_object ("tuplet-number"));
/*
- No bracket when it would be smaller than the number.
+ Don't print the bracket when it would be smaller than the number.
+ ...Unless the user has coded bracket-visibility = #t, that is.
*/
Real gap = 0.;
if (bracket_visibility && number_grob)
{
gap = ext.length () + 1.0;
- if (0.75 * x_span.length () < gap)
+ if ((0.75 * x_span.length () < gap) && !bracket_prop)
bracket_visibility = false;
}
}
scale_drul (&flare, ss);
scale_drul (&shorten, ss);
- Drul_array<bool> connect_to_other =
- robust_scm2booldrul (me->get_property ("connect-to-neighbor"),
- Drul_array<bool> (false, false));
+ Drul_array<bool> connect_to_other
+ = robust_scm2booldrul (me->get_property ("connect-to-neighbor"),
+ Drul_array<bool> (false, false));
Direction d = LEFT;
do
l++;
vsize r = columns.size ();
- while (r > l && Note_column::has_rests (columns[r-1]))
+ while (r > l && Note_column::has_rests (columns[r - 1]))
r--;
*left = *right = 0;
if (l < r)
{
*left = columns[l];
- *right = columns[r-1];
+ *right = columns[r - 1];
}
}
if (st && !to_boolean (me->get_property ("cross-staff")))
{
Real pad = robust_scm2double (me->get_property ("staff-padding"), -1.0);
- if (pad >= 0.0)
+ if (pad >= 0.0)
{
staff = st->extent (commony, Y_AXIS) - my_offset;
staff.widen (pad);
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"));
+ && !to_boolean (par_beam->get_property ("knee"));
vector<Offset> points;
if (columns.size ()
{
/*
trigger set_stem_ends
- */
+ */
(void) par_beam->get_property ("quantized-positions");
Drul_array<Grob *> stems (Note_column::get_stem (columns[0]),
Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0)
- + stems[LEFT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
+ + stems[LEFT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0)
- + stems[RIGHT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
+ + stems[RIGHT]->get_parent (Y_AXIS)->relative_coordinate (commony, Y_AXIS);
*dy = rp - lp;
points.push_back (Offset (stems[LEFT]->relative_coordinate (commonx, X_AXIS) - x0, lp));
points.push_back (Offset (x0 - x0, staff[dir]));
points.push_back (Offset (x1 - x0, staff[dir]));
}
-
+
/*
This is a slight hack. We compute two encompass points from the
bbox of the smaller tuplets.
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
for (vsize i = 0; i < columns.size (); i++)
{
Grob *nc = columns[i];
+ if (Note_column::has_rests (nc))
+ continue;
Direction d = Note_column::dir (nc);
if (d)
dirs[d]++;
}
- return dirs[UP] >= dirs[DOWN] ? UP : DOWN;
+ if (dirs[UP] == dirs[DOWN])
+ {
+ if (dirs[UP] == 0)
+ return UP;
+ Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
+ if (!staff)
+ return UP;
+ Interval staff_extent = staff->extent (staff, Y_AXIS);
+ Interval extremal_positions;
+ extremal_positions.set_empty ();
+ for (vsize i = 0; i < columns.size (); i++)
+ {
+ 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
+ extremal_positions[d] = -d * (staff_extent[d] - extremal_positions[d]);
+ while (flip (&d) != LEFT);
+
+ return extremal_positions[UP] <= extremal_positions[DOWN] ? UP : DOWN;
+ }
+
+ return dirs[UP] > dirs[DOWN] ? UP : DOWN;
}
void