diff --git a/src/engraving/dom/chordrest.cpp b/src/engraving/dom/chordrest.cpp index 85a1e94bdffeb..42435732d324f 100644 --- a/src/engraving/dom/chordrest.cpp +++ b/src/engraving/dom/chordrest.cpp @@ -1317,7 +1317,7 @@ bool ChordRest::hasFollowingJumpItem() const const Marker* marker = toMarker(e); - if (muse::contains(Marker::RIGHT_MARKERS, marker->markerType())) { + if (marker->isRightMarker()) { return true; } } @@ -1373,7 +1373,7 @@ bool ChordRest::hasPrecedingJumpItem() const } const Marker* marker = toMarker(e); - if (muse::contains(Marker::RIGHT_MARKERS, marker->markerType())) { + if (marker->isRightMarker()) { continue; } diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp index 956806a07723a..4f443206c5eff 100644 --- a/src/engraving/dom/edit.cpp +++ b/src/engraving/dom/edit.cpp @@ -1527,7 +1527,7 @@ void Score::cmdRemoveTimeSig(TimeSig* ts) // // we cannot remove a courtesy time signature // - if (m->tick() != s->tick()) { + if (s->isCourtesySegment()) { return; } Fraction tick = m->tick(); diff --git a/src/engraving/dom/marker.h b/src/engraving/dom/marker.h index 21356fc2a229f..2390fef0a87a6 100644 --- a/src/engraving/dom/marker.h +++ b/src/engraving/dom/marker.h @@ -57,6 +57,8 @@ class Marker final : public TextBase || m_markerType == MarkerType::DA_DBLCODA; } + inline bool isRightMarker() const { return muse::contains(Marker::RIGHT_MARKERS, m_markerType); } + Marker* clone() const override { return new Marker(*this); } int subtype() const override { return int(m_markerType); } diff --git a/src/engraving/dom/measure.cpp b/src/engraving/dom/measure.cpp index c6b7217eeec38..20b09f1c9d787 100644 --- a/src/engraving/dom/measure.cpp +++ b/src/engraving/dom/measure.cpp @@ -840,7 +840,7 @@ void Measure::add(EngravingItem* e) break; case ElementType::JUMP: case ElementType::MARKER: - if (e && (e->isJump() || muse::contains(Marker::RIGHT_MARKERS, toMarker(e)->markerType()))) { + if (e && (e->isJump() || (e->isMarker() && toMarker(e)->isRightMarker()))) { // "To coda" markings act like jumps setProperty(Pid::REPEAT_JUMP, true); } @@ -943,9 +943,10 @@ void Measure::remove(EngravingItem* e) break; case ElementType::JUMP: - setProperty(Pid::REPEAT_JUMP, false); - // fall through case ElementType::MARKER: + if (e->isJump() || (e->isMarker() && toMarker(e)->isRightMarker())) { + setProperty(Pid::REPEAT_JUMP, false); + } case ElementType::HBOX: if (!el().remove(e)) { LOGD("Measure(%p)::remove(%s,%p) not found", this, e->typeName(), e); diff --git a/src/engraving/dom/tiejumppointlist.cpp b/src/engraving/dom/tiejumppointlist.cpp index 7ee4372d00cae..7ec55078827cb 100644 --- a/src/engraving/dom/tiejumppointlist.cpp +++ b/src/engraving/dom/tiejumppointlist.cpp @@ -91,7 +91,7 @@ String TieJumpPoint::precedingJumpItemName() const } const Marker* marker = toMarker(e); - if (muse::contains(Marker::RIGHT_MARKERS, marker->markerType())) { + if (marker->isRightMarker()) { continue; } diff --git a/src/engraving/rendering/score/measurelayout.cpp b/src/engraving/rendering/score/measurelayout.cpp index fadd2307dd64b..23e63ab169058 100644 --- a/src/engraving/rendering/score/measurelayout.cpp +++ b/src/engraving/rendering/score/measurelayout.cpp @@ -1646,9 +1646,20 @@ void MeasureLayout::setCourtesyTimeSig(Measure* m, const Fraction& refSigTick, c const bool isTrailer = courtesySegType == SegmentType::TimeSigAnnounce; const bool isContinuationCourtesy = courtesySegType == SegmentType::TimeSigStartRepeatAnnounce; - const Segment* actualSegAtMeasureStart = m->findSegmentR(SegmentType::TimeSig, Fraction(0, 1)); - const bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyTimeSig() - && !(actualSegAtMeasureStart && actualSegAtMeasureStart->enabled()); + const Segment* prevCourtesySegment + = prevMeasure ? prevMeasure->findSegmentR(SegmentType::TimeSigRepeatAnnounce, prevMeasure->ticks()) : nullptr; + + // Cont. courtesies - check for sig at the start of the measure OR end of previous measure if changesBeforeBarline... is on + const bool checkPrevMeasure = isContinuationCourtesy && prevMeasure + && ((prevMeasure->repeatEnd() && ctx.conf().styleB(Sid::changesBeforeBarlineRepeats)) + || (prevMeasure->repeatJump() + && ctx.conf().styleB(Sid::changesBeforeBarlineOtherJumps))); + const Segment* tsSegAtCourtesyTick = m->findSegmentR(SegmentType::TimeSig, courtesySigRTick); + tsSegAtCourtesyTick = !tsSegAtCourtesyTick && checkPrevMeasure ? prevMeasure->findSegmentR(SegmentType::TimeSig, + courtesySigTick + - prevMeasure->tick()) : tsSegAtCourtesyTick; + const bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyTimeSig(); + Segment* courtesySigSeg = m->findSegmentR(courtesySegType, courtesySigRTick); for (track_idx_t track = 0; track < nstaves * VOICES; track += VOICES) { const Staff* staff = ctx.dom().staff(track2staff(track)); @@ -1658,14 +1669,17 @@ void MeasureLayout::setCourtesyTimeSig(Measure* m, const Fraction& refSigTick, c continue; } - const bool sigsDifferent = actualTimeSig->sig() != curTimeSig->sig(); - // Show repeat courtesy if the sigs are different // Show continuation courtesy if there's a repeat courtesy before it // Show trailer courtesy only when there's a time sig element in the next bar - const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy - : isTrailer ? actualTimeSig->tick() == m->endTick() : sigsDifferent; - const bool show = actualTimeSig && actualTimeSig->showCourtesySig() && needsCourtesy && ctx.conf().styleB(Sid::genCourtesyTimesig); + const bool sigsDifferent = actualTimeSig->sig() != curTimeSig->sig(); + const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy && prevCourtesySegment && prevCourtesySegment->elementAt( + track) : isTrailer ? actualTimeSig->tick() == m->endTick() : sigsDifferent; + // If there is a real key sig at this tick (in this bar or the previous), don't create a courtesy + const bool hasSigAtTick = tsSegAtCourtesyTick && tsSegAtCourtesyTick->enabled() && tsSegAtCourtesyTick->element(track); + // Only show courtesy if its real signature has courtesies enabled + const bool actualShowCourtesy = actualTimeSig && actualTimeSig->showCourtesySig(); + const bool show = actualShowCourtesy && needsCourtesy && !hasSigAtTick && ctx.conf().styleB(Sid::genCourtesyTimesig); if (!courtesySigSeg) { if (!show) { @@ -1677,7 +1691,9 @@ void MeasureLayout::setCourtesyTimeSig(Measure* m, const Fraction& refSigTick, c m->add(courtesySigSeg); m->setTrailer(m->trailer() || isTrailer); } - m->setHasCourtesyTimeSig(true); + if (!isContinuationCourtesy) { + m->setHasCourtesyTimeSig(true); + } courtesySigSeg->setTrailer(isTrailer); courtesySigSeg->setEnabled(true); @@ -1714,12 +1730,13 @@ void MeasureLayout::setCourtesyTimeSig(Measure* m, const Fraction& refSigTick, c TLayout::layoutTimeSig(courtesyTimeSig, courtesyTimeSig->mutldata(), ctx); } - if (courtesySigSeg && (!m->hasCourtesyTimeSig() || !ctx.conf().styleB(Sid::genCourtesyTimesig))) { + if (courtesySigSeg && ((!isContinuationCourtesy && !m->hasCourtesyTimeSig()) || !ctx.conf().styleB(Sid::genCourtesyTimesig))) { // Whole segment shouldn't be shown, remove any existing courtesy signatures - m->setHasCourtesyTimeSig(false); + if (!isContinuationCourtesy) { + m->setHasCourtesyTimeSig(false); + } if (courtesySigSeg) { courtesySigSeg->setEnabled(false); - m->setHasCourtesyTimeSig(false); } } @@ -1728,7 +1745,9 @@ void MeasureLayout::setCourtesyTimeSig(Measure* m, const Fraction& refSigTick, c courtesySigSeg->createShapes(); } else { courtesySigSeg->setEnabled(false); - m->setHasCourtesyTimeSig(false); + if (!isContinuationCourtesy) { + m->setHasCourtesyTimeSig(false); + } } } } @@ -1744,11 +1763,24 @@ void MeasureLayout::setCourtesyKeySig(Measure* m, const Fraction& refSigTick, co const bool isTrailer = courtesySegType == SegmentType::KeySigAnnounce; const bool isContinuationCourtesy = courtesySegType == SegmentType::KeySigStartRepeatAnnounce; - const Segment* actualSegAtMeasureStart = m->findSegmentR(SegmentType::KeySig, Fraction(0, 1)); - const bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyKeySig() - && !(actualSegAtMeasureStart && actualSegAtMeasureStart->enabled()); + const Segment* prevCourtesySegment + = prevMeasure ? prevMeasure->findSegmentR(SegmentType::KeySigRepeatAnnounce, prevMeasure->ticks()) : nullptr; + + // Cont. courtesies - check for sig at the start of the measure OR end of previous measure if changesBeforeBarline... is on + const bool checkPrevMeasure = isContinuationCourtesy && prevMeasure + && ((prevMeasure->repeatEnd() && ctx.conf().styleB(Sid::changesBeforeBarlineRepeats)) + || (prevMeasure->repeatJump() + && ctx.conf().styleB(Sid::changesBeforeBarlineOtherJumps))); + const Segment* ksSegAtCourtesyTick = m->findSegmentR(SegmentType::KeySig, courtesySigRTick); + ksSegAtCourtesyTick = !ksSegAtCourtesyTick && checkPrevMeasure ? prevMeasure->findSegmentR(SegmentType::KeySig, + courtesySigTick + - prevMeasure->tick()) : ksSegAtCourtesyTick; + + const bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyKeySig(); + Segment* courtesySigSeg = m->findSegmentR(courtesySegType, courtesySigRTick); for (track_idx_t track = 0; track < nstaves * VOICES; track += VOICES) { + // Find reference signature const Staff* staff = ctx.dom().staff(track2staff(track)); const Fraction refSigElementTick = staff->currentKeyTick(refSigTick); const Measure* refMeasure = ctx.dom().tick2measure(refSigElementTick); @@ -1759,12 +1791,19 @@ void MeasureLayout::setCourtesyKeySig(Measure* m, const Fraction& refSigTick, co const KeySigEvent refKey = staff->keySigEvent(refSigTick); // Get info from correct tick for repeats + // For trailers and pre-repeat courtesies, signatures should be different const bool sigsDifferent = staff->key(m->endTick() - Fraction::eps()) != refKey.key(); - const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy : sigsDifferent; + const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy && prevCourtesySegment && prevCourtesySegment->elementAt( + track) : sigsDifferent; + // Only show key sig changes on pitched staves const bool staffIsPitchedAtNextMeas = ctx.dom().lastMeasure() == m || (m->nextMeasure() && staff->isPitchedStaff(m->nextMeasure()->tick())); + // If there is a real key sig at this tick (in this bar or the previous), don't create a courtesy + const bool hasSigAtTick = ksSegAtCourtesyTick && ksSegAtCourtesyTick->enabled() && ksSegAtCourtesyTick->element(track); + // Only show courtesy if its real signature has courtesies enabled const bool actualShowCourtesy = actualKeySig ? actualKeySig->showCourtesy() : true; - const bool show = actualShowCourtesy && staffIsPitchedAtNextMeas && needsCourtesy && ctx.conf().styleB(Sid::genCourtesyKeysig); + const bool show = actualShowCourtesy && staffIsPitchedAtNextMeas && needsCourtesy && !hasSigAtTick && ctx.conf().styleB( + Sid::genCourtesyKeysig); if (!courtesySigSeg) { if (!show) { @@ -1776,7 +1815,9 @@ void MeasureLayout::setCourtesyKeySig(Measure* m, const Fraction& refSigTick, co m->add(courtesySigSeg); m->setTrailer(m->trailer() || isTrailer); } - m->setHasCourtesyKeySig(true); + if (!isContinuationCourtesy) { + m->setHasCourtesyKeySig(true); + } courtesySigSeg->setTrailer(isTrailer); courtesySigSeg->setEnabled(true); @@ -1808,12 +1849,13 @@ void MeasureLayout::setCourtesyKeySig(Measure* m, const Fraction& refSigTick, co TLayout::layoutKeySig(courtesyKeySig, courtesyKeySig->mutldata(), ctx.conf()); } - if (courtesySigSeg && (!m->hasCourtesyKeySig() || !ctx.conf().styleB(Sid::genCourtesyKeysig))) { + if (courtesySigSeg && ((!isContinuationCourtesy && !m->hasCourtesyKeySig()) || !ctx.conf().styleB(Sid::genCourtesyKeysig))) { // Whole segment shouldn't be shown, remove any existing courtesy signatures - m->setHasCourtesyKeySig(false); + if (!isContinuationCourtesy) { + m->setHasCourtesyKeySig(false); + } if (courtesySigSeg) { courtesySigSeg->setEnabled(false); - m->setHasCourtesyKeySig(false); } } @@ -1822,7 +1864,9 @@ void MeasureLayout::setCourtesyKeySig(Measure* m, const Fraction& refSigTick, co courtesySigSeg->createShapes(); } else { courtesySigSeg->setEnabled(false); - m->setHasCourtesyKeySig(false); + if (!isContinuationCourtesy) { + m->setHasCourtesyKeySig(false); + } } } } @@ -1839,16 +1883,19 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con const Segment* prevCourtesySegment = prevMeasure ? prevMeasure->findSegmentR(SegmentType::ClefRepeatAnnounce, prevMeasure->ticks()) : nullptr; - const Segment* actualSegAtMeasureStart = m->findSegmentR(SegmentType::Clef, Fraction(0, 1)); - bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyClef() - && !(actualSegAtMeasureStart && actualSegAtMeasureStart->enabled()) && prevCourtesySegment - && prevCourtesySegment->enabled(); + const Segment* clefSegAtCourtesyTick = m->findSegmentR(SegmentType::Clef | SegmentType::HeaderClef, courtesyClefRTick); + clefSegAtCourtesyTick + = !clefSegAtCourtesyTick + && prevMeasure ? prevMeasure->findSegmentR(SegmentType::KeySig, courtesyClefTick - prevMeasure->tick()) : clefSegAtCourtesyTick; + + bool shouldShowContCourtesy = prevMeasure && prevMeasure->hasCourtesyClef(); + Segment* courtesyClefSeg = m->findSegmentR(courtesySegType, courtesyClefRTick); for (track_idx_t track = 0; track < nstaves * VOICES; track += VOICES) { const Staff* staff = ctx.dom().staff(track2staff(track)); const Fraction refClefElementTick = staff->currentClefTick(refClefTick); const Measure* refMeasure = ctx.dom().tick2measure(refClefElementTick); - Segment* actualClefSeg + const Segment* actualClefSeg = refMeasure ? refMeasure->findSegmentR(SegmentType::Clef | SegmentType::HeaderClef, refClefElementTick - refMeasure->tick()) : nullptr; if (!actualClefSeg && refMeasure && refMeasure->prevMeasure()) { @@ -1861,10 +1908,15 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con const Clef* actualClef = el ? toClef(el) : nullptr; const ClefType refClef = staff->clef(refClefTick); - const bool clefsMatch = staff->clef(m->endTick() - Fraction::eps()) != refClef; - const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy && isContinuationCourtesy - && prevCourtesySegment && prevCourtesySegment->elementAt(track) : clefsMatch; - const bool show = actualClef && actualClef->showCourtesy() && needsCourtesy && ctx.conf().styleB(Sid::genCourtesyClef); + // For trailers and pre-repeat courtesies, clefs should be different + const bool clefsDifferent = staff->clef(m->endTick() - Fraction::eps()) != refClef; + const bool needsCourtesy = isContinuationCourtesy ? shouldShowContCourtesy && prevCourtesySegment && prevCourtesySegment->elementAt( + track) : clefsDifferent; + // If there is a real clef at this tick (in this bar or the previous), don't create a courtesy + const bool hasClefAtTick = clefSegAtCourtesyTick && clefSegAtCourtesyTick->enabled() && clefSegAtCourtesyTick->element(track); + // Only show courtesy if its real clef has courtesies enabled + const bool actualShowCourtesy = actualClef && actualClef->showCourtesy(); + const bool show = actualShowCourtesy && needsCourtesy && !hasClefAtTick && ctx.conf().styleB(Sid::genCourtesyClef); if (!courtesyClefSeg) { if (!show) { @@ -1876,7 +1928,9 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con m->add(courtesyClefSeg); courtesyClefSeg->setTrailer(false); } - m->setHasCourtesyClef(true); + if (!isContinuationCourtesy) { + m->setHasCourtesyClef(true); + } courtesyClefSeg->setEnabled(true); // Find courtesy element or create if it doesn't exist @@ -1886,7 +1940,7 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con courtesyClef = toClef(clefElem); } - // this key sig shouldn't be shown, remove from segment + // this clef shouldn't be shown, remove from segment if (!show) { if (courtesyClef) { courtesyClefSeg->remove(courtesyClef); @@ -1908,12 +1962,13 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con TLayout::layoutClef(courtesyClef, courtesyClef->mutldata(), ctx.conf()); } - if (courtesyClefSeg && (!ctx.conf().styleB(Sid::genCourtesyClef) || !m->hasCourtesyClef())) { + if (courtesyClefSeg && (!ctx.conf().styleB(Sid::genCourtesyClef) || (!isContinuationCourtesy && !m->hasCourtesyClef()))) { // Whole segment shouldn't be shown, remove any existing courtesy signatures - m->setHasCourtesyClef(false); + if (!isContinuationCourtesy) { + m->setHasCourtesyClef(false); + } if (courtesyClefSeg) { courtesyClefSeg->setEnabled(false); - m->setHasCourtesyClef(false); } } @@ -1922,7 +1977,9 @@ void MeasureLayout::setCourtesyClef(Measure* m, const Fraction& refClefTick, con courtesyClefSeg->createShapes(); } else { courtesyClefSeg->setEnabled(false); - m->setHasCourtesyClef(false); + if (isContinuationCourtesy) { + m->setHasCourtesyClef(false); + } } } } @@ -2226,8 +2283,8 @@ void MeasureLayout::removeRepeatCourtesyParenthesesSegment(Segment* seg, const t void MeasureLayout::setRepeatCourtesiesAndParens(Measure* m, LayoutContext& ctx) { - const bool showCourtesyRepeats = m->repeatEnd() && ctx.conf().styleB(Sid::showCourtesiesRepeats) && !m->endOfMeasureChange(); - const bool showCourtesyOtherJumps = m->repeatJump() && ctx.conf().styleB(Sid::showCourtesiesOtherJumps) && !m->endOfMeasureChange(); + const bool showCourtesyRepeats = m->repeatEnd() && ctx.conf().styleB(Sid::showCourtesiesRepeats); + const bool showCourtesyOtherJumps = m->repeatJump() && ctx.conf().styleB(Sid::showCourtesiesOtherJumps); if (showCourtesyRepeats) { MeasureLayout::addRepeatCourtesies(m, ctx); @@ -2249,14 +2306,13 @@ void MeasureLayout::setRepeatCourtesiesAndParens(Measure* m, LayoutContext& ctx) if (!showCourtesyRepeats && !showCourtesyOtherJumps) { MeasureLayout::removeRepeatCourtesyParenthesesMeasure(m, false, ctx); + removeRepeatCourtesies(m); } const bool courtesiesAfterCancellingRepeats = m->prevMeasure() && m->prevMeasure()->repeatEnd() - && !m->prevMeasure()->endOfMeasureChange() && ctx.conf().styleB(Sid::showCourtesiesAfterCancellingRepeats) && ctx.conf().styleB(Sid::showCourtesiesRepeats); const bool courtesiesAfterCancellingOtherJumps = m->prevMeasure() && m->prevMeasure()->repeatJump() - && !m->prevMeasure()->endOfMeasureChange() && ctx.conf().styleB(Sid::showCourtesiesAfterCancellingOtherJumps) && ctx.conf().styleB(Sid::showCourtesiesOtherJumps); if (courtesiesAfterCancellingRepeats) { @@ -2279,6 +2335,7 @@ void MeasureLayout::setRepeatCourtesiesAndParens(Measure* m, LayoutContext& ctx) if (!courtesiesAfterCancellingRepeats && !courtesiesAfterCancellingOtherJumps) { MeasureLayout::removeRepeatCourtesyParenthesesMeasure(m, true, ctx); + removeRepeatContinuationCourtesies(m); } } @@ -2286,6 +2343,7 @@ void MeasureLayout::addRepeatCourtesies(Measure* m, LayoutContext& ctx) { const std::vector measures = findFollowingRepeatMeasures(m); if (measures.empty()) { + removeRepeatCourtesies(m); return; } @@ -2299,6 +2357,26 @@ void MeasureLayout::addRepeatCourtesies(Measure* m, LayoutContext& ctx) } } +void MeasureLayout::removeRepeatCourtesies(Measure* m) +{ + for (Segment* seg = m->last(); seg != m->first(); seg = seg->prev()) { + if (seg->isChordRestType()) { + break; + } + if (!seg->isType(SegmentType::ClefRepeatAnnounce | SegmentType::TimeSigRepeatAnnounce | SegmentType::KeySigRepeatAnnounce)) { + continue; + } + seg->mutldata()->reset(); + + if (seg->enabled()) { + seg->setEnabled(false); + } + } + m->setHasCourtesyClef(false); + m->setHasCourtesyKeySig(false); + m->setHasCourtesyTimeSig(false); +} + void MeasureLayout::addRepeatContinuationCourtesies(Measure* m, LayoutContext& ctx) { setCourtesyTimeSig(m, m->tick(), m->tick(), SegmentType::TimeSigStartRepeatAnnounce, ctx); @@ -2306,6 +2384,25 @@ void MeasureLayout::addRepeatContinuationCourtesies(Measure* m, LayoutContext& c setCourtesyClef(m, m->tick(), m->tick(), SegmentType::ClefStartRepeatAnnounce, ctx); } +void MeasureLayout::removeRepeatContinuationCourtesies(Measure* m) +{ + for (Segment* seg = m->first(); seg != m->last(); seg = seg->next()) { + if (seg->isChordRestType()) { + break; + } + if (!seg->isType(SegmentType::ClefStartRepeatAnnounce | SegmentType::TimeSigStartRepeatAnnounce + | SegmentType::KeySigStartRepeatAnnounce)) { + continue; + } + + seg->mutldata()->reset(); + + if (seg->enabled()) { + seg->setEnabled(false); + } + } +} + Segment* MeasureLayout::addHeaderClef(Measure* m, bool isFirstClef, const Staff* staff, LayoutContext& ctx) { const staff_idx_t staffIdx = staff->idx(); diff --git a/src/engraving/rendering/score/measurelayout.h b/src/engraving/rendering/score/measurelayout.h index 6f689142094b8..12f27c9b0159c 100644 --- a/src/engraving/rendering/score/measurelayout.h +++ b/src/engraving/rendering/score/measurelayout.h @@ -111,6 +111,8 @@ class MeasureLayout static void addRepeatCourtesyParentheses(Measure* m, const bool continuation, LayoutContext& ctx); static void placeParentheses(const Segment* segment, track_idx_t trackIdx, LayoutContext& ctx); static void addRepeatCourtesies(Measure* m, LayoutContext& ctx); + static void removeRepeatCourtesies(Measure* m); static void addRepeatContinuationCourtesies(Measure* m, LayoutContext& ctx); + static void removeRepeatContinuationCourtesies(Measure* m); }; } diff --git a/src/engraving/rendering/score/modifydom.cpp b/src/engraving/rendering/score/modifydom.cpp index a458cb938edda..eb071774160a0 100644 --- a/src/engraving/rendering/score/modifydom.cpp +++ b/src/engraving/rendering/score/modifydom.cpp @@ -271,7 +271,13 @@ void ModifyDom::sortMeasureSegments(Measure* measure, LayoutContext& ctx) return ClefToBarlinePosition::AUTO; }; - Measure* nextMeasure = measure->nextMeasure(); + MeasureBase* nextMb = measure->next(); + + if (!nextMb || !nextMb->isMeasure()) { + return; + } + + Measure* nextMeasure = toMeasure(nextMb); const bool sigsShouldBeInThisMeasure = ((measure->repeatEnd() && ctx.conf().styleB(Sid::changesBeforeBarlineRepeats)) || (measure->repeatJump() && ctx.conf().styleB(Sid::changesBeforeBarlineOtherJumps))); @@ -308,7 +314,8 @@ void ModifyDom::sortMeasureSegments(Measure* measure, LayoutContext& ctx) } // Move key sigs and time sigs at the end of this measure into the next measure - if ((seg.isKeySigType() || seg.isTimeSigType()) && (!sigsShouldBeInThisMeasure || !changeAppliesToRepeatAndContinuation(seg))) { + if ((seg.isKeySigType() || seg.isTimeSigType()) && !seg.header() && !seg.trailer() + && (!sigsShouldBeInThisMeasure || !changeAppliesToRepeatAndContinuation(seg))) { segsToMoveToNextMeasure.push_back(&seg); } } @@ -352,7 +359,8 @@ void ModifyDom::sortMeasureSegments(Measure* measure, LayoutContext& ctx) } // Move key sigs and time sigs at the start of the next measure to the end of this measure - if ((seg.isTimeSigType() || seg.isKeySigType()) && sigsShouldBeInThisMeasure && changeAppliesToRepeatAndContinuation(seg)) { + if ((seg.isTimeSigType() || seg.isKeySigType()) && !seg.header() && !seg.trailer() + && sigsShouldBeInThisMeasure && changeAppliesToRepeatAndContinuation(seg)) { segsToMoveToThisMeasure.push_back(&seg); } } @@ -379,7 +387,7 @@ void ModifyDom::sortMeasureSegments(Measure* measure, LayoutContext& ctx) // Sort segments at start of first measure Measure* prevMeasure = measure->prevMeasure(); if (prevMeasure && prevMeasure == ctx.dom().firstMeasure()) { - ModifyDom::removeAndAddBeginSegments(prevMeasure); + removeAndAddBeginSegments(prevMeasure); } } diff --git a/src/engraving/rendering/score/slurtielayout.cpp b/src/engraving/rendering/score/slurtielayout.cpp index 0c65841c0b008..4596531e91005 100644 --- a/src/engraving/rendering/score/slurtielayout.cpp +++ b/src/engraving/rendering/score/slurtielayout.cpp @@ -1852,31 +1852,30 @@ void SlurTieLayout::setPartialTieEndPos(PartialTie* item, SlurTiePos& sPos) const Segment* seg = chord->segment(); const Measure* measure = seg->measure(); const System* system = measure->system(); - double width = item->style().styleS(Sid::minHangingTieLength).val() * item->spatium(); if (seg->measure()->isFirstInSystem() && !outgoing) { sPos.p1 = PointF((system ? system->firstNoteRestSegmentX(true) : 0), sPos.p2.y()); return; } - const Segment* adjSeg = outgoing ? seg->next() : seg->prev(); + const Segment* adjSeg = outgoing ? seg->next1() : seg->prev1(); while (adjSeg && (!adjSeg->isActive() || !adjSeg->enabled())) { - adjSeg = outgoing ? seg->next() : seg->prev(); + adjSeg = outgoing ? seg->next1() : seg->prev1(); } + double widthToSegment = 0.0; if (adjSeg) { EngravingItem* element = adjSeg->element(staff2track(item->vStaffIdx())); const double elementWidth = element ? element->width() : 0.0; - double widthToSegment = outgoing ? adjSeg->xPosInSystemCoords() - sPos.p1.x() : sPos.p2.x() - - (adjSeg->xPosInSystemCoords() + elementWidth); + widthToSegment = outgoing ? adjSeg->xPosInSystemCoords() - sPos.p1.x() : sPos.p2.x() + - (adjSeg->xPosInSystemCoords() + elementWidth); widthToSegment -= 0.25 * item->spatium(); - width = std::max(widthToSegment, width); } if (outgoing) { - sPos.p2 = PointF(sPos.p1.x() + width, sPos.p1.y()); + sPos.p2 = PointF(sPos.p1.x() + widthToSegment, sPos.p1.y()); } else { - sPos.p1 = PointF(sPos.p2.x() - width, sPos.p2.y()); + sPos.p1 = PointF(sPos.p2.x() - widthToSegment, sPos.p2.y()); } } diff --git a/src/engraving/rendering/score/systemlayout.cpp b/src/engraving/rendering/score/systemlayout.cpp index 2f591aa175b82..fb431a5bf176c 100644 --- a/src/engraving/rendering/score/systemlayout.cpp +++ b/src/engraving/rendering/score/systemlayout.cpp @@ -1417,10 +1417,14 @@ void SystemLayout::layoutSystemElements(System* system, LayoutContext& ctx) } if (s->isType(SegmentType::TimeSigType)) { - TimeSig* ts = toTimeSig(s->element(e->track())); - TimeSigPlacement timeSigPlacement = ts->style().styleV(Sid::timeSigPlacement).value(); + EngravingItem* el = s->element(e->track()); + TimeSig* timeSig = el ? toTimeSig(el) : nullptr; + if (!timeSig) { + continue; + } + TimeSigPlacement timeSigPlacement = timeSig->style().styleV(Sid::timeSigPlacement).value(); if (timeSigPlacement == TimeSigPlacement::ACROSS_STAVES) { - if (!ts->showOnThisStaff()) { + if (!timeSig->showOnThisStaff()) { e->mutldata()->reset(); } continue; diff --git a/src/engraving/rendering/score/tlayout.cpp b/src/engraving/rendering/score/tlayout.cpp index bb540cb3e6bf7..63df5059d7c3b 100644 --- a/src/engraving/rendering/score/tlayout.cpp +++ b/src/engraving/rendering/score/tlayout.cpp @@ -3683,6 +3683,13 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const if (item->staff()) { t2 = item->staff()->key(item->tick() - Fraction(1, 480 * 4)); } + if (item->segment() && item->segment()->isType(SegmentType::KeySigStartRepeatAnnounce)) { + // Handle naturals in continuation courtesy + Segment* prevCourtesySeg + = prevMeasure ? prevMeasure->findSegmentR(SegmentType::KeySigRepeatAnnounce, prevMeasure->ticks()) : nullptr; + EngravingItem* prevCourtesy = prevCourtesySeg ? prevCourtesySeg->element(item->track()) : nullptr; + t2 = prevCourtesy && prevCourtesy->isKeySig() ? toKeySig(prevCourtesy)->key() : t2; + } if (t2 == Key::C) { naturalsOn = false; } else { diff --git a/vtest/scores/courtesy-changes-5.mscz b/vtest/scores/courtesy-changes-5.mscz new file mode 100644 index 0000000000000..10e7de25fd9ed Binary files /dev/null and b/vtest/scores/courtesy-changes-5.mscz differ diff --git a/vtest/scores/courtesy-changes-6.mscz b/vtest/scores/courtesy-changes-6.mscz new file mode 100644 index 0000000000000..27172e815f7ec Binary files /dev/null and b/vtest/scores/courtesy-changes-6.mscz differ diff --git a/vtest/scores/courtesy-changes-7.mscz b/vtest/scores/courtesy-changes-7.mscz new file mode 100644 index 0000000000000..ddb68c8ded266 Binary files /dev/null and b/vtest/scores/courtesy-changes-7.mscz differ diff --git a/vtest/scores/courtesy-changes-8.mscz b/vtest/scores/courtesy-changes-8.mscz new file mode 100644 index 0000000000000..8b4e52e7379b1 Binary files /dev/null and b/vtest/scores/courtesy-changes-8.mscz differ diff --git a/vtest/scores/partialTieEndAlignment.mscz b/vtest/scores/partialTieEndAlignment.mscz new file mode 100644 index 0000000000000..94912e2340d9e Binary files /dev/null and b/vtest/scores/partialTieEndAlignment.mscz differ