static int line_count (Grob *);
static Real get_position (Grob *);
static Real pure_get_position (Grob *);
+
+ /**
+ Interval of staff lines.
+ */
+ static Interval staff_span (Grob *);
+
+ /**
+ Half of the height, in staff space, i.e. 2.0 for a normal staff.
+ */
static Real staff_radius (Grob *);
+
static int get_rounded_position (Grob *);
static int pure_get_rounded_position (Grob *);
static Interval extent_in_staff (Grob *);
Real rounded = directed_round (position, dir);
Grob *head = me->get_parent (X_AXIS);
- if (fabs (position) <= 2 * Staff_symbol_referencer::staff_radius (me) + 1
+ Interval staff_span = Staff_symbol::line_span (staff);
+ staff_span.widen (1);
+ if (staff_span.contains (position)
/* In case of a ledger lines, quantize even if we're outside the staff. */
|| (Note_head::has_interface (head)
Real p = 2 * (y - staff->relative_coordinate (state.common_[Y_AXIS], Y_AXIS))
/ state.staff_space_;
- Real distance = fabs (my_round (p) - p); // in halfspaces
- if (distance < 4 * state.thickness_
- && (int) fabs (my_round (p))
- <= 2 * Staff_symbol_referencer::staff_radius (staff) + 0.1
- && (int (fabs (my_round (p))) % 2
- != Staff_symbol_referencer::line_count (staff) % 2))
+ Real const round = my_round (p);
+ Real const frac = p - round;
+ if (fabs (frac) < 4 * state.thickness_
+ && Staff_symbol_referencer::on_staff_line (staff, int (round)))
{
- Direction resolution_dir
- = (distance ? state.dir_ : Direction (sign (p - my_round (p))));
+ Direction resolution_dir = frac ? state.dir_ : CENTER;
// TODO: parameter
- Real newp = my_round (p) + resolution_dir
- * 5 * state.thickness_;
+ Real newp = round + resolution_dir * 5 * state.thickness_;
Real dy = (newp - p) * state.staff_space_ / 2.0;
}
add_score (demerit, "encompass");
- if (convex_head_distances.size ())
+ if (vsize n = convex_head_distances.size ())
{
Real avg_distance = 0.0;
Real min_dist = infinity_f;
- for (vsize j = 0; j < convex_head_distances.size (); j++)
+
+ for (vsize j = 0; j < n; j++)
{
min_dist = min (min_dist, convex_head_distances[j]);
avg_distance += convex_head_distances[j];
For slurs over 3 or 4 heads, the average distance is not a
good normalizer.
*/
- Real n = convex_head_distances.size ();
if (n <= 2)
{
Real fact = 1.0;
avg_distance += height_ * fact;
- n += fact;
+ ++n;
}
/*
me->translate_axis ((p - oldpos) * ss * 0.5, Y_AXIS);
}
-/* Half of the height, in staff space, i.e. 2.0 for a normal staff. */
+Interval
+Staff_symbol_referencer::staff_span (Grob *me)
+{
+ Interval result;
+ if (me)
+ if (Grob *symb = get_staff_symbol (me))
+ result = Staff_symbol::line_span (symb);
+ return result;
+}
+
Real
Staff_symbol_referencer::staff_radius (Grob *me)
{
- return (line_count (me) - 1) / 2.0;
+ /*
+ line_span is measured in pitch steps, not in staff spaces
+ */
+ return staff_span (me).length () / 4.0;
}
int
size.
*/
+ Interval staff_span =
+ Staff_symbol_referencer::staff_span (details_.staff_symbol_referencer_);
+ staff_span.widen (-1);
+ bool const within_staff = staff_span.contains(pos);
if (head_positions_slice (columns[LEFT]).contains (pos)
|| head_positions_slice (columns[RIGHT]).contains (pos)
- || abs (pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_))
+ || within_staff)
{
if (h < details_.intra_space_threshold_ * 0.5 * details_.staff_space_)
{
- if (!Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos)
- && abs (pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_))
- {
- conf->center_tie_vertically (details_);
- }
- else if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos))
+ if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos))
{
conf->delta_y_ += dir *
details_.tip_staff_line_clearance_ * 0.5 * details_.staff_space_;
}
+ else if (within_staff)
+ {
+ conf->center_tie_vertically (details_);
+ }
}
else
{
Real top_y = tip_y + conf->dir_ * height;
Real top_pos = 2 * top_y / details_.staff_space_;
Real round_top_pos = rint (top_pos);
+ Interval staff_span =
+ Staff_symbol_referencer::staff_span (details_.staff_symbol_referencer_);
if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_,
int (round_top_pos))
- && Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_) > top_y)
+ && staff_span[UP] * 0.5 > top_y)
{
conf->add_score (details_.staff_line_collision_penalty_
* peak_around (0.1 * details_.center_staff_line_clearance_,
}
int rounded_tip_pos = int (rint (tip_pos));
+ staff_span.widen (-1);
if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, rounded_tip_pos)
&& (head_positions_slice (conf->column_ranks_[LEFT]).contains (rounded_tip_pos)
|| head_positions_slice (conf->column_ranks_[RIGHT]).contains (rounded_tip_pos)
- || abs (rounded_tip_pos) < 2 * Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_))
+ || staff_span.contains (rounded_tip_pos))
)
{
conf->add_score (details_.staff_line_collision_penalty_
/*
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;
}