Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for scoreDef order diverging from the data #3560

Merged
merged 6 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,4 @@ Release/
# Intermediate font files
fonts/**/tmp
libmei/tools/__pycache__
doc/.venv
2 changes: 2 additions & 0 deletions doc/diffTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ then
echo "Emptying directories ..."
rm $indir1/*/*.png
rm $indir1/*/*.svg
rm $indir1/*/*.json
rm $indir2/*/*.png
rm $indir2/*/*.svg
rm $indir2/*/*.json
rm $outdir/*/*.png
rm $outdir/index.html
fi
Expand Down
12 changes: 12 additions & 0 deletions include/vrv/verticalaligner.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ class SystemAligner : public Object {
SystemAligner();
virtual ~SystemAligner();

/**
* Override the method of adding AlignmentReference children
*/
bool IsSupportedChild(Object *object) override;

/**
* Do not copy children for HorizontalAligner
*/
Expand Down Expand Up @@ -67,6 +72,13 @@ class SystemAligner : public Object {
*/
StaffAlignment *GetStaffAlignment(int idx, Staff *staff, const Doc *doc);

/**
* Reorder the staff alignment as given in the staffNs.
* Reordering will fail if the number of staffAlignment does not correspond, or
* if some staffAlignment pointers are missing for a corresponding staffN
*/
void ReorderBy(const std::vector<int> &staffNs);

/**
* Get the StaffAlignment for the staffN.
* Return NULL if not found.
Expand Down
6 changes: 6 additions & 0 deletions src/alignfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,12 @@ FunctorCode AlignVerticallyFunctor::VisitSystemEnd(System *system)
m_cumulatedShift = 0;
m_staffIdx = 0;

// StaffAlignment are added following the staff element in the measures
// We can now reorder them according to the scoreDef order
if (system->GetDrawingScoreDef()) {
system->m_systemAligner.ReorderBy(system->GetDrawingScoreDef()->GetStaffNs());
}

system->m_systemAligner.Process(*this);

return FUNCTOR_SIBLINGS;
Expand Down
62 changes: 50 additions & 12 deletions src/verticalaligner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,28 @@ void SystemAligner::Reset()
Object::Reset();
m_spacingTypes.clear();
m_system = NULL;
m_bottomAlignment = NULL;
m_bottomAlignment = this->GetStaffAlignment(0, NULL, NULL);

ArrayOfObjects &children = this->GetChildrenForModification();
m_bottomAlignment = new StaffAlignment();
m_bottomAlignment->SetStaff(NULL, NULL, this->GetAboveSpacingType(NULL));
m_bottomAlignment->SetParentSystem(this->GetSystem());
this->AddChild(m_bottomAlignment);
}

bool SystemAligner::IsSupportedChild(Object *child)
{
assert(dynamic_cast<StaffAlignment *>(child));
return true;
}

StaffAlignment *SystemAligner::GetStaffAlignment(int idx, Staff *staff, const Doc *doc)
{
ArrayOfObjects &children = this->GetChildrenForModification();

// The last one is always the bottomAlignment (unless if not created)
if (m_bottomAlignment) {
// remove it temporarily
children.pop_back();
}
// The last one is always the bottomAlignment
assert(m_bottomAlignment);
// remove it temporarily
children.pop_back();

if (idx < this->GetChildCount()) {
children.push_back(m_bottomAlignment);
Expand All @@ -73,17 +82,46 @@ StaffAlignment *SystemAligner::GetStaffAlignment(int idx, Staff *staff, const Do
// We create the StaffAlignment
StaffAlignment *alignment = new StaffAlignment();
alignment->SetStaff(staff, doc, this->GetAboveSpacingType(staff));
alignment->SetParent(this);
alignment->SetParentSystem(this->GetSystem());
children.push_back(alignment);
this->AddChild(alignment);

if (m_bottomAlignment) {
children.push_back(m_bottomAlignment);
}
// put back the bottomAlignment
children.push_back(m_bottomAlignment);

return alignment;
}

void SystemAligner::ReorderBy(const std::vector<int> &staffNs)
{
std::vector<int> order = staffNs;
// First check that staffNs are unique
std::sort(order.begin(), order.end());
order.erase(std::unique(order.begin(), order.end()), order.end());
// If not, we should return because the re-ordering below will corrupt the data
// Returning will keep the order as it is
if (order.size() != staffNs.size()) return;

ArrayOfObjects &children = this->GetChildrenForModification();

// Since we have a bottom alignment, the number is +1
if (children.size() != staffNs.size() + 1) return;

ListOfObjects orderedAlignments;
for (auto staffN : staffNs) {
StaffAlignment *alignment = this->GetStaffAlignmentForStaffN(staffN);
// Something is wrong in the data, we keep the order as it is
if (!alignment) return;
orderedAlignments.push_back(alignment);
}
int i = 0;
// Since the number of staffAlignment is the same and they are unique, we can
// blindly replace them in the StaffAligner children
for (auto alignment : orderedAlignments) {
children.at(i) = alignment;
++i;
}
}

StaffAlignment *SystemAligner::GetStaffAlignmentForStaffN(int staffN)
{
return const_cast<StaffAlignment *>(std::as_const(*this).GetStaffAlignmentForStaffN(staffN));
Expand Down
Loading