Skip to content

Commit

Permalink
Merge pull request #18905 from mike-spa/fix#18818Slurmisshapedwhenfli…
Browse files Browse the repository at this point in the history
…pped

Fix #18818 Slur misshaped when flipped
  • Loading branch information
RomanPudashkin committed Aug 8, 2023
2 parents 8e4660a + c347d2e commit 3e0f912
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
56 changes: 30 additions & 26 deletions src/engraving/libmscore/slur.cpp
Expand Up @@ -320,6 +320,7 @@ Shape SlurSegment::getSegmentShape(Segment* seg, ChordRest* startCR, ChordRest*
staff_idx_t startStaffIdx = startCR->staffIdx();
staff_idx_t endStaffIdx = endCR->staffIdx();
Shape segShape = seg->staffShape(startStaffIdx).translated(seg->pos() + seg->measure()->pos());

// If cross-staff, also add the shape of second staff
if (slur()->isCrossStaff() && seg != startCR->segment()) {
endStaffIdx = (endCR->staffIdx() != startStaffIdx) ? endCR->staffIdx() : endCR->vStaffIdx();
Expand All @@ -330,31 +331,7 @@ Shape SlurSegment::getSegmentShape(Segment* seg, ChordRest* startCR, ChordRest*
secondStaffShape.translate(PointF(0.0, dist)); // translate vertically
segShape.add(secondStaffShape);
}
// Remove items that the slur shouldn't try to avoid
mu::remove_if(segShape, [&](ShapeElement& shapeEl) {
if (!shapeEl.toItem || !shapeEl.toItem->parentItem()) {
return true;
}
const EngravingItem* item = shapeEl.toItem;
const EngravingItem* parent = item->parentItem();
// Its own startCR or items belonging to it, lyrics, fingering, ledger lines, articulation on endCR
if (item == startCR || parent == startCR || item->isTextBase() || item->isLedgerLine()
|| (item->isArticulationFamily() && parent == endCR) || item->isBend() || item->isStretchedBend()) {
return true;
}
// Items that are on the start segment but in a different voice
if ((item->tick() == startCR->tick() && item->track() != startCR->track())
|| (item->tick() == endCR->tick() && item->track() != endCR->track())) {
return true;
}
// Edge-case: multiple voices and slur is on the inside
if (item->vStaffIdx() == startCR->staffIdx()
&& ((!slur()->up() && item->track() > startCR->track()) // slur-down: ignore lower voices
|| (slur()->up() && item->track() < startCR->track()))) { // slur-up: ignore higher voices
return true;
}
return false;
});

for (track_idx_t track = staff2track(startStaffIdx); track < staff2track(endStaffIdx, VOICES); ++track) {
EngravingItem* e = seg->elementAt(track);
if (!e || !e->isChordRest()) {
Expand All @@ -380,6 +357,33 @@ Shape SlurSegment::getSegmentShape(Segment* seg, ChordRest* startCR, ChordRest*
}
}
}

// Remove items that the slur shouldn't try to avoid
mu::remove_if(segShape, [&](ShapeElement& shapeEl) {
if (!shapeEl.toItem || !shapeEl.toItem->parentItem()) {
return true;
}
const EngravingItem* item = shapeEl.toItem;
const EngravingItem* parent = item->parentItem();
// Its own startCR or items belonging to it, lyrics, fingering, ledger lines, articulation on endCR
if (item == startCR || parent == startCR || item->isTextBase() || item->isLedgerLine()
|| (item->isArticulationFamily() && parent == endCR) || item->isBend() || item->isStretchedBend()) {
return true;
}
// Items that are on the start segment but in a different voice
if ((item->tick() == startCR->tick() && item->track() != startCR->track())
|| (item->tick() == endCR->tick() && item->track() != endCR->track())) {
return true;
}
// Edge-case: multiple voices and slur is on the inside
if (item->vStaffIdx() == startCR->staffIdx()
&& ((!slur()->up() && item->track() > startCR->track()) // slur-down: ignore lower voices
|| (slur()->up() && item->track() < startCR->track()))) { // slur-up: ignore higher voices
return true;
}
return false;
});

return segShape;
}

Expand Down Expand Up @@ -782,7 +786,7 @@ void SlurSegment::computeBezier(mu::PointF p6offset)
double d1 = (minH - re.height()) * .5;
re.adjust(0.0, -d1, 0.0, d1);
}
m_shape.add(re);
m_shape.add(re, this);
start = point;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/libmscore/tie.cpp
Expand Up @@ -302,7 +302,7 @@ void TieSegment::computeBezier(PointF shoulderOffset)
tieWidthInSp = (minH - re.height()) * .5;
re.adjust(0.0, -tieWidthInSp, 0.0, tieWidthInSp);
}
m_shape.add(re);
m_shape.add(re, this);
start = point;
}
}
Expand Down
Binary file modified vtest/scores/slurs-20.mscz
Binary file not shown.

0 comments on commit 3e0f912

Please sign in to comment.