Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/engraving/compat/engravingcompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ static void doMigrateOffset500(EngravingItem* item)
return;
}

// In versions <5 any adjustment to offset meant we couldn't centre items between staves
item->setProperty(Pid::CENTER_BETWEEN_STAVES, AutoOnOff::OFF);

item->setOffset(CompatUtils::getAdjustedOffset(item, item->offset()));
}

Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/score/alignmentlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void AlignmentLayout::moveItemToY(EngravingItem* item, double y, const System* s

double AlignmentLayout::yOpticalCenter(const EngravingItem* item)
{
double curY = item->pos().y();
double curY = item->ldata()->pos().y();
switch (item->type()) {
case ElementType::DYNAMIC:
case ElementType::EXPRESSION:
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/score/dynamicslayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void DynamicsLayout::layoutDynamicToEndOfPrevious(const Dynamic* item, TextBase:

void DynamicsLayout::manageBarlineCollisions(const Dynamic* item, TextBase::LayoutData* ldata)
{
if (item->score()->nstaves() <= 1 || item->anchorToEndOfPrevious() || !item->offset().isNull()) {
if (item->score()->nstaves() <= 1 || item->anchorToEndOfPrevious()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Respect user X nudges in the barline collision geometry.

Line 155 now lets offset items enter this path, but Lines 211-213 and 231-233 still evaluate the dynamic bbox at item->pagePos() - item->offset(). That strips manual X offsets out of the collision check, so a user-shifted dynamic can still overlap a barline or get pushed the wrong way. Use the rendered X position here, or only strip the Y component if the intent is to ignore vertical nudges.

Suggested fix
-            double rightMargin = e->ldata()->bbox().translated(e->pagePos()).left()
-                                 - referenceBBox.translated(item->pagePos() - item->offset()).right()
+            double rightMargin = e->ldata()->bbox().translated(e->pagePos()).left()
+                                 - referenceBBox.translated(item->pagePos()).right()
                                  - minBarLineDistance;
@@
-            double leftMargin = referenceBBox.translated(item->pagePos() - item->offset()).left()
+            double leftMargin = referenceBBox.translated(item->pagePos()).left()
                                 - e->ldata()->bbox().translated(e->pagePos()).right()
                                 - minBarLineDistance;

Also applies to: 211-213, 231-233

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/engraving/rendering/score/dynamicslayout.cpp` at line 155, The collision
check currently computes the dynamic bbox using item->pagePos() -
item->offset(), which removes user X nudges; update the geometry calculation in
dynamicslayout (the branch guarded by item->score()->nstaves() <= 1 ||
item->anchorToEndOfPrevious() and the checks around the code paths at the places
noted) to respect manual X shifts by using the rendered X position (e.g., keep
pagePos().x() with the user nudged value) and only subtract the Y component of
item->offset() if the intent is to ignore vertical nudges; specifically, replace
uses of item->pagePos() - item->offset() in the dynamic bbox computation (and
the checks at the other two sites) with a position preserving pagePos().x() and
adjusted Y (or equivalent: use pagePos() directly for X and pagePos().y() -
item->offset().y() for Y) so user X nudges are included in barline collision
geometry.

return;
}

Expand Down
15 changes: 1 addition & 14 deletions src/engraving/rendering/score/systemlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1845,9 +1845,6 @@ void SystemLayout::processLines(System* system, LayoutContext& ctx, const std::v
}
}
for (SpannerSegment* ss : segments) {
if (!ss->offset().isNull()) {
continue;
}
const double& staffY = ss->spanner() && ss->spanner()->placeAbove() ? yAbove[ss->staffIdx()] : yBelow[ss->staffIdx()];
if (staffY > -DBL_MAX) {
ss->mutldata()->setPosY(staffY);
Expand Down Expand Up @@ -2625,11 +2622,6 @@ void SystemLayout::centerBigTimeSigsAcrossStaves(const System* system)

bool SystemLayout::elementShouldBeCenteredBetweenStaves(const EngravingItem* item, const System* system)
{
if (item->offset().y() != item->propertyDefault(Pid::OFFSET).value<PointF>().y()) {
// NOTE: because of current limitations of the offset system, we can't center an element that's been manually moved.
return false;
}

const Part* itemPart = item->part();
IF_ASSERT_FAILED(itemPart) {
return false;
Expand Down Expand Up @@ -2689,11 +2681,6 @@ bool SystemLayout::mmRestShouldBeCenteredBetweenStaves(const MMRest* mmRest, con

bool SystemLayout::whammyBarShouldBeCenteredBetweenStaves(const WhammyBarSegment* wbar, const System* system)
{
if (wbar->offset().y() != wbar->propertyDefault(Pid::OFFSET).value<PointF>().y()) {
// NOTE: because of current limitations of the offset system, we can't center an element that's been manually moved.
return false;
}

staff_idx_t staffIdx = wbar->staffIdx();
Staff* thisStaff = wbar->staff();
Staff* nextStaff = wbar->score()->staff(staffIdx + 1);
Expand Down Expand Up @@ -2754,7 +2741,7 @@ void SystemLayout::centerElementBetweenStaves(EngravingItem* element, const Syst
const double minHorizontalClearance = system->style().styleAbsolute(Sid::skylineMinHorizontalClearance);

Shape elementShape = element->ldata()->shape()
.translated(PointF(elementXinSystemCoord, element->y()))
.translated(PointF(elementXinSystemCoord, element->ldata()->pos().y()))
.adjust(-minHorizontalClearance, 0.0, minHorizontalClearance, 0.0);
elementShape.remove_if([](ShapeElement& shEl) { return shEl.ignoreForLayout(); });

Expand Down
Loading