From: fred Date: Tue, 26 Mar 2002 22:44:14 +0000 (+0000) Subject: lilypond-1.3.11 X-Git-Tag: release/1.5.59~1951 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1766ac3544e4de0bf3f233e798dec30658000bbd;p=lilypond.git lilypond-1.3.11 --- diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc new file mode 100644 index 0000000000..b458095aa0 --- /dev/null +++ b/lily/side-position-interface.cc @@ -0,0 +1,243 @@ +/* + staff-side.cc -- implement Staff_side_element + + source file of the GNU LilyPond music typesetter + + (c) 1998--1999 Han-Wen Nienhuys + + */ + +#include "side-position-interface.hh" +#include "staff-symbol.hh" +#include "debug.hh" +#include "warn.hh" +#include "dimensions.hh" +#include "dimension-cache.hh" +#include "staff-symbol-referencer.hh" + +Side_position_interface::Side_position_interface (Score_element const *e) +{ + elt_l_ = (Score_element*)e; +} + + +void +Side_position_interface::add_support (Score_element*e) +{ + SCM sup = elt_l_->get_elt_property ("side-support"); + elt_l_->set_elt_property ("side-support", + gh_cons (e->self_scm_,sup)); +} + + + +Direction +Side_position_interface::get_direction () const +{ + SCM d = elt_l_->get_elt_property ("direction"); + if (isdir_b (d)) + return to_dir (d) ? to_dir (d) : DOWN; + + Direction relative_dir = UP; + SCM reldir = elt_l_->get_elt_property ("side-relative-direction"); // should use a lambda. + if (isdir_b (reldir)) + { + relative_dir = to_dir (reldir); + } + + SCM other_elt = elt_l_->get_elt_property ("direction-source"); + Score_element * e = unsmob_element(other_elt); + if (e) + { + return (Direction)(relative_dir * Side_position_interface (e).get_direction ()); + } + + return DOWN; +} + +/** + Callback that does the aligning. + */ +Real +Side_position_interface::side_position (Dimension_cache const * c) +{ + Score_element * me = dynamic_cast (c->element_l ()); + + Interval dim; + Axis axis = c->axis (); + Score_element *common = me->parent_l (axis); + SCM support = me->get_elt_property ("side-support"); + for (SCM s = support; s != SCM_EOL; s = gh_cdr (s)) + { + Score_element * e = unsmob_element ( gh_car (s)); + if (e) + common = common->common_refpoint (e, axis); + } + + for (SCM s = support; s != SCM_EOL; s = gh_cdr (s)) + { + + Score_element * e = unsmob_element ( gh_car (s)); + if (e) + { + Real coord = e->relative_coordinate (common, axis); + + dim.unite (coord + e->extent (axis)); + } + } + + if (dim.empty_b ()) + { + dim = Interval(0,0); + } + + Real off = me->parent_l (axis)->relative_coordinate (common, axis); + + + Direction dir = Side_position_interface (me).get_direction (); + + SCM pad = me->remove_elt_property ("padding"); + if (pad != SCM_UNDEFINED) + { + off += gh_scm2double (pad) * dir; + } + Real total_off = dim[dir] + off; + + if (fabs (total_off) > 100 CM) + programming_error ("Huh ? Improbable staff side dim."); + + return total_off; +} + +Real +Side_position_interface::self_alignment (Dimension_cache const *c) +{ + String s ("self-alignment-"); + Axis ax = c->axis (); + s += (ax == X_AXIS) ? "X" : "Y"; + Score_element *elm = dynamic_cast (c->element_l ()); + SCM align (elm->get_elt_property (s)); + if (isdir_b (align)) + { + Direction d = to_dir (align); + Interval ext(elm->extent (ax)); + if (d) + { + return - ext[d]; + } + return - ext.center (); + } + else + return 0.0; +} + + +Real +directed_round (Real f, Direction d) +{ + if (d < 0) + return floor (f); + else + return ceil (f); +} + +Real +Side_position_interface::quantised_position (Dimension_cache const *c) +{ + Score_element * me = dynamic_cast (c->element_l ()); + Side_position_interface s(me); + Direction d = s.get_direction (); + Staff_symbol_referencer_interface si (me); + + if (si.has_interface_b ()) + { + Real p = si.position_f (); + Real rp = directed_round (p, d); + + int ip = int (rp); + if ((ip % 2) == 0) + { + ip += d; + rp += d; + } + + return (rp - p) * si.staff_line_leading_f () / 2.0; + } + return 0.0; +} + +Real +Side_position_interface::aligned_side (Dimension_cache const *c) +{ + Score_element * me = dynamic_cast (c->element_l ()); + Side_position_interface s(me); + Direction d = s.get_direction (); + Axis ax = c->axis (); + Real o = side_position (c); + + Interval iv = me->extent (ax); + + if (!iv.empty_b ()) + { + o += - iv[-d]; + + SCM pad = me->get_elt_property ("padding"); + if (gh_number_p (pad)) + o += d *gh_scm2double (pad) ; + } + return o; +} + + + + +void +Side_position_interface::set_axis (Axis a) +{ + // prop transparent ? + if (elt_l_->get_elt_property ("side-support") == SCM_UNDEFINED) + elt_l_->set_elt_property ("side-support" ,SCM_EOL); + + elt_l_->dim_cache_[a]->off_callbacks_.push (aligned_side); +} + + +void +Side_position_interface::set_quantised (Axis a) +{ + Dimension_cache * c = elt_l_->dim_cache_[a]; + + c->off_callbacks_.push (quantised_position); +} + +Axis +Side_position_interface::get_axis () const +{ + Dimension_cache * c = elt_l_->dim_cache_[X_AXIS]; + for (int i=0 ; i < c->off_callbacks_.size();i ++) + if (c->off_callbacks_[i] == side_position + ||c->off_callbacks_[i] == aligned_side) + return X_AXIS; + + + return Y_AXIS; +} + +void +Side_position_interface::set_direction (Direction d) +{ + elt_l_->set_elt_property ("direction", gh_int2scm (d)); +} + +bool +Side_position_interface::has_interface_b () const +{ + return elt_l_->get_elt_property ("side-support") != SCM_UNDEFINED; +} + +bool +Side_position_interface::supported_b () const +{ + SCM s =elt_l_->get_elt_property ("side-support"); + return s != SCM_UNDEFINED && s != SCM_EOL; +} diff --git a/lily/staff-symbol-referencer.cc b/lily/staff-symbol-referencer.cc index f2532f0d43..8bd451109a 100644 --- a/lily/staff-symbol-referencer.cc +++ b/lily/staff-symbol-referencer.cc @@ -13,56 +13,70 @@ #include "paper-def.hh" #include "dimension-cache.hh" -Staff_symbol_referencer::Staff_symbol_referencer () +Staff_symbol_referencer_interface::Staff_symbol_referencer_interface (Score_element const *sc) { - set_elt_property ("staff-position", gh_double2scm (0.0)); - dim_cache_[Y_AXIS]->off_callbacks_.push (callback); + elt_l_ = (Score_element*)sc; +} + +void +Staff_symbol_referencer_interface::set_interface () +{ + elt_l_->set_elt_property ("staff-position", gh_double2scm (0.0)); + elt_l_->dim_cache_[Y_AXIS]->off_callbacks_.push (callback); +} + + +bool +Staff_symbol_referencer_interface::has_interface_b () +{ + return unsmob_element (elt_l_->get_elt_property ("staff-symbol")) + || gh_number_p (elt_l_->get_elt_property ("staff-position")); } int -Staff_symbol_referencer::lines_i () const +Staff_symbol_referencer_interface::lines_i () const { Staff_symbol *st = staff_symbol_l (); return st ? st->no_lines_i_ : 5; } Staff_symbol* -Staff_symbol_referencer::staff_symbol_l () const +Staff_symbol_referencer_interface::staff_symbol_l () const { - SCM st = get_elt_property ("staff-symbol"); + SCM st = elt_l_->get_elt_property ("staff-symbol"); return dynamic_cast (unsmob_element(st)); } Real -Staff_symbol_referencer::staff_line_leading_f () const +Staff_symbol_referencer_interface::staff_line_leading_f () const { Staff_symbol * st = staff_symbol_l (); if (st) return st->staff_line_leading_f_; - else if (pscore_l_ && paper_l ()) - paper_l ()->get_var ("interline"); + else if (elt_l_->pscore_l_ && elt_l_->paper_l ()) + elt_l_->paper_l ()->get_var ("interline"); return 0.0; } Real -Staff_symbol_referencer::position_f () const +Staff_symbol_referencer_interface::position_f () const { Real p =0.0; - SCM pos = get_elt_property ("staff-position"); + SCM pos = elt_l_->get_elt_property ("staff-position"); if (gh_number_p (pos)) p = gh_scm2double (pos); Staff_symbol * st = staff_symbol_l (); if (st) { - Score_element * c = common_refpoint (st, Y_AXIS); - Real y = relative_coordinate (c, Y_AXIS) + Score_element * c = elt_l_->common_refpoint (st, Y_AXIS); + Real y = elt_l_->relative_coordinate (c, Y_AXIS) - st->relative_coordinate (c, Y_AXIS); - p += 2.0 * y / staff_line_leading_f (); + p += 2.0 * y / st->staff_line_leading_f (); } return p; } @@ -73,15 +87,17 @@ Staff_symbol_referencer::position_f () const should use offset callback! */ Real -Staff_symbol_referencer::callback (Dimension_cache const * c) +Staff_symbol_referencer_interface::callback (Dimension_cache const * c) { Score_element * sc = dynamic_cast (c->element_l ()); - Staff_symbol_referencer * ref = dynamic_cast (sc); + + SCM pos = sc->get_elt_property ("staff-position"); Real off =0.0; if (gh_number_p (pos)) { - off = gh_scm2double (pos) * ref->staff_line_leading_f () /2.0; + Real space = staff_symbol_referencer_interface (sc).staff_line_leading_f (); + off = gh_scm2double (pos) * space/2.0; } sc->set_elt_property ("staff-position", gh_double2scm (0.0)); @@ -90,20 +106,31 @@ Staff_symbol_referencer::callback (Dimension_cache const * c) void -Staff_symbol_referencer::set_position (Real p) +Staff_symbol_referencer_interface::set_position (Real p) { - Real halfspace = staff_line_leading_f ()* 0.5; - - translate_axis (- halfspace * position_f (), Y_AXIS); - Staff_symbol *st = staff_symbol_l (); - if (st) - translate_axis (halfspace * p, Y_AXIS); + Staff_symbol * st = staff_symbol_l (); + if (st && elt_l_->common_refpoint(st, Y_AXIS)) + { + Real oldpos = position_f (); + elt_l_->set_elt_property ("staff-position", gh_double2scm (p - oldpos)); + } else { - // SCM pos = get_elt_property ("staff-position"); - set_elt_property ("staff-position", - gh_double2scm (p)); - // gh_double2scm (p + gh_scm2double (pos))); + elt_l_->set_elt_property ("staff-position", + gh_double2scm (p)); + } + + Array &callbacks (elt_l_->dim_cache_[Y_AXIS]->off_callbacks_); + for (int i=0; i < callbacks.size ();i++) + if (callbacks[i] == callback) + return ; + + callbacks.push (callback); } +Staff_symbol_referencer_interface +staff_symbol_referencer_interface (Score_element const*e) +{ + return e; // gee, I'm so smart! +} diff --git a/lily/text-engraver.cc b/lily/text-engraver.cc index 40646392ed..56f7b3eae1 100644 --- a/lily/text-engraver.cc +++ b/lily/text-engraver.cc @@ -9,7 +9,7 @@ #include "dimension-cache.hh" #include "engraver.hh" -#include "staff-side.hh" +#include "side-position-interface.hh" #include "text-item.hh" #include "musical-request.hh" #include "note-head.hh"