@lilypondfile[printfilename]{collision-dots.ly}
+@lilypondfile[printfilename]{collision-mesh.ly}
+
@lilypondfile[printfilename]{number-staff-lines.ly}
--- /dev/null
+\header {
+texidoc = "Oppositely stemmed chords, meshing into each other,
+are resolved."
+}
+
+\score {
+ \context Staff \notes \relative c' {
+ \time 3/4
+ % Here's what I was trying to do:
+ < \context Voice = VI {\stemDown <g4 b g'>
+ r4 r4 }
+ \context Voice=VII {\stemUp d'2.} >
+
+ % Or:
+
+ <\context Voice = VI {\stemUp <g4 b g'> r r}
+ \context Voice= VII {\stemDown d'2.} >
+ }
+}
+
+
+
+
+
}
+
+
+
zager = \context Staff = zager \notes \relative c'' {
\clef treble
- c1
+ c1 c1
+}
+
+zeuger = \context Staff = zeuger \notes \relative c'' {
+ \clef treble
+ c1 c1
}
zoger = \context Staff = zoger \notes \relative c'' {
\clef treble
- \skip 1* 1
+ \skip 2* 1
}
-zagers = \context GrandStaff <
+zagers = \context StaffGroup <
\zager
\zoger
+ \zeuger
>
\score{
- <
- \context StaffGroup = zagers <
+ < \context StaffGroup = zagers <
\zagers
- >
- >
+ > >
\paper{
linewidth = 80.0\mm
box around arbitrary grobs.
TODO: check whether the corners are really correct.
-
+
+ TODO: circled molecules.
+
"
}
+
#(define (box-molecule xext yext)
(ly-make-molecule
(list 'filledbox (- (car xext)) (cdr xext)
% see ly/drumpitch.ly for list of instruments and paper-kits.
% scm/midi.scm for list of midi-drumkits.
-\include "drumpitch.ly"
+\include "drumpitch-init.ly"
\version "1.3.146"
#include "paper-def.hh"
#include "axis-group-interface.hh"
#include "item.hh"
-
+#include "stem.hh"
MAKE_SCHEME_CALLBACK (Collision,force_shift_callback,2);
return gh_double2scm (0.0);
}
+
+void
+check_meshing_chords (Grob*me,
+ Drul_array< Array < Real > > *offsets,
+ Drul_array< Array < Slice > > const &extents,
+ Drul_array<Link_array<Grob> > const &clash_groups)
+
+{
+ if (!extents[UP].size () || ! extents[DOWN].size ())
+ return ;
+
+
+ Grob *cu =clash_groups[UP][0];
+ Grob *cd =clash_groups[DOWN][0];
+
+ Grob * nu_l= Note_column::first_head (cu);
+ Grob * nd_l = Note_column::first_head (cd);
+
+
+
+ bool half_collide = false;
+ bool full_collide = false;
+
+ /*
+ TODO:
+
+ filter out the 'o's in this configuration, since they're no part
+ in the collision.
+
+ |
+ x|o
+ x|o
+ x
+
+
+ */
+ Array<int> ups = Stem::note_head_positions (Note_column::stem_l (cu));
+ Array<int> dps = Stem::note_head_positions (Note_column::stem_l (cd));
+
+ /*
+ they're too far apart to collide.
+
+ */
+
+ if (ups[0] > dps.top () + 1)
+ return ;
+
+ bool touch = (ups[0] - dps.top () >= 0);
+
+ bool merge_possible = (ups[0] >= dps[0]) && (ups.top () <= dps.top ());
+
+ merge_possible = merge_possible &&
+ Rhythmic_head::balltype_i (nu_l) == Rhythmic_head::balltype_i (nd_l);
+
+ if (!to_boolean (me->get_grob_property ("merge-differently-dotted")))
+ merge_possible = merge_possible && Rhythmic_head::dot_count (nu_l) == Rhythmic_head::dot_count (nd_l);
+
+ int i = 0, j=0;
+ while (i < ups.size () && j < dps.size ())
+ {
+ if (abs (ups[i] - dps[j]) == 1)
+ {
+ merge_possible = false;
+ half_collide = true;
+ }
+ else if (ups[i]==dps[j])
+ full_collide = true;
+ else if (ups[i] >dps[0] && ups[i] < dps.top ())
+ merge_possible = false;
+ else if (dps[j] >ups[0] && dps[j] < ups.top ())
+ merge_possible = false;
+
+ if (ups[i] < dps[j])
+ i++;
+ else if (ups[i] > dps[j])
+ j++;
+ else
+ {
+ i++;
+ j++;
+ }
+ }
+
+ Drul_array<Real> center_note_shifts;
+ center_note_shifts[LEFT] = 0.0;
+ center_note_shifts[RIGHT] = 0.0;
+
+
+ Real shift_amount = 1;
+
+ if ( touch)
+ shift_amount *= -1;
+ else
+ /*
+ for full collisions, the right hand head may obscure dots, so
+ make sure the dotted heads go to the right.
+ */
+ if ((Rhythmic_head::dot_count (nu_l) < Rhythmic_head::dot_count (nd_l)
+ && full_collide))
+ shift_amount *= -1;
+
+ if (merge_possible)
+ shift_amount *= 0.0;
+ else if (half_collide || full_collide)
+ shift_amount *= 0.5;
+ else
+ shift_amount *= 0.25;
+
+ Direction d = UP;
+ do
+ {
+ for (int i=0; i < clash_groups[d].size (); i++)
+ (*offsets)[d][i] += d * shift_amount;
+ }
+ while ((flip (&d))!= UP);
+}
+
+
/*
TODO: make callback of this.
}
}
while ((flip (&d))!= UP);
+
+ /*
+ do horizontal shifts of each direction
+
+ |
+ x||
+ x||
+ x|
+ */
do
{
}
while ((flip (&d))!= UP);
+
+ /*
+ Check if chords are meshing
+ */
+
+ check_meshing_chords (me, &offsets, extents, clash_groups);
+
+#if 0
/*
if the up and down version are close, and can not be merged, move
all of them again. */
}
while ((flip (&d))!= UP);
}
-
+#endif
+
do
{
for (int i=0; i < clash_groups[d].size (); i++)
w = sneaky_insert_extra_moment (w);
- cout << "Proccing " << w << endl;
+ // cout << "Proccing " << w << endl;
if (first)
public:
DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM ));
+ static Array<int> note_head_positions (Grob*);
static int flag_i (Grob*) ;
static int beam_count (Grob*,Direction) ;
static void set_beaming (Grob*,int, Direction d);
}
/*
- ugh: use gh_call ()
+ ugh: use gh_call () / scm_apply ().
UGH: use grob-property.
*/
// compose span_bar_mol
Molecule span_bar_mol;
- Grob *prev_staff_bar = 0;
+
+ Interval prev_extent;
for (SCM elts = first_elt; gh_pair_p (elts); elts = gh_cdr (elts))
{
SCM smobbed_staff_bar = gh_car (elts);
Grob *staff_bar = unsmob_grob (smobbed_staff_bar);
- if (prev_staff_bar)
+ Interval ext = staff_bar->extent (refp, Y_AXIS);
+ if (ext.empty_b ())
+ continue;
+
+ if (!prev_extent.empty_b ())
{
- Interval l(prev_staff_bar->extent (refp, Y_AXIS)[UP],
- staff_bar->extent (refp, Y_AXIS)[DOWN]);
+ Interval l(prev_extent [UP],
+ ext[DOWN]);
Molecule interbar
= Bar::compound_barline (staff_bar, glyph_str, l.length());
interbar.translate_axis (l.center (), Y_AXIS);
span_bar_mol.add_molecule (interbar);
}
- prev_staff_bar = staff_bar;
+ prev_extent = ext;
}
span_bar_mol.translate_axis (- me->relative_coordinate (refp, Y_AXIS), Y_AXIS);
return exthead;
}
+static int
+icmp (int const &a, int const &b)
+{
+ return a-b;
+}
+
+Array<int>
+Stem::note_head_positions (Grob *me)
+{
+ Array<int> ps ;
+ for (SCM s = me->get_grob_property ("heads"); gh_pair_p (s); s = gh_cdr (s))
+ {
+ Grob * n = unsmob_grob (gh_car (s));
+ int p = int (Staff_symbol_referencer::position_f (n));
+
+ ps.push (p);
+ }
+
+ ps.sort (icmp);
+ return ps;
+}
+
+
void
Stem::add_head (Grob*me, Grob *n)
{
return st;
}
+
+
/*
Number of hooks on the flag, ie. the log of the duration.
*/
Molecule
Stem::flag (Grob*me)
{
- // TODO: rename flag-style into something more appropriate,
- // e.g. "stroke-style", maybe with values "" (i.e. no stroke),
- // "single" and "double". Needs more discussion.
- String style, fstyle, stafflineOffs;
+ /* TODO: rename flag-style into something more appropriate,
+ e.g. "stroke-style", maybe with values "" (i.e. no stroke),
+ "single" and "double". Needs more discussion.
+ */
+ String style, fstyle, staffline_offs;
SCM fst = me->get_grob_property ("flag-style");
if (gh_string_p (fst))
{
style = "";
}
if (String::compare_i (style, "mensural") == 0)
- // Mensural notation: For notes on staff lines, use different
- // flags than for notes between staff lines. The idea is that
- // flags are always vertically aligned with the staff lines,
- // regardless if the note head is on a staff line or between two
- // staff lines. In other words, the inner end of a flag always
- // touches a staff line.
+ /* Mensural notation: For notes on staff lines, use different
+ flags than for notes between staff lines. The idea is that
+ flags are always vertically aligned with the staff lines,
+ regardless if the note head is on a staff line or between two
+ staff lines. In other words, the inner end of a flag always
+ touches a staff line.
+ */
{
- // Urrgh! We have to detect wether this stem ends on a staff
- // line or between two staff lines. But we can not call
- // stem_end_position(me) or get_default_stem_end_position(me),
- // since this encounters the flag and hence results in an
- // infinite recursion. However, in pure mensural notation,
- // there are no multiple note heads attached to a single stem,
- // neither is there usually need for using the stem_shorten
- // property (except for 32th and 64th notes, but that is not a
- // problem since the stem length in this case is augmented by
- // an integral multiple of staff_space). Hence, it should be
- // sufficient to just take the first note head, assume it's
- // the only one, look if it's on a staff line, and select the
- // flag's shape accordingly. In the worst case, the shape
- // looks slightly misplaced, but that will usually be the
- // programmer's fault (e.g. when trying to attach multiple
- // note heads to a single stem in mensural notation).
- Grob *firstHead = first_head(me);
+ /* Urrgh! We have to detect wether this stem ends on a staff
+ line or between two staff lines. But we can not call
+ stem_end_position(me) or get_default_stem_end_position(me),
+ since this encounters the flag and hence results in an
+ infinite recursion. However, in pure mensural notation,
+ there are no multiple note heads attached to a single stem,
+ neither is there usually need for using the stem_shorten
+ property (except for 32th and 64th notes, but that is not a
+ problem since the stem length in this case is augmented by
+ an integral multiple of staff_space). Hence, it should be
+ sufficient to just take the first note head, assume it's
+ the only one, look if it's on a staff line, and select the
+ flag's shape accordingly. In the worst case, the shape
+ looks slightly misplaced, but that will usually be the
+ programmer's fault (e.g. when trying to attach multiple
+ note heads to a single stem in mensural notation).
+
+ */
+ Grob *first = first_head(me);
int sz = Staff_symbol_referencer::line_count (me)-1;
- int p = (int)rint (Staff_symbol_referencer::position_f (firstHead));
- stafflineOffs = (((p ^ sz) & 0x1) == 0) ? "1" : "0";
+ int p = (int)rint (Staff_symbol_referencer::position_f (first));
+ staffline_offs = (((p ^ sz) & 0x1) == 0) ? "1" : "0";
}
else
{
- stafflineOffs = "";
+ staffline_offs = "";
}
char c = (get_direction (me) == UP) ? 'u' : 'd';
- Molecule m =
- Font_interface::get_default_font (me)->
- find_by_name (String ("flags-") + style + to_str (c) + stafflineOffs +
- to_str (flag_i (me)));
+ String index_str
+ = String ("flags-") + style + to_str (c) + staffline_offs + to_str (flag_i (me));
+ Molecule m
+ = Font_interface::get_default_font (me)->find_by_name (index_str);
if (!fstyle.empty_b ())
m.add_molecule (Font_interface::get_default_font (me)->find_by_name (String ("flags-") + to_str (c) + fstyle));
return m;
(hip_width, foot_depth),
hip_depth_ratio,foot_width_ratio, hip_thickness, foot_thickness);
+ pickup pencircle scaled stemthickness;
+ draw (0, 0) .. (0,-2 staff_space);
+ y_mirror_char;
+fet_endchar;
+
%%%%%%%%
%
%
(w, h);
fet_endchar;
- pickup pencircle scaled stemthickness;
- draw (0, 0) .. (0,-2 staff_space);
- y_mirror_char;
-fet_endchar;
-
fet_beginchar("16th (down)", "d4", "dsixteenthflag")
save flare,
hip_depth_ratio, hip_width,