-\header {
-texidoc = "Stems are extended if flags and dots collide."
-}
-
+\header { texidoc = "Dots are moved right if flags and dots
+collide. This doesn't happens when the dot fits beneath the flag " }
+
\score{
\notes\relative c'{ f8. g f16. g f32. g}
}
return ly_interval2scm (r - my_coord);
}
-
-
void
Axis_group_interface::set_axes (Grob*me,Axis a1, Axis a2)
{
return me && me->has_interface (ly_symbol2scm ("axis-group-interface"));
}
-
-
void
Axis_group_interface::set_interface (Grob*me)
{
#include "dot-column.hh"
#include "side-position-interface.hh"
#include "engraver.hh"
+#include "stem.hh"
class Dot_column_engraver : public Engraver
{
- Grob *dotcol_p_ ;
+ Grob *dotcol_ ;
+ Grob * stem_;
Link_array<Item> head_l_arr_;
public:
VIRTUAL_COPY_CONS (Translator);
Dot_column_engraver::Dot_column_engraver ()
{
- dotcol_p_ =0;
+ dotcol_ =0;
+ stem_ = 0;
}
void
Dot_column_engraver::stop_translation_timestep ()
{
- if (dotcol_p_)
+ if (dotcol_)
{
- typeset_grob (dotcol_p_);
- dotcol_p_ =0;
+
+ /*
+ Add the stem to the support so dots stay clear of flags.
+
+ See [Ross, p 171]
+ */
+ if (stem_)
+ dotcol_->set_grob_property ("stem", stem_->self_scm ());
+
+ typeset_grob (dotcol_);
+ dotcol_ =0;
}
head_l_arr_.clear ();
+ stem_ =0;
}
void
Grob *d = unsmob_grob (info.elem_l_->get_grob_property ("dot"));
if (d)
{
- if (!dotcol_p_)
+ if (!dotcol_)
{
- dotcol_p_ = new Item (get_property ("DotColumn"));
+ dotcol_ = new Item (get_property ("DotColumn"));
- Dot_column::set_interface (dotcol_p_);
- Side_position_interface::set_axis (dotcol_p_, X_AXIS);
- Side_position_interface::set_direction (dotcol_p_, RIGHT);
- announce_grob (dotcol_p_, 0);
+ Dot_column::set_interface (dotcol_);
+ announce_grob (dotcol_, 0);
}
- Dot_column::add_head (dotcol_p_, info.elem_l_);
+ Dot_column::add_head (dotcol_, info.elem_l_);
+ }
+ else if (Stem::has_interface (info.elem_l_))
+ {
+ stem_ = info.elem_l_;
}
}
#include "directional-element-interface.hh"
#include "side-position-interface.hh"
#include "axis-group-interface.hh"
-
-
-
-
+#include "stem.hh"
void
Dot_column::set_interface (Grob* me)
{
+}
+MAKE_SCHEME_CALLBACK (Dot_column,force_shift_callback,2);
+SCM
+Dot_column::force_shift_callback (SCM element_smob, SCM axis)
+{
+ Grob *me = unsmob_grob (element_smob);
+ Axis a = (Axis) gh_scm2int (axis);
+ assert (a == Y_AXIS);
+ me = me->parent_l (X_AXIS);
+ SCM l = me->get_grob_property ("dots");
+ do_shifts (l);
+ return gh_double2scm (0.0);
+}
- Directional_element_interface::set (me, RIGHT);
-
- Axis_group_interface::set_interface (me);
- Axis_group_interface::set_axes (me, X_AXIS,X_AXIS);
+MAKE_SCHEME_CALLBACK(Dot_column,side_position, 2);
+SCM
+Dot_column::side_position (SCM element_smob, SCM axis)
+{
+ Grob *me = unsmob_grob (element_smob);
+ Axis a = (Axis) gh_scm2int (axis);
+ assert (a == X_AXIS);
+
+ Grob * stem = unsmob_grob (me->get_grob_property ("stem"));
+ if (stem
+ && !Stem::beam_l (stem)
+ && Stem::flag_i (stem))
+ {
+ /*
+ trigger stem end & direction calculation.
+
+ This will add the stem to the support if a flag collision happens.
+ */
+ Stem::stem_end_position (stem);
+ }
+ return Side_position_interface::aligned_side (element_smob, axis);
}
+
/*
Will fuck up in this case.
Should be smarter.
*/
-
-
-MAKE_SCHEME_CALLBACK (Dot_column,force_shift_callback,2);
-SCM
-Dot_column::force_shift_callback (SCM element_smob, SCM axis)
-{
- Grob *me = unsmob_grob (element_smob);
- Axis a = (Axis) gh_scm2int (axis);
- assert (a == Y_AXIS);
- me = me->parent_l (X_AXIS);
- SCM dots = me->get_grob_property ("dots");
- do_shifts (dots);
- return gh_double2scm (0.0);
-}
-
SCM
Dot_column::do_shifts (SCM l)
{
static void set_interface (Grob*);
static bool has_interface (Grob*);
DECLARE_SCHEME_CALLBACK (force_shift_callback, (SCM ,SCM));
+ DECLARE_SCHEME_CALLBACK (side_position, (SCM ,SCM));
static SCM do_shifts (SCM dotlist);
};
#endif // DOT_COLUMN_HH
Side_position_interface::general_side_position (Grob * me, Axis a, bool use_extents)
{
Grob *common = me->parent_l (a);
+
+ /*
+ As this is only used as a callback, this is called only once. We
+ could wipe SIDE-SUPPORT-ELEMENTS after we retrieve it to conserve
+ memory; however -- we should look more into benefits of such actions?
+
+ The benefit is small, it seems: total GC times taken don't
+ differ. Would this also hamper Generational GC ?
+
+ */
SCM support = me->get_grob_property ("side-support-elements");
+ // me->remove_grob_property ("side-support-elements");
for (SCM s = support; s != SCM_EOL; s = gh_cdr (s))
{
Grob * e = unsmob_grob (gh_car (s));
#include "group-interface.hh"
#include "staff-symbol-referencer.hh"
#include "spanner.hh"
-
+#include "side-position-interface.hh"
void
Stem::set_beaming (Grob*me ,int i, Direction d)
Interval hp = head_positions (me);
Real st = hp[dir] + dir * length_f;
+
+
+
/*
Make a little room if we have a flag and there is a dot.
maybe we should consider moving the dot to the right?
*/
-
if (!beam_l (me)
&& flag_i (me))
{
{
Real dp = Staff_symbol_referencer::position_f (dots);
Real flagy = flag (me).extent (Y_AXIS)[-dir] * 2; // should divide by staffspace
-
- if (dir * (st + flagy - dp) < 0)
- st += (fabs (st + flagy - dp) + 1.0) *dir;
+
+ /*
+ Very gory: add myself to the X-support of the parent,
+ which should be a dot-column.
+ */
+ if (dir * (st + flagy - dp) < 0.5)
+ Side_position_interface::add_support (dots->parent_l (X_AXIS), me);
+
+ /*
+ previous approach was to lengthen the stem. This is not
+ good typesetting practice. */
}
}
-
- bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
+
+
+ bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend"));
if (!grace_b && !no_extend_b && dir * st < 0) // junkme?
st = 0.0;