source file of the GNU LilyPond music typesetter
- (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
+ (c) 1998--1999 Jan Nieuwenhuizen <janneke@gnu.org>
*/
-
+#include "dimension-cache.hh"
#include "proto.hh"
#include "stem.hh"
#include "note-column.hh"
#include "paper-def.hh"
#include "encompass-info.hh"
#include "slur.hh"
-#include "staff-sym.hh"
+#include "staff-symbol.hh"
+#include "note-head.hh"
#include "debug.hh"
+#include "align-element.hh"
Encompass_info::Encompass_info ()
{
- assert (0);
}
-Encompass_info::Encompass_info (Note_column const* note, Direction dir)
+Encompass_info::Encompass_info (Note_column const* note_column, Direction dir, Slur const* slur_l)
{
- Paper_def* paper = note->paper ();
- Real interline = paper->interline_f ();
- // UGH
- Real notewidth = paper->note_width () * 0.8;
- Real internote = interline / 2;
-
- Stem* stem_l_ = note->stem_l_;
- /*
- set o_.x () to middle of notehead or on the exact position of stem,
- according to slur direction
- */
- o_.x () = stem_l_->hpos_f ();
+ interstaff_f_ = 0;
+
+ Stem* stem_l = note_column->stem_l_;
+ if (!stem_l)
+ {
+ warning (_ ("Slur over rest?"));
+ o_[X_AXIS] = note_column->hpos_f ();
+ o_[Y_AXIS] = note_column->extent (Y_AXIS)[dir];
+ return;
+ }
+
+ o_[X_AXIS] = stem_l->hpos_f ();
/*
- stem_l_->dir == dir
- ________
- | | / \
- x| x| |x |x
- \________/ | |
-
+ Simply set x to middle of notehead
*/
- if (stem_l_->dir_ != dir)
- o_.x () -= 0.5 * notewidth * stem_l_->dir_;
+ o_[X_AXIS] -= 0.5 * stem_l->dir_ * note_column->extent (X_AXIS).length ();
+
+ if ((stem_l->dir_ == dir)
+ && !stem_l->extent (Y_AXIS).empty_b ())
+ {
+ o_[Y_AXIS] = stem_l->extent (Y_AXIS)[dir];
+ }
+ else
+ {
+ o_[Y_AXIS] = note_column->extent (Y_AXIS)[dir];
+ }
- o_.y () = stem_l_->extent (Y_AXIS)[dir];
/*
leave a gap: slur mustn't touch head/stem
*/
- o_.y () += 2.5 * internote * dir;
-
- if (stem_l_->dir_ != dir)
- o_.y () += 1.0 * internote * dir;
+ o_[Y_AXIS] += dir * slur_l->paper_l ()->get_var ("slur_y_free");
- Slur* slur_l_ = stem_l_->slur_l_;
- if (slur_l_->encompass_arr_.size ()
- && stem_l_->staff_sym_l_ != slur_l_->encompass_arr_[0]->stem_l_->staff_sym_l_)
+ Graphical_element *common = stem_l->common_refpoint (slur_l, Y_AXIS);
+ Align_element * align = dynamic_cast<Align_element*> (common);
+ if (align && align->axis() == Y_AXIS)
{
- if (stem_l_->staff_sym_l_->dim_cache_[Y_AXIS].valid_b ())
- {
- slur_l_->interstaff_f_ = stem_l_->staff_sym_l_->absolute_coordinate (Y_AXIS)
- - slur_l_->encompass_arr_[0]->stem_l_->staff_sym_l_->absolute_coordinate (Y_AXIS);
- }
- else
- {
- warning (_ ("invalid dimension cache: guessing staff position"));
- if (slur_l_->vertical_align_drul_[MIN] !=
- slur_l_->vertical_align_drul_[MAX])
- warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff slurs may be broken"));
- slur_l_->interstaff_f_ = slur_l_->vertical_align_drul_[MIN];
- // urg, guess staff order:
- // if our stem ends higher, our staff is probably lower...
- if (stem_l_->chord_start_f () > slur_l_->encompass_arr_[0]->stem_l_->chord_start_f ())
- slur_l_->interstaff_f_ *= -1;
- }
- o_.y () += slur_l_->interstaff_f_;
+ if (align->threshold_interval_[MIN] !=
+ align->threshold_interval_[MAX])
+ warning (_ ("minVerticalAlign != maxVerticalAlign: interstaff beams/slurs may be broken"));
+
+ interstaff_f_ = align->threshold_interval_[MIN];
+
+ Graphical_element const * slur_refpoint = slur_l;
+ while (slur_refpoint->parent_l (Y_AXIS) != common)
+ slur_refpoint = slur_refpoint->parent_l (Y_AXIS);
+
+ Graphical_element const * note_refpoint = note_column;
+ while (note_refpoint->parent_l (Y_AXIS) != common)
+ note_refpoint = note_refpoint->parent_l (Y_AXIS);
+
+ int slur_prio =
+ align->get_priority ((Score_element*) dynamic_cast<Score_element const*> (slur_refpoint));
+ int stem_prio =
+ align->get_priority ((Score_element*) dynamic_cast<Score_element const *> (note_refpoint));
+
+ /*
+ our staff is lower -> interstaff_f_ *= -1
+ */
+
+ if (slur_prio < stem_prio)
+ interstaff_f_ *= -1;
+ o_[Y_AXIS] += interstaff_f_;
}
}