Reviewers: ,
Message:
Please review, fixes issue 4979.
-Paul
Description:
Don't merge non-overlapping ledger lines
Issue 4979/2: Add regression test for non-merging ledger lines
Issue 4979/1: Don't merge non-overlapping ledger lines
Please review this at https://codereview.appspot.com/308560043/
Affected files (+71, -26 lines):
A input/regression/ledger-lines-non-merging.ly
M lily/ledger-line-spanner.cc
Index: input/regression/ledger-lines-non-merging.ly
diff --git a/input/regression/ledger-lines-non-merging.ly
b/input/regression/ledger-lines-non-merging.ly
new file mode 100644
index
0000000000000000000000000000000000000000..ac3bbed2cc4f8c9622e060ef333eebe369dd7e5c
--- /dev/null
+++ b/input/regression/ledger-lines-non-merging.ly
@@ -0,0 +1,32 @@
+\version "2.19.49"
+
+\header {
+ texidoc = "In some rare cases like these the
+extents of two ledger lines at the same vertical
+position in the same note column do not overlap
+horizontally, and they should not be merged into
+a single ledger line.
+See LSR 505: Displaying complex chords
+http://lsr.di.unimi.it/LSR/Item?id=505
+"
+}
+
+fixA = {
+ \once \override Stem.length = #11
+}
+
+fixB = {
+ \once \override NoteHead.X-offset = #1.7
+ \once \override Stem.length = #7
+ \once \override Stem.rotation = #'(45 0 0)
+ \once \override Stem.extra-offset = #'(-0.1 . -0.2)
+ \once \override Flag.style = #'no-flag
+ \once \override Accidental.extra-offset = #'(4 . -.1)
+}
+
+\relative c' {
+ % case 1
+ \pitchedTrill a'' \startTrillSpan a
+ % case 2
+ << { \fixA <b,,, d!>8 } \\ { \voiceThree \fixB dis } >> s
+}
Index: lily/ledger-line-spanner.cc
diff --git a/lily/ledger-line-spanner.cc b/lily/ledger-line-spanner.cc
index
2fe2d7d9c3896e0b627dccc8f78ab51444007006..8aeb71aab2004dc661f4cac41278c2993299fb2d
100644
--- a/lily/ledger-line-spanner.cc
+++ b/lily/ledger-line-spanner.cc
@@ -161,7 +161,9 @@ struct Ledger_request
Interval max_head_extent_;
int max_position_;
vector <Head_data> heads_;
- map <Real, Interval> ledger_extents_;
+ // The map's keys are vertical ledger line positions. The values are
+ // vectors of the x-extents of ledger lines.
+ map <Real, vector <Interval> > ledger_extents_;
Ledger_request ()
{
max_ledger_extent_.set_empty ();
@@ -294,9 +296,7 @@ Ledger_line_spanner::print (SCM smob)
// Iterate through ledger requests and the data they have about each
// note head to generate the final extents for all ledger lines.
- // Note heads that are different widths produce different ledger
- // extents and these are merged so the widest extent prevails
- // (the union of the intervals) for each ledger line.
+ // Note heads of different widths produce different ledger extents.
for (Ledger_requests::iterator i (reqs.begin ());
i != reqs.end (); i++)
{
@@ -337,10 +337,25 @@ Ledger_line_spanner::print (SCM smob)
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 ())
- lr.ledger_extents_[lpos] = x_extent;
+ // Found nothing for this lpos.
+ lr.ledger_extents_[lpos].push_back(x_extent);
else
- lr.ledger_extents_[lpos].unite (x_extent);
+ {
+ 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);
+ }
+ }
}
}
}
@@ -349,36 +364,34 @@ Ledger_line_spanner::print (SCM smob)
// Create the stencil for the ledger line spanner by iterating
// through the ledger requests and their data on ledger extents.
Stencil ledgers;
- Real ledgerlinethickness
- = Staff_symbol::get_ledger_line_thickness (staff);
+ Real thickness = Staff_symbol::get_ledger_line_thickness (staff);
+ Real half_thickness = thickness * 0.5;
+ Interval y_extent = Interval (-half_thickness, half_thickness);
- for (Ledger_requests::iterator i (reqs.begin ());
- i != reqs.end (); i++)
+ for (Ledger_requests::iterator i (reqs.begin ()); i != reqs.end (); i++)
{
for (DOWN_and_UP (d))
{
- map<Real, Interval> &lex = i->second[d].ledger_extents_;
- for (map<Real, Interval>::iterator k = lex.begin ();
+ map<Real, vector<Interval> > &lex = i->second[d].ledger_extents_;
+ for (map<Real, vector<Interval> >::iterator k = lex.begin ();
k != lex.end (); k++)
{
- Real blotdiameter = ledgerlinethickness;
Real lpos = k->first;
- Interval x_extent = k->second;
- Interval y_extent
- = Interval (-0.5 * (ledgerlinethickness),
- +0.5 * (ledgerlinethickness));
- Stencil ledger_line
- = Lookup::round_filled_box (Box (x_extent, y_extent),
blotdiameter);
-
- ledger_line.translate_axis ( lpos * halfspace, Y_AXIS);
- ledgers.add_stencil (ledger_line);
+ vector<Interval> &x_extents = k->second;
+
+ for (vsize n = 0; n < x_extents.size (); n++)
+ {
+ // thickness (ledger line thickness) is the blot diameter
+ Stencil line = Lookup::round_filled_box (Box
(x_extents[n], y_extent),
+ thickness);
+
+ line.translate_axis (lpos * halfspace, Y_AXIS);
+ ledgers.add_stencil (line);
+ }
}
}
}
-
- ledgers.translate_axis (-me->relative_coordinate (common_x, X_AXIS),
- X_AXIS);
-
+ ledgers.translate_axis (-me->relative_coordinate (common_x, X_AXIS),
X_AXIS);
return ledgers.smobbed_copy ();
}
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel