/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2002--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 2002--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
}
void
-Accidental_placement::add_accidental (Grob *me, Grob *a)
+Accidental_placement::add_accidental (Grob *me, Grob *a, bool stagger, long context_hash)
{
Pitch *p = accidental_pitch (a);
if (!p)
a->set_parent (me, X_AXIS);
a->set_property ("X-offset", Grob::x_parent_positioning_proc);
- int n = p->get_notename ();
+ long n = p->get_notename ();
SCM accs = me->get_object ("accidental-grobs");
- SCM key = scm_from_int (n);
- SCM entry = scm_assq (key, accs);
+ SCM key = scm_cons (scm_from_int (n), scm_from_long (stagger ? context_hash : 1));
+ // assoc because we're dealing with pairs
+ SCM entry = scm_assoc (key, accs);
if (entry == SCM_BOOL_F)
entry = SCM_EOL;
else
entry = scm_cons (a->self_scm (), entry);
- accs = scm_assq_set_x (accs, key, entry);
+ accs = scm_assoc_set_x (accs, key, entry);
me->set_object ("accidental-grobs", accs);
}
bool ape_less (Accidental_placement_entry *const &a,
Accidental_placement_entry *const &b)
{
+ vsize size_a = a->grobs_.size ();
+ vsize size_b = b->grobs_.size ();
+ if (size_a != size_b)
+ return size_b < size_a;
+
return ape_priority (a) < ape_priority (b);
}
vector<Accidental_placement_entry *> asc = *apes;
vector_sort (asc, &ape_less);
+ // we do the staggering below based on size
+ // this ensures that if a placement has 4 entries, it will
+ // always be closer to the NoteColumn than a placement with 1
+ // this allows accidentals to be on-average closer to notes
+ // while still preserving octave alignment
+ vector<vector<Accidental_placement_entry *> > ascs;
+
+ vsize sz = INT_MAX;
+ for (vsize i = 0; i < asc.size (); i++)
+ {
+ vsize my_sz = asc[i]->grobs_.size ();
+ if (sz != my_sz)
+ ascs.push_back (vector<Accidental_placement_entry *> ());
+ ascs.back ().push_back (asc[i]);
+ sz = my_sz;
+ }
apes->clear ();
- int parity = 1;
- for (vsize i = 0; i < asc.size ();)
+ for (vsize i = 0; i < ascs.size (); i++)
{
- Accidental_placement_entry *a = 0;
- if (parity)
+ int parity = 1;
+ for (vsize j = 0; j < ascs[i].size ();)
{
- a = asc.back ();
- asc.pop_back ();
- }
- else
- a = asc[i++];
+ Accidental_placement_entry *a = 0;
+ if (parity)
+ {
+ a = ascs[i].back ();
+ ascs[i].pop_back ();
+ }
+ else
+ a = ascs[i][j++];
- apes->push_back (a);
- parity = !parity;
+ apes->push_back (a);
+ parity = !parity;
+ }
}
reverse (*apes);
for (vsize i = ret.size (); i--;)
if (Grob *s = Rhythmic_head::get_stem (ret[i]))
ret.push_back (s);
-
- vector_sort (ret, less<Grob *> ());
- uniq (ret);
+
+ uniquify (ret);
return ret;
}
{
Accidental_placement_entry *ape = apes[i];
- Real offset = -ape->horizontal_skylines_[RIGHT].distance (left_skyline);
+ Real offset = -ape->horizontal_skylines_[RIGHT]
+ .distance (left_skyline, 0.1);
if (isinf (offset))
offset = last_offset;
else