From af62cace04dcdf5a78340e53023e9464cb8de62a Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sun, 27 Oct 2024 18:02:57 +0100 Subject: [PATCH 1/3] Improve principal staff calculation where the slur's floating positioner lives => adapt for cases where all spanning elements of the slur are cross staff --- include/vrv/slur.h | 4 ++-- src/slur.cpp | 28 +++++++++++++++++----------- src/view_control.cpp | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/vrv/slur.h b/include/vrv/slur.h index 15fb1174a3c..6c6e6ac8d79 100644 --- a/include/vrv/slur.h +++ b/include/vrv/slur.h @@ -152,8 +152,8 @@ class Slur : public ControlElement, * Calculate the staff where the slur's floating curve positioner lives */ ///@{ - Staff *CalculateExtremalStaff(const Staff *staff, int xMin, int xMax); - const Staff *CalculateExtremalStaff(const Staff *staff, int xMin, int xMax) const; + Staff *CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax); + const Staff *CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax) const; ///@} /** diff --git a/src/slur.cpp b/src/slur.cpp index 6a8c5a063f7..5250e5ef56d 100644 --- a/src/slur.cpp +++ b/src/slur.cpp @@ -487,27 +487,32 @@ void Slur::AddPositionerToArticulations(FloatingCurvePositioner *curve) } } -Staff *Slur::CalculateExtremalStaff(const Staff *staff, int xMin, int xMax) +Staff *Slur::CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax) { - return const_cast(std::as_const(*this).CalculateExtremalStaff(staff, xMin, xMax)); + return const_cast(std::as_const(*this).CalculatePrincipalStaff(staff, xMin, xMax)); } -const Staff *Slur::CalculateExtremalStaff(const Staff *staff, int xMin, int xMax) const +const Staff *Slur::CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax) const { - const Staff *extremalStaff = staff; + assert(staff); + + const Staff *principalStaff = NULL; const SlurCurveDirection curveDir = this->GetDrawingCurveDir(); const SpannedElements spanned = this->CollectSpannedElements(staff, xMin, xMax); + if (spanned.elements.empty()) { + return staff; + } // The floating curve positioner of cross staff slurs should live in the lower/upper staff alignment // corresponding to whether the slur is curved below or not - auto adaptStaff = [&extremalStaff, curveDir](const LayerElement *element) { + auto adaptStaff = [&principalStaff, curveDir](const LayerElement *element) { const Staff *elementStaff = element->GetAncestorStaff(RESOLVE_CROSS_STAFF); - const bool updateExtremal = (curveDir == SlurCurveDirection::Below) - ? (elementStaff->GetN() > extremalStaff->GetN()) - : (elementStaff->GetN() < extremalStaff->GetN()); - if (updateExtremal) { - extremalStaff = elementStaff; + const bool updatePrincipal = !principalStaff + || ((curveDir == SlurCurveDirection::Below) ? (elementStaff->GetN() > principalStaff->GetN()) + : (elementStaff->GetN() < principalStaff->GetN())); + if (updatePrincipal) { + principalStaff = elementStaff; } }; @@ -521,7 +526,8 @@ const Staff *Slur::CalculateExtremalStaff(const Staff *staff, int xMin, int xMax } }); - return extremalStaff; + assert(principalStaff); + return principalStaff; } bool Slur::IsElementBelow(const LayerElement *element, const Staff *startStaff, const Staff *endStaff) const diff --git a/src/view_control.cpp b/src/view_control.cpp index 6c908fb21ff..7406c1509a4 100644 --- a/src/view_control.cpp +++ b/src/view_control.cpp @@ -311,7 +311,7 @@ void View::DrawTimeSpanningElement(DeviceContext *dc, Object *element, System *s if (this->GetSlurHandling() == SlurHandling::Ignore) break; Slur *slur = vrv_cast(element); assert(slur); - staff = slur->CalculateExtremalStaff(staff, x1, x2); + staff = slur->CalculatePrincipalStaff(staff, x1, x2); } // Create the floating positioner From d59a0bb7407fc0dbfdd95d46ad153420a2ad1067 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sun, 27 Oct 2024 18:06:38 +0100 Subject: [PATCH 2/3] Improve comment --- src/view_control.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view_control.cpp b/src/view_control.cpp index 7406c1509a4..9d57236dc09 100644 --- a/src/view_control.cpp +++ b/src/view_control.cpp @@ -305,7 +305,7 @@ void View::DrawTimeSpanningElement(DeviceContext *dc, Object *element, System *s bool isFirst = true; for (Staff *staff : staffList) { - // TimeSpanning element are not necessary floating elements (e.g., syl) - we have a bounding box only for them + // TimeSpanning elements are not necessary floating elements (e.g., syl) - we have a bounding box only for them if (element->IsControlElement()) { if (element->Is({ PHRASE, SLUR })) { if (this->GetSlurHandling() == SlurHandling::Ignore) break; From 7ed928e9991e1bd5b5e916373093442666bb2a2e Mon Sep 17 00:00:00 2001 From: David Bauer Date: Mon, 28 Oct 2024 23:48:01 +0100 Subject: [PATCH 3/3] Consider beam staff for artic cross staff --- include/vrv/calcarticfunctor.h | 2 ++ src/adjustarticfunctor.cpp | 6 +++--- src/calcarticfunctor.cpp | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/vrv/calcarticfunctor.h b/include/vrv/calcarticfunctor.h index 8b1884e6653..bca9579df01 100644 --- a/include/vrv/calcarticfunctor.h +++ b/include/vrv/calcarticfunctor.h @@ -48,6 +48,8 @@ class CalcArticFunctor : public DocFunctor { private: // Calculate shift for the articulation based on its type and presence of other articulations int CalculateHorizontalShift(const Artic *artic, bool virtualStem) const; + // Include the parent beam staff in the calculation of the above and below staff + void IncludeBeamStaff(LayerElement *layerElement); public: // diff --git a/src/adjustarticfunctor.cpp b/src/adjustarticfunctor.cpp index 7bfe283e428..9257b65fba3 100644 --- a/src/adjustarticfunctor.cpp +++ b/src/adjustarticfunctor.cpp @@ -34,11 +34,11 @@ FunctorCode AdjustArticFunctor::VisitArtic(Artic *artic) int yIn, yOut, yRel; Staff *staff = artic->GetAncestorStaff(RESOLVE_CROSS_STAFF); - Beam *beam = vrv_cast(artic->GetFirstAncestor(BEAM)); + const Beam *beam = artic->GetAncestorBeam(); const int staffHeight = m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * (staff->m_drawingLines - 1); - Stem *stem = vrv_cast(m_parent->FindDescendantByType(STEM)); - Flag *flag = vrv_cast(m_parent->FindDescendantByType(FLAG)); + const Stem *stem = vrv_cast(m_parent->FindDescendantByType(STEM)); + const Flag *flag = vrv_cast(m_parent->FindDescendantByType(FLAG)); // Avoid artic to be in ledger lines if (artic->GetDrawingPlace() == STAFFREL_above) { int yAboveStem = m_parent->GetDrawingTop(m_doc, staff->m_drawingStaffSize, false) - staff->GetDrawingY(); diff --git a/src/calcarticfunctor.cpp b/src/calcarticfunctor.cpp index 6464dbac848..92f54c3d01a 100644 --- a/src/calcarticfunctor.cpp +++ b/src/calcarticfunctor.cpp @@ -134,6 +134,8 @@ FunctorCode CalcArticFunctor::VisitChord(Chord *chord) } } + this->IncludeBeamStaff(chord); + return FUNCTOR_CONTINUE; } @@ -164,6 +166,8 @@ FunctorCode CalcArticFunctor::VisitNote(Note *note) m_crossStaffBelow = true; } + this->IncludeBeamStaff(note); + return FUNCTOR_CONTINUE; } @@ -194,4 +198,16 @@ int CalcArticFunctor::CalculateHorizontalShift(const Artic *artic, bool virtualS return shift; } +void CalcArticFunctor::IncludeBeamStaff(LayerElement *layerElement) +{ + if (Beam *beam = layerElement->GetAncestorBeam(); beam) { + if (m_crossStaffAbove && (beam->m_drawingPlace == BEAMPLACE_above)) { + m_staffAbove = beam->GetAncestorStaff(RESOLVE_CROSS_STAFF); + } + else if (m_crossStaffBelow && (beam->m_drawingPlace == BEAMPLACE_below)) { + m_staffBelow = beam->GetAncestorStaff(RESOLVE_CROSS_STAFF); + } + } +} + } // namespace vrv