From da8a7f32f6cdd9803e1791f555e1cef51befc686 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Tue, 12 Sep 2023 13:43:35 +0200 Subject: [PATCH 01/18] Store list of scores in Doc --- include/vrv/doc.h | 21 ++++++++++++++++----- src/doc.cpp | 27 +++++++++++++++------------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/include/vrv/doc.h b/include/vrv/doc.h index d1cfdc7a7af..099a5e90702 100644 --- a/include/vrv/doc.h +++ b/include/vrv/doc.h @@ -121,11 +121,6 @@ class Doc : public Object { */ bool HasPage(int pageIdx) const; - /** - * Get all the Score in the visible Mdiv. - */ - std::list GetScores(); - /** * Get the Pages in the visible Mdiv. * Will find it only when having read a pages-based MEI file, @@ -141,6 +136,11 @@ class Doc : public Object { */ int GetPageCount() const; + /** + * Get all scores + */ + std::list GetScores() { return m_scores; } + /** * Return true if the MIDI generation is already done */ @@ -477,6 +477,11 @@ class Doc : public Object { */ void PrepareMeasureIndices(); + /** + * Determine all scores + */ + void CollectScores(); + public: Page *m_selectionPreceding; Page *m_selectionFollowing; @@ -545,6 +550,12 @@ class Doc : public Object { */ Resources m_resources; + /** + * The list of all scores + * Used in Doc::GetScoreDefFor to quickly determine the corresponding score for an object + */ + std::list m_scores; + /** * @name Holds a pointer to the current score/scoreDef. * Set by Doc::GetCurrentScoreDef or explicitly through Doc::SetCurrentScoreDef diff --git a/src/doc.cpp b/src/doc.cpp index 3fd5b393d28..7fd1c9e1501 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -574,6 +574,10 @@ void Doc::PrepareData() this->PrepareMeasureIndices(); + /************ Collect all scores ************/ + + this->CollectScores(); + /************ Store default durations ************/ PrepareDurationFunctor prepareDuration; @@ -1446,18 +1450,6 @@ bool Doc::HasPage(int pageIdx) const return ((pageIdx >= 0) && (pageIdx < pages->GetChildCount())); } -std::list Doc::GetScores() -{ - std::list scores; - ListOfObjects objects = this->FindAllDescendantsByType(SCORE, false, 3); - for (const auto object : objects) { - Score *score = vrv_cast(object); - assert(score); - scores.push_back(score); - } - return scores; -} - Pages *Doc::GetPages() { return vrv_cast(this->FindDescendantByType(PAGES)); @@ -1474,6 +1466,17 @@ int Doc::GetPageCount() const return ((pages) ? pages->GetChildCount() : 0); } +void Doc::CollectScores() +{ + m_scores.clear(); + ListOfObjects objects = this->FindAllDescendantsByType(SCORE, false, 3); + for (Object *object : objects) { + Score *score = vrv_cast(object); + assert(score); + m_scores.push_back(score); + } +} + int Doc::GetGlyphHeight(char32_t code, int staffSize, bool graceSize) const { int x, y, w, h; From d4e6fa9004956fe02844fbd5cca1e91dac960126 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Thu, 14 Sep 2023 17:08:37 +0200 Subject: [PATCH 02/18] Replace current scoreDef in import/export --- include/vrv/doc.h | 8 ++++++++ include/vrv/iomei.h | 2 +- src/doc.cpp | 14 ++++++++++++++ src/ioabc.cpp | 2 +- src/iodarms.cpp | 2 +- src/iohumdrum.cpp | 34 +++++++++++++++++----------------- src/iomei.cpp | 19 ++++++++++--------- src/iomusxml.cpp | 10 +++++----- src/iopae.cpp | 18 +++++++++--------- 9 files changed, 66 insertions(+), 43 deletions(-) diff --git a/include/vrv/doc.h b/include/vrv/doc.h index 099a5e90702..a41b88558da 100644 --- a/include/vrv/doc.h +++ b/include/vrv/doc.h @@ -141,6 +141,14 @@ class Doc : public Object { */ std::list GetScores() { return m_scores; } + /** + * Get the first scoreDef + */ + ///@{ + ScoreDef *GetFirstScoreDef(); + const ScoreDef *GetFirstScoreDef() const; + ///@} + /** * Return true if the MIDI generation is already done */ diff --git a/include/vrv/iomei.h b/include/vrv/iomei.h index e162f386646..6b0d7800119 100644 --- a/include/vrv/iomei.h +++ b/include/vrv/iomei.h @@ -306,7 +306,7 @@ class MEIOutput : public Output { * Scoredef manipulation */ ///@{ - void WriteCustomScoreDef(); + void WriteCustomScoreDef(ScoreDef *scoreDef); void AdjustStaffDef(StaffDef *staffDef, Measure *measure); bool AdjustLabel(Label *label); ///@} diff --git a/src/doc.cpp b/src/doc.cpp index 7fd1c9e1501..7be35f4dac1 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -1466,6 +1466,20 @@ int Doc::GetPageCount() const return ((pages) ? pages->GetChildCount() : 0); } +ScoreDef *Doc::GetFirstScoreDef() +{ + return const_cast(std::as_const(*this).GetFirstScoreDef()); +} + +const ScoreDef *Doc::GetFirstScoreDef() const +{ + // Use precalculated list of scores, if possible + const Score *score + = m_scores.empty() ? vrv_cast(this->FindDescendantByType(SCORE, 3)) : m_scores.front(); + + return score ? score->GetScoreDef() : NULL; +} + void Doc::CollectScores() { m_scores.clear(); diff --git a/src/ioabc.cpp b/src/ioabc.cpp index 5ce7bdae43d..a7473bdae60 100644 --- a/src/ioabc.cpp +++ b/src/ioabc.cpp @@ -224,7 +224,7 @@ int ABCInput::SetBarLine(const std::string &musicCode, int i) void ABCInput::CalcUnitNoteLength() { - MeterSig *meterSig = vrv_cast(m_doc->GetCurrentScoreDef()->FindDescendantByType(METERSIG)); + MeterSig *meterSig = vrv_cast(m_doc->GetFirstScoreDef()->FindDescendantByType(METERSIG)); if (!meterSig || !meterSig->HasUnit() || double(meterSig->GetTotalCount()) / double(meterSig->GetUnit()) >= 0.75) { m_unitDur = 8; m_durDefault = DURATION_8; diff --git a/src/iodarms.cpp b/src/iodarms.cpp index 36082e95284..debf3f3181a 100644 --- a/src/iodarms.cpp +++ b/src/iodarms.cpp @@ -521,7 +521,7 @@ bool DarmsInput::Import(const std::string &data_str) StaffDef *staffDef = new StaffDef(); staffDef->SetN(1); staffGrp->AddChild(staffDef); - m_doc->GetCurrentScoreDef()->AddChild(staffGrp); + m_doc->GetFirstScoreDef()->AddChild(staffGrp); m_doc->ConvertToPageBasedDoc(); diff --git a/src/iohumdrum.cpp b/src/iohumdrum.cpp index 801556e9b85..907caf7992c 100644 --- a/src/iohumdrum.cpp +++ b/src/iohumdrum.cpp @@ -3411,7 +3411,7 @@ void HumdrumInput::prepareStaffGroups(int top, int bot) const std::vector &staffstarts = m_staffstarts; if (staffstarts.size() > 0) { - addMidiTempo(m_doc->GetCurrentScoreDef(), staffstarts[0], top, bot); + addMidiTempo(m_doc->GetFirstScoreDef(), staffstarts[0], top, bot); } hum::HumRegex hre; for (int i = 0; i < (int)staffstarts.size(); ++i) { @@ -3445,7 +3445,7 @@ void HumdrumInput::prepareStaffGroups(int top, int bot) // If there is one staff, then no extra decoration. else if (staffstarts.size() == 1) { StaffGrp *sg = new StaffGrp(); - m_doc->GetCurrentScoreDef()->AddChild(sg); + m_doc->GetFirstScoreDef()->AddChild(sg); sg->AddChild(m_staffdef[0]); } // do something if there is no staff in the score? @@ -3454,7 +3454,7 @@ void HumdrumInput::prepareStaffGroups(int top, int bot) bool status = processStaffDecoration(decoration); if (!status) { StaffGrp *sg = new StaffGrp(); - m_doc->GetCurrentScoreDef()->AddChild(sg); + m_doc->GetFirstScoreDef()->AddChild(sg); sg->SetBarThru(BOOLEAN_false); // setGroupSymbol(sg, staffGroupingSym_SYMBOL_bracket); for (int i = 0; i < (int)m_staffdef.size(); ++i) { @@ -3481,7 +3481,7 @@ void HumdrumInput::prepareStaffGroups(int top, int bot) void HumdrumInput::promoteInstrumentNamesToGroup() { - ScoreDef *sdf = m_doc->GetCurrentScoreDef(); + ScoreDef *sdf = m_doc->GetFirstScoreDef(); int count = sdf->GetChildCount(); for (int i = 0; i < count; ++i) { Object *obj = sdf->GetChild(i); @@ -3555,7 +3555,7 @@ void HumdrumInput::promoteInstrumentsForStaffGroup(StaffGrp *group) void HumdrumInput::promoteInstrumentAbbreviationsToGroup() { - ScoreDef *sdf = m_doc->GetCurrentScoreDef(); + ScoreDef *sdf = m_doc->GetFirstScoreDef(); int count = sdf->GetChildCount(); for (int i = 0; i < count; ++i) { @@ -4007,14 +4007,14 @@ bool HumdrumInput::processStaffDecoration(const std::string &decoration) // There is no barline across the staves in this case. root = new StaffGrp(); root->SetBarThru(BOOLEAN_false); - m_doc->GetCurrentScoreDef()->AddChild(root); + m_doc->GetFirstScoreDef()->AddChild(root); } else if (d[0] == '(') { // The outer group is not bracketed, but bar goes all of // the way through system. root = new StaffGrp(); root->SetBarThru(BOOLEAN_true); - m_doc->GetCurrentScoreDef()->AddChild(root); + m_doc->GetFirstScoreDef()->AddChild(root); } else if (pairing.back() == 0) { skipfirst = true; @@ -4030,7 +4030,7 @@ bool HumdrumInput::processStaffDecoration(const std::string &decoration) else if (d[0] == '[') { setGroupSymbol(root, staffGroupingSym_SYMBOL_bracket); } - m_doc->GetCurrentScoreDef()->AddChild(root); + m_doc->GetFirstScoreDef()->AddChild(root); } std::vector spine; // kernstart index @@ -4271,7 +4271,7 @@ bool HumdrumInput::processStaffDecoration(const std::string &decoration) root->AddChild(sg); } else { - m_doc->GetCurrentScoreDef()->AddChild(sg); + m_doc->GetFirstScoreDef()->AddChild(sg); } for (int i = 0; i < (int)m_staffdef.size(); ++i) { sg->AddChild(m_staffdef[i]); @@ -4294,7 +4294,7 @@ bool HumdrumInput::processStaffDecoration(const std::string &decoration) root->AddChild(sg); } else { - m_doc->GetCurrentScoreDef()->AddChild(sg); + m_doc->GetFirstScoreDef()->AddChild(sg); } } @@ -4371,7 +4371,7 @@ bool HumdrumInput::processStaffDecoration(const std::string &decoration) } else { root_sg = new StaffGrp(); - m_doc->GetCurrentScoreDef()->AddChild(root_sg); + m_doc->GetFirstScoreDef()->AddChild(root_sg); root_sg->SetBarThru(BOOLEAN_false); } for (int i = 0; i < (int)newgroups.size(); ++i) { @@ -4857,7 +4857,7 @@ bool HumdrumInput::prepareFooter( // std::cout << "MEI CONTENT " << meicontent << std::endl; AttFormeworkComparison comparison(PGFOOT, PGFUNC_first); - Object *pgfoot = tempdoc.GetCurrentScoreDef()->FindDescendantByComparison(&comparison); + Object *pgfoot = tempdoc.GetFirstScoreDef()->FindDescendantByComparison(&comparison); if (pgfoot == NULL) { return false; } @@ -4875,10 +4875,10 @@ bool HumdrumInput::prepareFooter( return false; } - m_doc->GetCurrentScoreDef()->AddChild(pgfoot); + m_doc->GetFirstScoreDef()->AddChild(pgfoot); AttFormeworkComparison comparison2(PGFOOT, PGFUNC_all); - Object *pgfoot2 = tempdoc.GetCurrentScoreDef()->FindDescendantByComparison(&comparison2); + Object *pgfoot2 = tempdoc.GetFirstScoreDef()->FindDescendantByComparison(&comparison2); if (pgfoot2 == NULL) { return true; } @@ -4896,7 +4896,7 @@ bool HumdrumInput::prepareFooter( return true; } - m_doc->GetCurrentScoreDef()->AddChild(pgfoot2); + m_doc->GetFirstScoreDef()->AddChild(pgfoot2); return true; } @@ -5032,7 +5032,7 @@ bool HumdrumInput::prepareHeader( // std::string meicontent = meioutput.GetOutput(); // std::cout << "MEI CONTENT " << meicontent << std::endl; - Object *pghead = tempdoc.GetCurrentScoreDef()->FindDescendantByType(ClassId::PGHEAD); + Object *pghead = tempdoc.GetFirstScoreDef()->FindDescendantByType(ClassId::PGHEAD); if (pghead == NULL) { return false; } @@ -5050,7 +5050,7 @@ bool HumdrumInput::prepareHeader( return false; } - m_doc->GetCurrentScoreDef()->AddChild(pghead); + m_doc->GetFirstScoreDef()->AddChild(pghead); return true; } diff --git a/src/iomei.cpp b/src/iomei.cpp index 9f3e2b6c52f..e11544cc1c2 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -914,12 +914,13 @@ bool MEIOutput::WriteObjectInternal(Object *object, bool useCustomScoreDef) if (this->IsTreeObject(object)) m_nodeStack.push_back(m_currentNode); if (object->Is(SCORE)) { + ScoreDef *scoreDef = vrv_cast(object)->GetScoreDef(); if (useCustomScoreDef) { - this->WriteCustomScoreDef(); + this->WriteCustomScoreDef(scoreDef); } else { // Save the main scoreDef - m_doc->GetCurrentScoreDef()->SaveObject(this, this->GetBasic()); + scoreDef->SaveObject(this, this->GetBasic()); } } @@ -1278,7 +1279,7 @@ void MEIOutput::WriteStackedObjectsEnd() [this](Object *object) { this->WriteObjectInternalEnd(object); }); } -void MEIOutput::WriteCustomScoreDef() +void MEIOutput::WriteCustomScoreDef(ScoreDef *scoreDef) { // Determine the first measure with respect to the first filter match Measure *measure = NULL; @@ -1305,8 +1306,8 @@ void MEIOutput::WriteCustomScoreDef() if (measure && refScoreDef) { // Create a copy of the reference scoredef and adjust it to keep track of clef changes, key signature changes, // etc. - ScoreDef *scoreDef = vrv_cast(refScoreDef->Clone()); - ListOfObjects staffDefs = scoreDef->FindAllDescendantsByType(STAFFDEF); + ScoreDef *customScoreDef = vrv_cast(refScoreDef->Clone()); + ListOfObjects staffDefs = customScoreDef->FindAllDescendantsByType(STAFFDEF); for (Object *staffDef : staffDefs) { this->AdjustStaffDef(vrv_cast(staffDef), measure); } @@ -1319,7 +1320,7 @@ void MEIOutput::WriteCustomScoreDef() } if (!drawLabels) { // If not, replace labels by abbreviation or delete them - ListOfObjects labels = scoreDef->FindAllDescendantsByType(LABEL); + ListOfObjects labels = customScoreDef->FindAllDescendantsByType(LABEL); for (Object *label : labels) { if (!this->AdjustLabel(vrv_cast