diff --git a/src/engraving/rendering/score/chordlayout.cpp b/src/engraving/rendering/score/chordlayout.cpp index 6eeed77f0b030..7c900f94d579b 100644 --- a/src/engraving/rendering/score/chordlayout.cpp +++ b/src/engraving/rendering/score/chordlayout.cpp @@ -1656,6 +1656,26 @@ static void layoutSegmentElements(Segment* segment, track_idx_t startTrack, trac } } +static void relayoutChordBracketsAfterSegmentLayout(const std::vector& chords, LayoutContext& ctx) +{ + for (Chord* chord : chords) { + bool hasChordBracket = false; + + for (EngravingItem* e : chord->el()) { + if (!e->isChordBracket()) { + continue; + } + + hasChordBracket = true; + TLayout::layoutItem(e, ctx); + } + + if (hasChordBracket) { + ChordLayout::fillShape(chord, chord->mutldata(), ctx.conf()); + } + } +} + void ChordLayout::skipAccidentals(Segment* segment, track_idx_t startTrack, track_idx_t endTrack) { for (track_idx_t track = startTrack; track < endTrack; ++track) { @@ -2301,6 +2321,10 @@ void ChordLayout::layoutChords1(LayoutContext& ctx, Segment* segment, staff_idx_ TLayout::layoutOrnamentCueNote(ornament, ctx); } } + + // Chord brackets depend on the final layouts of all voices in the same segment and visual staff. + // Re-layout them after the segment elements have been laid out. + relayoutChordBracketsAfterSegmentLayout(posInfo.chords, ctx); } //--------------------------------------------------------- diff --git a/src/engraving/rendering/score/tlayout.cpp b/src/engraving/rendering/score/tlayout.cpp index ff48e59d73a88..f354242828a8a 100644 --- a/src/engraving/rendering/score/tlayout.cpp +++ b/src/engraving/rendering/score/tlayout.cpp @@ -870,6 +870,42 @@ void TLayout::layoutArpeggio(const Arpeggio* item, Arpeggio::LayoutData* ldata, } } +static Shape getChordsShape(const ChordBracket* item) +{ + Chord* owner = item->chord(); + Shape result = owner->shape(); + result.removeTypes({ ElementType::CHORD_BRACKET, ElementType::ARPEGGIO }); + if (!owner->segment() || !owner->staff()) { + return result; + } + + const track_idx_t startTrack = staff2track(owner->staffIdx()); + const track_idx_t endTrack = startTrack + VOICES; + + for (track_idx_t track = startTrack; track < endTrack; ++track) { + EngravingItem* e = owner->segment()->element(track); + if (track == owner->track()) { + continue; + } + + if (!e || !e->isChord()) { + continue; + } + + Chord* chord = toChord(e); + if (chord->vStaffIdx() != owner->vStaffIdx()) { + continue; + } + + Shape chordShape = chord->shape(); + chordShape.removeTypes({ ElementType::CHORD_BRACKET, ElementType::ARPEGGIO }); + chordShape.translate(chord->pos() - owner->pos()); + result.add(chordShape); + } + + return result; +} + void TLayout::layoutChordBracket(const ChordBracket* item, Arpeggio::LayoutData* ldata, const LayoutConfiguration& conf) { double spatium = item->spatium(); @@ -896,8 +932,7 @@ void TLayout::layoutChordBracket(const ChordBracket* item, Arpeggio::LayoutData* const Note* upnote = item->chord()->upNote(); ldata->setPosY(upnote->y() + upnote->ldata()->bbox().top()); - Shape chordShape = item->chord()->shape(); - chordShape.removeTypes({ ElementType::CHORD_BRACKET, ElementType::ARPEGGIO }); + Shape chordShape = getChordsShape(item); Shape itemShape = item->shape().translated(PointF(0.0, item->ldata()->pos().y())); if (item->rightSide()) { double x = HorizontalSpacing::minHorizontalDistance(chordShape, itemShape, spatium);