Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #305487: Invisible accidentals take space #6100

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,7 @@ void Chord::layoutPitched()
lhead = qMax(lhead, -x1);

Accidental* accidental = note->accidental();
if (accidental && !note->fixed()) {
if (accidental && accidental->addToSkyline() && !note->fixed()) {
// convert x position of accidental to segment coordinate system
qreal x = accidental->pos().x() + note->pos().x() + chordX;
// distance from accidental to note already taken into account
Expand Down
65 changes: 35 additions & 30 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,39 +843,44 @@ void Score::layoutChords3(std::vector<Note*>& notes, const Staff* staff, Segment
Accidental* ac = note->accidental();
if (ac && !note->fixed()) {
ac->layout();
AcEl acel;
acel.note = note;
int line = note->line();
acel.line = line;
acel.x = 0.0;
acel.top = line * 0.5 * sp + ac->bbox().top();
acel.bottom = line * 0.5 * sp + ac->bbox().bottom();
acel.width = ac->width();
QPointF bboxNE = ac->symBbox(ac->symbol()).topRight();
QPointF bboxSW = ac->symBbox(ac->symbol()).bottomLeft();
QPointF cutOutNE = ac->symCutOutNE(ac->symbol());
QPointF cutOutSW = ac->symCutOutSW(ac->symbol());
if (!cutOutNE.isNull()) {
acel.ascent = cutOutNE.y() - bboxNE.y();
acel.rightClear = bboxNE.x() - cutOutNE.x();
if (!ac->visible()) {
ac->setPos(ac->bbox().x() - ac->width(), 0.0);
}
else {
acel.ascent = 0.0;
acel.rightClear = 0.0;
}
if (!cutOutSW.isNull()) {
acel.descent = bboxSW.y() - cutOutSW.y();
acel.leftClear = cutOutSW.x() - bboxSW.x();
}
else {
acel.descent = 0.0;
acel.leftClear = 0.0;
AcEl acel;
acel.note = note;
int line = note->line();
acel.line = line;
acel.x = 0.0;
acel.top = line * 0.5 * sp + ac->bbox().top();
acel.bottom = line * 0.5 * sp + ac->bbox().bottom();
acel.width = ac->width();
QPointF bboxNE = ac->symBbox(ac->symbol()).topRight();
QPointF bboxSW = ac->symBbox(ac->symbol()).bottomLeft();
QPointF cutOutNE = ac->symCutOutNE(ac->symbol());
QPointF cutOutSW = ac->symCutOutSW(ac->symbol());
if (!cutOutNE.isNull()) {
acel.ascent = cutOutNE.y() - bboxNE.y();
acel.rightClear = bboxNE.x() - cutOutNE.x();
}
else {
acel.ascent = 0.0;
acel.rightClear = 0.0;
}
if (!cutOutSW.isNull()) {
acel.descent = bboxSW.y() - cutOutSW.y();
acel.leftClear = cutOutSW.x() - bboxSW.x();
}
else {
acel.descent = 0.0;
acel.leftClear = 0.0;
}
int pitchClass = (line + 700) % 7;
acel.next = columnBottom[pitchClass];
columnBottom[pitchClass] = nAcc;
aclist.append(acel);
++nAcc;
}
int pitchClass = (line + 700) % 7;
acel.next = columnBottom[pitchClass];
columnBottom[pitchClass] = nAcc;
aclist.append(acel);
++nAcc;
}

Chord* chord = note->chord();
Expand Down
2 changes: 1 addition & 1 deletion libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4238,7 +4238,7 @@ static bool hasAccidental(Segment* s)
continue;
Chord* c = toChord(e);
for (Note* n : c->notes()) {
if (n->accidental())
if (n->accidental() && n->accidental()->addToSkyline())
return true;
}
}
Expand Down
8 changes: 4 additions & 4 deletions libmscore/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3429,10 +3429,10 @@ Shape Note::shape() const
Shape shape(r, name());
for (NoteDot* dot : _dots)
shape.add(symBbox(SymId::augmentationDot).translated(dot->pos()), dot->name());
if (_accidental)
if (_accidental && _accidental->addToSkyline())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the purpose of making sure accidentals can tuck over/under other notes, this is not needed. Which is to say, it could be visible() instead of addToSkyline(). As it is, this change means non-autoplaced accidentals can not only tuck over/under, they can also collide with previous notes. I guess that's expected, although not what I was originally thinking might be nice. I suppose it's more of a hack, though, so I'm fine leaving this as you have it. Just wanted to mention it in case it sparks any additional thoughts.

shape.add(_accidental->bbox().translated(_accidental->pos()), _accidental->name());
for (auto e : _el) {
if (e->autoplace() && e->visible()) {
if (e->addToSkyline()) {
if (e->isFingering() && toFingering(e)->layoutType() != ElementType::NOTE)
continue;
shape.add(e->bbox().translated(e->pos()), e->name());
Expand All @@ -3442,10 +3442,10 @@ Shape Note::shape() const
Shape shape(r);
for (NoteDot* dot : _dots)
shape.add(symBbox(SymId::augmentationDot).translated(dot->pos()));
if (_accidental)
if (_accidental && _accidental->addToSkyline())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I wonder if we could lose this NDEBUG duplication? Right now it buys us some better debug info on the shapes when compiling in debug mode, without a performance penalty otherwise. But maybe there is a less error-prone way of doing that? Way too easy for these two sections of code to get out of sync.

shape.add(_accidental->bbox().translated(_accidental->pos()));
for (auto e : _el) {
if (e->autoplace() && e->visible()) {
if (e->addToSkyline()) {
if (e->isFingering() && toFingering(e)->layoutType() != ElementType::NOTE)
continue;
shape.add(e->bbox().translated(e->pos()));
Expand Down