Skip to content

Commit

Permalink
Add JustifyYAdjustCrossStaff
Browse files Browse the repository at this point in the history
  • Loading branch information
brdvd committed Apr 13, 2023
1 parent 3386f96 commit 1035d92
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 3 deletions.
51 changes: 49 additions & 2 deletions include/vrv/justifyfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class JustifyXFunctor : public DocFunctor {
// JustifyYFunctor
//----------------------------------------------------------------------------

using ShiftMap = std::map<const StaffAlignment *, int>;

/**
* This class justifies the Y positions.
*/
Expand All @@ -99,7 +101,7 @@ class JustifyYFunctor : public DocFunctor {
///@{
void SetJustificationSum(double justificationSum) { m_justificationSum = justificationSum; }
void SetSpaceToDistribute(int space) { m_spaceToDistribute = space; }
const std::map<StaffAlignment *, int> &GetShiftForStaff() const { return m_shiftForStaff; }
const ShiftMap &GetShiftForStaff() const { return m_shiftForStaff; }
///@}

/*
Expand Down Expand Up @@ -127,7 +129,52 @@ class JustifyYFunctor : public DocFunctor {
double m_justificationSum;
// A map of calculated shifts per StaffAlignment
// => this is transferred to the JustifyYAdjustCrossStaffFunctor
std::map<StaffAlignment *, int> m_shiftForStaff;
ShiftMap m_shiftForStaff;
};

//----------------------------------------------------------------------------
// JustifyYAdjustCrossStaffFunctor
//----------------------------------------------------------------------------

/**
* This class adjusts the cross staff content after vertical justification.
*/
class JustifyYAdjustCrossStaffFunctor : public DocFunctor {
public:
/**
* @name Constructors, destructors
*/
///@{
JustifyYAdjustCrossStaffFunctor(Doc *doc);
virtual ~JustifyYAdjustCrossStaffFunctor() = default;
///@}

/*
* Abstract base implementation
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Functor interface
*/
///@{
FunctorCode VisitChord(Chord *chord) override;
///@}

protected:
//
private:
/*
* Calculate the shift due to vertical justification
*/
int GetShift(const Staff *staff) const;

public:
//
private:
// A map of calculated shifts per StaffAlignment
// => this is transferred from the JustifyYFunctor
ShiftMap m_shiftForStaff;
};

} // namespace vrv
Expand Down
61 changes: 61 additions & 0 deletions src/justifyfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
//----------------------------------------------------------------------------

#include "doc.h"
#include "elementpart.h"
#include "section.h"
#include "staff.h"
#include "stem.h"
#include "system.h"
#include "vrv.h"

Expand Down Expand Up @@ -182,4 +185,62 @@ FunctorCode JustifyYFunctor::VisitSystem(System *system)
return FUNCTOR_SIBLINGS;
}

//----------------------------------------------------------------------------
// JustifyYAdjustCrossStaffFunctor
//----------------------------------------------------------------------------

JustifyYAdjustCrossStaffFunctor::JustifyYAdjustCrossStaffFunctor(Doc *doc) : DocFunctor(doc) {}

FunctorCode JustifyYAdjustCrossStaffFunctor::VisitChord(Chord *chord)
{
// Check if chord spreads across several staves
std::map<int, Staff *> extremalStaves;
for (Note *note : { chord->GetTopNote(), chord->GetBottomNote() }) {
Staff *staff = note->GetAncestorStaff(RESOLVE_CROSS_STAFF);
extremalStaves.insert({ staff->GetN(), staff });
}
// get chord parent staff
Staff *staff = chord->GetAncestorStaff(RESOLVE_CROSS_STAFF);
extremalStaves.insert({ staff->GetN(), staff });

if (extremalStaves.size() < 2) return FUNCTOR_CONTINUE;

const int shift = this->GetShift(extremalStaves.rbegin()->second) - this->GetShift(extremalStaves.begin()->second);

// Add the shift to the stem length of the chord
Stem *stem = vrv_cast<Stem *>(chord->FindDescendantByType(STEM));
if (!stem) return FUNCTOR_CONTINUE;

const int stemLen = stem->GetDrawingStemLen();
if (stem->GetDrawingStemDir() == STEMDIRECTION_up) {
stem->SetDrawingStemLen(stemLen - shift);
}
else {
stem->SetDrawingStemLen(stemLen + shift);
}

// Reposition the stem
Staff *rootStaff = (stem->GetDrawingStemDir() == STEMDIRECTION_up) ? extremalStaves.rbegin()->second
: extremalStaves.begin()->second;
stem->SetDrawingYRel(stem->GetDrawingYRel() + this->GetShift(staff) - this->GetShift(rootStaff));

// Add the shift to the flag position
Flag *flag = vrv_cast<Flag *>(stem->FindDescendantByType(FLAG));
if (flag) {
const int sign = (stem->GetDrawingStemDir() == STEMDIRECTION_up) ? 1 : -1;
flag->SetDrawingYRel(flag->GetDrawingYRel() + sign * shift);
}

return FUNCTOR_CONTINUE;
}

int JustifyYAdjustCrossStaffFunctor::GetShift(const Staff *staff) const
{
const StaffAlignment *alignment = staff->GetAlignment();
if (m_shiftForStaff.find(alignment) != m_shiftForStaff.end()) {
return m_shiftForStaff.at(alignment);
}
return 0;
}

} // namespace vrv
3 changes: 2 additions & 1 deletion src/page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,8 @@ void Page::JustifyVertically()
// Adjust cross staff content which is displaced through vertical justification
Functor justifyYAdjustCrossStaff(&Object::JustifyYAdjustCrossStaff);
JustifyYAdjustCrossStaffParams justifyYAdjustCrossStaffParams(doc);
justifyYAdjustCrossStaffParams.m_shiftForStaff = justifyY.GetShiftForStaff();
// TODO: adjust later
// justifyYAdjustCrossStaffParams.m_shiftForStaff = justifyY.GetShiftForStaff();
this->Process(&justifyYAdjustCrossStaff, &justifyYAdjustCrossStaffParams);
}
}
Expand Down

0 comments on commit 1035d92

Please sign in to comment.