/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2005--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 2005--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
#include "misc.hh"
#include "note-head.hh"
#include "rhythmic-head.hh"
+#include "semi-tie.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
Tie_formatting_problem::get_attachment (Real y, Drul_array<int> columns) const
{
Interval attachments (0, 0);
- Direction d = LEFT;
- do
+
+ for (LEFT_and_RIGHT (d))
{
Tuple2<int> key (columns[d], int (d));
Chord_outline_map::const_iterator i (chord_outlines_.find (key));
else
attachments[d] = i->second.height (y);
}
- while (flip (&d) != LEFT);
return attachments;
}
for (vsize i = 0; i < bounds.size (); i++)
{
Grob *head = bounds[i];
- if (!Note_head::has_interface (head))
+ if (!has_interface<Note_head> (head))
continue;
if (!stem)
- stem = unsmob_grob (head->get_object ("stem"));
+ stem = unsmob<Grob> (head->get_object ("stem"));
Real p = Staff_symbol_referencer::get_position (head);
Interval y ((p - 1) * 0.5 * staff_space,
else
{
if (use_horizontal_spacing_ || !Stem::get_beam (stem))
- stem_end_position = Stem::stem_end_position (stem) * staff_space * .5;
+ stem_end_position = stem->extent (stem, Y_AXIS)[get_grob_direction (stem)];
else
- stem_end_position = Stem::note_head_positions (stem)[get_grob_direction (stem)]
+ // May want to change this to the stem's pure height...
+ stem_end_position = Stem::head_positions (stem)[get_grob_direction (stem)]
* staff_space * .5;
}
if (dir == LEFT)
{
- Box flag_box = Stem::get_translated_flag (stem).extent_box ();
- flag_box.translate ( Offset (x[RIGHT], X_AXIS));
- boxes.push_back (flag_box);
+ Grob *flag = Stem::flag (stem);
+ if (flag)
+ {
+ Grob *commony = stem->common_refpoint (flag, Y_AXIS);
+ boxes.push_back (Box (flag->extent (x_refpoint_, X_AXIS),
+ flag->extent (commony, Y_AXIS)));
+ }
}
}
else
boxes.push_back (Box (x, y));
}
- Grob *acc = unsmob_grob (heads[i]->get_object ("accidental-grob"));
+ Grob *acc = unsmob<Grob> (heads[i]->get_object ("accidental-grob"));
if (acc)
- acc->get_property ("stencil"); /* trigger tie-related suicide */
+ acc->get_property ("after-line-breaking"); /* trigger tie-related suicide */
if (acc && acc->is_live () && dir == RIGHT)
{
}
- Direction updowndir = DOWN;
- do
+ for (DOWN_and_UP (updowndir))
{
Interval x;
Interval y;
if (!x.is_empty ())
boxes.push_back (Box (x, y));
}
- while (flip (&updowndir) != DOWN);
- /* todo: the horizon_padding is somewhat arbitrary */
- chord_outlines_[key] = Skyline (boxes, details_.skyline_padding_, Y_AXIS, -dir);
+ chord_outlines_[key] = Skyline (boxes, Y_AXIS, -dir).padded (details_.skyline_padding_);
if (bounds[0]->break_status_dir ())
{
Interval iv (Axis_group_interface::staff_extent (bounds[0], x_refpoint_, X_AXIS, y_refpoint_, Y_AXIS));
details_.from_grob (ties[0]);
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
vector<Item *> bounds;
for (vsize i = 0; i < ties.size (); i++)
{
- Item *it = dynamic_cast<Spanner *> (ties[i])->get_bound (d);
+ Spanner *tie = dynamic_cast<Spanner *> (ties[i]);
+ Item *it = tie->get_bound (d);
if (it->break_status_dir ())
it = it->get_column ();
set_chord_outline (bounds, d);
}
- while (flip (&d) != LEFT);
for (vsize i = 0; i < ties.size (); i++)
{
+ Spanner *tie = dynamic_cast<Spanner *> (ties[i]);
Tie_specification spec;
- spec.from_grob (ties[i]);
+ spec.from_grob (tie);
- do
+ for (LEFT_and_RIGHT (d))
{
- spec.note_head_drul_[d] = Tie::head (ties[i], d);
- spec.column_ranks_[d] = Tie::get_column_rank (ties[i], d);
+ spec.note_head_drul_[d] = Tie::head (tie, d);
+ spec.column_ranks_[d] = Tie::get_column_rank (tie, d);
}
- while (flip (&d) != LEFT);
specifications_.push_back (spec);
}
}
int column_rank = -1;
for (vsize i = 0; i < semi_ties.size (); i++)
{
+ Item *semi_tie = dynamic_cast<Item *> (semi_ties[i]);
Tie_specification spec;
- Item *head = unsmob_item (semi_ties[i]->get_object ("note-head"));
+ Item *head = Semi_tie::head (semi_tie);
if (!head)
programming_error ("LV tie without head?!");
spec.position_ = int (Staff_symbol_referencer::get_position (head));
}
- spec.from_grob (semi_ties[i]);
+ spec.from_grob (semi_tie);
spec.note_head_drul_[head_dir] = head;
- column_rank = Tie::get_column_rank (semi_ties[i], head_dir);
+ column_rank = Semi_tie::get_column_rank (semi_tie);
spec.column_ranks_ = Drul_array<int> (column_rank, column_rank);
heads.push_back (head);
specifications_.push_back (spec);
Tie_formatting_problem::get_configuration (int pos, Direction dir, Drul_array<int> columns,
bool tune_dy) const
{
- int key_components[] =
+ int key_components[]
+ =
{
pos, dir, columns[LEFT], columns[RIGHT]
};
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
{
It would be better to check D against HEAD-DIRECTION if
applicable.
*/
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
Real y = conf->position_ * details_.staff_space_ * 0.5 + conf->delta_y_;
if (get_stem_extent (conf->column_ranks_[d], d, X_AXIS).is_empty ()
= d * min (d * conf->attachment_x_[d],
d * (get_stem_extent (conf->column_ranks_[d], d, X_AXIS)[-d] - d * details_.stem_gap_));
}
- while (flip (&d) != LEFT);
}
return conf;
}
penalty += p;
}
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
if (!spec.note_head_drul_[d])
continue;
penalty += p;
}
- while (flip (&d) != LEFT);
if (ties_conf
&& ties_conf->size () == 1)
{
- Direction d = LEFT;
Drul_array<Grob *> stems (0, 0);
- do
+ for (LEFT_and_RIGHT (d))
{
if (!spec.note_head_drul_[d])
continue;
- Grob *stem = unsmob_grob (spec.note_head_drul_[d]->get_object ("stem"));
+ Grob *stem = unsmob<Grob> (spec.note_head_drul_[d]->get_object ("stem"));
if (stem
&& Stem::is_normal_stem (stem))
stems[d] = stem;
}
- while (flip (&d) != LEFT);
bool tie_stem_dir_ok = true;
bool tie_position_dir_ok = true;
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_
Tie_formatting_problem::generate_extremal_tie_variations (Ties_configuration const &ties) const
{
vector<Tie_configuration_variation> vars;
- Direction d = DOWN;
for (int i = 1; i <= details_.multi_tie_region_size_; i++)
{
Drul_array<Tie_configuration *> configs (0, 0);
- do
+ for (DOWN_and_UP (d))
{
const Tie_configuration &config = boundary (ties, d, 0);
if (config.dir_ == d
vars.push_back (var);
}
}
- while (flip (&d) != DOWN);
if (configs[LEFT] && configs[RIGHT])
{
Tie_configuration_variation var;
sz = 1;
for (int i = 0; i < sz; i++)
{
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
if (i == 0
&& ties[0].dir_ == d)
vars.push_back (var);
}
}
- while (flip (&d) != LEFT);
}
return vars;
}
{
spec.has_manual_position_ = true;
spec.manual_position_ = scm_to_double (scm_car (entry));
- spec.has_manual_delta_y_ = (scm_inexact_p (scm_car (entry)) == SCM_BOOL_T);
+ /* TODO: check whether inexact? is an appropriate condition here */
+ spec.has_manual_delta_y_ = (scm_is_true (scm_inexact_p (scm_car (entry))));
}
if (scm_is_number (scm_cdr (entry)))