Skip to content

Commit c63f04e

Browse files
authored
Merge pull request #21192 from miiizen/20747-cross-ties
Fix cross staff tie layout
2 parents 775e221 + ecc953f commit c63f04e

File tree

5 files changed

+33
-11
lines changed

5 files changed

+33
-11
lines changed

src/engraving/dom/tie.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,11 @@ bool Tie::isCrossStaff() const
501501
{
502502
const Note* startN = startNote();
503503
const Note* endN = endNote();
504+
const Chord* startChord = startN ? startN->chord() : nullptr;
505+
const Chord* endChord = endN ? endN->chord() : nullptr;
506+
const staff_idx_t staff = staffIdx();
504507

505-
return (startN && startN->chord()->staffMove() != 0) || (endN && endN->chord()->staffMove() != 0);
508+
return (startChord && (startChord->staffMove() != 0 || startChord->vStaffIdx() != staff))
509+
|| (endChord && (endChord->staffMove() != 0 || endChord->vStaffIdx() != staff));
506510
}
507511
}

src/engraving/dom/tie.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,15 @@ class TieSegment final : public SlurTieSegment
5858

5959
void addLineAttachPoints();
6060

61+
void setStaffMove(int val) { m_staffMove = val; }
62+
staff_idx_t vStaffIdx() const override { return staffIdx() + m_staffMove; }
63+
6164
protected:
6265
void changeAnchor(EditData&, EngravingItem*) override;
6366

6467
private:
6568

69+
int m_staffMove = 0;
6670
std::array<PointF, static_cast<size_t>(Grip::GRIPS)> m_adjustmentOffsets;
6771
};
6872

src/engraving/rendering/dev/measurelayout.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ void MeasureLayout::layout2(Measure* item, LayoutContext& ctx)
106106
// layout cross-staff ties
107107
//---------------------------------------------------
108108

109-
Fraction stick = item->system()->measures().front()->tick();
110-
size_t tracks = ctx.dom().ntracks();
109+
const Fraction stick = item->system()->measures().front()->tick();
110+
const size_t tracks = ctx.dom().ntracks();
111111
static const SegmentType st { SegmentType::ChordRest };
112112
for (track_idx_t track = 0; track < tracks; ++track) {
113113
if (!ctx.dom().staff(track / VOICES)->show()) {

src/engraving/rendering/dev/slurtielayout.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,7 +1502,7 @@ TieSegment* SlurTieLayout::tieLayoutFor(Tie* item, System* system)
15021502
segment->setSystem(system); // Needed to populate System.spannerSegments
15031503
segment->resetAdjustmentOffset();
15041504

1505-
Chord* startChord = item->startNote()->chord();
1505+
const Chord* startChord = item->startNote()->chord();
15061506
item->setTick(startChord->tick()); // Why is this here?? (M.S.)
15071507

15081508
if (segment->autoplace() && !segment->isEdited()) {
@@ -1529,9 +1529,11 @@ TieSegment* SlurTieLayout::tieLayoutFor(Tie* item, System* system)
15291529

15301530
TieSegment* SlurTieLayout::tieLayoutBack(Tie* item, System* system, LayoutContext& ctx)
15311531
{
1532+
Chord* chord = item->endNote() ? item->endNote()->chord() : nullptr;
1533+
15321534
if (item->staffType() && item->staffType()->isTabStaff()) {
15331535
// On TAB, the presence of this tie may require to add a parenthesis
1534-
ChordLayout::layout(item->endNote()->chord(), ctx);
1536+
ChordLayout::layout(chord, ctx);
15351537
}
15361538
// do not layout ties in tablature if not showing back-tied fret marks
15371539
if (tieSegmentShouldBeSkipped(item)) {
@@ -1556,6 +1558,10 @@ TieSegment* SlurTieLayout::tieLayoutBack(Tie* item, System* system, LayoutContex
15561558
segment->setSystem(system);
15571559
segment->resetAdjustmentOffset();
15581560

1561+
if (chord) {
1562+
segment->setStaffMove(chord->vStaffIdx() - segment->staffIdx());
1563+
}
1564+
15591565
adjustY(segment);
15601566
segment->setSpannerSegmentType(SpannerSegmentType::END);
15611567

@@ -1672,7 +1678,7 @@ void SlurTieLayout::correctForCrossStaff(Tie* tie, SlurTiePos& sPos)
16721678
return;
16731679
}
16741680

1675-
if (startChord->vStaffIdx() != tie->staffIdx() && sPos.system1) {
1681+
if (startChord->vStaffIdx() != tie->staffIdx() && sPos.system1 && sPos.system1 == sPos.system2) {
16761682
double yOrigin = sPos.system1->staff(tie->staffIdx())->y();
16771683
double yMoved = sPos.system1->staff(startChord->vStaffIdx())->y();
16781684
double yDiff = yMoved - yOrigin;
@@ -1684,7 +1690,7 @@ void SlurTieLayout::correctForCrossStaff(Tie* tie, SlurTiePos& sPos)
16841690
return;
16851691
}
16861692

1687-
if (endChord->vStaffIdx() != tie->staffIdx() && sPos.system2) {
1693+
if (endChord->vStaffIdx() != tie->staffIdx() && sPos.system2 && sPos.system2 == sPos.system1) {
16881694
double yOrigin = sPos.system2->staff(tie->staffIdx())->y();
16891695
double yMoved = sPos.system2->staff(endChord->vStaffIdx())->y();
16901696
double yDiff = yMoved - yOrigin;
@@ -1744,7 +1750,7 @@ void SlurTieLayout::adjustX(TieSegment* tieSegment, SlurTiePos& sPos, Grip start
17441750
}
17451751

17461752
PointF chordSystemPos = chord->pos() + chord->segment()->pos() + chord->measure()->pos();
1747-
if (chord->vStaffIdx() != tieSegment->staffIdx()) {
1753+
if (chord->vStaffIdx() != tieSegment->vStaffIdx()) {
17481754
System* system = tieSegment->system();
17491755
double yDiff = system->staff(chord->vStaffIdx())->y() - system->staff(tie->staffIdx())->y();
17501756
chordSystemPos += PointF(0.0, yDiff);
@@ -1852,7 +1858,7 @@ void SlurTieLayout::adjustYforLedgerLines(TieSegment* tieSegment, SlurTiePos& sP
18521858

18531859
void SlurTieLayout::adjustY(TieSegment* tieSegment)
18541860
{
1855-
Staff* staff = tieSegment->staff();
1861+
Staff* staff = tieSegment->score() ? tieSegment->score()->staff(tieSegment->vStaffIdx()) : nullptr;
18561862
if (!staff) {
18571863
return;
18581864
}
@@ -2009,7 +2015,14 @@ void SlurTieLayout::resolveVerticalTieCollisions(const std::vector<TieSegment*>&
20092015
return;
20102016
}
20112017

2012-
Staff* staff = thisTie->staff();
2018+
if (!thisTie->score()) {
2019+
return;
2020+
}
2021+
Staff* staff = thisTie->score() ? thisTie->score()->staff(thisTie->vStaffIdx()) : nullptr;
2022+
if (!staff) {
2023+
return;
2024+
}
2025+
20132026
Fraction tick = thisTie->tick();
20142027
double yMidPoint = 0.5 * (thisTieOuterY + nextTieInnerY);
20152028
double halfLineDist = 0.5 * staff->lineDistance(tick) * spatium;
@@ -2481,7 +2494,8 @@ void SlurTieLayout::computeMidThickness(SlurTieSegment* slurTieSeg, double slurT
24812494
: slurTieSeg->style().styleMM(Sid::SlurEndWidth);
24822495
const Millimetre midWidth = slurTieSeg->isTieSegment() ? slurTieSeg->style().styleMM(Sid::TieMidWidth)
24832496
: slurTieSeg->style().styleMM(Sid::SlurMidWidth);
2484-
const double mag = slurTieSeg->staff() ? slurTieSeg->staff()->staffMag(slurTieSeg->slurTie()->tick()) : 1.0;
2497+
Staff* staff = slurTieSeg->score() ? slurTieSeg->score()->staff(slurTieSeg->vStaffIdx()) : nullptr;
2498+
const double mag = staff ? staff->staffMag(slurTieSeg->slurTie()->tick()) : 1.0;
24852499
const double minTieLength = mag * slurTieSeg->style().styleS(Sid::MinTieLength).val();
24862500
const double shortTieLimit = mag * 4.0;
24872501
const double minTieThickness = mag * (0.15 * slurTieSeg->spatium() - endWidth);

vtest/scores/tie-18.mscz

24.9 KB
Binary file not shown.

0 commit comments

Comments
 (0)