+ vector<Real> &ledger_posns = lr.heads_[h].ledger_positions_;
+ Interval &ledger_size = lr.heads_[h].ledger_extent_;
+ Interval &head_size = lr.heads_[h].head_extent_;
+ Interval &acc_extent = lr.heads_[h].accidental_extent_;
+
+ // Limit ledger extents to a maximum to preserve space
+ // between ledgers when note heads get close.
+ if (!lr.max_ledger_extent_.is_empty ())
+ ledger_size.intersect (lr.max_ledger_extent_);
+
+ // Iterate through the ledgers for a given note head.
+ for (vsize l = 0; l < ledger_posns.size (); l++)
+ {
+ Real lpos = ledger_posns[l];
+ Interval x_extent = ledger_size;
+
+ // Notes with accidental signs get shorter ledgers.
+ // (Only happens for the furthest note in the column.)
+ if (l == 0 && !acc_extent.is_empty ())
+ {
+ Real dist
+ = linear_combination (Drul_array<Real> (acc_extent[RIGHT],
+ head_size[LEFT]),
+ 0.0);
+
+ Real left_shorten = max (-ledger_size[LEFT] + dist, 0.0);
+ x_extent[LEFT] += left_shorten;
+ /*
+ TODO: shorten 2 ledger lines for the case
+ natural + downstem.
+ */
+ }
+ // When the extents of two ledgers at the same
+ // vertical position overlap horizontally, we merge
+ // them together to produce a single stencil. In rare
+ // cases they do not overlap and we do not merge them.
+
+ if (lr.ledger_extents_.find (lpos) == lr.ledger_extents_.end ())
+ // Found nothing for this lpos.
+ lr.ledger_extents_[lpos].push_back(x_extent);
+ else
+ {
+ vector<Interval> &extents = lr.ledger_extents_.find (lpos)->second;
+ for (vsize e = 0; e < extents.size (); e++)
+ {
+ if (intersection (extents[e], x_extent).is_empty ())
+ extents.push_back (x_extent);
+ else
+ extents[e].unite (x_extent);
+ }
+ }
+ }