- /*
- First we must extract *all* pointers. We can only determine
- extents if we're sure that we've found the right common refpoint
- */
- Link_array<Grob> note_cols, heads;
- for (int i= apes.size (); i--;)
- {
- Accidental_placement_entry * ape = apes[i];
- for (int j = ape->grobs_.size (); j--;)
- {
- Grob * a = ape->grobs_[j];
-
- if (common[Y_AXIS])
- common[Y_AXIS] = common[Y_AXIS]->common_refpoint (a, Y_AXIS);
- else
- common[Y_AXIS] = a;
-
- Grob *head = a->get_parent (Y_AXIS);
-
- Grob * col = head->get_parent (X_AXIS);
- if (Note_column::has_interface (col))
- note_cols.push (col);
- else
- heads.push (head);
- }
+static void
+set_ape_skylines (Accidental_placement_entry *ape,
+ Grob **common, Real padding)
+{
+ vector<Grob *> accs (ape->grobs_);
+ vector_sort (accs, &acc_less);
+
+ /* We know that each accidental has the same note name and we assume that
+ accidentals in different octaves won't collide. If two or more
+ accidentals are in the same octave:
+ 1) if they are the same accidental, print them in overstrike
+ 2) otherwise, shift one to the left so they don't overlap. */
+ int last_octave = 0;
+ Real offset = 0;
+ Real last_offset = 0;
+ Rational last_alteration (0);
+ for (vsize i = accs.size (); i--;)
+ {
+ Grob *a = accs[i];
+ Pitch *p = accidental_pitch (a);
+
+ if (!p)
+ continue;
+
+ if (i == accs.size () - 1 || p->get_octave () != last_octave)
+ {
+ last_offset = 0;
+ offset = a->extent (a, X_AXIS)[LEFT] - padding;
+ }
+ else if (p->get_alteration () == last_alteration)
+ a->translate_axis (last_offset, X_AXIS);
+ else /* Our alteration is different from the last one */
+ {
+ Real this_offset = offset - a->extent (a, X_AXIS)[RIGHT];
+ a->translate_axis (this_offset, X_AXIS);
+
+ last_offset = this_offset;
+ offset -= a->extent (a, X_AXIS).length () + padding;
+ }
+
+ if (Skyline_pair *sky = Skyline_pair::unsmob (a->get_property ("horizontal-skylines")))
+ {
+ Skyline_pair copy (*sky);
+ copy.raise (a->relative_coordinate (common[X_AXIS], X_AXIS));
+ copy.shift (a->relative_coordinate (common[Y_AXIS], Y_AXIS));
+ ape->horizontal_skylines_.merge (copy);
+ }
+
+ last_octave = p->get_octave ();
+ last_alteration = p->get_alteration ();
+ }
+}
+
+static vector<Grob *>
+extract_heads_and_stems (vector<Accidental_placement_entry *> const &apes)
+{
+ vector<Grob *> note_cols;
+ vector<Grob *> ret;
+
+ for (vsize i = apes.size (); i--;)
+ {
+ Accidental_placement_entry *ape = apes[i];
+ for (vsize j = ape->grobs_.size (); j--;)
+ {
+ Grob *acc = ape->grobs_[j];
+ Grob *head = acc->get_parent (Y_AXIS);
+ Grob *col = head->get_parent (X_AXIS);
+
+ if (Note_column::has_interface (col))
+ note_cols.push_back (col);
+ else
+ ret.push_back (head);
+ }