From 0d0907617dfe655ca0cd258307f469ff31222e94 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 09:42:25 +0100 Subject: [PATCH 1/6] Move bottom aligner creation to Reset() --- src/verticalaligner.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index b1b4e1578eb..98a4fcd2c05 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -47,19 +47,23 @@ 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->SetParent(this); + m_bottomAlignment->SetParentSystem(this->GetSystem()); + children.push_back(m_bottomAlignment); } 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); @@ -77,9 +81,8 @@ StaffAlignment *SystemAligner::GetStaffAlignment(int idx, Staff *staff, const Do alignment->SetParentSystem(this->GetSystem()); children.push_back(alignment); - if (m_bottomAlignment) { - children.push_back(m_bottomAlignment); - } + // put back the bottomAlignment + children.push_back(m_bottomAlignment); return alignment; } From f1871ca189a6cc5f871e2e560d5e69178256c054 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 16:31:44 +0100 Subject: [PATCH 2/6] Enable support for different scoreDef order --- include/vrv/verticalaligner.h | 12 ++++++++++ src/alignfunctor.cpp | 4 ++++ src/verticalaligner.cpp | 41 +++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/include/vrv/verticalaligner.h b/include/vrv/verticalaligner.h index 5a209b611c7..d5ce55c8644 100644 --- a/include/vrv/verticalaligner.h +++ b/include/vrv/verticalaligner.h @@ -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 */ @@ -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 &staffNs); + /** * Get the StaffAlignment for the staffN. * Return NULL if not found. diff --git a/src/alignfunctor.cpp b/src/alignfunctor.cpp index c862fadf1aa..8e1b1368e5b 100644 --- a/src/alignfunctor.cpp +++ b/src/alignfunctor.cpp @@ -642,6 +642,10 @@ 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 + system->m_systemAligner.ReorderBy(system->GetDrawingScoreDef()->GetStaffNs()); + system->m_systemAligner.Process(*this); return FUNCTOR_SIBLINGS; diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index 98a4fcd2c05..cb8214feec8 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -51,9 +51,14 @@ void SystemAligner::Reset() ArrayOfObjects &children = this->GetChildrenForModification(); m_bottomAlignment = new StaffAlignment(); m_bottomAlignment->SetStaff(NULL, NULL, this->GetAboveSpacingType(NULL)); - m_bottomAlignment->SetParent(this); m_bottomAlignment->SetParentSystem(this->GetSystem()); - children.push_back(m_bottomAlignment); + this->AddChild(m_bottomAlignment); +} + +bool SystemAligner::IsSupportedChild(Object *child) +{ + assert(dynamic_cast(child)); + return true; } StaffAlignment *SystemAligner::GetStaffAlignment(int idx, Staff *staff, const Doc *doc) @@ -77,9 +82,8 @@ 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); // put back the bottomAlignment children.push_back(m_bottomAlignment); @@ -87,6 +91,35 @@ StaffAlignment *SystemAligner::GetStaffAlignment(int idx, Staff *staff, const Do return alignment; } +void SystemAligner::ReorderBy(const std::vector &staffNs) +{ + std::vector 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 + 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); + if (!alignment) return; + // Something is wrong in the data, we keep the order as it is + orderedAlignments.push_back(alignment); + } + int i = 0; + // We know that + for (auto alignment : orderedAlignments) { + children.at(i) = alignment; + ++i; + } +} + StaffAlignment *SystemAligner::GetStaffAlignmentForStaffN(int staffN) { return const_cast(std::as_const(*this).GetStaffAlignmentForStaffN(staffN)); From 8f1ddf71a1f7df9a50129b9fad6391a34d7de99a Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 16:50:47 +0100 Subject: [PATCH 3/6] Adjust comments --- src/verticalaligner.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index cb8214feec8..0bf5b3ed82e 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -98,6 +98,7 @@ void SystemAligner::ReorderBy(const std::vector &staffNs) 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(); @@ -108,12 +109,13 @@ void SystemAligner::ReorderBy(const std::vector &staffNs) ListOfObjects orderedAlignments; for (auto staffN : staffNs) { StaffAlignment *alignment = this->GetStaffAlignmentForStaffN(staffN); - if (!alignment) return; // Something is wrong in the data, we keep the order as it is + if (!alignment) return; orderedAlignments.push_back(alignment); } int i = 0; - // We know that + // 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; From 240c5cc46df4f2fc5b0b0f81852dcd46f3e16950 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 18:01:39 +0100 Subject: [PATCH 4/6] Also remove .json when cleanup test suite files --- doc/diffTests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/diffTests.sh b/doc/diffTests.sh index 2e4513c57e4..1f49b58bb10 100755 --- a/doc/diffTests.sh +++ b/doc/diffTests.sh @@ -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 From 1f90bcb08beaa9ce93446e57fe282c00f0e01f45 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 18:02:25 +0100 Subject: [PATCH 5/6] Ignore python environment file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1c2172a8b7b..a452c339bc1 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,4 @@ Release/ # Intermediate font files fonts/**/tmp libmei/tools/__pycache__ +doc/.venv From 5efcff63b9336006585f3b0658842c7f2265baf6 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 13 Dec 2023 18:02:52 +0100 Subject: [PATCH 6/6] Prevent crash when trying to reorder systems without scoreDef --- src/alignfunctor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/alignfunctor.cpp b/src/alignfunctor.cpp index 8e1b1368e5b..8a1e1b35e51 100644 --- a/src/alignfunctor.cpp +++ b/src/alignfunctor.cpp @@ -644,7 +644,9 @@ FunctorCode AlignVerticallyFunctor::VisitSystemEnd(System *system) // StaffAlignment are added following the staff element in the measures // We can now reorder them according to the scoreDef order - system->m_systemAligner.ReorderBy(system->GetDrawingScoreDef()->GetStaffNs()); + if (system->GetDrawingScoreDef()) { + system->m_systemAligner.ReorderBy(system->GetDrawingScoreDef()->GetStaffNs()); + } system->m_systemAligner.Process(*this);