Skip to content

Commit

Permalink
Merge pull request musescore#20064 from miiizen/19206-slur-direction
Browse files Browse the repository at this point in the history
Update chord direction under slur
  • Loading branch information
cbjeukendrup authored Nov 30, 2023
2 parents 43713af + 809534e commit 2b33488
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 40 deletions.
15 changes: 14 additions & 1 deletion src/engraving/dom/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5597,6 +5597,19 @@ void Score::doLayoutRange(const Fraction& st, const Fraction& et)
{
TRACEFUNC;

Fraction start = st;
Fraction end = et;

auto spanners = score()->spannerMap().findOverlapping(st.ticks(), et.ticks());
for (auto interval : spanners) {
Spanner* spanner = interval.value;
if (!spanner->staff()->visible()) {
continue;
}
start = std::min(st, spanner->tick());
end = std::max(et, spanner->tick2());
}

m_engravingFont = engravingFonts()->fontByName(style().value(Sid::MusicalSymbolFont).value<String>().toStdString());
m_layoutOptions.noteHeadWidth = m_engravingFont->width(SymId::noteheadBlack, style().spatium() / SPATIUM20);

Expand All @@ -5610,7 +5623,7 @@ void Score::doLayoutRange(const Fraction& st, const Fraction& et)
this->updateVelo();
}

renderer()->layoutScore(this, st, et);
renderer()->layoutScore(this, start, end);

if (m_resetAutoplace) {
m_resetAutoplace = false;
Expand Down
44 changes: 8 additions & 36 deletions src/engraving/dom/slur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,12 @@ Shape SlurSegment::getSegmentShape(Segment* seg, ChordRest* startCR, ChordRest*
if (!e || !e->isChordRest()) {
continue;
}
// Gets ties shapes
// Gets tie and 2 note tremolo shapes
if (e->isChord()) {
Chord* chord = toChord(e);
if (chord->tremolo() && chord->tremolo()->twoNotes()) {
segShape.add(chord->tremolo()->shape());
}
for (Note* note : toChord(e)->notes()) {
Tie* tieFor = note->tieFor();
Tie* tieBack = note->tieBack();
Expand Down Expand Up @@ -913,41 +917,9 @@ int Slur::calcStemArrangement(EngravingItem* start, EngravingItem* end)

bool Slur::isDirectionMixture(Chord* c1, Chord* c2)
{
if (c1->track() != c2->track()) {
return false;
}
bool up = c1->up();
if (c2->isGrace() && c2->up() != up) {
return true;
}
if (c1->isGraceBefore() && c2->isGraceAfter() && c1->parentItem() == c2->parentItem()) {
if (toChord(c1->parentItem())->stem() && toChord(c1->parentItem())->up() != up) {
return true;
}
}
track_idx_t track = c1->track();
for (Measure* m = c1->measure(); m; m = m->nextMeasure()) {
for (Segment* seg = m->first(); seg; seg = seg->next(SegmentType::ChordRest)) {
if (!seg || seg->tick() < c1->tick() || !seg->isChordRestType()) {
continue;
}
if (seg->tick() > c2->tick()) {
return false;
}
if ((c1->isGrace() || c2->isGraceBefore()) && seg->tick() >= c2->tick()) {
// if slur ends at a grace-note-before, we don't need to look at the main note
return false;
}
EngravingItem* e = seg->element(track);
if (!e || !e->isChord()) {
continue;
}
Chord* c = toChord(e);
if (c->up() != up) {
return true;
}
}
}
UNUSED(c1);
UNUSED(c2);
UNREACHABLE;
return false;
}

Expand Down
47 changes: 44 additions & 3 deletions src/engraving/rendering/dev/slurtielayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void SlurTieLayout::layout(Slur* item, LayoutContext& ctx)
item->setUp(!(item->startCR()->up()));
}

if (c1 && c2 && Slur::isDirectionMixture(c1, c2) && (c1->noteType() == NoteType::NORMAL)) {
if (c1 && c2 && isDirectionMixture(c1, c2, ctx) && (c1->noteType() == NoteType::NORMAL)) {
// slurs go above if start and end note have different stem directions,
// but grace notes are exceptions
item->setUp(true);
Expand Down Expand Up @@ -1739,11 +1739,11 @@ void SlurTieLayout::computeUp(Slur* slur, LayoutContext& ctx)
} else {
slur->setUp(true);
}
} else if (chord1 && chord2 && !chord1->isGrace() && slur->isDirectionMixture(chord1, chord2)) {
} else if (chord1 && chord2 && !chord1->isGrace() && isDirectionMixture(chord1, chord2, ctx)) {
// slurs go above if there are mixed direction stems between c1 and c2
// but grace notes are exceptions
slur->setUp(true);
} else if (chord1 && chord2 && chord1->isGrace() && chord2 != chord1->parent() && slur->isDirectionMixture(chord1, chord2)) {
} else if (chord1 && chord2 && chord1->isGrace() && chord2 != chord1->parent() && isDirectionMixture(chord1, chord2, ctx)) {
slur->setUp(true);
}
}
Expand All @@ -1765,6 +1765,47 @@ double SlurTieLayout::defaultStemLengthEnd(Tremolo* tremolo)
tremolo->chord2()->defaultStemLength()).second;
}

bool SlurTieLayout::isDirectionMixture(const Chord* c1, const Chord* c2, LayoutContext& ctx)
{
if (c1->track() != c2->track()) {
return false;
}
const bool up = c1->up();
if (c2->isGrace() && c2->up() != up) {
return true;
}
if (c1->isGraceBefore() && c2->isGraceAfter() && c1->parentItem() == c2->parentItem()) {
if (toChord(c1->parentItem())->stem() && toChord(c1->parentItem())->up() != up) {
return true;
}
}
const track_idx_t track = c1->track();
for (const Segment* seg = c1->segment(); seg && seg->tick() <= c2->tick(); seg = seg->next1(SegmentType::ChordRest)) {
if ((c1->isGrace() || c2->isGraceBefore()) && seg->tick() == c2->tick()) {
// if slur ends at a grace-note-before, we don't need to look at the main note
return false;
}
EngravingItem* e = seg->element(track);
if (!e || !e->isChord()) {
continue;
}
Chord* c = toChord(e);
const Measure* m = c->measure();
if (!c->staff()->isDrumStaff(c->tick()) && c1->measure()->system() != m->system()) {
// This chord is on a different system and may not have been laid out yet
for (Note* note : c->notes()) {
note->updateLine(); // because chord direction is based on note lines
}
ChordLayout::computeUp(c, ctx);
}

if (c->up() != up) {
return true;
}
}
return false;
}

void SlurTieLayout::layoutSegment(SlurSegment* item, LayoutContext& ctx, const PointF& p1, const PointF& p2)
{
SlurSegment::LayoutData* ldata = item->mutldata();
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/rendering/dev/slurtielayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ class SlurTieLayout
static double defaultStemLengthStart(Tremolo* tremolo);
static double defaultStemLengthEnd(Tremolo* tremolo);

static bool isDirectionMixture(const Chord* c1, const Chord* c2, LayoutContext& ctx);

static void layoutSegment(SlurSegment* item, LayoutContext& ctx, const PointF& p1, const PointF& p2);
};
}
Expand Down
Binary file added vtest/scores/slurs-25.mscz
Binary file not shown.

0 comments on commit 2b33488

Please sign in to comment.