From 7321c0ab2750f080591b00e15c8c4e69e1d8de19 Mon Sep 17 00:00:00 2001 From: Monceber Date: Mon, 14 Jun 2021 18:35:11 +0300 Subject: [PATCH 001/179] Keep vertical position of extender lines - added code to save maximal relative Y drawing for dir/dynam to keep positioning of the extender lines consistent before and after system breaks --- include/vrv/floatingobject.h | 5 +++++ src/floatingobject.cpp | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/vrv/floatingobject.h b/include/vrv/floatingobject.h index f29fbf0b46c..3d076f5d033 100644 --- a/include/vrv/floatingobject.h +++ b/include/vrv/floatingobject.h @@ -70,6 +70,9 @@ class FloatingObject : public Object { void SetDrawingGrpId(int drawingGrpId) { m_drawingGrpId = drawingGrpId; } int SetDrawingGrpObject(void *drawingGrpObject); ///@} + + void SetMaxDrawingYRel(int maxDrawingYRel) { m_maxDrawingYRel = maxDrawingYRel; }; + int GetMaxDrawingYRel() const { return m_maxDrawingYRel; }; //----------// // Functors // @@ -124,6 +127,8 @@ class FloatingObject : public Object { /* Drawing Id to group floating elements horizontally */ int m_drawingGrpId; + + int m_maxDrawingYRel; //----------------// // Static members // diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index 4a644f3dc99..85efd06f54f 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -60,6 +60,7 @@ FloatingObject::FloatingObject(const std::string &classid) : Object(classid) Reset(); m_currentPositioner = NULL; + m_maxDrawingYRel = 0; } FloatingObject::~FloatingObject() {} @@ -367,9 +368,14 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen return true; } yRel = -staffAlignment->CalcOverflowAbove(horizOverlapingBBox) + GetContentY1() - margin; + Object *object = dynamic_cast(horizOverlapingBBox); + if (m_object->Is({ DIR, DYNAM })) { + if (m_object->GetMaxDrawingYRel() > yRel) m_object->SetMaxDrawingYRel(yRel); + SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); + } // With LayerElement always move them up - if (object && object->IsLayerElement()) { + else if (object && object->IsLayerElement()) { if (yRel < 0) this->SetDrawingYRel(yRel); } // Otherwise only if the is a vertical overlap @@ -388,9 +394,14 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen } yRel = staffAlignment->CalcOverflowBelow(horizOverlapingBBox) + staffAlignment->GetStaffHeight() + GetContentY2() + margin; + Object *object = dynamic_cast(horizOverlapingBBox); + if (m_object->Is({ DIR, DYNAM })) { + if (m_object->GetMaxDrawingYRel() < yRel) m_object->SetMaxDrawingYRel(yRel); + SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); + } // With LayerElement always move them down - if (object && object->IsLayerElement()) { + else if (object && object->IsLayerElement()) { if (yRel > 0) this->SetDrawingYRel(yRel); } // Otherwise only if the is a vertical overlap From eb7567d77d6c1a8727452a5119866820dd65d31a Mon Sep 17 00:00:00 2001 From: Monceber Date: Tue, 15 Jun 2021 14:28:59 +0300 Subject: [PATCH 002/179] Minor fixes - adjusted default positioning for the dir/dynam (when BB is NULL) - removed `this` keyword from the CalcDrawingYRel() calls for them to be consistent --- src/floatingobject.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index 85efd06f54f..b07d0217b44 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -336,14 +336,24 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen if (m_place == STAFFREL_above) { yRel = GetContentY1(); yRel -= doc->GetBottomMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); - this->SetDrawingYRel(yRel); - this->SetDrawingYRel(-minStaffDistance); + if (m_object->Is({ DIR, DYNAM })) { + SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); + } + else { + SetDrawingYRel(yRel); + SetDrawingYRel(-minStaffDistance); + } } else { yRel = staffAlignment->GetStaffHeight() + GetContentY2(); yRel += doc->GetTopMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); - this->SetDrawingYRel(yRel); - this->SetDrawingYRel(minStaffDistance + staffAlignment->GetStaffHeight()); + if (m_object->Is({ DIR, DYNAM })) { + SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); + } + else { + SetDrawingYRel(yRel); + SetDrawingYRel(minStaffDistance + staffAlignment->GetStaffHeight()); + } } } else { @@ -357,8 +367,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen if (curve && curve->m_object->Is({ LV, PHRASE, SLUR, TIE })) { int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); if (shift != 0) { - this->SetDrawingYRel(this->GetDrawingYRel() - shift); - // LogDebug("Shift %d", shift); + SetDrawingYRel(GetDrawingYRel() - shift); } return true; } @@ -376,18 +385,18 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen } // With LayerElement always move them up else if (object && object->IsLayerElement()) { - if (yRel < 0) this->SetDrawingYRel(yRel); + if (yRel < 0) SetDrawingYRel(yRel); } // Otherwise only if the is a vertical overlap - else if (this->VerticalContentOverlap(horizOverlapingBBox, margin)) { - this->SetDrawingYRel(yRel); + else if (VerticalContentOverlap(horizOverlapingBBox, margin)) { + SetDrawingYRel(yRel); } } else { if (curve && curve->m_object->Is({ LV, PHRASE, SLUR, TIE })) { int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); if (shift != 0) { - this->SetDrawingYRel(this->GetDrawingYRel() - shift); + SetDrawingYRel(GetDrawingYRel() - shift); // LogDebug("Shift %d", shift); } return true; @@ -402,11 +411,11 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen } // With LayerElement always move them down else if (object && object->IsLayerElement()) { - if (yRel > 0) this->SetDrawingYRel(yRel); + if (yRel > 0) SetDrawingYRel(yRel); } // Otherwise only if the is a vertical overlap - else if (this->VerticalContentOverlap(horizOverlapingBBox, margin)) { - this->SetDrawingYRel(yRel); + else if (VerticalContentOverlap(horizOverlapingBBox, margin)) { + SetDrawingYRel(yRel); } } } From e6181b4428178e02ed551d21612e5b837af57c24 Mon Sep 17 00:00:00 2001 From: Monceber Date: Tue, 22 Jun 2021 19:40:26 +0300 Subject: [PATCH 003/179] Minor fixes - return usage of the pointer `this` - added comments regarding {dir, dynam} externder lines handling - adjusted code for the default positioning --- src/floatingobject.cpp | 63 +++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index b07d0217b44..74e1f0010b0 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -334,26 +334,18 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen int minStaffDistance = doc->GetStaffDistance(m_object->GetClassId(), staffIndex, m_place) * doc->GetDrawingUnit(staffSize); if (m_place == STAFFREL_above) { - yRel = GetContentY1(); + yRel = this->GetContentY1(); yRel -= doc->GetBottomMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); - if (m_object->Is({ DIR, DYNAM })) { - SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); - } - else { - SetDrawingYRel(yRel); - SetDrawingYRel(-minStaffDistance); - } + this->SetDrawingYRel(yRel); + this->SetDrawingYRel(m_object->GetMaxDrawingYRel()); + this->SetDrawingYRel(-minStaffDistance); } else { - yRel = staffAlignment->GetStaffHeight() + GetContentY2(); + yRel = staffAlignment->GetStaffHeight() + this->GetContentY2(); yRel += doc->GetTopMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); - if (m_object->Is({ DIR, DYNAM })) { - SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); - } - else { - SetDrawingYRel(yRel); - SetDrawingYRel(minStaffDistance + staffAlignment->GetStaffHeight()); - } + this->SetDrawingYRel(yRel); + this->SetDrawingYRel(m_object->GetMaxDrawingYRel()); + this->SetDrawingYRel(minStaffDistance + staffAlignment->GetStaffHeight()); } } else { @@ -365,9 +357,9 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen if (m_place == STAFFREL_above) { if (curve && curve->m_object->Is({ LV, PHRASE, SLUR, TIE })) { - int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); + const int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); if (shift != 0) { - SetDrawingYRel(GetDrawingYRel() - shift); + this->SetDrawingYRel(this->GetDrawingYRel() - shift); } return true; } @@ -376,46 +368,49 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen // whitespace. For such cases, DYNAM should be compared to individual elements of BEAM instead return true; } - yRel = -staffAlignment->CalcOverflowAbove(horizOverlapingBBox) + GetContentY1() - margin; + yRel = -staffAlignment->CalcOverflowAbove(horizOverlapingBBox) + this->GetContentY1() - margin; Object *object = dynamic_cast(horizOverlapingBBox); + // For elements, that can have extender lines, we need to make sure that they continue in next system on the + // same height, as they were before (even if there are no overlapping elements in subsequent measures) if (m_object->Is({ DIR, DYNAM })) { if (m_object->GetMaxDrawingYRel() > yRel) m_object->SetMaxDrawingYRel(yRel); - SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); + this->SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); } // With LayerElement always move them up else if (object && object->IsLayerElement()) { - if (yRel < 0) SetDrawingYRel(yRel); + if (yRel < 0) this->SetDrawingYRel(yRel); } - // Otherwise only if the is a vertical overlap - else if (VerticalContentOverlap(horizOverlapingBBox, margin)) { - SetDrawingYRel(yRel); + // Otherwise only if there is a vertical overlap + else if (this->VerticalContentOverlap(horizOverlapingBBox, margin)) { + this->SetDrawingYRel(yRel); } } else { if (curve && curve->m_object->Is({ LV, PHRASE, SLUR, TIE })) { - int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); + const int shift = this->Intersects(curve, CONTENT, doc->GetDrawingUnit(staffSize)); if (shift != 0) { - SetDrawingYRel(GetDrawingYRel() - shift); - // LogDebug("Shift %d", shift); + this->SetDrawingYRel(this->GetDrawingYRel() - shift); } return true; } yRel = staffAlignment->CalcOverflowBelow(horizOverlapingBBox) + staffAlignment->GetStaffHeight() - + GetContentY2() + margin; - + + this->GetContentY2() + margin; + Object *object = dynamic_cast(horizOverlapingBBox); + // For elements, that can have extender lines, we need to make sure that they continue in next system on the + // same height, as they were before (even if there are no overlapping elements in subsequent measures) if (m_object->Is({ DIR, DYNAM })) { if (m_object->GetMaxDrawingYRel() < yRel) m_object->SetMaxDrawingYRel(yRel); - SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); + this->SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); } // With LayerElement always move them down else if (object && object->IsLayerElement()) { - if (yRel > 0) SetDrawingYRel(yRel); + if (yRel > 0) this->SetDrawingYRel(yRel); } - // Otherwise only if the is a vertical overlap - else if (VerticalContentOverlap(horizOverlapingBBox, margin)) { - SetDrawingYRel(yRel); + // Otherwise only if there is a vertical overlap + else if (this->VerticalContentOverlap(horizOverlapingBBox, margin)) { + this->SetDrawingYRel(yRel); } } } From ace694e1765858a9d02134487bb812b5a55ed84a Mon Sep 17 00:00:00 2001 From: Monceber Date: Mon, 5 Jul 2021 17:49:47 +0300 Subject: [PATCH 004/179] Change default max drawing yRel value and how it's handled - fixed code around maxDrawingY being 0, which led to invalid rendering in some cases (due to 0 being a valid value and being considered for the positionig); max value is going to be initialized on first set now - added missing group comment for the set/get for max drawingYRel --- include/vrv/floatingobject.h | 8 +++++++- src/floatingobject.cpp | 20 +++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/vrv/floatingobject.h b/include/vrv/floatingobject.h index 3d076f5d033..cc59ffea70e 100644 --- a/include/vrv/floatingobject.h +++ b/include/vrv/floatingobject.h @@ -71,8 +71,14 @@ class FloatingObject : public Object { int SetDrawingGrpObject(void *drawingGrpObject); ///@} - void SetMaxDrawingYRel(int maxDrawingYRel) { m_maxDrawingYRel = maxDrawingYRel; }; + /** + * @name Get and set maximum drawing yRel that is persistent for the floating object across all its floating + * positioners, which allows for persisten vertical positioning for some elements + */ + ///@{ + void SetMaxDrawingYRel(int maxDrawingYRel); int GetMaxDrawingYRel() const { return m_maxDrawingYRel; }; + ///@} //----------// // Functors // diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index 74e1f0010b0..8108921998f 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -60,7 +60,7 @@ FloatingObject::FloatingObject(const std::string &classid) : Object(classid) Reset(); m_currentPositioner = NULL; - m_maxDrawingYRel = 0; + m_maxDrawingYRel = VRV_UNSET; } FloatingObject::~FloatingObject() {} @@ -108,6 +108,18 @@ int FloatingObject::GetDrawingY() const return m_currentPositioner->GetDrawingY(); } +void FloatingObject::SetMaxDrawingYRel(int maxDrawingYRel) +{ + if (!m_currentPositioner) return; + data_STAFFREL drawingPlace = m_currentPositioner->GetDrawingPlace(); + if (drawingPlace == STAFFREL_above) { + if ((m_maxDrawingYRel == VRV_UNSET) || (m_maxDrawingYRel > maxDrawingYRel)) m_maxDrawingYRel = maxDrawingYRel; + } + else { + if ((m_maxDrawingYRel == VRV_UNSET) || (m_maxDrawingYRel < maxDrawingYRel)) m_maxDrawingYRel = maxDrawingYRel; + } +} + void FloatingObject::SetCurrentFloatingPositioner(FloatingPositioner *boundingBox) { m_currentPositioner = boundingBox; @@ -337,14 +349,12 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen yRel = this->GetContentY1(); yRel -= doc->GetBottomMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); this->SetDrawingYRel(yRel); - this->SetDrawingYRel(m_object->GetMaxDrawingYRel()); this->SetDrawingYRel(-minStaffDistance); } else { yRel = staffAlignment->GetStaffHeight() + this->GetContentY2(); yRel += doc->GetTopMargin(m_object->GetClassId()) * doc->GetDrawingUnit(staffSize); this->SetDrawingYRel(yRel); - this->SetDrawingYRel(m_object->GetMaxDrawingYRel()); this->SetDrawingYRel(minStaffDistance + staffAlignment->GetStaffHeight()); } } @@ -374,7 +384,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen // For elements, that can have extender lines, we need to make sure that they continue in next system on the // same height, as they were before (even if there are no overlapping elements in subsequent measures) if (m_object->Is({ DIR, DYNAM })) { - if (m_object->GetMaxDrawingYRel() > yRel) m_object->SetMaxDrawingYRel(yRel); + m_object->SetMaxDrawingYRel(yRel); this->SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); } // With LayerElement always move them up @@ -401,7 +411,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen // For elements, that can have extender lines, we need to make sure that they continue in next system on the // same height, as they were before (even if there are no overlapping elements in subsequent measures) if (m_object->Is({ DIR, DYNAM })) { - if (m_object->GetMaxDrawingYRel() < yRel) m_object->SetMaxDrawingYRel(yRel); + m_object->SetMaxDrawingYRel(yRel); this->SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); } // With LayerElement always move them down From 1d8f7074d019e6bbf1178d233ed8bc961bd4b7d9 Mon Sep 17 00:00:00 2001 From: Klaus Rettinghaus Date: Tue, 13 Jul 2021 10:08:58 +0200 Subject: [PATCH 005/179] use baseline for extensions --- src/view_control.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/view_control.cpp b/src/view_control.cpp index 65a6d1aa1ba..b4023da275c 100644 --- a/src/view_control.cpp +++ b/src/view_control.cpp @@ -1033,8 +1033,6 @@ void View::DrawControlElementConnector( assert(element->GetNextLink() || interface->GetEnd()); if (!element->GetNextLink() && !interface->GetEnd()) return; - int y = element->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 2; - // Adjust the x1 if ((spanningType == SPANNING_START) || (spanningType == SPANNING_START_END)) { if (element->GetCurrentFloatingPositioner() && element->GetCurrentFloatingPositioner()->HasContentBB()) { @@ -1054,6 +1052,7 @@ void View::DrawControlElementConnector( } const int width = m_options->m_lyricLineThickness.GetValue() * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + const int y = element->GetDrawingY() + width / 2; // the length of the dash and the space between them - can be made a parameter const int dashLength = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 4 / 3; From 505eade82730ec6038b40985c71536e978623695 Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 14 Jul 2021 10:49:28 +0300 Subject: [PATCH 006/179] Adjust staff overlap with extender lines - changed code to consider overlaps with extender lines to avoid lines below staff overlapping with elements from next staff --- src/verticalaligner.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index 7d6fc5bf933..596e052f45f 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -953,6 +953,15 @@ int StaffAlignment::AdjustStaffOverlap(FunctorParams *functorParams) while (i != end) { // find all the elements from the bottom staff that have an overflow at the top with an horizontal overlap i = std::find_if(i, end, [iter](BoundingBox *elem) { return (*iter)->HorizontalContentOverlap(elem); }); + i = std::find_if(i, end, [iter](BoundingBox *elem) { + if ((*iter)->Is(FLOATING_POSITIONER)) { + FloatingPositioner *fp = vrv_cast(*iter); + if (fp->GetObject()->Is({ DIR, DYNAM })) { + return (*iter)->HorizontalContentOverlap(elem) || (*iter)->VerticalContentOverlap(elem); + } + } + return (*iter)->HorizontalContentOverlap(elem); + }); if (i != end) { // calculate the vertical overlap and see if this is more than the expected space int overflowBelow = params->m_previous->CalcOverflowBelow(*iter); From 5ecf6e392de020ad4b4c42d393f5a9764390962c Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 14 Jul 2021 14:26:07 +0300 Subject: [PATCH 007/179] Adjust positioning for the extender lines - removed redundant line of code - changed what overflowing elements are used to determite relative positioning of the extender lines --- include/vrv/dir.h | 5 +++++ include/vrv/dynam.h | 5 +++++ include/vrv/floatingobject.h | 5 +++++ include/vrv/object.h | 5 +++++ src/verticalaligner.cpp | 23 ++++++++++++++--------- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/vrv/dir.h b/include/vrv/dir.h index eddc56c8f46..a6043bef21d 100644 --- a/include/vrv/dir.h +++ b/include/vrv/dir.h @@ -60,6 +60,11 @@ class Dir : public ControlElement, */ virtual bool IsSupportedChild(Object *object); + /** + * See FloatingObject::IsExtenderElement + */ + virtual bool IsExtenderElement() const { return GetCurrentSize() == 0; } + //----------// // Functors // //----------// diff --git a/include/vrv/dynam.h b/include/vrv/dynam.h index d94c5885e01..ea824dd5f3b 100644 --- a/include/vrv/dynam.h +++ b/include/vrv/dynam.h @@ -70,6 +70,11 @@ class Dynam : public ControlElement, */ std::wstring GetSymbolStr() const; + /** + * See FloatingObject::IsExtenderElement + */ + virtual bool IsExtenderElement() const { return GetSymbolStr().empty(); } + //----------------// // Static methods // //----------------// diff --git a/include/vrv/floatingobject.h b/include/vrv/floatingobject.h index cc59ffea70e..693695429e1 100644 --- a/include/vrv/floatingobject.h +++ b/include/vrv/floatingobject.h @@ -80,6 +80,11 @@ class FloatingObject : public Object { int GetMaxDrawingYRel() const { return m_maxDrawingYRel; }; ///@} + /** + * Check whether current object represents initial element or extender lines + */ + virtual bool IsExtenderElement() const { return false; } + //----------// // Functors // //----------// diff --git a/include/vrv/object.h b/include/vrv/object.h index e2369e2fdf8..6c32227ae30 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -1394,6 +1394,11 @@ class ObjectListInterface { */ Object *GetListNext(Object *listElement); + /** + * Returns current size of the m_list + */ + int GetCurrentSize() const { return static_cast(m_list.size()); } + /** * Return the list. * Before returning the list, it checks that the list is up-to-date with Object::IsModified diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index 596e052f45f..85e821d4d45 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -616,7 +616,8 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) AdjustFloatingPositionersParams *params = vrv_params_cast(functorParams); assert(params); - int staffSize = this->GetStaffSize(); + const int staffSize = this->GetStaffSize(); + const int drawingUnit = params->m_doc->GetDrawingUnit(staffSize); const bool verseCollapse = params->m_doc->GetOptions()->m_lyricVerseCollapse.GetValue(); if (params->m_classId == SYL) { @@ -624,9 +625,8 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) FontInfo *lyricFont = params->m_doc->GetDrawingLyricFont(m_staff->m_drawingStaffSize); int descender = params->m_doc->GetTextGlyphDescender(L'q', lyricFont, false); int height = params->m_doc->GetTextGlyphHeight(L'I', lyricFont, false); - int margin = params->m_doc->GetBottomMargin(SYL) * params->m_doc->GetDrawingUnit(staffSize); - int minMargin = std::max((int)(params->m_doc->GetOptions()->m_lyricTopMinMargin.GetValue() - * params->m_doc->GetDrawingUnit(staffSize)), + int margin = params->m_doc->GetBottomMargin(SYL) * drawingUnit; + int minMargin = std::max((int)(params->m_doc->GetOptions()->m_lyricTopMinMargin.GetValue() * drawingUnit), this->GetOverflowBelow()); this->SetOverflowBelow(minMargin + this->GetVerseCount(verseCollapse) * (height - descender + margin)); // For now just clear the overflowBelow, which avoids the overlap to be calculated. We could also keep them @@ -703,12 +703,18 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) auto i = overflowBoxes->begin(); auto end = overflowBoxes->end(); while (i != end) { - // find all the overflowing elements from the staff that overlap horizontally - const int margin = ((*iter)->GetObject()->Is(DYNAM) && GetFirstAncestor(BEAM)) + // find all the overflowing elements from the staff that overlap horizontally (and, in case of extender + // elements - vertically) + const int margin = ((*iter)->GetObject()->Is(DYNAM) && GetFirstAncestor(BEAM)) ? params->m_doc->GetDrawingDoubleUnit(m_staff->m_drawingStaffSize) : 0; - i = std::find_if( - i, end, [iter, margin](BoundingBox *elem) { return (*iter)->HorizontalContentOverlap(elem, margin); }); + i = std::find_if(i, end, [iter, drawingUnit, margin](BoundingBox *elem) { + if ((*iter)->GetObject()->IsExtenderElement()) { + return (*iter)->HorizontalContentOverlap(elem, drawingUnit * 8) + || (*iter)->VerticalContentOverlap(elem); + } + return (*iter)->HorizontalContentOverlap(elem, margin); + }); if (i != end) { // update the yRel accordingly (*iter)->CalcDrawingYRel(params->m_doc, this, *i); @@ -952,7 +958,6 @@ int StaffAlignment::AdjustStaffOverlap(FunctorParams *functorParams) auto end = m_overflowAboveBBoxes.end(); while (i != end) { // find all the elements from the bottom staff that have an overflow at the top with an horizontal overlap - i = std::find_if(i, end, [iter](BoundingBox *elem) { return (*iter)->HorizontalContentOverlap(elem); }); i = std::find_if(i, end, [iter](BoundingBox *elem) { if ((*iter)->Is(FLOATING_POSITIONER)) { FloatingPositioner *fp = vrv_cast(*iter); From 0c09a9a95dea1006cbedf8ebc309c42880e1fba0 Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 14 Jul 2021 16:36:14 +0300 Subject: [PATCH 008/179] Change how extender element is tracked - changed condition to take attributes into account instead of symbol/text - reverted code for the ObjectLise size, as it's redundant --- include/vrv/dir.h | 2 +- include/vrv/dynam.h | 2 +- include/vrv/object.h | 5 ----- src/verticalaligner.cpp | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/vrv/dir.h b/include/vrv/dir.h index a6043bef21d..c61f9da4ef1 100644 --- a/include/vrv/dir.h +++ b/include/vrv/dir.h @@ -63,7 +63,7 @@ class Dir : public ControlElement, /** * See FloatingObject::IsExtenderElement */ - virtual bool IsExtenderElement() const { return GetCurrentSize() == 0; } + virtual bool IsExtenderElement() const { return GetExtender() == BOOLEAN_true; } //----------// // Functors // diff --git a/include/vrv/dynam.h b/include/vrv/dynam.h index ea824dd5f3b..4b65a62261a 100644 --- a/include/vrv/dynam.h +++ b/include/vrv/dynam.h @@ -73,7 +73,7 @@ class Dynam : public ControlElement, /** * See FloatingObject::IsExtenderElement */ - virtual bool IsExtenderElement() const { return GetSymbolStr().empty(); } + virtual bool IsExtenderElement() const { return GetExtender() == BOOLEAN_true; } //----------------// // Static methods // diff --git a/include/vrv/object.h b/include/vrv/object.h index 6c32227ae30..e2369e2fdf8 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -1394,11 +1394,6 @@ class ObjectListInterface { */ Object *GetListNext(Object *listElement); - /** - * Returns current size of the m_list - */ - int GetCurrentSize() const { return static_cast(m_list.size()); } - /** * Return the list. * Before returning the list, it checks that the list is up-to-date with Object::IsModified diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index 85e821d4d45..5c09f1acce3 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -709,7 +709,7 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) ? params->m_doc->GetDrawingDoubleUnit(m_staff->m_drawingStaffSize) : 0; i = std::find_if(i, end, [iter, drawingUnit, margin](BoundingBox *elem) { - if ((*iter)->GetObject()->IsExtenderElement()) { + if ((*iter)->GetObject()->IsExtenderElement() && !elem->Is(FLOATING_POSITIONER)) { return (*iter)->HorizontalContentOverlap(elem, drawingUnit * 8) || (*iter)->VerticalContentOverlap(elem); } From 80437b202ce32d849e43a8b8074b41be525a89bd Mon Sep 17 00:00:00 2001 From: Monceber Date: Fri, 16 Jul 2021 10:48:04 +0300 Subject: [PATCH 009/179] Minor fix --- src/verticalaligner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index 5c09f1acce3..e826832e472 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -705,7 +705,7 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) while (i != end) { // find all the overflowing elements from the staff that overlap horizontally (and, in case of extender // elements - vertically) - const int margin = ((*iter)->GetObject()->Is(DYNAM) && GetFirstAncestor(BEAM)) + const int margin = ((*iter)->GetObject()->Is(DYNAM) && GetFirstAncestor(BEAM)) ? params->m_doc->GetDrawingDoubleUnit(m_staff->m_drawingStaffSize) : 0; i = std::find_if(i, end, [iter, drawingUnit, margin](BoundingBox *elem) { From b350437371c06329eb86540ee6c712be9d08f27a Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 21 Jul 2021 16:50:03 +0300 Subject: [PATCH 010/179] Improve cross-staff clurs - adjusted code to improve handling of cross-staff slurs that have more vertical space than horizontal space --- src/slur.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/slur.cpp b/src/slur.cpp index c86c21bdbc4..016bb790d0b 100644 --- a/src/slur.cpp +++ b/src/slur.cpp @@ -197,6 +197,17 @@ bool Slur::AdjustSlurPosition( bezierCurve.SetLeftControlPointOffset(2 * bezierCurve.GetLeftControlPointOffset()); bezierCurve.SetLeftControlHeight(0.5 * bezierCurve.GetLeftControlHeight()); } + if (std::abs(double(bezierCurve.p2.y - bezierCurve.p1.y) / double(bezierCurve.p2.x - bezierCurve.p1.x)) + > 2.0) { + if (((curve->GetDir() == curvature_CURVEDIR_below) && (bezierCurve.p1.y > bezierCurve.p2.y)) + || ((curve->GetDir() == curvature_CURVEDIR_above) && (bezierCurve.p1.y < bezierCurve.p2.y))) { + bezierCurve.SetLeftControlPointOffset(0.5 * bezierCurve.GetLeftControlPointOffset()); + } + else if (((curve->GetDir() == curvature_CURVEDIR_above) && (bezierCurve.p1.y > bezierCurve.p2.y)) + || ((curve->GetDir() == curvature_CURVEDIR_below) && (bezierCurve.p1.y < bezierCurve.p2.y))) { + bezierCurve.SetRightControlPointOffset(0.5 * bezierCurve.GetRightControlPointOffset()); + } + } return true; } else { @@ -311,6 +322,14 @@ std::pair Slur::CalculateAdjustedSlurShift(FloatingCurvePositioner *cu continue; } + // In case of cross-staff, intersection with the note that is in the staff directly under the start/end point + // might result in too big curve or strange slurs. If intersection is bigger than maximum height of the + // cross-staff slur, we should ignore it. + if (curve->IsCrossStaff() + && (intersection > std::max(std::abs(rightPointMaxHeight), std::abs(leftPointMaxHeight)))) { + continue; + } + int xLeft = std::max(bezierCurve.p1.x, spannedElement->m_boundingBox->GetSelfLeft()); int xRight = std::min(bezierCurve.p2.x, spannedElement->m_boundingBox->GetSelfRight()); int xMiddle = xLeft + ((xRight - xLeft) / 2); From af2732cea7041943160a434e031818bd46313f56 Mon Sep 17 00:00:00 2001 From: Alpha Date: Wed, 21 Jul 2021 16:23:56 -0400 Subject: [PATCH 011/179] Support android ndk logging --- src/vrv.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/vrv.cpp b/src/vrv.cpp index 5688a76c6ac..7b67ab79dea 100644 --- a/src/vrv.cpp +++ b/src/vrv.cpp @@ -52,6 +52,11 @@ #include #endif +#ifdef ANDROID +#include +#define android_log_puts(prio, msg) __android_log_print(prio, "Verovio", "%s", msg) +#endif + #define STRING_FORMAT_MAX_LEN 2048 namespace vrv { @@ -402,6 +407,14 @@ void LogString(std::string message, consoleLogLevel level) case CONSOLE_INFO: EM_ASM_ARGS({ console.info(UTF8ToString($0)); }, message.c_str()); break; default: EM_ASM_ARGS({ console.log(UTF8ToString($0)); }, message.c_str()); break; } +#elif defined ANDROID + switch (level) { + case CONSOLE_DEBUG: android_log_puts(ANDROID_LOG_DEBUG, message.c_str()); break; + case CONSOLE_ERROR: android_log_puts(ANDROID_LOG_ERROR, message.c_str()); break; + case CONSOLE_WARN: android_log_puts(ANDROID_LOG_WARN, message.c_str()); break; + case CONSOLE_INFO: + default: android_log_puts(ANDROID_LOG_INFO, message.c_str()); break; + } #else fputs(message.c_str(), stderr); #endif From 866ca0cd0858cbf0a7b33a8497a29736096915ca Mon Sep 17 00:00:00 2001 From: Monceber Date: Thu, 22 Jul 2021 15:02:31 +0300 Subject: [PATCH 012/179] Extender fix - fixed code for overlap to check vertical overlap only for elements that have extender attribute --- include/vrv/functorparams.h | 7 +++++-- src/page.cpp | 2 +- src/verticalaligner.cpp | 12 ++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/vrv/functorparams.h b/include/vrv/functorparams.h index e2f03773053..7e29dd6d69f 100644 --- a/include/vrv/functorparams.h +++ b/include/vrv/functorparams.h @@ -492,17 +492,20 @@ class AdjustSlursParams : public FunctorParams { /** * member 0: a pointer to the previous staff alignment - * member 1: a pointer to the functor for passing it to the system aligner + * member 1: the doc + * member 2: a pointer to the functor for passing it to the system aligner **/ class AdjustStaffOverlapParams : public FunctorParams { public: - AdjustStaffOverlapParams(Functor *functor) + AdjustStaffOverlapParams(Doc *doc, Functor *functor) { m_previous = NULL; + m_doc = doc; m_functor = functor; } StaffAlignment *m_previous; + Doc *m_doc; Functor *m_functor; }; diff --git a/src/page.cpp b/src/page.cpp index c3a9858e226..f6bd6411bc7 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -483,7 +483,7 @@ void Page::LayOutVertically() // Adjust the overlap of the staff aligments by looking at the overflow bounding boxes params.clear(); Functor adjustStaffOverlap(&Object::AdjustStaffOverlap); - AdjustStaffOverlapParams adjustStaffOverlapParams(&adjustStaffOverlap); + AdjustStaffOverlapParams adjustStaffOverlapParams(doc, &adjustStaffOverlap); this->Process(&adjustStaffOverlap, &adjustStaffOverlapParams); // Set the Y position of each StaffAlignment diff --git a/src/verticalaligner.cpp b/src/verticalaligner.cpp index e826832e472..4766b610e1d 100644 --- a/src/verticalaligner.cpp +++ b/src/verticalaligner.cpp @@ -711,7 +711,7 @@ int StaffAlignment::AdjustFloatingPositioners(FunctorParams *functorParams) i = std::find_if(i, end, [iter, drawingUnit, margin](BoundingBox *elem) { if ((*iter)->GetObject()->IsExtenderElement() && !elem->Is(FLOATING_POSITIONER)) { return (*iter)->HorizontalContentOverlap(elem, drawingUnit * 8) - || (*iter)->VerticalContentOverlap(elem); + || (*iter)->VerticalContentOverlap(elem); } return (*iter)->HorizontalContentOverlap(elem, margin); }); @@ -950,6 +950,9 @@ int StaffAlignment::AdjustStaffOverlap(FunctorParams *functorParams) return FUNCTOR_SIBLINGS; } + const int staffSize = this->GetStaffSize(); + const int drawingUnit = params->m_doc->GetDrawingUnit(staffSize); + ArrayOfBoundingBoxes::iterator iter; // go through all the elements of the top staff that have an overflow below for (iter = params->m_previous->m_overflowBelowBBoxes.begin(); @@ -958,11 +961,12 @@ int StaffAlignment::AdjustStaffOverlap(FunctorParams *functorParams) auto end = m_overflowAboveBBoxes.end(); while (i != end) { // find all the elements from the bottom staff that have an overflow at the top with an horizontal overlap - i = std::find_if(i, end, [iter](BoundingBox *elem) { + i = std::find_if(i, end, [iter, drawingUnit](BoundingBox *elem) { if ((*iter)->Is(FLOATING_POSITIONER)) { FloatingPositioner *fp = vrv_cast(*iter); - if (fp->GetObject()->Is({ DIR, DYNAM })) { - return (*iter)->HorizontalContentOverlap(elem) || (*iter)->VerticalContentOverlap(elem); + if (fp->GetObject()->Is({ DIR, DYNAM }) && fp->GetObject()->IsExtenderElement()) { + return (*iter)->HorizontalContentOverlap(elem, drawingUnit * 4) + || (*iter)->VerticalContentOverlap(elem); } } return (*iter)->HorizontalContentOverlap(elem); From 6deab9316280d9eb7c715b2aab2742083121821e Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 23 Jul 2021 08:58:00 +0200 Subject: [PATCH 013/179] Start 3.6.0-dev --- CHANGELOG.md | 2 ++ Verovio.podspec | 2 +- bindings/java/pom.xml | 2 +- bindings/python/.pypi-version | 2 +- codemeta.json | 4 ++-- emscripten/npm/package.json | 2 +- include/vrv/vrvdef.h | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 292b2cacc1d..dbf96d720cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [unreleased] + +## [3.5.0] - 2021-07-22 * Support for `lv` (@eNote-GmbH) * Support for additive meters (@eNote-GmbH) * Support for `bTrem` (bowed tremolos) in the MIDI output (@eNote-GmbH) diff --git a/Verovio.podspec b/Verovio.podspec index 25dfbcdfdb6..0c6561330c7 100644 --- a/Verovio.podspec +++ b/Verovio.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Verovio' - s.version = '3.5.0-dev' + s.version = '3.6.0-dev' s.license = { :type => 'LGPL' } s.homepage = 'https://www.verovio.org/index.xhtml' s.authors = { 'Contributors List' => 'https://github.com/rism-digital/verovio/graphs/contributors' } diff --git a/bindings/java/pom.xml b/bindings/java/pom.xml index c8bce6760fc..22f8ae2dac5 100644 --- a/bindings/java/pom.xml +++ b/bindings/java/pom.xml @@ -4,7 +4,7 @@ org.rism.verovio VerovioToolkit - 3.5.0-dev + 3.6.0-dev jar VerovioToolkit diff --git a/bindings/python/.pypi-version b/bindings/python/.pypi-version index 16d76313f54..5378cc9cb52 100644 --- a/bindings/python/.pypi-version +++ b/bindings/python/.pypi-version @@ -1,3 +1,3 @@ # dummy file used by setup.py for counting revisions when publishing to test.pypi # counting can be reset by making a change to this file -3.5.0 +3.6.0 diff --git a/codemeta.json b/codemeta.json index d201665ad03..0e4b910fd2c 100644 --- a/codemeta.json +++ b/codemeta.json @@ -4,8 +4,8 @@ "identifier": "Verovio", "name": "Verovio", "description": "Verovio is a fast, portable and lightweight open-source library for engraving Music Encoding Initiative (MEI) music scores into SVG.", - "softwareVersion": "3.5.0-dev", - "datePublished": "2021-05-01", + "softwareVersion": "3.6.0-dev", + "datePublished": "2021-07-22", "license": "https://www.gnu.org/licenses/lgpl-3.0", "programmingLanguage": [{ "@type": "ComputerLanguage", diff --git a/emscripten/npm/package.json b/emscripten/npm/package.json index 57fd7d69ba1..8332c206fa6 100644 --- a/emscripten/npm/package.json +++ b/emscripten/npm/package.json @@ -1,6 +1,6 @@ { "name": "verovio", - "version": "3.4.0", + "version": "3.6.0", "description": "This is the stable version of the verovio package", "main": "index.js", "keywords": [ diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 5ed9cb03121..04bf9627db0 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -36,7 +36,7 @@ namespace vrv { //---------------------------------------------------------------------------- #define VERSION_MAJOR 3 -#define VERSION_MINOR 5 +#define VERSION_MINOR 6 #define VERSION_REVISION 0 // Adds "-dev" in the version number - should be set to false for releases #define VERSION_DEV true From f599a7b77aa64e36060258a8ad5f076e32cf3168 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 26 Jul 2021 16:35:22 +0200 Subject: [PATCH 014/179] Bug fix for #2310 --- src/tie.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tie.cpp b/src/tie.cpp index d074b0ad9e4..6037dba92b7 100644 --- a/src/tie.cpp +++ b/src/tie.cpp @@ -229,12 +229,13 @@ void Tie::CalculateXPosition(Doc *doc, Staff *staff, Chord *startParentChord, Ch startPoint.x += r1 + drawingUnit / 2; endPoint.x -= r2 + drawingUnit / 2; } - if (startParentChord && !isOuterChordNote && startParentChord->HasDots()) { + if (startParentChord && !isOuterChordNote && (startParentChord->GetDots() > 0)) { if ((endPoint.x - startPoint.x) <= 4 * drawingUnit) { startPoint.x += drawingUnit; } else { Dots *dots = vrv_cast(startParentChord->FindDescendantByType(DOTS)); + assert(dots); startPoint.x = dots->GetDrawingX() + (1 + startParentChord->GetDots()) * drawingUnit; } } @@ -256,8 +257,9 @@ void Tie::CalculateXPosition(Doc *doc, Staff *staff, Chord *startParentChord, Ch startPoint.x += 2 * drawingUnit * startParentChord->GetDots(); } } - if (startParentChord && !isOuterChordNote && startParentChord->HasDots()) { + if (startParentChord && !isOuterChordNote && (startParentChord->GetDots() > 0)) { Dots *dots = vrv_cast(startParentChord->FindDescendantByType(DOTS)); + assert(dots); startPoint.x = dots->GetDrawingX() + (1 + startParentChord->GetDots()) * drawingUnit; } endPoint.x -= (drawingUnit + doc->GetDrawingBarLineWidth(staff->m_drawingStaffSize)) / 2; From 6edf783bec379d6c27e44e52e121a930ee02c8db Mon Sep 17 00:00:00 2001 From: Monceber Date: Tue, 27 Jul 2021 12:51:05 +0300 Subject: [PATCH 015/179] Add spacing between tied notes in chords - added code to increase offset between tied notes in chords to avoid ties being rendered in unrecognizable ways --- include/vrv/functorparams.h | 2 ++ include/vrv/measure.h | 8 +++++++- src/layerelement.cpp | 5 +++++ src/measure.cpp | 22 ++++++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/vrv/functorparams.h b/include/vrv/functorparams.h index e2f03773053..29892cd5369 100644 --- a/include/vrv/functorparams.h +++ b/include/vrv/functorparams.h @@ -674,6 +674,7 @@ class AdjustXPosParams : public FunctorParams { m_functorEnd = functorEnd; m_currentAlignment.Reset(); m_previousAlignment.Reset(); + m_measureTieEndpoints.clear(); } int m_minPos; int m_upcomingMinPos; @@ -685,6 +686,7 @@ class AdjustXPosParams : public FunctorParams { std::vector m_upcomingBoundingBoxes; std::vector m_includes; std::vector m_excludes; + std::vector m_measureTieEndpoints; Doc *m_doc; Functor *m_functor; Functor *m_functorEnd; diff --git a/include/vrv/measure.h b/include/vrv/measure.h index 953e38b9d0d..c2ee7b9253e 100644 --- a/include/vrv/measure.h +++ b/include/vrv/measure.h @@ -16,8 +16,9 @@ namespace vrv { -class Ending; class ControlElement; +class Ending; +class LayerElement; class ScoreDef; class System; class TimestampAttr; @@ -245,6 +246,11 @@ class Measure : public Object, */ double GetRealTimeOffsetMilliseconds(int repeat) const; + /** + * Return vector with tie endpoints for ties that start and end in current measure + */ + std::vector GetInternalTieEndpoints(); + //----------// // Functors // //----------// diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 6740b3b0f0a..c9d66249544 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -1814,6 +1814,11 @@ int LayerElement::AdjustXPos(FunctorParams *functorParams) } offset = std::min(offset, selfLeft - params->m_minPos); + if ((std::find(params->m_measureTieEndpoints.begin(), params->m_measureTieEndpoints.end(), this) + != params->m_measureTieEndpoints.end()) + && (GetFirstAncestor(CHORD) != NULL) && (offset >= 0)) { + offset = -drawingUnit; + } if (offset < 0) { this->GetAlignment()->SetXRel(this->GetAlignment()->GetXRel() - offset); // Also move the accumulated x shift and the minimum position for the next alignment accordingly diff --git a/src/measure.cpp b/src/measure.cpp index bcef96b8ef4..836f1bc5fa8 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -29,6 +29,7 @@ #include "syl.h" #include "system.h" #include "tempo.h" +#include "tie.h" #include "timeinterface.h" #include "timestamp.h" #include "vrv.h" @@ -618,6 +619,26 @@ void Measure::SetInvisibleStaffBarlines( } } +std::vector Measure::GetInternalTieEndpoints() +{ + ListOfObjects children; + ClassIdComparison comp(TIE); + this->FindAllDescendantByComparison(&children, &comp); + + std::vector endpoints; + for (Object *object : children) { + Tie *tie = vrv_cast(object); + // If both start and end points of the tie are not within current measure - skip it + LayerElement *start = tie->GetStart(); + if (!start || (start->GetFirstAncestor(MEASURE) != this)) continue; + LayerElement *end = tie->GetEnd(); + if (!end || (end->GetFirstAncestor(MEASURE) != this)) continue; + endpoints.push_back(end); + } + + return endpoints; +} + //---------------------------------------------------------------------------- // Measure functor methods //---------------------------------------------------------------------------- @@ -992,6 +1013,7 @@ int Measure::AdjustXPos(FunctorParams *functorParams) AttNIntegerAnyComparison matchStaff(ALIGNMENT_REFERENCE, ns); filters.push_back(&matchStaff); + params->m_measureTieEndpoints = this->GetInternalTieEndpoints(); m_measureAligner.Process(params->m_functor, params, params->m_functorEnd, &filters); } From b8a80f471194467ed42ba65d85ce6bb6bfc27791 Mon Sep 17 00:00:00 2001 From: Klaus Rettinghaus Date: Tue, 27 Jul 2021 12:27:25 +0200 Subject: [PATCH 016/179] fix layout detection --- src/iomusxml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iomusxml.cpp b/src/iomusxml.cpp index d6aaeb41821..fba2103987e 100644 --- a/src/iomusxml.cpp +++ b/src/iomusxml.cpp @@ -767,7 +767,7 @@ bool MusicXmlInput::ReadMusicXml(pugi::xml_node root) Section *section = new Section(); score->AddChild(section); // initialize layout - if (root.select_node("/score-partwise/part/measure/print")) { + if (root.select_node("/score-partwise/part/measure/print[@new-system or @new-page]")) { m_hasLayoutInformation = true; if (!root.select_node("/score-partwise/part[1]/measure[1]/print[@new-system or @new-page]")) { // always start with a new page From 88773f93cbc9ed70eeba0753c9542a2f5e444143 Mon Sep 17 00:00:00 2001 From: Monceber Date: Tue, 27 Jul 2021 18:51:25 +0300 Subject: [PATCH 017/179] Minor fix - extend comments for the AdjustXPosParams --- include/vrv/functorparams.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/vrv/functorparams.h b/include/vrv/functorparams.h index 29892cd5369..394b982c159 100644 --- a/include/vrv/functorparams.h +++ b/include/vrv/functorparams.h @@ -652,11 +652,14 @@ class AdjustXPosAlignmentOffset { * member 5: the list of staffN in the top-level scoreDef * member 6: the bounding box in the previous aligner * member 7: the upcoming bounding boxes (to be used in the next aligner) - * member 8: the Doc - * member 9: the Functor for redirection to the MeasureAligner - * member 10: the end Functor for redirection - * member 11: current aligner that is being processed - * member 12: preceeding aligner that was handled before + * member 8: list of types to include + * member 9: list of types to exclude + * member 10: list of tie endpoints for the current measure + * member 11: the Doc + * member 12: the Functor for redirection to the MeasureAligner + * member 13: the end Functor for redirection + * member 14: current aligner that is being processed + * member 15: preceeding aligner that was handled before **/ class AdjustXPosParams : public FunctorParams { From 3c4bbb24d503c335d06db81397c2a0e430eb1878 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 28 Jul 2021 08:49:37 +0200 Subject: [PATCH 018/179] Add support for att.section.vis to section --- include/vrv/section.h | 3 ++- src/iomei.cpp | 2 ++ src/section.cpp | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/vrv/section.h b/include/vrv/section.h index 4c00d358247..117411d72c4 100644 --- a/include/vrv/section.h +++ b/include/vrv/section.h @@ -9,6 +9,7 @@ #define __VRV_SECTION_H__ #include "atts_shared.h" +#include "atts_visual.h" #include "boundary.h" #include "systemelement.h" @@ -24,7 +25,7 @@ class Section; * This class represents a MEI section. * It can be both a container (in score-based MEI) and a boundary (in page-based MEI) */ -class Section : public SystemElement, public BoundaryStartInterface, public AttNNumberLike { +class Section : public SystemElement, public BoundaryStartInterface, public AttNNumberLike, public AttSectionVis { public: /** * @name Constructors, destructors, and other standard methods diff --git a/src/iomei.cpp b/src/iomei.cpp index 55da1c99834..93417618bbe 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -1016,6 +1016,7 @@ void MEIOutput::WriteSection(pugi::xml_node currentNode, Section *section) WriteSystemElement(currentNode, section); section->WriteNNumberLike(currentNode); + section->WriteSectionVis(currentNode); } void MEIOutput::WriteEnding(pugi::xml_node currentNode, Ending *ending) @@ -3263,6 +3264,7 @@ bool MEIInput::ReadSection(Object *parent, pugi::xml_node section) SetMeiUuid(section, vrvSection); vrvSection->ReadNNumberLike(section); + vrvSection->ReadSectionVis(section); parent->AddChild(vrvSection); ReadUnsupportedAttr(section, vrvSection); diff --git a/src/section.cpp b/src/section.cpp index 48f03a89b61..4deffc7f719 100644 --- a/src/section.cpp +++ b/src/section.cpp @@ -32,9 +32,10 @@ namespace vrv { static const ClassRegistrar
s_factory("section", SECTION); -Section::Section() : SystemElement("section-"), BoundaryStartInterface(), AttNNumberLike() +Section::Section() : SystemElement("section-"), BoundaryStartInterface(), AttNNumberLike(), AttSectionVis() { RegisterAttClass(ATT_NNUMBERLIKE); + RegisterAttClass(ATT_SECTIONVIS); Reset(); } @@ -46,6 +47,7 @@ void Section::Reset() SystemElement::Reset(); BoundaryStartInterface::Reset(); ResetNNumberLike(); + ResetSectionVis(); } bool Section::IsSupportedChild(Object *child) From 7a66142e27f011cddcab5c442baf40756c540633 Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 28 Jul 2021 14:45:15 +0300 Subject: [PATCH 019/179] Update code to adjust only short ties - fixed an issue with tie being adjusted even if there was enough space to draw a proper tie - alignment now will only be shifted if there is not enough space --- include/vrv/functorparams.h | 2 +- include/vrv/measure.h | 2 +- src/layerelement.cpp | 19 ++++++++++++++----- src/measure.cpp | 6 +++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/vrv/functorparams.h b/include/vrv/functorparams.h index 394b982c159..9ef8204829c 100644 --- a/include/vrv/functorparams.h +++ b/include/vrv/functorparams.h @@ -689,7 +689,7 @@ class AdjustXPosParams : public FunctorParams { std::vector m_upcomingBoundingBoxes; std::vector m_includes; std::vector m_excludes; - std::vector m_measureTieEndpoints; + std::vector> m_measureTieEndpoints; Doc *m_doc; Functor *m_functor; Functor *m_functorEnd; diff --git a/include/vrv/measure.h b/include/vrv/measure.h index c2ee7b9253e..55d1fe698ae 100644 --- a/include/vrv/measure.h +++ b/include/vrv/measure.h @@ -249,7 +249,7 @@ class Measure : public Object, /** * Return vector with tie endpoints for ties that start and end in current measure */ - std::vector GetInternalTieEndpoints(); + std::vector> GetInternalTieEndpoints(); //----------// // Functors // diff --git a/src/layerelement.cpp b/src/layerelement.cpp index c9d66249544..a4183f076d1 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -1814,11 +1814,6 @@ int LayerElement::AdjustXPos(FunctorParams *functorParams) } offset = std::min(offset, selfLeft - params->m_minPos); - if ((std::find(params->m_measureTieEndpoints.begin(), params->m_measureTieEndpoints.end(), this) - != params->m_measureTieEndpoints.end()) - && (GetFirstAncestor(CHORD) != NULL) && (offset >= 0)) { - offset = -drawingUnit; - } if (offset < 0) { this->GetAlignment()->SetXRel(this->GetAlignment()->GetXRel() - offset); // Also move the accumulated x shift and the minimum position for the next alignment accordingly @@ -1851,6 +1846,20 @@ int LayerElement::AdjustXPos(FunctorParams *functorParams) params->m_upcomingMinPos = std::max(selfRight, params->m_upcomingMinPos); } + auto it = std::find_if(params->m_measureTieEndpoints.begin(), params->m_measureTieEndpoints.end(), + [this](const std::pair &pair) { return pair.second == this; }); + if ((it != params->m_measureTieEndpoints.end()) && (GetFirstAncestor(CHORD) != NULL)) { + const int minTiedDistance = 7 * drawingUnit; + const int alignmentDistance = it->second->GetAlignment()->GetXRel() - it->first->GetAlignment()->GetXRel(); + if (alignmentDistance < minTiedDistance) { + const int adjust = minTiedDistance - alignmentDistance; + this->GetAlignment()->SetXRel(this->GetAlignment()->GetXRel() + adjust); + // Also move the accumulated x shift and the minimum position for the next alignment accordingly + params->m_cumulatedXShift += adjust; + params->m_upcomingMinPos += adjust; + } + } + return FUNCTOR_SIBLINGS; } diff --git a/src/measure.cpp b/src/measure.cpp index 836f1bc5fa8..f5a825d3c88 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -619,13 +619,13 @@ void Measure::SetInvisibleStaffBarlines( } } -std::vector Measure::GetInternalTieEndpoints() +std::vector> Measure::GetInternalTieEndpoints() { ListOfObjects children; ClassIdComparison comp(TIE); this->FindAllDescendantByComparison(&children, &comp); - std::vector endpoints; + std::vector> endpoints; for (Object *object : children) { Tie *tie = vrv_cast(object); // If both start and end points of the tie are not within current measure - skip it @@ -633,7 +633,7 @@ std::vector Measure::GetInternalTieEndpoints() if (!start || (start->GetFirstAncestor(MEASURE) != this)) continue; LayerElement *end = tie->GetEnd(); if (!end || (end->GetFirstAncestor(MEASURE) != this)) continue; - endpoints.push_back(end); + endpoints.emplace_back(start, end); } return endpoints; From 5753fd1de35779713a72048acc924123e859cc80 Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 28 Jul 2021 15:17:32 +0300 Subject: [PATCH 020/179] Extend condition to cover ties that start at note with flag - this should fix barely disitnguishable ties that start at notes with short duration (i.e. flagged ones) --- src/layerelement.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/layerelement.cpp b/src/layerelement.cpp index a4183f076d1..b0325903af3 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -1848,10 +1848,11 @@ int LayerElement::AdjustXPos(FunctorParams *functorParams) auto it = std::find_if(params->m_measureTieEndpoints.begin(), params->m_measureTieEndpoints.end(), [this](const std::pair &pair) { return pair.second == this; }); - if ((it != params->m_measureTieEndpoints.end()) && (GetFirstAncestor(CHORD) != NULL)) { + if (it != params->m_measureTieEndpoints.end()) { const int minTiedDistance = 7 * drawingUnit; const int alignmentDistance = it->second->GetAlignment()->GetXRel() - it->first->GetAlignment()->GetXRel(); - if (alignmentDistance < minTiedDistance) { + if ((alignmentDistance < minTiedDistance) + && ((this->GetFirstAncestor(CHORD) != NULL) || (it->first->FindDescendantByType(FLAG) != NULL))) { const int adjust = minTiedDistance - alignmentDistance; this->GetAlignment()->SetXRel(this->GetAlignment()->GetXRel() + adjust); // Also move the accumulated x shift and the minimum position for the next alignment accordingly From 03c4a15eebde614845278b36fcba41af901daa06 Mon Sep 17 00:00:00 2001 From: Monceber Date: Wed, 28 Jul 2021 16:54:28 +0300 Subject: [PATCH 021/179] Minor fix - changed code to use maxDrawingYRel only for extender objects --- src/floatingobject.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index 8108921998f..644ab515e16 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -383,7 +383,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen Object *object = dynamic_cast(horizOverlapingBBox); // For elements, that can have extender lines, we need to make sure that they continue in next system on the // same height, as they were before (even if there are no overlapping elements in subsequent measures) - if (m_object->Is({ DIR, DYNAM })) { + if (m_object->Is({ DIR, DYNAM }) && m_object->IsExtenderElement()) { m_object->SetMaxDrawingYRel(yRel); this->SetDrawingYRel(std::min(yRel, m_object->GetMaxDrawingYRel())); } @@ -410,7 +410,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen Object *object = dynamic_cast(horizOverlapingBBox); // For elements, that can have extender lines, we need to make sure that they continue in next system on the // same height, as they were before (even if there are no overlapping elements in subsequent measures) - if (m_object->Is({ DIR, DYNAM })) { + if (m_object->Is({ DIR, DYNAM }) && m_object->IsExtenderElement()) { m_object->SetMaxDrawingYRel(yRel); this->SetDrawingYRel(std::max(yRel, m_object->GetMaxDrawingYRel())); } From ffffdcf64c46952438e7aa0a84b6f1dfd41d152f Mon Sep 17 00:00:00 2001 From: Monceber Date: Thu, 29 Jul 2021 16:27:08 +0300 Subject: [PATCH 022/179] Formatting fix --- include/vrv/floatingobject.h | 4 ++-- src/floatingobject.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/vrv/floatingobject.h b/include/vrv/floatingobject.h index 693695429e1..62999e89b91 100644 --- a/include/vrv/floatingobject.h +++ b/include/vrv/floatingobject.h @@ -70,7 +70,7 @@ class FloatingObject : public Object { void SetDrawingGrpId(int drawingGrpId) { m_drawingGrpId = drawingGrpId; } int SetDrawingGrpObject(void *drawingGrpObject); ///@} - + /** * @name Get and set maximum drawing yRel that is persistent for the floating object across all its floating * positioners, which allows for persisten vertical positioning for some elements @@ -138,7 +138,7 @@ class FloatingObject : public Object { /* Drawing Id to group floating elements horizontally */ int m_drawingGrpId; - + int m_maxDrawingYRel; //----------------// diff --git a/src/floatingobject.cpp b/src/floatingobject.cpp index 644ab515e16..f75a1081443 100644 --- a/src/floatingobject.cpp +++ b/src/floatingobject.cpp @@ -379,7 +379,7 @@ bool FloatingPositioner::CalcDrawingYRel(Doc *doc, StaffAlignment *staffAlignmen return true; } yRel = -staffAlignment->CalcOverflowAbove(horizOverlapingBBox) + this->GetContentY1() - margin; - + Object *object = dynamic_cast(horizOverlapingBBox); // For elements, that can have extender lines, we need to make sure that they continue in next system on the // same height, as they were before (even if there are no overlapping elements in subsequent measures) From 99204ed0269813380e81de027e53cd72b9c79da9 Mon Sep 17 00:00:00 2001 From: Monceber Date: Thu, 29 Jul 2021 18:22:49 +0300 Subject: [PATCH 023/179] Add handling of whole note collision --- src/layerelement.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 6740b3b0f0a..5349e28dcdb 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -1552,10 +1552,10 @@ std::pair LayerElement::CalcElementHorizontalOverlap(Doc *doc, Note *previousNote = vrv_cast(otherElements.at(i)); assert(previousNote); isUnisonElement = currentNote->IsUnisonWith(previousNote, true); + const bool isPreviousCoord = previousNote->GetParent()->Is(CHORD); // Unisson, look at the duration for the note heads if (unison && currentNote->IsUnisonWith(previousNote, false)) { int previousDuration = previousNote->GetDrawingDur(); - const bool isPreviousCoord = previousNote->GetParent()->Is(CHORD); bool isEdgeElement = false; if (isPreviousCoord) { Chord *parentChord = vrv_cast(previousNote->GetParent()); @@ -1642,6 +1642,18 @@ std::pair LayerElement::CalcElementHorizontalOverlap(Doc *doc, - HorizontalRightOverlap(otherElements.at(i), doc, horizontalMargin - shift, verticalMargin); } } + else if (Note *currentNote = vrv_cast(this); + Is(NOTE) && (currentNote->GetDrawingDur() == DUR_1) && otherElements.at(i)->Is(STEM)) { + const int horizontalMargin = doc->GetDrawingStemWidth(staff->m_drawingStaffSize); + Stem *stem = vrv_cast(otherElements.at(i)); + data_STEMDIRECTION stemDir = stem->GetDrawingStemDir(); + if (this->HorizontalLeftOverlap(otherElements.at(i), doc, 0, 0) != 0) { + shift = 3 * horizontalMargin; + if (stemDir == STEMDIRECTION_up) { + shift *= -1; + } + } + } } // If note is not in unison, has accidental and were to be shifted to the right - shift it to the left From 149517ed7c376a370da7cf1bebb96765ce7cbb26 Mon Sep 17 00:00:00 2001 From: Monceber Date: Fri, 30 Jul 2021 18:00:12 +0300 Subject: [PATCH 024/179] Minor fix - remove redundat change --- src/layerelement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 5349e28dcdb..94da54f9c7b 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -1552,10 +1552,10 @@ std::pair LayerElement::CalcElementHorizontalOverlap(Doc *doc, Note *previousNote = vrv_cast(otherElements.at(i)); assert(previousNote); isUnisonElement = currentNote->IsUnisonWith(previousNote, true); - const bool isPreviousCoord = previousNote->GetParent()->Is(CHORD); // Unisson, look at the duration for the note heads if (unison && currentNote->IsUnisonWith(previousNote, false)) { int previousDuration = previousNote->GetDrawingDur(); + const bool isPreviousCoord = previousNote->GetParent()->Is(CHORD); bool isEdgeElement = false; if (isPreviousCoord) { Chord *parentChord = vrv_cast(previousNote->GetParent()); From 4262c260bcfc44a00c3cf684c2a232e018a94aa9 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:22:34 +0200 Subject: [PATCH 025/179] Add grpSym to space when drawing labels --- src/view_page.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view_page.cpp b/src/view_page.cpp index d8cce055e5c..2031617ef70 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -325,7 +325,9 @@ void View::DrawStaffGrp( DrawVerticalLine(dc, yTop, yBottom, x + barLineWidth / 2, barLineWidth); } // draw the group symbol + int staffGrpX = x; DrawGrpSym(dc, measure, staffGrp, x); + int grpSymSpace = staffGrpX - x; // recursively draw the children StaffGrp *childStaffGrp = NULL; @@ -341,7 +343,7 @@ void View::DrawStaffGrp( const int space = m_doc->GetDrawingDoubleUnit(staffGrp->GetMaxStaffSize()); int xLabel = x - space; int yLabel = yBottom - (yBottom - yTop) / 2 - m_doc->GetDrawingUnit(100); - this->DrawLabels(dc, system, staffGrp, xLabel, yLabel, abbreviations, 100, 2 * space); + this->DrawLabels(dc, scoreDef, staffGrp, xLabel, yLabel, abbreviations, 100, 2 * space + grpSymSpace); DrawStaffDefLabels(dc, measure, staffGrp, x, abbreviations); } From 32044e2e769d2ab9286e5778e54fb5764be5be36 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:25:26 +0200 Subject: [PATCH 026/179] Moving m_drawingLabelsWidth to ScoreDef --- include/vrv/scoredef.h | 10 ++++++++++ include/vrv/system.h | 6 ++---- src/scoredef.cpp | 15 +++++++++++++++ src/system.cpp | 13 ++++++++----- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 227393a39a9..b19fb2e82eb 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -178,6 +178,9 @@ class ScoreDef : public ScoreDefElement, void SetDrawingWidth(int drawingWidth); ///@} + int GetDrawingLabelsWidth() const { return m_drawingLabelsWidth; } + void SetDrawingLabelsWidth(int width); + /** * @name Getters for running elements */ @@ -197,6 +200,11 @@ class ScoreDef : public ScoreDefElement, // Functors // //----------// + /** + * See Object::ResetHorizontalAlignment + */ + virtual int ResetHorizontalAlignment(FunctorParams *functorParams); + /** * See Object::ConvertToPageBased */ @@ -230,6 +238,8 @@ class ScoreDef : public ScoreDefElement, bool m_drawLabels; /** Store the drawing width (clef and key sig) of the scoreDef */ int m_drawingWidth; + /** Store the label drawing width of the scoreDef */ + int m_drawingLabelsWidth; }; } // namespace vrv diff --git a/include/vrv/system.h b/include/vrv/system.h index f2f657c8266..f7b90420cb0 100644 --- a/include/vrv/system.h +++ b/include/vrv/system.h @@ -76,7 +76,7 @@ class System : public Object, public DrawingListInterface, public AttTyped { * @name Set and get the labels drawing width (normal and abbreviated) */ ///@{ - int GetDrawingLabelsWidth() const { return m_drawingLabelsWidth; } + int GetDrawingLabelsWidth() const; void SetDrawingLabelsWidth(int width); int GetDrawingAbbrLabelsWidth() const { return m_drawingAbbrLabelsWidth; } void SetDrawingAbbrLabelsWidth(int width); @@ -292,11 +292,9 @@ class System : public Object, public DrawingListInterface, public AttTyped { */ int m_xAbs; /** - * The width used by the labels at the left of the system. + * The width used by the abbreviated labels at the left of the system. * It is used internally when calculating the layout and it is not stored in the file. */ - int m_drawingLabelsWidth; - /** The width used by the abbreviated labels */ int m_drawingAbbrLabelsWidth; /** * @name The total width of the system. diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 92b3d9a134a..35c88d6e941 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -197,6 +197,7 @@ void ScoreDef::Reset() m_drawLabels = false; m_drawingWidth = 0; + m_drawingLabelsWidth = 0; m_setAsDrawing = false; } @@ -403,6 +404,13 @@ void ScoreDef::SetDrawingWidth(int drawingWidth) m_drawingWidth = drawingWidth; } +void ScoreDef::SetDrawingLabelsWidth(int width) +{ + if (m_drawingLabelsWidth < width) { + m_drawingLabelsWidth = width; + } +} + PgFoot *ScoreDef::GetPgFoot() { return dynamic_cast(this->FindDescendantByType(PGFOOT)); @@ -433,6 +441,13 @@ int ScoreDef::GetMaxStaffSize() // Functors methods //---------------------------------------------------------------------------- +int ScoreDef::ResetHorizontalAlignment(FunctorParams *functorParams) +{ + m_drawingLabelsWidth = 0; + + return FUNCTOR_CONTINUE; +} + int ScoreDef::ConvertToPageBased(FunctorParams *functorParams) { ConvertToPageBasedParams *params = vrv_params_cast(functorParams); diff --git a/src/system.cpp b/src/system.cpp index 5231abc4503..b4d2f4b15eb 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -78,7 +78,6 @@ void System::Reset() m_drawingYRel = 0; m_drawingTotalWidth = 0; m_drawingJustifiableWidth = 0; - m_drawingLabelsWidth = 0; m_drawingAbbrLabelsWidth = 0; m_drawingIsOptimized = false; } @@ -152,11 +151,16 @@ int System::GetMinimumSystemSpacing(const Doc *doc) const return spacingSystem.GetValue() * doc->GetDrawingUnit(100); } +int System::GetDrawingLabelsWidth() const +{ + assert(m_drawingScoreDef); + return m_drawingScoreDef->GetDrawingLabelsWidth(); +} + void System::SetDrawingLabelsWidth(int width) { - if (m_drawingLabelsWidth < width) { - m_drawingLabelsWidth = width; - } + assert(m_drawingScoreDef); + m_drawingScoreDef->SetDrawingLabelsWidth(width); } void System::SetDrawingAbbrLabelsWidth(int width) @@ -399,7 +403,6 @@ int System::ScoreDefSetGrpSym(FunctorParams *functorParams) int System::ResetHorizontalAlignment(FunctorParams *functorParams) { SetDrawingXRel(0); - m_drawingLabelsWidth = 0; m_drawingAbbrLabelsWidth = 0; return FUNCTOR_CONTINUE; From 6f011495be7d258cef3fa9a801bdeea84ea990e9 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:26:46 +0200 Subject: [PATCH 027/179] Storing labelswidth in scoreDef --- include/vrv/view.h | 4 ++-- src/view_page.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 897d6efb3bd..692b4de543c 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -195,8 +195,8 @@ class View { void DrawStaffDefCautionary(DeviceContext *dc, Staff *staff, Measure *measure); void DrawStaffDefLabels(DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int x, bool abbreviations = false); void DrawGrpSym(DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int &x); - void DrawLabels( - DeviceContext *dc, System *system, Object *object, int x, int y, bool abbreviations, int staffSize, int space); + void DrawLabels(DeviceContext *dc, ScoreDef *scoreDef, Object *object, int x, int y, bool abbreviations, + int staffSize, int space); void DrawBracket(DeviceContext *dc, int x, int y1, int y2, int staffSize); void DrawBracketsq(DeviceContext *dc, int x, int y1, int y2, int staffSize); void DrawBrace(DeviceContext *dc, int x, int y1, int y2, int staffSize); diff --git a/src/view_page.cpp b/src/view_page.cpp index 2031617ef70..bb933963d3a 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -339,7 +339,7 @@ void View::DrawStaffGrp( } // DrawStaffGrpLabel - System *system = dynamic_cast(measure->GetFirstAncestor(SYSTEM)); + ScoreDef *scoreDef = dynamic_cast(staffGrp->GetFirstAncestor(SCOREDEF)); const int space = m_doc->GetDrawingDoubleUnit(staffGrp->GetMaxStaffSize()); int xLabel = x - space; int yLabel = yBottom - (yBottom - yTop) / 2 - m_doc->GetDrawingUnit(100); @@ -364,10 +364,10 @@ void View::DrawStaffDefLabels(DeviceContext *dc, Measure *measure, StaffGrp *sta AttNIntegerComparison comparison(STAFF, staffDef->GetN()); Staff *staff = dynamic_cast(measure->FindDescendantByComparison(&comparison, 1)); - System *system = dynamic_cast(measure->GetFirstAncestor(SYSTEM)); + ScoreDef *scoreDef = dynamic_cast(staffGrp->GetFirstAncestor(SCOREDEF)); - if (!staff || !system) { - LogDebug("Staff or System missing in View::DrawStaffDefLabels"); + if (!staff || !scoreDef) { + LogDebug("Staff or ScoreDef missing in View::DrawStaffDefLabels"); continue; } @@ -380,7 +380,7 @@ void View::DrawStaffDefLabels(DeviceContext *dc, Measure *measure, StaffGrp *sta int y = staff->GetDrawingY() - (staffDef->GetLines() * m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) / 2); - this->DrawLabels(dc, system, staffDef, x - space, y, abbreviations, staff->m_drawingStaffSize, 2 * space); + this->DrawLabels(dc, scoreDef, staffDef, x - space, y, abbreviations, staff->m_drawingStaffSize, 2 * space); } } @@ -444,7 +444,7 @@ void View::DrawGrpSym(DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, i } void View::DrawLabels( - DeviceContext *dc, System *system, Object *object, int x, int y, bool abbreviations, int staffSize, int space) + DeviceContext *dc, ScoreDef *scoreDef, Object *object, int x, int y, bool abbreviations, int staffSize, int space) { assert(dc); assert(system); @@ -494,7 +494,7 @@ void View::DrawLabels( dc->EndGraphic(graphic, this); // keep the widest width for the system - careful: this can be the label OR labelAbbr - system->SetDrawingLabelsWidth(graphic->GetContentX2() - graphic->GetContentX1() + space); + scoreDef->SetDrawingLabelsWidth(graphic->GetContentX2() - graphic->GetContentX1() + space); // also store in the system the maximum width with abbreviations for justification if (labelAbbr && !abbreviations && (labelAbbrStr.length() > 0)) { TextExtend extend; @@ -505,7 +505,7 @@ void View::DrawLabels( dc->GetTextExtent(line, &extend, true); maxLength = (extend.m_width > maxLength) ? extend.m_width : maxLength; } - system->SetDrawingAbbrLabelsWidth(maxLength + space); + /// system->SetDrawingAbbrLabelsWidth(maxLength + space); } dc->ResetFont(); From 02bdfe0092c8e4cc23bcbb73b4bdff9f7db9e245 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:29:03 +0200 Subject: [PATCH 028/179] Call ScoreDefSetGrpSymDoc in View::SetPage * Also make it go trough the entire Doc to reach intermediate ScoreDef --- src/system.cpp | 2 +- src/view.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system.cpp b/src/system.cpp index b4d2f4b15eb..0f753c37501 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -397,7 +397,7 @@ int System::ScoreDefSetGrpSym(FunctorParams *functorParams) if (m_drawingScoreDef) m_drawingScoreDef->Process(params->m_functor, functorParams); - return FUNCTOR_SIBLINGS; + return FUNCTOR_CONTINUE; } int System::ResetHorizontalAlignment(FunctorParams *functorParams) diff --git a/src/view.cpp b/src/view.cpp index b1fb535d496..2f5d1d3609b 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -73,6 +73,7 @@ void View::SetPage(int pageIdx, bool doLayout) if (doLayout) { m_doc->ScoreDefSetCurrentDoc(); + m_doc->ScoreDefSetGrpSymDoc(); // if we once deal with multiple views, it would be better // to redo the layout only when necessary? if (m_doc->GetType() == Transcription || m_doc->GetType() == Facs) From 5282f6088916d7915e6541b3d18295395f66e33e Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:30:56 +0200 Subject: [PATCH 029/179] Adjust ScoreDefSetCurrent to take into account scoreDef with restart --- include/vrv/functorparams.h | 8 +++++++- include/vrv/scoredef.h | 1 + src/object.cpp | 30 ++++++++++++++++++++++++++++-- src/scoredef.cpp | 5 +++++ src/view_page.cpp | 5 +++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/vrv/functorparams.h b/include/vrv/functorparams.h index e2f03773053..5c0470a25c3 100644 --- a/include/vrv/functorparams.h +++ b/include/vrv/functorparams.h @@ -2111,7 +2111,9 @@ class ScoreDefOptimizeParams : public FunctorParams { * member 3: the previous measure (for setting cautionary scoreDef) * member 4: the current system (for setting the system scoreDef) * member 5: the flag indicating whereas full labels have to be drawn - * member 6: the doc + * member 6: the flag indicating that the scoreDef restarts (draw brace and label) + * member 7: the flag indicating is we already have a measure in the system + * member 8: the doc **/ class ScoreDefSetCurrentParams : public FunctorParams { @@ -2124,6 +2126,8 @@ class ScoreDefSetCurrentParams : public FunctorParams { m_previousMeasure = NULL; m_currentSystem = NULL; m_drawLabels = false; + m_restart = false; + m_hasMeasure = false; m_doc = doc; } ScoreDef *m_currentScoreDef; @@ -2132,6 +2136,8 @@ class ScoreDefSetCurrentParams : public FunctorParams { Measure *m_previousMeasure; System *m_currentSystem; bool m_drawLabels; + bool m_restart; + bool m_hasMeasure; Doc *m_doc; }; diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index b19fb2e82eb..b37a4173a76 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -68,6 +68,7 @@ class ScoreDefElement : public Object, public ScoreDefInterface, public AttTyped bool HasMensurInfo(int depth = 1); bool HasMeterSigInfo(int depth = 1); bool HasMeterSigGrpInfo(int depth = 1); + bool HasLabelInfo(int depth = 1); ///@} /** diff --git a/src/object.cpp b/src/object.cpp index 342264e253c..7a2304ee75b 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1504,11 +1504,17 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) assert(system); // This is the only thing we do for now - we need to wait until we reach the first measure params->m_currentSystem = system; + params->m_hasMeasure = false; return FUNCTOR_CONTINUE; } // starting a new measure if (this->Is(MEASURE)) { + // If we have a restart scoreDef before, for redrawing of everything on the measure + if (params->m_restart) { + params->m_upcomingScoreDef->SetRedrawFlags(StaffDefRedrawFlags::REDRAW_ALL); + } + Measure *measure = vrv_cast(this); assert(measure); int drawingFlags = 0; @@ -1518,7 +1524,8 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) // We had a scoreDef so we need to put cautionnary values // This will also happend with clef in the last measure - however, the cautionnary functor will not do // anything then - if (params->m_upcomingScoreDef->m_setAsDrawing && params->m_previousMeasure) { + // The cautionary scoreDef for restart is already done when hitting the scoreDef + if (params->m_upcomingScoreDef->m_setAsDrawing && params->m_previousMeasure && !params->m_restart) { ScoreDef cautionaryScoreDef = *params->m_upcomingScoreDef; SetCautionaryScoreDefParams setCautionaryScoreDefParams(&cautionaryScoreDef); Functor setCautionaryScoreDef(&Object::SetCautionaryScoreDef); @@ -1539,6 +1546,7 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) params->m_upcomingScoreDef->SetRedrawFlags(StaffDefRedrawFlags::FORCE_REDRAW); params->m_upcomingScoreDef->m_setAsDrawing = false; } + params->m_drawLabels = false; // set other flags based on score def change if (params->m_upcomingScoreDef->m_insertScoreDef) { @@ -1564,6 +1572,9 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) measure->SetDrawingBarLines(params->m_previousMeasure, drawingFlags); params->m_previousMeasure = measure; + params->m_restart = false; + params->m_hasMeasure = true; + return FUNCTOR_CONTINUE; } @@ -1579,7 +1590,22 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) params->m_upcomingScoreDef->ReplaceDrawingValues(scoreDef); params->m_upcomingScoreDef->m_insertScoreDef = true; } - return FUNCTOR_CONTINUE; + if (scoreDef->GetType() == "restart") { + // Trigger the redrawing of the labels - including for the system scoreDef if at the beginning + params->m_drawLabels = true; + params->m_restart = true; + // Redraw the labels only if we already have a mesure in the system. Otherwise this will be + // done through the system scoreDef + scoreDef->SetDrawLabels(params->m_hasMeasure); + // If we have a previous measure, we need to set the cautionary scoreDef indenpendently from the + // presence of a system break + if (params->m_previousMeasure) { + ScoreDef cautionaryScoreDef = *params->m_upcomingScoreDef; + SetCautionaryScoreDefParams setCautionaryScoreDefParams(&cautionaryScoreDef); + Functor setCautionaryScoreDef(&Object::SetCautionaryScoreDef); + params->m_previousMeasure->Process(&setCautionaryScoreDef, &setCautionaryScoreDefParams); + } + } } // starting a new staffDef diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 35c88d6e941..4f10e1a5420 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -79,6 +79,11 @@ bool ScoreDefElement::HasMeterSigGrpInfo(int depth) return (this->FindDescendantByType(METERSIGGRP, depth)); } +bool ScoreDefElement::HasLabelInfo(int depth) +{ + return (this->FindDescendantByType(LABEL, depth)); +} + Clef *ScoreDefElement::GetClef() { // Always check if HasClefInfo() is true before asking for it diff --git a/src/view_page.cpp b/src/view_page.cpp index bb933963d3a..9f0c953188a 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -1503,6 +1503,11 @@ void View::DrawSystemChildren(DeviceContext *dc, Object *parent, System *system) // nothing to do, then ScoreDef *scoreDef = vrv_cast(current); assert(scoreDef); + + Measure *nextMeasure = dynamic_cast(system->GetNext(scoreDef, MEASURE)); + if (nextMeasure && scoreDef->DrawLabels()) + DrawScoreDef(dc, scoreDef, nextMeasure, nextMeasure->GetDrawingX()); + SetScoreDefDrawingWidth(dc, scoreDef); } else if (current->IsSystemElement()) { From e509cfa456e496e65eaa9c3fc7678f91afb85137 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:31:32 +0200 Subject: [PATCH 030/179] Adjust measure alignment and justification --- include/vrv/scoredef.h | 10 ++++++++++ src/scoredef.cpp | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index b37a4173a76..71742e34696 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -222,6 +222,16 @@ class ScoreDef : public ScoreDefElement, */ virtual int CastOffEncoding(FunctorParams *functorParams); + /** + * See Object::AlignMeasures + */ + virtual int AlignMeasures(FunctorParams *functorParams); + + /** + * See Object::JustifyX + */ + virtual int JustifyX(FunctorParams *functorParams); + protected: /** * Filter the flat list and keep only StaffDef elements. diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 4f10e1a5420..70fd86a4464 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -498,4 +498,25 @@ int ScoreDef::CastOffEncoding(FunctorParams *functorParams) return FUNCTOR_SIBLINGS; } +int ScoreDef::AlignMeasures(FunctorParams *functorParams) +{ + AlignMeasuresParams *params = vrv_params_cast(functorParams); + assert(params); + + // SetDrawingXRel(m_systemLeftMar + this->GetDrawingWidth()); + params->m_shift += m_drawingLabelsWidth; + + return FUNCTOR_CONTINUE; +} + +int ScoreDef::JustifyX(FunctorParams *functorParams) +{ + JustifyXParams *params = vrv_params_cast(functorParams); + assert(params); + + params->m_measureXRel += m_drawingLabelsWidth; + + return FUNCTOR_SIBLINGS; +} + } // namespace vrv From 73757c17afc1c9da015922cfc7050b12f4a2d0ab Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:32:04 +0200 Subject: [PATCH 031/179] Scaffolding method for retrieving restart scoreDef --- include/vrv/scoredef.h | 2 ++ src/scoredef.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 71742e34696..653dbb301cb 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -197,6 +197,8 @@ class ScoreDef : public ScoreDefElement, */ int GetMaxStaffSize(); + bool DrawWithinStaff(); + //----------// // Functors // //----------// diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 70fd86a4464..d7c8e3f6e1f 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -26,6 +26,7 @@ #include "pgfoot2.h" #include "pghead.h" #include "pghead2.h" +#include "section.h" #include "staffdef.h" #include "staffgrp.h" #include "system.h" @@ -442,6 +443,14 @@ int ScoreDef::GetMaxStaffSize() return (staffGrp) ? staffGrp->GetMaxStaffSize() : 100; } +bool ScoreDef::DrawWithinStaff() +{ + if (!this->GetParent() || !this->GetParent()->Is(SECTION)) return false; + Section *section = vrv_cast
(this->GetParent()); + assert(section); + return (section->GetRestart() == BOOLEAN_true); +} + //---------------------------------------------------------------------------- // Functors methods //---------------------------------------------------------------------------- From 47361c5856716a0f1ea4a9cabb0b24a70b6d7ff3 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 19:44:12 +0200 Subject: [PATCH 032/179] Fix crash for empty files (see beam-024.mei) --- src/system.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 0f753c37501..0ad9090c051 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -153,8 +153,7 @@ int System::GetMinimumSystemSpacing(const Doc *doc) const int System::GetDrawingLabelsWidth() const { - assert(m_drawingScoreDef); - return m_drawingScoreDef->GetDrawingLabelsWidth(); + return (m_drawingScoreDef) ? m_drawingScoreDef->GetDrawingLabelsWidth() : 0; } void System::SetDrawingLabelsWidth(int width) From 4e359f1763c4a3d7e426fc9ce799ae795851010e Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 20:08:39 +0200 Subject: [PATCH 033/179] Rely on section@restart --- include/vrv/scoredef.h | 2 +- src/object.cpp | 2 +- src/scoredef.cpp | 14 ++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 653dbb301cb..298b1bde749 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -197,7 +197,7 @@ class ScoreDef : public ScoreDefElement, */ int GetMaxStaffSize(); - bool DrawWithinStaff(); + bool IsSectionRestart(); //----------// // Functors // diff --git a/src/object.cpp b/src/object.cpp index 7a2304ee75b..8dc68f6315d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1590,7 +1590,7 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) params->m_upcomingScoreDef->ReplaceDrawingValues(scoreDef); params->m_upcomingScoreDef->m_insertScoreDef = true; } - if (scoreDef->GetType() == "restart") { + if (scoreDef->IsSectionRestart()) { // Trigger the redrawing of the labels - including for the system scoreDef if at the beginning params->m_drawLabels = true; params->m_restart = true; diff --git a/src/scoredef.cpp b/src/scoredef.cpp index d7c8e3f6e1f..d2c8e83106e 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -443,12 +443,14 @@ int ScoreDef::GetMaxStaffSize() return (staffGrp) ? staffGrp->GetMaxStaffSize() : 100; } -bool ScoreDef::DrawWithinStaff() -{ - if (!this->GetParent() || !this->GetParent()->Is(SECTION)) return false; - Section *section = vrv_cast
(this->GetParent()); - assert(section); - return (section->GetRestart() == BOOLEAN_true); +bool ScoreDef::IsSectionRestart() +{ + if (!this->GetParent()) return false; + // In page-based structure, Section is a sibling to scoreDef + // This has limitations: will not work with editorial markup, additional nested sections, and + // if the section milestone is in the previous system. + Section *section = dynamic_cast
(this->GetParent()->GetPrevious(this, SECTION)); + return (section && (section->GetRestart() == BOOLEAN_true)); } //---------------------------------------------------------------------------- From 2695172ffc236c10d13f7676d999be0d82529128 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 23:40:30 +0200 Subject: [PATCH 034/179] Remove HasLabelInfo from ScoreDef --- include/vrv/scoredef.h | 1 - src/scoredef.cpp | 5 ----- 2 files changed, 6 deletions(-) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 298b1bde749..3f4c839040b 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -68,7 +68,6 @@ class ScoreDefElement : public Object, public ScoreDefInterface, public AttTyped bool HasMensurInfo(int depth = 1); bool HasMeterSigInfo(int depth = 1); bool HasMeterSigGrpInfo(int depth = 1); - bool HasLabelInfo(int depth = 1); ///@} /** diff --git a/src/scoredef.cpp b/src/scoredef.cpp index d2c8e83106e..9a0e397adcf 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -80,11 +80,6 @@ bool ScoreDefElement::HasMeterSigGrpInfo(int depth) return (this->FindDescendantByType(METERSIGGRP, depth)); } -bool ScoreDefElement::HasLabelInfo(int depth) -{ - return (this->FindDescendantByType(LABEL, depth)); -} - Clef *ScoreDefElement::GetClef() { // Always check if HasClefInfo() is true before asking for it From 35a379670180903db169c36d97b79c284358c170 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 23:41:22 +0200 Subject: [PATCH 035/179] Add methods to replace labels in ScoreDef --- include/vrv/scoredef.h | 11 +++++++++++ src/scoredef.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 3f4c839040b..682154d2a05 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -145,11 +145,22 @@ class ScoreDef : public ScoreDefElement, */ void ReplaceDrawingValues(StaffDef *newStaffDef); + /** + * Replace the corresponding staffGrp with the labels of the newStaffGrp. + * Looks for the staffGrp with the same m_n (@n) and replaces label child + */ + void ReplaceDrawingLabels(StaffGrp *newStaffGrp); + /** * Get the staffDef with number n (NULL if not found). */ StaffDef *GetStaffDef(int n); + /** + * Get the staffGrp with number n (NULL if not found). + */ + StaffGrp *GetStaffGrp(const std::string &n); + /** * Return all the @n values of the staffDef in a scoreDef */ diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 9a0e397adcf..76e6e897a27 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -14,6 +14,7 @@ //---------------------------------------------------------------------------- #include "clef.h" +#include "comparison.h" #include "editorial.h" #include "functorparams.h" #include "grpsym.h" @@ -339,6 +340,27 @@ void ScoreDef::ReplaceDrawingValues(StaffDef *newStaffDef) } } +void ScoreDef::ReplaceDrawingLabels(StaffGrp *newStaffGrp) +{ + assert(newStaffGrp); + + // first find the staffGrp with the same @n + StaffGrp *staffGrp = this->GetStaffGrp(newStaffGrp->GetN()); + if (staffGrp) { + if (newStaffGrp->HasLabelInfo()) { + Label *label = newStaffGrp->GetLabelCopy(); + if (staffGrp->HasLabelInfo()) { + Label *oldLabel = staffGrp->GetLabel(); + staffGrp->ReplaceChild(oldLabel, label); + delete oldLabel; + } + else { + staffGrp->AddChild(label); + } + } + } +} + void ScoreDef::FilterList(ArrayOfObjects *childList) { // We want to keep only staffDef @@ -373,6 +395,22 @@ StaffDef *ScoreDef::GetStaffDef(int n) return staffDef; } +StaffGrp *ScoreDef::GetStaffGrp(const std::string &n) +{ + // First get all the staffGrps + ClassIdComparison matchType(STAFFGRP); + ListOfObjects staffGrps; + this->FindAllDescendantByComparison(&staffGrps, &matchType); + + // Then the @n of each first staffDef + for (auto &item : staffGrps) { + StaffGrp *staffGrp = vrv_cast(item); + assert(staffGrp); + if (staffGrp->GetN() == n) return staffGrp; + } + return NULL; +} + std::vector ScoreDef::GetStaffNs() { this->ResetList(this); From fe6a2a5b601dc02f20ed925bfa5706ddb3c8260d Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 30 Jul 2021 23:42:40 +0200 Subject: [PATCH 036/179] Replace labels in StaffGrp * Add `@n` to staffGrp * Method to check / get / clone label and labelAbbr --- include/vrv/staffgrp.h | 24 +++++++++++++++++++++ src/iomei.cpp | 2 ++ src/object.cpp | 9 ++++++++ src/staffgrp.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/include/vrv/staffgrp.h b/include/vrv/staffgrp.h index f2a7a12a222..3752e3b7506 100644 --- a/include/vrv/staffgrp.h +++ b/include/vrv/staffgrp.h @@ -17,6 +17,9 @@ namespace vrv { +class Label; +class LabelAbbr; + //---------------------------------------------------------------------------- // StaffGrp //---------------------------------------------------------------------------- @@ -29,6 +32,7 @@ class StaffGrp : public Object, public ObjectListInterface, public AttBasic, public AttLabelled, + public AttNNumberLike, public AttStaffGroupingSym, public AttStaffGrpVis, public AttTyped { @@ -79,6 +83,26 @@ class StaffGrp : public Object, GrpSym *GetGroupSymbol() const { return m_groupSymbol; } ///@} + /** + * @name Methods for checking the presence of label and labelAbbr information and getting them. + */ + ///@{ + bool HasLabelInfo(); + bool HasLabelAbbrInfo(); + + ///@} + + /** + * @name Get a copy of the label and labelAbbr. + * These methods create new objects (heap) that will need to be deleted. + */ + ///@{ + Label *GetLabel(); + Label *GetLabelCopy(); + LabelAbbr *GetLabelAbbr(); + LabelAbbr *GetLabelAbbrCopy(); + ///@} + //----------// // Functors // //----------// diff --git a/src/iomei.cpp b/src/iomei.cpp index 93417618bbe..040a74b192c 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -1137,6 +1137,7 @@ void MEIOutput::WriteStaffGrp(pugi::xml_node currentNode, StaffGrp *staffGrp) WriteXmlId(currentNode, staffGrp); staffGrp->WriteBasic(currentNode); staffGrp->WriteLabelled(currentNode); + staffGrp->WriteNNumberLike(currentNode); staffGrp->WriteStaffGroupingSym(currentNode); staffGrp->WriteStaffGrpVis(currentNode); staffGrp->WriteTyped(currentNode); @@ -3809,6 +3810,7 @@ bool MEIInput::ReadStaffGrp(Object *parent, pugi::xml_node staffGrp) vrvStaffGrp->ReadBasic(staffGrp); vrvStaffGrp->ReadLabelled(staffGrp); + vrvStaffGrp->ReadNNumberLike(staffGrp); AttStaffGroupingSym groupingSym; groupingSym.ReadStaffGroupingSym(staffGrp); if (groupingSym.HasSymbol()) { diff --git a/src/object.cpp b/src/object.cpp index 8dc68f6315d..9734d3d46a4 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1608,6 +1608,15 @@ int Object::ScoreDefSetCurrent(FunctorParams *functorParams) } } + // starting a new staffDef + if (this->Is(STAFFGRP)) { + StaffGrp *staffGrp = vrv_cast(this); + assert(staffGrp); + if (params->m_restart) { + params->m_upcomingScoreDef->ReplaceDrawingLabels(staffGrp); + } + } + // starting a new staffDef if (this->Is(STAFFDEF)) { StaffDef *staffDef = vrv_cast(this); diff --git a/src/staffgrp.cpp b/src/staffgrp.cpp index a93f7f7edfa..d69733a45fd 100644 --- a/src/staffgrp.cpp +++ b/src/staffgrp.cpp @@ -34,12 +34,14 @@ StaffGrp::StaffGrp() , ObjectListInterface() , AttBasic() , AttLabelled() + , AttNNumberLike() , AttStaffGroupingSym() , AttStaffGrpVis() , AttTyped() { RegisterAttClass(ATT_BASIC); RegisterAttClass(ATT_LABELLED); + RegisterAttClass(ATT_NNUMBERLIKE); RegisterAttClass(ATT_STAFFGROUPINGSYM); RegisterAttClass(ATT_STAFFGRPVIS); RegisterAttClass(ATT_TYPED); @@ -54,6 +56,7 @@ void StaffGrp::Reset() Object::Reset(); ResetBasic(); ResetLabelled(); + ResetNNumberLike(); ResetStaffGroupingSym(); ResetStaffGrpVis(); ResetTyped(); @@ -169,6 +172,50 @@ void StaffGrp::SetGroupSymbol(GrpSym *grpSym) } } +bool StaffGrp::HasLabelInfo() +{ + return (this->FindDescendantByType(LABEL, 1)); +} + +bool StaffGrp::HasLabelAbbrInfo() +{ + return (this->FindDescendantByType(LABELABBR, 1)); +} + +Label *StaffGrp::GetLabel() +{ + // Always check if HasLabelInfo() is true before asking for it + Label *label = vrv_cast