Skip to content

Commit

Permalink
Merge pull request #3839 from brdvd/fix/accent-dynam-interaction
Browse files Browse the repository at this point in the history
Fix interaction between dynam and cross-staff accent
  • Loading branch information
lpugin authored Oct 30, 2024
2 parents a31c9f6 + 7ed928e commit c811450
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 18 deletions.
2 changes: 2 additions & 0 deletions include/vrv/calcarticfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
//
Expand Down
4 changes: 2 additions & 2 deletions include/vrv/slur.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
///@}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/adjustarticfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ FunctorCode AdjustArticFunctor::VisitArtic(Artic *artic)
int yIn, yOut, yRel;

Staff *staff = artic->GetAncestorStaff(RESOLVE_CROSS_STAFF);
Beam *beam = vrv_cast<Beam *>(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<Stem *>(m_parent->FindDescendantByType(STEM));
Flag *flag = vrv_cast<Flag *>(m_parent->FindDescendantByType(FLAG));
const Stem *stem = vrv_cast<const Stem *>(m_parent->FindDescendantByType(STEM));
const Flag *flag = vrv_cast<const Flag *>(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();
Expand Down
16 changes: 16 additions & 0 deletions src/calcarticfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ FunctorCode CalcArticFunctor::VisitChord(Chord *chord)
}
}

this->IncludeBeamStaff(chord);

return FUNCTOR_CONTINUE;
}

Expand Down Expand Up @@ -164,6 +166,8 @@ FunctorCode CalcArticFunctor::VisitNote(Note *note)
m_crossStaffBelow = true;
}

this->IncludeBeamStaff(note);

return FUNCTOR_CONTINUE;
}

Expand Down Expand Up @@ -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
28 changes: 17 additions & 11 deletions src/slur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Staff *>(std::as_const(*this).CalculateExtremalStaff(staff, xMin, xMax));
return const_cast<Staff *>(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;
}
};

Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/view_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,13 @@ 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;
Slur *slur = vrv_cast<Slur *>(element);
assert(slur);
staff = slur->CalculateExtremalStaff(staff, x1, x2);
staff = slur->CalculatePrincipalStaff(staff, x1, x2);
}

// Create the floating positioner
Expand Down

0 comments on commit c811450

Please sign in to comment.