From 1653022fda0ed05c4f5f172cd423d067d33dca1f Mon Sep 17 00:00:00 2001 From: Aaron Sattely Date: Fri, 27 Aug 2021 18:59:23 -0400 Subject: [PATCH 1/3] add ability to get last nr or trailing x similar to firstNoteRestSegmentX(bool) --- src/engraving/libmscore/system.cpp | 39 ++++++++++++++++++++++++++++++ src/engraving/libmscore/system.h | 1 + 2 files changed, 40 insertions(+) diff --git a/src/engraving/libmscore/system.cpp b/src/engraving/libmscore/system.cpp index b25a5eb8c1b2..fc9efc080f94 100644 --- a/src/engraving/libmscore/system.cpp +++ b/src/engraving/libmscore/system.cpp @@ -1653,6 +1653,45 @@ qreal System::firstNoteRestSegmentX(bool leading) return margin; } +//--------------------------------------------------------- +// lastNoteRestSegmentX +// in System() coordinates +// returns the position of the last note or rest, +// or the position just before the first non-chordrest segment +//--------------------------------------------------------- + +qreal System::lastNoteRestSegmentX(bool trailing) +{ + qreal margin = score()->spatium() / 4; // TODO: this can be parameterizable + //for (const MeasureBase* mb : measures()) { + for (auto measureBaseIter = measures().rbegin(); measureBaseIter != measures().rend(); measureBaseIter++) { + if ((*measureBaseIter)->isMeasure()) { + const Measure* measure = static_cast(*measureBaseIter); + for (const Segment* seg = measure->last(); seg; seg = seg->prev()) { + if (seg->isChordRestType()) { + qreal noteRestPos = seg->measure()->pos().x() + seg->pos().x(); + if (!trailing) { + return noteRestPos; + } + + // last CR found; find next segment after this one + seg = seg->nextActive(); + while (seg && seg->allElementsInvisible()) { + seg = seg->nextActive(); + } + if (seg) { + return qMax(seg->measure()->pos().x() + seg->pos().x() - margin, noteRestPos); + } else { + return bbox().x() - margin; + } + } + } + } + } + qDebug("lastNoteRestSegmentX: did not find segment"); + return margin; +} + //--------------------------------------------------------- // pageBreak //--------------------------------------------------------- diff --git a/src/engraving/libmscore/system.h b/src/engraving/libmscore/system.h index 7e9ca32719f1..c996aa46586b 100644 --- a/src/engraving/libmscore/system.h +++ b/src/engraving/libmscore/system.h @@ -209,6 +209,7 @@ class System final : public Element Spacer* downSpacer(int staffIdx) const; qreal firstNoteRestSegmentX(bool leading = false); + qreal lastNoteRestSegmentX(bool trailing = false); bool hasFixedDownDistance() const { return fixedDownDistance; } int firstVisibleStaff() const; From 80bcec4f5136ee84400e10601ce36169a8318997 Mon Sep 17 00:00:00 2001 From: Aaron Sattely Date: Fri, 27 Aug 2021 19:01:19 -0400 Subject: [PATCH 2/3] fix lines continuing to end of system replaced bbox() stuff with new lastNoteRestSegmentX function --- src/engraving/libmscore/line.cpp | 6 +++--- src/engraving/libmscore/lyricsline.cpp | 8 +++++--- src/engraving/libmscore/slur.cpp | 4 ++-- src/engraving/libmscore/tie.cpp | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/engraving/libmscore/line.cpp b/src/engraving/libmscore/line.cpp index cc5392b87c99..bf355c8d59d9 100644 --- a/src/engraving/libmscore/line.cpp +++ b/src/engraving/libmscore/line.cpp @@ -129,7 +129,7 @@ PointF LineSegment::leftAnchorPosition(const qreal& systemPositionY) const PointF LineSegment::rightAnchorPosition(const qreal& systemPositionY) const { if (isMiddleType() || isBeginType()) { - return PointF(system()->lastMeasure()->abbox().right(), systemPositionY); + return PointF(system()->lastNoteRestSegmentX(true), systemPositionY); } PointF result; @@ -1119,13 +1119,13 @@ SpannerSegment* SLine::layoutSystem(System* system) System* s; PointF p1 = linePos(Grip::START, &s); lineSegm->setPos(p1); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); lineSegm->setPos2(PointF(x2 - p1.x(), 0.0)); } break; case SpannerSegmentType::MIDDLE: { qreal x1 = system->firstNoteRestSegmentX(true); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); System* s; PointF p1 = linePos(Grip::START, &s); lineSegm->setPos(PointF(x1, p1.y())); diff --git a/src/engraving/libmscore/lyricsline.cpp b/src/engraving/libmscore/lyricsline.cpp index 3630c94fdc33..90815f25faaa 100644 --- a/src/engraving/libmscore/lyricsline.cpp +++ b/src/engraving/libmscore/lyricsline.cpp @@ -237,14 +237,14 @@ SpannerSegment* LyricsLine::layoutSystem(System* system) System* s; PointF p1 = linePos(Grip::START, &s); lineSegm->setPos(p1); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); lineSegm->setPos2(PointF(x2 - p1.x(), 0.0)); } break; case SpannerSegmentType::MIDDLE: { bool leading = (anchor() == Anchor::SEGMENT || anchor() == Anchor::MEASURE); qreal x1 = system->firstNoteRestSegmentX(leading); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); System* s; PointF p1 = linePos(Grip::START, &s); lineSegm->setPos(PointF(x1, p1.y())); @@ -419,10 +419,12 @@ void LyricsLineSegment::layout() if (isEndMelisma) { // melisma _numOfDashes = 1; rypos() -= lyricsLine()->lineWidth() * .5; // let the line 'sit on' the base line - // if not final segment, shorten it + // if not final segment, shorten it (why? -AS) + /* if (isBeginType() || isMiddleType()) { rxpos2() -= score()->styleP(Sid::minNoteDistance) * mag(); } + */ } else { // dash(es) // set conventional dash Y pos rypos() -= lyr->fontMetrics().xHeight() * score()->styleD(Sid::lyricsDashYposRatio); diff --git a/src/engraving/libmscore/slur.cpp b/src/engraving/libmscore/slur.cpp index f2f1f92c5af7..fad5603e2893 100644 --- a/src/engraving/libmscore/slur.cpp +++ b/src/engraving/libmscore/slur.cpp @@ -1159,11 +1159,11 @@ SpannerSegment* Slur::layoutSystem(System* system) slurSegment->layoutSegment(sPos.p1, sPos.p2); break; case SpannerSegmentType::BEGIN: - slurSegment->layoutSegment(sPos.p1, PointF(system->bbox().width(), sPos.p1.y())); + slurSegment->layoutSegment(sPos.p1, PointF(system->lastNoteRestSegmentX(true), sPos.p1.y())); break; case SpannerSegmentType::MIDDLE: { qreal x1 = system->firstNoteRestSegmentX(true); - qreal x2 = system->bbox().width(); + qreal x2 = system->lastNoteRestSegmentX(true); qreal y = staffIdx() > system->staves()->size() ? system->y() : system->staff(staffIdx())->y(); slurSegment->layoutSegment(PointF(x1, y), PointF(x2, y)); } diff --git a/src/engraving/libmscore/tie.cpp b/src/engraving/libmscore/tie.cpp index f861250cce75..c46ac53f800e 100644 --- a/src/engraving/libmscore/tie.cpp +++ b/src/engraving/libmscore/tie.cpp @@ -712,7 +712,7 @@ TieSegment* Tie::layoutFor(System* system) int n; if (sPos.system1 != sPos.system2) { n = 2; - sPos.p2 = PointF(system->width(), sPos.p1.y()); + sPos.p2 = PointF(system->lastNoteRestSegmentX(true), sPos.p1.y()); } else { n = 1; } From 71ba56c0b3a2ee985b1b6c316c0fd35a9321a146 Mon Sep 17 00:00:00 2001 From: Aaron Sattely Date: Mon, 30 Aug 2021 10:25:45 -0400 Subject: [PATCH 3/3] fix glisses as well --- src/engraving/libmscore/line.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engraving/libmscore/line.cpp b/src/engraving/libmscore/line.cpp index bf355c8d59d9..be0d9ceb3d7a 100644 --- a/src/engraving/libmscore/line.cpp +++ b/src/engraving/libmscore/line.cpp @@ -1235,13 +1235,13 @@ void SLine::layout() // start segment lineSegm->setSpannerSegmentType(SpannerSegmentType::BEGIN); lineSegm->setPos(p1); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); lineSegm->setPos2(PointF(x2 - p1.x(), 0.0)); } else if (i > 0 && i != sysIdx2) { // middle segment lineSegm->setSpannerSegmentType(SpannerSegmentType::MIDDLE); qreal x1 = system->firstNoteRestSegmentX(true); - qreal x2 = system->bbox().right(); + qreal x2 = system->lastNoteRestSegmentX(true); lineSegm->setPos(PointF(x1, p1.y())); lineSegm->setPos2(PointF(x2 - x1, 0.0)); } else if (i == sysIdx2) {