source file of the GNU LilyPond music typesetter
- (c) 1997--2005 Jan Nieuwenhuizen <janneke@gnu.org>
+ (c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
#include "lookup.hh"
+#include "paper-column.hh"
+#include "moment.hh"
static Item *
get_x_bound_item (Grob *me_grob, Direction hdir, Direction my_dir)
Direction xdir, SCM sym)
{
Drul_array<Real> zero (0, 0);
- Drul_array<Real> pair = robust_scm2drul (me->internal_get_property (sym), zero);
+ Drul_array<Real> pair
+ = robust_scm2drul (me->internal_get_property (sym), zero);
pair[xdir] = 0.0;
- me->internal_set_property (sym, ly_interval2scm (pair));
+ 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, Link_array<Grob> const &cols, bool *equally_long)
+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.top ()));
+ Note_column::get_stem (cols.back ()));
if (dynamic_cast<Item*> (stems[RIGHT])->get_column ()
!= me->get_bound (RIGHT)->get_column())
return 0;
}
- *equally_long = (beam_stems[0] == stems[LEFT] && beam_stems.top () == stems[RIGHT]);
+ *equally_long =
+ (beam_stems[0] == stems[LEFT]
+ && beam_stems.back () == stems[RIGHT]);
return beams[LEFT];
}
Spanner *orig_spanner = dynamic_cast<Spanner*> (me->original ());
- int neighbor_idx = me->get_break_index () - break_dir;
+ vsize neighbor_idx = me->get_break_index () - break_dir;
if (break_dir
&& d == RIGHT
&& neighbor_idx < orig_spanner->broken_intos_.size ())
connect_to_other[d]
= (break_dir
- && (neighbor_idx < orig_spanner->broken_intos_.size ()
- && neighbor_idx >= 0)
+ && neighbor_idx < orig_spanner->broken_intos_.size ()
&& orig_spanner->broken_intos_[neighbor_idx]->is_live ());
}
while (flip (&d) != LEFT);
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
- = ly_scm2realdrul (me->get_property ("positions"));
+ = robust_scm2drul (scm_positions, Drul_array<Real> (0,0));
Grob *commonx = get_common_x (me);
Direction dir = get_grob_direction (me);
bounds[RIGHT] = get_x_bound_item (me, RIGHT, dir);
Drul_array<bool> connect_to_other =
- robust_scm2booldrul (me->get_property ("connect-to-other"),
+ robust_scm2booldrul (me->get_property ("connect-to-neighbor"),
Drul_array<bool> (false, false));
x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS)[RIGHT]
- overshoot[LEFT];
}
+
else if (d == RIGHT
- && (columns.is_empty ()
+ && (columns.empty ()
|| (bounds[d]->get_column ()
- != dynamic_cast<Item *> (columns.top ())->get_column ())))
+ != dynamic_cast<Item *> (columns.back ())->get_column ())))
{
/*
+ We're connecting to a column, for the last bit of a broken
+ fullLength bracket.
+
TODO: make padding tunable?
*/
Real padding = 1.0;
if (bounds[d]->break_status_dir ())
padding = 0.0;
- x_span[d] = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT] - padding;
+ x_span[d]
+ = robust_relative_extent (bounds[d], commonx, X_AXIS) [LEFT]
+ - padding;
}
}
while (flip (&d) != LEFT);
scale_drul (&shorten, ss);
Drul_array<bool> connect_to_other =
- robust_scm2booldrul (me->get_property ("connect-to-other"),
+ robust_scm2booldrul (me->get_property ("connect-to-neighbor"),
Drul_array<bool> (false, false));
Direction d = LEFT;
Direction d = LEFT;
do
straight_corners[d] += -d * shorten[d] / length * dz;
- while (flip (&d) != LEFT)
- ;
+ while (flip (&d) != LEFT);
- if (gap.is_empty ())
- gap = Interval (0, 0);
- do
- gap_corners[d] = (dz * 0.5) + gap[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<Offset> flare_corners = straight_corners;
do
Stencil m;
do
{
- m.add_stencil (Line_interface::line (me, straight_corners[d],
- gap_corners[d]));
+ 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;
}
Tuplet_bracket::get_bounds (Grob *me, Grob **left, Grob **right)
{
extract_grob_set (me, "note-columns", columns);
- int l = 0;
+ vsize l = 0;
while (l < columns.size () && Note_column::has_rests (columns[l]))
l++;
- int r = columns.size ()- 1;
- while (r >= l && Note_column::has_rests (columns[r]))
+ vsize r = columns.size ();
+ while (r > l && Note_column::has_rests (columns[r-1]))
r--;
*left = *right = 0;
- if (l <= r)
+ if (l < r)
{
*left = columns[l];
- *right = columns[r];
+ *right = columns[r-1];
}
}
Real x0 = robust_relative_extent (lgr, commonx, X_AXIS)[LEFT];
Real x1 = robust_relative_extent (rgr, commonx, X_AXIS)[RIGHT];
- Array<Offset> points;
- points.push (Offset (x0 - x0, staff[dir]));
- points.push (Offset (x1 - x0, staff[dir]));
+ vector<Offset> points;
+ points.push_back (Offset (x0 - x0, staff[dir]));
+ points.push_back (Offset (x1 - x0, staff[dir]));
- for (int i = 0; i < columns.size (); i++)
+ for (vsize i = 0; i < columns.size (); i++)
{
Interval note_ext = columns[i]->extent (commony, Y_AXIS);
Real notey = note_ext[dir] - me->relative_coordinate (commony, Y_AXIS);
Real x = columns[i]->relative_coordinate (commonx, X_AXIS) - x0;
- points.push (Offset (x, notey));
+ points.push_back (Offset (x, notey));
}
/*
We assume that the smaller bracket is 1.0 space high.
*/
Real ss = Staff_symbol_referencer::staff_space (me);
- for (int i = 0; i < tuplets.size (); i++)
+ for (vsize i = 0; i < tuplets.size (); i++)
{
Interval tuplet_x (tuplets[i]->extent (commonx, X_AXIS));
Interval tuplet_y (tuplets[i]->extent (commony, Y_AXIS));
+ if (!tuplets[i]->is_live ())
+ continue;
+
Direction d = LEFT;
- Drul_array<Real> positions = ly_scm2realdrul (tuplets[i]->get_property ("positions"));
+ Drul_array<Real> positions = robust_scm2interval (tuplets[i]->get_property ("positions"),
+ Interval (0,0));
Real other_dy = positions[RIGHT] - positions[LEFT];
Real y
= tuplet_y.linear_combination (d * sign (other_dy));
-#if 0
/*
- Let's not take padding into account for nested tuplets.
+ We don't take padding into account for nested tuplets.
the edges can come very close to the stems, likewise for
nested tuplets?
*/
- Drul_array<Real> my_height
- = robust_scm2drul (me->get_property ("edge-height"),
- Interval (0, 0));
- if (dynamic_cast<Spanner *> (tuplets[i])->get_bound (d)
- == me->get_bound (d))
- y += dir * my_height[d];
-#endif
-
- points.push (Offset (tuplet_x[d] - x0, y));
+
+ points.push_back (Offset (tuplet_x[d] - x0, y));
}
while (flip (&d) != LEFT);
}
Real factor = (columns.size () > 1) ? 1 / (x1 - x0) : 1.0;
- for (int i = 0; i < points.size (); i++)
+ for (vsize i = 0; i < points.size (); i++)
{
Real x = points[i][X_AXIS];
Real tuplety = (*dy) * x * factor;
*offset *= 2 / ss;
*offset = rint (*offset);
- if (Staff_symbol_referencer::on_staffline (me, (int) rint (*offset)))
+ if (Staff_symbol_referencer::on_line (me, (int) rint (*offset)))
*offset += dir;
*offset *= 0.5 * ss;
SCM
Tuplet_bracket::calc_positions (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Spanner *me = unsmob_spanner (smob);
extract_grob_set (me, "note-columns", columns);
- if (columns.is_empty())
+ /*
+ Don't print if it doesn't span time.
+ */
+ 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)))
{
me->suicide ();
- return scm_cons (scm_from_double (0),
- scm_from_double (0));
+ return SCM_EOL;
}
+
Direction dir = get_grob_direction (me);
bool equally_long = false;
if (!par_beam
|| get_grob_direction (par_beam) != dir)
calc_position_and_height (me, &offset, &dy);
- else
+ else if (columns.size ()
+ && Note_column::get_stem (columns[0])
+ && Note_column::get_stem (columns.back ()))
{
- SCM ps = par_beam->get_property ("positions");
+ /*
+ trigger set_stem_ends
+ */
+ (void) par_beam->get_property ("quantized-positions");
- Real lp = scm_to_double (scm_car (ps));
- Real rp = scm_to_double (scm_cdr (ps));
- /*
- duh. magic.
- */
+ Drul_array<Grob *> stems (Note_column::get_stem (columns[0]),
+ Note_column::get_stem (columns.back ()));
+
+
+
+
+ Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
+ Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0);
+ Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0);
+
+
offset = lp + dir * (0.5 + scm_to_double (me->get_property ("padding")));
- dy = rp - lp;
+ dy = (rp - lp);
}
{
Drul_array<int> dirs (0, 0);
extract_grob_set (me, "note-columns", columns);
- for (int i = 0; i < columns.size (); i++)
+ for (vsize i = 0; i < columns.size (); i++)
{
Grob *nc = columns[i];
Direction d = Note_column::dir (nc);
}
ADD_INTERFACE (Tuplet_bracket,
- "tuplet-bracket-interface",
"A bracket with a number in the middle, used for tuplets. "
"When the bracket spans a line break, the value of "
"@code{break-overshoot} determines how far it extends "