/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1996--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 1996--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
Jan Nieuwenhuizen <janneke@gnu.org>
LilyPond is free software: you can redistribute it and/or modify
#include <queue>
+#include "axis-group-interface.hh"
#include "accidental-interface.hh"
#include "beam.hh"
#include "clef.hh"
#include "main.hh"
#include "misc.hh"
#include "note-column.hh"
+#include "note-head.hh"
#include "output-def.hh"
#include "paper-column.hh"
#include "pitch.hh"
#include "staff-symbol-referencer.hh"
#include "staff-symbol.hh"
#include "stem.hh"
-#include "time-signature.hh"
#include "warn.hh"
/*
Encompass_info
Slur_score_state::get_encompass_info (Grob *col) const
{
- Grob *stem = unsmob_grob (col->get_object ("stem"));
+ Grob *stem = unsmob<Grob> (col->get_object ("stem"));
Encompass_info ei;
if (!stem)
for (LEFT_and_RIGHT (d))
{
extremes[d].bound_ = slur_->get_bound (d);
- if (Note_column::has_interface (extremes[d].bound_))
+ if (has_interface<Note_column> (extremes[d].bound_))
{
extremes[d].note_column_ = extremes[d].bound_;
extremes[d].stem_ = Note_column::get_stem (extremes[d].note_column_);
+ extremes[d].flag_ = Note_column::get_flag (extremes[d].note_column_);
+
if (extremes[d].stem_)
{
extremes[d].stem_dir_ = get_grob_direction (extremes[d].stem_);
{
Axis ax = Axis (a);
Interval s = extremes[d].stem_->extent (common_[ax], ax);
+ if (extremes[d].flag_)
+ s.unite (extremes[d].flag_->extent (common_[ax], ax));
if (s.is_empty ())
{
/*
::staff_space (extremes[d].stem_);
}
- if (extremes[d].slur_head_)
- extremes[d].slur_head_x_extent_
- = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS);
-
}
+ else if (has_interface<Note_head> (extremes[d].bound_))
+ {
+ extremes[d].slur_head_ = extremes[d].bound_;
+ }
+ if (extremes[d].slur_head_)
+ extremes[d].slur_head_x_extent_
+ = extremes[d].slur_head_->extent (common_[X_AXIS], X_AXIS);
}
return extremes;
Slur::replace_breakable_encompass_objects (me);
staff_space_ = Staff_symbol_referencer::staff_space (me);
- Real lt = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
- thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * lt;
+ line_thickness_ = me->layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
+ thickness_ = robust_scm2double (me->get_property ("thickness"), 1.0) * line_thickness_;
dir_ = slur_direction ();
parameters_.fill (me);
}
extremes_ = get_bound_info ();
- is_broken_ = (!extremes_[LEFT].note_column_
- || !extremes_[RIGHT].note_column_);
+ is_broken_ = (!(extremes_[LEFT].note_column_ || extremes_[LEFT].slur_head_)
+ || !(extremes_[RIGHT].note_column_ || extremes_[RIGHT].slur_head_));
has_same_beam_
= (extremes_[LEFT].stem_ && extremes_[RIGHT].stem_
end_ys[RIGHT],
end_ys[LEFT]);
Real encompass_place = extra_encompass_infos_[i].extents_[Y_AXIS][dir_];
- if (extra_encompass_infos_[i].type_ == ly_symbol2scm ("inside")
+ if (scm_is_eq (extra_encompass_infos_[i].type_,
+ ly_symbol2scm ("inside"))
&& minmax (dir_, encompass_place, y_place) == encompass_place
&& (!extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("key-signature-interface"))
- && !Clef::has_interface (extra_encompass_infos_[i].grob_)
- && !Time_signature::has_interface (extra_encompass_infos_[i].grob_)))
+ && !has_interface<Clef> (extra_encompass_infos_[i].grob_)
+ && !extra_encompass_infos_[i].grob_->internal_has_interface (ly_symbol2scm ("time-signature-interface"))))
{
for (LEFT_and_RIGHT (d))
additional_ys[d] = minmax (dir_,
SCM
Slur::calc_control_points (SCM smob)
{
- Spanner *me = unsmob_spanner (smob);
+ Spanner *me = unsmob<Spanner> (smob);
Slur_score_state state;
state.fill (me);
return best;
}
-Grob *
-Slur_score_state::breakable_bound_item (Direction d) const
+Interval
+Slur_score_state::breakable_bound_extent (Direction d) const
{
Grob *col = slur_->get_bound (d)->get_column ();
+ Interval ret;
+ ret.set_empty ();
extract_grob_set (slur_, "encompass-objects", extra_encompasses);
{
Item *item = dynamic_cast<Item *> (extra_encompasses[i]);
if (item && col == item->get_column ())
- return item;
+ ret.unite (robust_relative_extent (item, common_[X_AXIS], X_AXIS));
}
- return 0;
+ return ret;
}
/*
{
if (extremes_[d].note_column_)
{
- end_ys[d] = dir_
- * max (max (dir_ * (base_attachments_[d][Y_AXIS]
- + parameters_.region_size_ * dir_),
- dir_ * (dir_ + extremes_[d].note_column_->extent (common_[Y_AXIS], Y_AXIS)[dir_])),
- dir_ * base_attachments_[-d][Y_AXIS]);
+ Interval nc_extent = extremes_[d].note_column_
+ ->extent (common_[Y_AXIS], Y_AXIS);
+ if (nc_extent.is_empty ())
+ slur_->warning ("slur trying to encompass an empty note column.");
+ else
+ end_ys[d] = dir_
+ * max (max (dir_ * (base_attachments_[d][Y_AXIS]
+ + parameters_.region_size_ * dir_),
+ dir_ * (dir_ + nc_extent[dir_])),
+ dir_ * base_attachments_[-d][Y_AXIS]);
+ }
+ else if (extremes_[d].slur_head_)
+ {
+ // allow only minimal movement
+ end_ys[d] = base_attachments_[d][Y_AXIS] + 0.3 * dir_;
}
else
end_ys[d] = base_attachments_[d][Y_AXIS] + parameters_.region_size_ * dir_;
: extremes_[d].bound_->extent (common_[X_AXIS], X_AXIS))
.linear_combination (CENTER);
}
+ else if (head)
+ {
+ y = head->extent (common_[Y_AXIS], Y_AXIS)
+ .linear_combination (0.5*dir_);
+
+ // Don't "move_away_from_staffline" because that makes it
+ // harder to recognize the specific attachment point
+ x = head->extent (common_[X_AXIS], X_AXIS)[-d];
+ }
+
base_attachment[d] = Offset (x, y);
}
for (LEFT_and_RIGHT (d))
{
- if (!extremes_[d].note_column_)
+ if (!extremes_[d].note_column_ && !extremes_[d].slur_head_)
{
Real x = 0;
Real y = 0;
- if (Grob *g = breakable_bound_item (d))
- {
- x = robust_relative_extent (g, common_[X_AXIS], X_AXIS)[RIGHT];
- }
- else if (d == RIGHT)
- x = robust_relative_extent (extremes_[d].bound_, common_[X_AXIS], X_AXIS)[d];
- else
- x = slur_->get_broken_left_end_align ();
+ Interval ext = breakable_bound_extent (d);
+ if (ext.is_empty ())
+ ext = Axis_group_interface::
+ generic_bound_extent (extremes_[d].bound_,
+ common_[X_AXIS], X_AXIS);
+ x = ext[-d];
Grob *col = (d == LEFT) ? columns_[0] : columns_.back ();
extract_grob_set (slur_, "encompass-objects", extra_encompasses);
for (vsize i = 0; i < extra_encompasses.size (); i++)
{
- if (Slur::has_interface (extra_encompasses[i]))
+ if (has_interface<Slur> (extra_encompasses[i]))
{
Grob *small_slur = extra_encompasses[i];
Bezier b = Slur::get_curve (small_slur);
z[Y_AXIS] += dir_ * parameters_.free_slur_distance_;
avoid.push_back (z);
}
- else if (extra_encompasses[i]->get_property ("avoid-slur") == ly_symbol2scm ("inside"))
+ else if (scm_is_eq (extra_encompasses[i]->get_property ("avoid-slur"),
+ ly_symbol2scm ("inside")))
{
Grob *g = extra_encompasses [i];
Interval xe = g->extent (common_[X_AXIS], X_AXIS);
}
}
- dz = os[RIGHT] - os[LEFT];
+ dz = (os[RIGHT] - os[LEFT]).direction ();
for (LEFT_and_RIGHT (d))
{
if (extremes_[d].slur_head_
TODO: parameter */
os[d][X_AXIS]
-= dir_ * extremes_[d].slur_head_x_extent_.length ()
- * sin (dz.arg ()) / 3;
+ * dz[Y_AXIS] / 3;
}
}
vector<Extra_collision_info> collision_infos;
for (vsize i = encompasses.size (); i--;)
{
- if (Slur::has_interface (encompasses[i]))
+ if (has_interface<Slur> (encompasses[i]))
{
Spanner *small_slur = dynamic_cast<Spanner *> (encompasses[i]);
Bezier b = Slur::get_curve (small_slur);
Grob *g = encompasses [i];
Interval xe = g->extent (common_[X_AXIS], X_AXIS);
Interval ye = g->extent (common_[Y_AXIS], Y_AXIS);
- if (Dots::has_interface (g))
+ if (has_interface<Dots> (g))
ye.widen (0.2);
Real xp = 0.0;
Real penalty = parameters_.extra_object_collision_penalty_;
- if (Accidental_interface::has_interface (g))
+ if (has_interface<Accidental_interface> (g))
{
penalty = parameters_.accidental_collision_;