@@ -261,6 +261,10 @@ bool StaveSharingLayout::isUnison(track_idx_t prevTrack, track_idx_t nextTrack,
261261 return false ;
262262 }
263263 }
264+
265+ if (!checkArticulationsForSameVoice (c1, c2)) {
266+ return false ;
267+ }
264268 }
265269
266270 for (Segment* segment : ctx.allSegments ) {
@@ -348,6 +352,10 @@ bool StaveSharingLayout::canGoToSameVoice(track_idx_t prevTrack, track_idx_t nex
348352
349353 potentialUnisonNotes.push_back (n2);
350354 }
355+
356+ if (!checkArticulationsForSameVoice (c1, c2)) {
357+ return false ;
358+ }
351359 }
352360
353361 for (Segment* segment : ctx.allSegments ) {
@@ -512,6 +520,26 @@ bool StaveSharingLayout::checkSpannersForSameVoice(track_idx_t prevTrack, track_
512520 return true ;
513521}
514522
523+ bool StaveSharingLayout::checkArticulationsForSameVoice (Chord* chord1, Chord* chord2)
524+ {
525+ const std::vector<Articulation*>& articulations1 = chord1->articulations ();
526+ const std::vector<Articulation*>& articulations2 = chord2->articulations ();
527+
528+ if (articulations1.size () != articulations2.size ()) {
529+ return false ;
530+ }
531+
532+ for (size_t i = 0 ; i < articulations1.size (); ++i) {
533+ Articulation* art1 = articulations1[i];
534+ Articulation* art2 = articulations2[i];
535+ if (art1->subtype () != art2->subtype ()) {
536+ return false ;
537+ }
538+ }
539+
540+ return true ;
541+ }
542+
515543bool StaveSharingLayout::canGoToSameStave (track_idx_t prevTrack, track_idx_t nextTrack,
516544 StaveSharingContext& ctx)
517545{
@@ -626,6 +654,10 @@ void StaveSharingLayout::disconnectAll(SharedPart* p, StaveSharingContext& ctx)
626654 EngravingItem::disconnectAllOriginItems (spannerBack);
627655 }
628656 }
657+
658+ for (Articulation* art : toChord (cr)->articulations ()) {
659+ EngravingItem::disconnectAllOriginItems (art);
660+ }
629661 }
630662 }
631663 }
@@ -741,7 +773,34 @@ void StaveSharingLayout::makeSharedChordRests(SharedPart* p, StaveSharingContext
741773 EngravingItem::connectSharedItem (sharedNote, originNote);
742774
743775 makeSharedTiesAndNoteSpanners (originNote, sharedNote);
776+
777+ makeSharedArticulations (originChord, sharedChord);
778+ }
779+ }
780+ }
781+
782+ void StaveSharingLayout::makeSharedArticulations (Chord* originChord, Chord* sharedChord)
783+ {
784+ Score* score = originChord->score ();
785+
786+ for (Articulation* originArt : originChord->articulations ()) {
787+ Articulation* sharedArt = nullptr ;
788+ for (Articulation* possibleSharedArt : sharedChord->articulations ()) {
789+ if (possibleSharedArt->subtype () == originArt->subtype ()) {
790+ sharedArt = possibleSharedArt;
791+ break ;
792+ }
744793 }
794+
795+ if (!sharedArt) {
796+ sharedArt = originArt->clone ();
797+ sharedArt->setTrack (sharedChord->track ());
798+ sharedArt->setParent (sharedChord);
799+
800+ score->undoAddElement (sharedArt);
801+ }
802+
803+ EngravingItem::connectSharedItem (sharedArt, originArt);
745804 }
746805}
747806
@@ -1010,6 +1069,14 @@ void StaveSharingLayout::cleanup(SharedPart* p, StaveSharingContext& ctx)
10101069
10111070 if (cr->isChord ()) {
10121071 Chord* c = toChord (cr);
1072+
1073+ std::vector<Articulation*> articulations = c->articulations (); // copy because may be removed
1074+ for (Articulation* art : articulations) {
1075+ if (art->originItems ().empty ()) {
1076+ score->undoRemoveElement (art);
1077+ }
1078+ }
1079+
10131080 std::vector<Note*> notes = c->notes (); // copy because may be removed
10141081 for (Note* note : notes) {
10151082 if (Tie* tieBack = note->tieBack (); tieBack && tieBack->originItems ().empty ()) {
0 commit comments