+<<<<<<< ChangeLog
+2006-01-19 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/tie-formatting-problem.cc (generate_configuration): make
+ large ties avoid stafflines in the horizontal section.
+ (score_configuration): use softcoded penalties
+ (score_aptitude): idem.
+
+ * lily/tie-helper.cc (from_grob): softcode tie details
+
+ * lily/staff-symbol-referencer.cc (on_staff_line): new function
+
+ * lily/staff-symbol-referencer.cc (on_line): rename from
+ on_staffline
+
+=======
2006-01-18 Han-Wen Nienhuys <hanwen@xs4all.nl>
* ly/music-functions-init.ly: remove duplicate tag.
* lily/include/*.hh: GCC 4.1 fixes.
+>>>>>>> 1.4455
006-01-16 Erlend Aasland <erlenda@gmail.com>
* Documentation/user/global.itely: fix typos; @bugs -> @refbugs
int p = i->first;
if (p == k)
{
- if (Staff_symbol_referencer::on_staffline (i->second.dot_, p))
+ if (Staff_symbol_referencer::on_line (i->second.dot_, p))
p += d;
else
p += 2* d;
int p = i->first;
if (p == k)
{
- if (Staff_symbol_referencer::on_staffline (i->second.dot_, p))
+ if (Staff_symbol_referencer::on_line (i->second.dot_, p))
p += d;
else
p += 2* d;
remove_collision (cfg, p);
cfg[p] = dp;
- if (Staff_symbol_referencer::on_staffline (dp.dot_, p))
+ if (Staff_symbol_referencer::on_line (dp.dot_, p))
remove_collision (cfg, p);
}
#include "staff-symbol-referencer.hh"
#include "stem.hh"
+/*
+
+TODO: move to scheme
+
+*/
MAKE_SCHEME_CALLBACK (Note_head, brew_ez_stencil, 1);
SCM
Note_head::brew_ez_stencil (SCM smob)
static Real line_thickness (Grob *);
static Real staff_space (Grob *);
static Grob *get_staff_symbol (Grob *);
- static bool on_staffline (Grob *);
- static bool on_staffline (Grob *, int);
+ static bool on_line (Grob *);
+ static bool on_line (Grob *, int);
+ static bool on_staff_line (Grob *, int);
+ static bool on_staff_line (Grob *);
static int line_count (Grob *);
static Real get_position (Grob *);
static Real staff_radius (Grob *);
Real staff_space_;
Real x_gap_;
Real between_length_limit_;
+ Real wrong_direction_offset_penalty_;
+ Real distance_penalty_factor_;
+ Real length_penalty_factor_;
+ Real min_length_;
+ Real staff_line_clearance_;
+ Real staff_line_collision_penalty_;
+ Real dot_collision_clearance_;
+ Real dot_collision_penalty_;
+ Real tie_column_monotonicity_penalty_;
+ Real tie_tie_collision_penalty_;
+ Real tie_tie_collision_distance_;
+
Grob *staff_symbol_referencer_;
Tie_details ();
struct Tie_specification
{
int position_;
-
+ Drul_array<Grob*> note_head_drul_;
+
bool has_manual_position_;
bool has_manual_dir_;
Tie_configuration *generate_configuration (int position, Direction dir) const;
Array<Tie_configuration_variation> get_variations (Ties_configuration const &ties);
- Real score_configuration (Tie_configuration const&) const;
- Real score_aptitude (Tie_configuration const&, int) const;
+ Real score_configuration (Tie_configuration const &) const;
+ Real score_aptitude (Tie_configuration const &, Tie_specification const &) const;
Real score_ties_aptitude (Ties_configuration const &ties) const;
Real score_ties_configuration (Ties_configuration const &ties) const;
void set_ties_config_standard_directions (Ties_configuration *tie_configs_ptr);
Tie_formatting_problem ();
~Tie_formatting_problem ();
-
+ Tie_specification get_tie_specification (int) const;
Ties_configuration generate_optimal_chord_configuration ();
Ties_configuration generate_ties_configuration (Ties_configuration const &);
- Tie_configuration find_optimal_tie_configuration (int p, Direction d) const;
+ Tie_configuration find_optimal_tie_configuration (Tie_specification const &) const;
void from_ties (Link_array<Grob> const &ties);
void from_tie (Grob *tie);
void from_lv_ties (Link_array<Grob> const &);
= Lookup::round_filled_box (Box (x_extent, y_extent), blotdiameter);
Direction dir = (Direction)sign (pos);
- Real offs = (Staff_symbol_referencer::on_staffline (staff, pos))
+ Real offs = (Staff_symbol_referencer::on_line (staff, pos))
? 0.0
: -dir * halfspace;
Real r;
int cnv = sscanf (YYText (), "%lf", &r);
assert (cnv == 1);
+ (void) cnv;
yylval.scm = scm_from_double (r);
return REAL;
&& sign (Staff_symbol_referencer::get_position (head)) == - dir))
{
o += dir *(rounded - position) * 0.5 * ss;
- if (Staff_symbol_referencer::on_staffline (me, int (rounded)))
+ if (Staff_symbol_referencer::on_line (me, int (rounded)))
o += dir * 0.5 * ss;
}
}
* 2.0 / staff_space_;
if (fabs (pos - my_round (pos)) < 0.2
- && Staff_symbol_referencer::on_staffline (on_staff, (int) rint (pos))
+ && Staff_symbol_referencer::on_line (on_staff, (int) rint (pos))
&& Staff_symbol_referencer::line_count (on_staff) - 1 >= rint (pos))
y += 1.5 * staff_space_ * dir_ / 10;
--- /dev/null
+/*
+ staff-symbol-referencer-scheme.cc -- implement Staff_symbol_referencer bindings
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "grob.hh"
+#include "staff-symbol-referencer.hh"
+#include "libc-extension.hh"
+
+LY_DEFINE (ly_grob_staff_position, "ly:grob-staff-position",
+ 1, 0, 0, (SCM sg),
+ "Return the Y-position of @var{sg} relative to the staff.")
+{
+ Grob *g = unsmob_grob (sg);
+
+ SCM_ASSERT_TYPE (g, sg, SCM_ARG1, __FUNCTION__, "grob");
+ Real pos = Staff_symbol_referencer::get_position (g);
+
+ if (fabs (rint (pos) -pos) < 1e-6) // ugh.
+ return scm_from_int ((int) my_round (pos));
+ else
+ return scm_from_double (pos);
+}
}
bool
-Staff_symbol_referencer::on_staffline (Grob *me)
+Staff_symbol_referencer::on_line (Grob *me)
{
- return on_staffline (me, (int) rint (get_position (me)));
+ return on_line (me, (int) rint (get_position (me)));
+}
+
+bool
+Staff_symbol_referencer::on_staff_line (Grob *me)
+{
+ return on_staff_line (me, (int) rint (get_position (me)));
}
-/*
- This does not take size into account.
- maybe rename: on_virtual_staffline, on_staff_or_ledger_line?
-*/
bool
-Staff_symbol_referencer::on_staffline (Grob *me, int pos)
+Staff_symbol_referencer::on_line (Grob *me, int pos)
{
int sz = line_count (me) - 1;
return ((pos + sz) % 2) == 0;
}
+bool
+Staff_symbol_referencer::on_staff_line (Grob *me, int pos)
+{
+ return on_line (me, pos) && fabs (pos) <= 2 * staff_radius (me);
+}
+
Grob *
Staff_symbol_referencer::get_staff_symbol (Grob *me)
{
return int (rint (get_position (me)));
}
-LY_DEFINE (ly_grob_staff_position, "ly:grob-staff-position",
- 1, 0, 0, (SCM sg),
- "Return the Y-position of @var{sg} relative to the staff.")
-{
- Grob *g = unsmob_grob (sg);
-
- SCM_ASSERT_TYPE (g, sg, SCM_ARG1, __FUNCTION__, "grob");
- Real pos = Staff_symbol_referencer::get_position (g);
-
- if (fabs (rint (pos) -pos) < 1e-6) // ugh.
- return scm_from_int ((int) my_round (pos));
- else
- return scm_from_double (pos);
-}
-
MAKE_SCHEME_CALLBACK (Staff_symbol_referencer, callback, 1);
SCM
Staff_symbol_referencer::callback (SCM smob)
{
int p = (int) (rint (stem_end_position (me)));
staffline_offs
- = Staff_symbol_referencer::on_staffline (me, p) ? "0" : "1";
+ = Staff_symbol_referencer::on_line (me, p) ? "0" : "1";
}
else
staffline_offs = "2";
#include <set>
-
-void
-shift_small_ties (Ties_configuration *tie_configs,
- Grob *staff_referencer,
- Tie_details const &details)
-{
- set<int> positions_taken;
- for (int i = 0; i < tie_configs->size (); i++)
- positions_taken.insert (int (rint (tie_configs->elem (i).position_)));
-
- for (int i = 0; i < tie_configs->size (); i++)
- {
- Tie_configuration * conf = &tie_configs->elem_ref (i);
-
- /*
- on staff line and small enough, translate a little further
- */
- Real h = conf->height (details);
- bool next_free = positions_taken.find (int (rint (conf->position_ + conf->dir_)))
- == positions_taken.end ();
-
- int rounded_pos = int (rint (conf->position_ + conf->delta_y_ / details.staff_space_));
- bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer, rounded_pos);
-
- if (next_free)
- if (on_line && h < 0.4 * details.staff_space_)
- {
- positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
- conf->delta_y_ += 0.2 * details.staff_space_ * conf->dir_;
- }
- else if (!on_line && h > 0.6 * details.staff_space_)
- {
- positions_taken.insert (int (rint (conf->position_ + conf->dir_)));
- conf->delta_y_ += 0.5 * details.staff_space_ * conf->dir_;
- }
- }
-}
-
-
-void
-final_shape_adjustment (Tie_configuration &conf,
- Tie_formatting_problem const &problem,
- Grob *staff_referencer)
-{
- Tie_details const &details (problem.details_);
- Real line_dy = 0.0;
- bool on_line = Staff_symbol_referencer::on_staffline (staff_referencer,
- int (rint (conf.position_)));
- if (on_line)
- line_dy = - sign (conf.height (details) - 0.6 * details.staff_space_)
- * 0.2 * details.staff_space_ * conf.dir_;
-
- Real y = conf.position_ * details.staff_space_ * 0.5
- + line_dy;
-
- conf.attachment_x_ = problem.get_attachment (y);
- conf.attachment_x_.intersect (problem.get_attachment (y + conf.dir_ * details.staff_space_ * 0.5));
-
- conf.delta_y_ += line_dy;
- conf.attachment_x_.widen (-details.x_gap_);
- if (!on_line
- && Staff_symbol_referencer::staff_radius (staff_referencer) * details.staff_space_ > y)
- conf.center_tie_vertically (details);
-}
-
-
/*
- tie-formatting-problem.cc -- implement Tie_formatting_problem6
+ tie-formatting-problem.cc -- implement Tie_formatting_problem
source file of the GNU LilyPond music typesetter
}
spec.position_ = Tie::get_position (ties[i]);
+
+ do
+ {
+ spec.note_head_drul_[d] = Tie::head (ties[i], d);
+ }
+ while (flip (&d) != LEFT);
specifications_.push (spec);
}
{
spec.position_ = int (Staff_symbol_referencer::get_position (head));
}
-
+
+ spec.note_head_drul_[LEFT] = head;
heads.push (head);
specifications_.push (spec);
}
chord_outlines_[RIGHT].push (right_entry);
}
+
+Tie_specification
+Tie_formatting_problem::get_tie_specification (int i) const
+{
+ return specifications_[i];
+}
+
+
Tie_configuration*
Tie_formatting_problem::get_configuration (int pos, Direction dir)
{
Real h = conf->height (details_);
if (!conf->delta_y_)
{
- if (h < 0.5 * details_.staff_space_
- && !Staff_symbol_referencer::on_staffline (details_.staff_symbol_referencer_, pos))
+ if (h < 0.5 * details_.staff_space_)
{
- conf->center_tie_vertically (details_);
+ if (!Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos))
+ {
+ conf->center_tie_vertically (details_);
+ }
+ else if (Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_, pos))
+ {
+ conf->delta_y_ += dir * 0.2 * details_.staff_space_;
+ }
}
- else if (h < 0.5 * details_.staff_space_
- && Staff_symbol_referencer::on_staffline (details_.staff_symbol_referencer_, pos))
+ else
{
- conf->delta_y_ += dir * 0.2 * details_.staff_space_;
+ Real top_y = y + conf->delta_y_ + conf->dir_ * h;
+ Real top_pos = top_y / (0.5*details_.staff_space_);
+ int round_pos = int (my_round (top_pos));
+
+ /* TODO: should use other variable? */
+ Real clearance = details_.staff_line_clearance_;
+ if (fabs (top_pos - round_pos) < clearance
+ && Staff_symbol_referencer::on_staff_line (details_.staff_symbol_referencer_,
+ round_pos))
+ {
+ Real new_y = (round_pos + clearance * conf->dir_) * 0.5 * details_.staff_space_;
+ conf->delta_y_ = (new_y - top_y);
+ }
}
}
Real
Tie_formatting_problem::score_aptitude (Tie_configuration const &conf,
- int tie_position) const
+ Tie_specification const &spec) const
{
- Real wrong_direction_offset_penalty_;
- Real distance_penalty_factor_;
-
- wrong_direction_offset_penalty_ = 10;
- distance_penalty_factor_ = 5;
-
Real penalty = 0.0;
Real curve_y = conf.position_ * details_.staff_space_ * 0.5 + conf.delta_y_;
- Real tie_y = tie_position * details_.staff_space_ * 0.5;
+ Real tie_y = spec.position_ * details_.staff_space_ * 0.5;
if (sign (curve_y - tie_y) != conf.dir_)
- penalty += wrong_direction_offset_penalty_;
+ penalty += details_.wrong_direction_offset_penalty_;
- penalty += distance_penalty_factor_ * fabs (curve_y - tie_y);
+ penalty += details_.distance_penalty_factor_ * fabs (curve_y - tie_y);
return penalty;
}
-
Real
Tie_formatting_problem::score_configuration (Tie_configuration const &conf) const
{
- Real length_penalty_factor = 1.0;
- Real min_length = 0.333;
- Real staff_line_clearance = 0.1;
- Real staff_line_collision_penalty = 5;
- Real dot_collision_clearance = 0.25;
- Real dot_collision_penalty = 10;
-
-
Real penalty = 0.0;
Real length = conf.attachment_x_.length ();
- if (length < min_length)
- penalty += length_penalty_factor / max (0.01, length);
+ if (length < details_.min_length_)
+ penalty += details_.length_penalty_factor_ / max (0.01, length);
Real tip_pos = conf.position_ + conf.delta_y_ / 0.5 * details_.staff_space_;
Real tip_y = tip_pos * details_.staff_space_ * 0.5;
Real top_y = tip_y + conf.dir_ * height;
Real top_pos = 2 * top_y / details_.staff_space_;
Real round_top_pos = rint (top_pos);
- if (fabs (top_pos - round_top_pos) < staff_line_clearance
- && Staff_symbol_referencer::on_staffline (details_.staff_symbol_referencer_,
+ if (fabs (top_pos - round_top_pos) < details_.staff_line_clearance_
+ && Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_,
int (round_top_pos))
&& Staff_symbol_referencer::staff_radius (details_.staff_symbol_referencer_) > top_y)
{
- penalty += staff_line_collision_penalty;
+ penalty += details_.staff_line_collision_penalty_;
}
- if (fabs (tip_pos - rint (tip_pos)) < staff_line_clearance
- && Staff_symbol_referencer::on_staffline (details_.staff_symbol_referencer_,
- int (rint (tip_pos))))
+ if (fabs (tip_pos - rint (tip_pos)) < details_.staff_line_clearance_
+ && Staff_symbol_referencer::on_line (details_.staff_symbol_referencer_,
+ int (rint (tip_pos))))
{
- penalty += staff_line_collision_penalty;
+ penalty += details_.staff_line_collision_penalty_;
}
if (!dot_x_.is_empty ())
i != dot_positions_.end (); i ++)
{
int dot_pos = (*i);
- if (fabs (dot_pos * details_.staff_space_ * 0.5 - y) < dot_collision_clearance)
+ if (fabs (dot_pos * details_.staff_space_ * 0.5 - y) < details_.dot_collision_clearance_)
{
- penalty += dot_collision_penalty;
+ penalty += details_.dot_collision_penalty_;
}
}
- }
+ }
}
return penalty;
}
Tie_configuration
-Tie_formatting_problem::find_optimal_tie_configuration (int pos, Direction dir) const
+Tie_formatting_problem::find_optimal_tie_configuration (Tie_specification const &spec) const
{
Link_array<Tie_configuration> confs;
+ int pos = spec.position_;
+ Direction dir = spec.manual_dir_;
+
int region_size = 3;
for (int i = 0; i < region_size; i ++)
{
{
Real score = 0.0;
score += score_configuration (*confs[i]);
- score += score_aptitude (*confs[i], pos);
+ score += score_aptitude (*confs[i], spec);
if (score < best_score)
{
position_ = 0;
manual_position_ = 0;
manual_dir_ = CENTER;
+ note_head_drul_[LEFT] =
+ note_head_drul_[RIGHT] = 0;
}
}
for (int i = 0; i < ties.size (); i++)
- score += score_aptitude (ties[i], specifications_[i].position_);
+ score += score_aptitude (ties[i], specifications_[i]);
return score;
}
Real
Tie_formatting_problem::score_ties_configuration (Ties_configuration const &ties) const
{
- const Real tie_monotonicity_penalty = 100;
- const Real tie_collision_penalty = 30;
- const Real tie_collision_distance = 0.25;
-
Real score = 0.0;
for (int i = 0; i < ties.size (); i++)
{
if (i)
{
if (edge <= last_edge)
- score += tie_monotonicity_penalty;
+ score += details_.tie_column_monotonicity_penalty_;
if (center <= last_center)
- score += tie_monotonicity_penalty;
+ score +=details_. tie_column_monotonicity_penalty_;
score +=
- tie_collision_penalty
- * max (tie_collision_distance - fabs (center - last_center), 0.0) / tie_collision_distance;
+ details_.tie_tie_collision_penalty_
+ * max (details_.tie_tie_collision_distance_ - fabs (center - last_center), 0.0)
+ / details_.tie_tie_collision_distance_;
score +=
- tie_collision_penalty
- * max (tie_collision_distance - fabs (edge - last_edge), 0.0) / tie_collision_distance;
+ details_.tie_tie_collision_penalty_
+ * max (details_.tie_tie_collision_distance_ - fabs (edge - last_edge), 0.0)
+ / details_.tie_tie_collision_distance_;
}
last_edge = edge;
Tie_formatting_problem::generate_base_chord_configuration ()
{
Ties_configuration ties_config;
-
-
for (int i = 0; i < specifications_.size (); i ++)
{
Tie_configuration conf;
#include "warn.hh"
#include "tie-formatting-problem.hh"
+
+#define get_real_detail(src, defvalue) robust_scm2double(ly_assoc_get (ly_symbol2scm (src), details, SCM_EOL), defvalue)
+
void
Tie_details::from_grob (Grob *me)
{
staff_symbol_referencer_ = me;
staff_space_ = Staff_symbol_referencer::staff_space (me);
+ x_gap_ = robust_scm2double (me->get_property ("x-gap"), 0.2);
+
SCM details = me->get_property ("details");
- height_limit_ = robust_scm2double (ly_assoc_get (ly_symbol2scm ("height-limit"), details, SCM_EOL),
- 0.75) * staff_space_;
-
- ratio_ = robust_scm2double (ly_assoc_get (ly_symbol2scm ("ratio"), details, SCM_EOL),
- .333);
-
- x_gap_ = robust_scm2double (me->get_property ("x-gap"), 0.2);
- between_length_limit_
- = robust_scm2double (ly_assoc_get (ly_symbol2scm ("between-length-limit"), details, SCM_EOL),
- 1.0);
+ height_limit_ = get_real_detail("height-limit", 0.75);
+ ratio_ = get_real_detail("ratio", .333);
+ between_length_limit_ = get_real_detail ("between-length-limit", 1.0);
+ wrong_direction_offset_penalty_ = get_real_detail("wrong-direction-offset-penalty", 10);
+ distance_penalty_factor_ = get_real_detail("distance-penalty-factor", 5);
+ length_penalty_factor_ = get_real_detail("length-penalty-factor", 1.0);
+ min_length_ = get_real_detail("min-length", 0.333);
+
+ // in half-space
+ staff_line_clearance_ = get_real_detail ("staff-line-clearance", 0.4);
+ staff_line_collision_penalty_ = get_real_detail("staff-line-collision-penalty", 5);
+ dot_collision_clearance_ = get_real_detail ( "dot-collision-clearance", 0.25);
+ dot_collision_penalty_ = get_real_detail ( "dot-collision-penalty", 0.25);
+
+ tie_column_monotonicity_penalty_ = get_real_detail ("tie-column-monotonicity-penalty", 100);
+ tie_tie_collision_penalty_ = get_real_detail ("tie-tie-collision-penalty", 30);
+ tie_tie_collision_distance_ = get_real_detail ("tie-tie-collision-distance", .25);
}
Tie_details::Tie_details ()
Tie_formatting_problem problem;
problem.from_tie (me);
+ Tie_specification spec = problem.get_tie_specification (0);
+ spec.has_manual_dir_ = true;
+ spec.manual_dir_ = get_grob_direction (me);
- // get_configuration (me, &conf, problem);
- int tie_position = (int) Tie::get_position (me);
Tie_configuration conf
- = problem.find_optimal_tie_configuration (tie_position, get_grob_direction (me));
+ = problem.find_optimal_tie_configuration (spec);
+
set_control_points (me, problem.common_x_refpoint (),
conf, problem.details_);
}
*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;
Real thickness,
Real blotdiameter)
{
- bool on_staffline = Staff_symbol_referencer::on_staffline (me, pos);
+ bool on_staffline = Staff_symbol_referencer::on_line (me, pos);
int interspaces = Staff_symbol_referencer::line_count (me) - 1;
bool above_staff = pos > interspaces;
(direction . ,Tie::calc_direction)
(stencil . ,Tie::print)
(details . ((ratio . 0.333)
+ (staff-line-clearance . 0.6)
(height-limit . 1.0)
(between-length-limit . 1.0)))
(thickness . 1.0)