From 1df521bad98eb2303825610fe6ef39ce4804c3f6 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Tue, 8 Oct 2024 08:30:00 +0100 Subject: [PATCH] Use segment shape to adjust tie length & reduce collisions --- .../rendering/score/slurtielayout.cpp | 37 +++++++++++------- vtest/scores/tie-22.mscz | Bin 0 -> 24143 bytes 2 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 vtest/scores/tie-22.mscz diff --git a/src/engraving/rendering/score/slurtielayout.cpp b/src/engraving/rendering/score/slurtielayout.cpp index 753cc7bd22139..88a84b62d06f0 100644 --- a/src/engraving/rendering/score/slurtielayout.cpp +++ b/src/engraving/rendering/score/slurtielayout.cpp @@ -1625,19 +1625,24 @@ void SlurTieLayout::adjustX(TieSegment* tieSegment, SlurTiePos& sPos, Grip start { bool start = startOrEnd == Grip::START; - Tie* tie = tieSegment->tie(); + const Tie* tie = tieSegment->tie(); Note* note = start ? tie->startNote() : tie->endNote(); + const Note* otherNote = start ? tie->endNote() : tie->startNote(); if (!note || note->shouldHideFret()) { return; } Chord* chord = note->chord(); + const Chord* otherChord = otherNote ? otherNote->chord() : nullptr; + const Segment* chordSeg = chord->segment(); const double spatium = tieSegment->spatium(); + const bool isGrace = (chord && chord->isGrace()) + || ((otherChord && otherChord->isGrace()) && chord->segment() == otherChord->segment()); PointF& tiePoint = start ? sPos.p1 : sPos.p2; double resultingX = tiePoint.x(); - bool isOuterTieOfChord = tie->isOuterTieOfChord(startOrEnd); + const bool isOuterTieOfChord = tie->isOuterTieOfChord(startOrEnd); if (isOuterTieOfChord) { Tie* otherTie = start ? note->tieBack() : note->tieFor(); @@ -1647,7 +1652,7 @@ void SlurTieLayout::adjustX(TieSegment* tieSegment, SlurTiePos& sPos, Grip start } } - bool avoidStem = chord->stem() && chord->stem()->visible() && chord->up() == tie->up(); + const bool avoidStem = chord->stem() && chord->stem()->visible() && chord->up() == tie->up(); if (isOuterTieOfChord && !avoidStem) { tieSegment->addAdjustmentOffset(PointF(resultingX - tiePoint.x(), 0.0), startOrEnd); @@ -1655,39 +1660,43 @@ void SlurTieLayout::adjustX(TieSegment* tieSegment, SlurTiePos& sPos, Grip start return; } - PointF chordSystemPos = chord->pos() + chord->segment()->pos() + chord->measure()->pos(); + // Use segment shape except for when either end of the tie is a grace note + PointF systemPos = chordSeg->pos() + chordSeg->measure()->pos() + (isGrace ? chord->pos() : PointF()); if (chord->vStaffIdx() != tieSegment->vStaffIdx()) { System* system = tieSegment->system(); double yDiff = system->staff(chord->vStaffIdx())->y() - system->staff(tie->staffIdx())->y(); - chordSystemPos += PointF(0.0, yDiff); + systemPos += PointF(0.0, yDiff); } - Shape chordShape = chord->shape().translate(chordSystemPos); - bool ignoreDot = start && isOuterTieOfChord; - bool ignoreAccidental = !start && isOuterTieOfChord; + Shape shape = isGrace ? chord->shape().translate(systemPos) : chordSeg->staffShape(chord->vStaffIdx()).translated(systemPos); + + const bool ignoreDot = start && isOuterTieOfChord; + const bool ignoreAccidental = !start && isOuterTieOfChord; static const std::set IGNORED_TYPES = { ElementType::HOOK, ElementType::STEM_SLASH, ElementType::LEDGER_LINE, ElementType::LYRICS }; - chordShape.remove_if([&](ShapeElement& s) { - return !s.item() || s.item() == note || muse::contains(IGNORED_TYPES, s.item()->type()) - || (s.item()->isNoteDot() && ignoreDot) || (s.item()->isAccidental() && ignoreAccidental) || !s.item()->addToSkyline(); + shape.remove_if([&](ShapeElement& s) { + bool remove = !s.item() || s.item() == note || muse::contains(IGNORED_TYPES, s.item()->type()) + || (s.item()->isNoteDot() && ignoreDot) + || (s.item()->isAccidental() && ignoreAccidental && s.item()->track() == chord->track()) || !s.item()->addToSkyline(); + return remove; }); const double arcSideMargin = 0.3 * spatium; const double pointsSideMargin = 0.15 * spatium; const double yBelow = tiePoint.y() - (tie->up() ? arcSideMargin : pointsSideMargin); const double yAbove = tiePoint.y() + (tie->up() ? pointsSideMargin : arcSideMargin); - double pointToClear = start ? chordShape.rightMostEdgeAtHeight(yBelow, yAbove) - : chordShape.leftMostEdgeAtHeight(yBelow, yAbove); + double pointToClear = start ? shape.rightMostEdgeAtHeight(yBelow, yAbove) + : shape.leftMostEdgeAtHeight(yBelow, yAbove); const double padding = 0.20 * spatium * (start ? 1 : -1); // TODO: style pointToClear += padding; resultingX = start ? std::max(resultingX, pointToClear) : std::min(resultingX, pointToClear); - adjustXforLedgerLines(tieSegment, start, chord, note, chordSystemPos, padding, resultingX); + adjustXforLedgerLines(tieSegment, start, chord, note, systemPos, padding, resultingX); tieSegment->addAdjustmentOffset(PointF(resultingX - tiePoint.x(), 0.0), startOrEnd); tiePoint.setX(resultingX); diff --git a/vtest/scores/tie-22.mscz b/vtest/scores/tie-22.mscz new file mode 100644 index 0000000000000000000000000000000000000000..6bb0b3bd902c7dfed1302271831e534ca63a3d05 GIT binary patch literal 24143 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 literal 0 HcmV?d00001