2005-12-19 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/slur-engraver.cc (acknowledge_tuplet_number): new function.
+
* flower/include/offset.hh (class Offset): new operator /=
* lily/tuplet-number.cc (print): new file, new interface.
@itemize @bullet
+
+@item Tuplet brackets and numbers are implemented as separate grobs,
+@code{TupletBracket} and @code{TupletNumber}.
+
@item String arguments for music functions may be specified without
@code{#} marks. This allows syntactical constructs (like \clef and
\bar) to be expressed in generic music functions.
Real non_horizontal_penalty_;
Real max_slope_;
Real max_slope_factor_;
- Real extra_object_collision_;
+ Real extra_object_collision_penalty_;
Real accidental_collision_;
Real free_slur_distance_;
Real free_head_distance_;
Box extents_;
Real penalty_;
Grob *grob_;
+ SCM type_;
+
+ Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p);
+ Extra_collision_info ();
- Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p)
- {
- idx_ = idx;
- extents_[X_AXIS] = x;
- extents_[Y_AXIS] = y;
- penalty_ = p;
- grob_ = g;
- }
- Extra_collision_info ()
- {
- idx_ = 0.0;
- penalty_ = 0.;
- grob_ = 0;
- }
};
struct Encompass_info
for (int j = 0; j < state.extra_encompass_infos_.size (); j++)
{
Drul_array<Offset> attachment = attachment_;
+ Extra_collision_info const &info (state.extra_encompass_infos_[j]);
+
Interval slur_wid (attachment[LEFT][X_AXIS], attachment[RIGHT][X_AXIS]);
/*
if (!found)
{
- Real x = state.extra_encompass_infos_[j].extents_[X_AXIS]
- .linear_combination (state.extra_encompass_infos_[j].idx_);
+ Real x = info.extents_[X_AXIS].linear_combination (info.idx_);
if (!slur_wid.contains (x))
continue;
y = curve_.get_other_coordinate (X_AXIS, x);
}
- Real dist = state.extra_encompass_infos_[j].extents_[Y_AXIS].distance (y);
+ Real dist = 0.0;
+ if (info.type_ == ly_symbol2scm ("avoid"))
+ dist = info.extents_[Y_AXIS].distance (y);
+
+ /*
+ Have to score too: the curve enumeration is limited in its
+ shape, and may produce curves which collide anyway.
+ */
+ else if (info.type_ == ly_symbol2scm ("inside"))
+ dist = state.dir_ * (y - info.extents_[Y_AXIS][state.dir_]);
+ else
+ programming_error ("unknown avoidance type");
+
+ Real epsilon = 0.1;
+ Real factor
+ = (1.0 / (max (dist, 0.0) + epsilon * state.parameters_.extra_encompass_free_distance_));
+ Real threshold
+ = 1.0 / ((1 + epsilon) * state.parameters_.extra_encompass_free_distance_);
+
+
demerit
- += fabs (max (0.0, (state.parameters_.extra_encompass_free_distance_ - dist)))
- / state.parameters_.extra_encompass_free_distance_
- * state.extra_encompass_infos_[j].penalty_;
+ += max (info.penalty_ * (factor - threshold), 0.0);
}
#if DEBUG_SLUR_SCORING
score_card_ += to_string ("X%.2f", demerit);
#endif
+
score_ += demerit;
}
DECLARE_ACKNOWLEDGER (script);
DECLARE_ACKNOWLEDGER (text_script);
DECLARE_ACKNOWLEDGER (tie);
+ DECLARE_ACKNOWLEDGER (tuplet_number);
void acknowledge_extra_object (Grob_info);
void stop_translation_timestep ();
virtual void finalize ();
e->set_object ("slur", slur->self_scm ());
}
}
+ else
+ e->warning ("Ignoring grob for slur. avoid-slur not set?");
}
void
acknowledge_extra_object (info);
}
+void
+Slur_engraver::acknowledge_tuplet_number (Grob_info info)
+{
+ acknowledge_extra_object (info);
+}
+
+
void
Slur_engraver::acknowledge_script (Grob_info info)
{
ADD_ACKNOWLEDGER (Slur_engraver, script);
ADD_ACKNOWLEDGER (Slur_engraver, text_script);
ADD_ACKNOWLEDGER (Slur_engraver, tie);
+ADD_ACKNOWLEDGER (Slur_engraver, tuplet_number);
ADD_TRANSLATOR (Slur_engraver,
/* doc */ "Build slur grobs from slur events",
/* create */ "Slur",
void
Slur_score_parameters::fill (Grob *me)
{
- SCM details = me->get_property ("slur-details");
+ SCM details = me->get_property ("details");
region_size_
= (int) get_detail (details, ly_symbol2scm ("region-size"));
= get_detail (details, ly_symbol2scm ("free-head-distance"));
absolute_closeness_measure_
= get_detail (details, ly_symbol2scm ("absolute-closeness-measure"));
- extra_object_collision_
- = get_detail (details, ly_symbol2scm ("extra-object-collision"));
+ extra_object_collision_penalty_
+ = get_detail (details, ly_symbol2scm ("extra-object-collision-penalty"));
accidental_collision_
= get_detail (details, ly_symbol2scm ("accidental-collision"));
extra_encompass_free_distance_
extract_grob_set (slur_, "encompass-objects", extra_encompasses);
for (int i = 0; i < extra_encompasses.size (); i++)
- if (Slur::has_interface (extra_encompasses[i]))
- {
- Grob *small_slur = extra_encompasses[i];
- Bezier b = Slur::get_curve (small_slur);
+ {
+ if (Slur::has_interface (extra_encompasses[i]))
+ {
+ Grob *small_slur = extra_encompasses[i];
+ Bezier b = Slur::get_curve (small_slur);
- Offset z = b.curve_point (0.5);
- z += Offset (small_slur->relative_coordinate (common_[X_AXIS], X_AXIS),
- small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS));
+ Offset z = b.curve_point (0.5);
+ z += Offset (small_slur->relative_coordinate (common_[X_AXIS], X_AXIS),
+ small_slur->relative_coordinate (common_[Y_AXIS], Y_AXIS));
- z[Y_AXIS] += dir_ * parameters_.free_slur_distance_;
- avoid.push (z);
- }
+ z[Y_AXIS] += dir_ * parameters_.free_slur_distance_;
+ avoid.push (z);
+ }
+ else if (extra_encompasses[i]->get_property ("avoid-slur") == ly_symbol2scm ("inside"))
+ {
+ Grob *g = extra_encompasses [i];
+ Interval xe = g->extent (common_[X_AXIS], X_AXIS);
+ Interval ye = g->extent (common_[Y_AXIS], Y_AXIS);
+ if (!xe.is_empty ()
+ && !ye.is_empty ())
+ avoid.push (Offset (xe.center(), ye[dir_]));
+ }
+ }
return avoid;
}
k - 1.0,
xext,
yext,
- parameters_.extra_object_collision_);
+ parameters_.extra_object_collision_penalty_);
collision_infos.push (info);
}
}
Interval ye = g->extent (common_[Y_AXIS], Y_AXIS);
Real xp = 0.0;
- Real penalty = parameters_.extra_object_collision_;
+ Real penalty = parameters_.extra_object_collision_penalty_;
if (Accidental_interface::has_interface (g))
{
penalty = parameters_.accidental_collision_;
return collision_infos;
}
+
+Extra_collision_info::Extra_collision_info (Grob *g, Real idx, Interval x, Interval y, Real p)
+{
+ idx_ = idx;
+ extents_[X_AXIS] = x;
+ extents_[Y_AXIS] = y;
+ penalty_ = p;
+ grob_ = g;
+ type_ = g->get_property ("avoid-slur");
+}
+Extra_collision_info::Extra_collision_info ()
+{
+ idx_ = 0.0;
+ penalty_ = 0.;
+ grob_ = 0;
+ type_ = SCM_EOL;
+}
if (!slur)
return offset_scm;
+ SCM avoid = script->get_property ("avoid-slur");
+ if (avoid != ly_symbol2scm ("outside"))
+ return scm_from_int (0);
+
Direction dir = get_grob_direction (script);
if (dir == CENTER)
return offset_scm;
bool consider[] = { false, false, false };
Real ys[] = {0, 0, 0};
bool do_shift = false;
- SCM avoid = script->get_property ("avoid-slur");
-
+
for (int d = LEFT, k = 0; d <= RIGHT; d++, k++)
{
Real x = xext.linear_combination ((Direction) d);
/* Request shift if slur is contained script's Y, or if
script is inside slur and avoid == outside. */
if (yext.contains (ys[k])
- || (avoid == ly_symbol2scm ("outside")
- && dir * ys[k] > dir * yext[-dir]))
+ || dir * ys[k] > dir * yext[-dir])
do_shift = true;
}
}
"positions "
"quant-score "
"ratio "
- "slur-details "
+ "details "
"thickness ");
(size ,number? "Size of object, relative to standard size.")
(slope ,number? "The slope of this object.")
(slur-padding ,number? "Extra distance between slur and script.")
- (slur-details ,list?
- "An alist of scoring parameters for slur formatting")
(space-alist ,list? "A table that specifies distances between
prefatory items, like clef and time-signature. The format is an alist
of spacing tuples: @code{(@var{break-align-symbol} @var{type}
spaceable-grob-interface))))))
(PhrasingSlur
- . ((slur-details . ,default-slur-details)
+ . ((details . ,default-slur-details)
(control-points . ,Slur::calc_control_points)
(direction . ,Slur::calc_direction)
separation-spanner-interface))))))
(Slur
- . ((slur-details . ,default-slur-details)
+ . ((details . ,default-slur-details)
(control-points . ,Slur::calc_control_points)
(direction . ,Slur::calc_direction)
(stencil . ,Tuplet_number::print)
(font-shape . italic)
(font-size . -2)
+ (avoid-slur . inside)
(meta . ((class . Spanner)
(interfaces . (text-interface tuplet-number-interface
font-interface))))))
(max-slope-factor . 10)
(free-head-distance . 0.3)
(free-slur-distance . 0.8)
- (extra-object-collision . 50)
+ (extra-object-collision-penalty . 50)
(accidental-collision . 3)
(extra-encompass-free-distance . 0.3)
(head-slur-distance-max-ratio . 3)