Skip to content

Commit

Permalink
Merge pull request #3560 from rism-digital/develop-scoredef-order
Browse files Browse the repository at this point in the history
Add support for scoreDef order diverging from the data
  • Loading branch information
ahankinson authored Dec 15, 2023
2 parents 8500687 + 5efcff6 commit 0234bfc
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 12 deletions.
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

0 comments on commit 0234bfc

Please sign in to comment.