Skip to content

Commit

Permalink
Fix placement of parens on single segment
Browse files Browse the repository at this point in the history
  • Loading branch information
miiizen committed Feb 6, 2025
1 parent bb49e83 commit beaed54
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/engraving/dom/parenthesis.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Parenthesis : public EngravingItem
ld_field<muse::draw::PainterPath> path = "path";
ld_field<double> startY = "startY";
ld_field<double> height = "height";
ld_field<double> thickness = "thickness";
};
DECLARE_LAYOUTDATA_METHODS(Parenthesis);
};
Expand Down
7 changes: 3 additions & 4 deletions src/engraving/dom/segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "tuplet.h"
#include "undo.h"
#include "utils.h"
#include "rendering/score/segmentlayout.h"

#include "navigate.h"

Expand Down Expand Up @@ -2563,16 +2564,14 @@ void Segment::createShape(staff_idx_t staffIdx)
}
}

rendering::score::SegmentLayout::placeParentheses(this, staffIdx);

for (EngravingItem* e : m_annotations) {
if (!e || e->staffIdx() != staffIdx) {
continue;
}

setVisible(true);
if (e->isParenthesis()) {
// Calculate layout, this needs to be placed at the edge of the segment
renderer()->layoutItem(toParenthesis(e));
}

if (!e->addToSkyline()) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/score/measurelayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2027,7 +2027,7 @@ void MeasureLayout::addRepeatCourtesyParentheses(Measure* m, const bool continua
}

Parenthesis* rightParen = findOrCreateParenthesis(rightMostSeg, DirectionH::RIGHT, track);
if (ctx.conf().styleB(Sid::smallParens)) {
if (ctx.conf().styleB(Sid::smallParens) && leftParen && rightParen) {
calcParenTopBottom(leftParen, top, bottom);
calcParenTopBottom(rightParen, top, bottom);

Expand Down
83 changes: 83 additions & 0 deletions src/engraving/rendering/score/segmentlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@

#include "dom/part.h"
#include "dom/drumset.h"
#include "dom/parenthesis.h"

#include "tlayout.h"
#include "chordlayout.h"
#include "horizontalspacing.h"

using namespace mu::engraving::rendering::score;

Expand Down Expand Up @@ -231,3 +233,84 @@ void SegmentLayout::layoutChordsStem(const Segment& segment, track_idx_t startTr
}
}
}

void SegmentLayout::placeParentheses(const Segment* segment, staff_idx_t staffIdx)
{
const EngravingItem* segItem = segment->elementAt(staff2track(staffIdx));
const std::vector<EngravingItem*> parens = segment->findAnnotations(ElementType::PARENTHESIS, staffIdx * VOICES, staffIdx * VOICES);
assert(parens.size() <= 2);
if (parens.empty() || !segItem) {
return;
}

if (parens.size() == 1) {
// 1 parenthesis
Parenthesis* paren = toParenthesis(parens.front());
const bool leftBracket = paren->direction() == DirectionH::LEFT;
segment->renderer()->layoutItem(paren);
if (!leftBracket) {
// Space against existing segment shape
const double minDist = HorizontalSpacing::minHorizontalDistance(segment->staffShape(paren->staffIdx()),
paren->shape().translated(paren->pos()), paren->spatium());
paren->mutldata()->moveX(minDist);
} else {
// Space following segment shape against this
const double minDist = HorizontalSpacing::minHorizontalDistance(paren->shape().translated(paren->pos()),
segment->staffShape(paren->staffIdx()), paren->spatium());
paren->mutldata()->moveX(-minDist);
}
return;
}

// 2 parentheses
Parenthesis* leftParen = nullptr;
Parenthesis* rightParen = nullptr;
for (EngravingItem* paren : parens) {
if (toParenthesis(paren)->direction() == DirectionH::LEFT) {
leftParen = toParenthesis(paren);
continue;
}

rightParen = toParenthesis(paren);
}

assert(leftParen && rightParen);

segment->renderer()->layoutItem(toParenthesis(leftParen));
segment->renderer()->layoutItem(toParenthesis(rightParen));
Shape dummySegShape = segment->staffShape(leftParen->staffIdx());

const double itemLeftX = segItem->pos().x();
const double itemRightX = itemLeftX + segItem->width();

const double leftParenPadding = HorizontalSpacing::minHorizontalDistance(leftParen->shape().translated(leftParen->pos()),
dummySegShape, leftParen->spatium());
leftParen->mutldata()->moveX(-leftParenPadding);
dummySegShape.add(leftParen->shape().translate(leftParen->pos() + leftParen->staffOffset()));

const double rightParenPadding = HorizontalSpacing::minHorizontalDistance(dummySegShape, rightParen->shape().translated(
rightParen->pos()), rightParen->spatium());
rightParen->mutldata()->moveX(rightParenPadding);

// If the right parenthesis has been padded against the left parenthesis, this means the parenthesis -> parenthesis padding distance
// is larger than the width of the item the parentheses surrounds. In this case, the result is visually unbalanced. Move both parens
// to the left (relative to the segment) in order to centre the item: (b ) -> ( b )
const double itemWidth = segItem->width();
const double parenPadding = segment->score()->paddingTable().at(ElementType::PARENTHESIS).at(ElementType::PARENTHESIS);

if (itemWidth >= parenPadding) {
return;
}

// Move parentheses to place item in the middle
const double leftParenX = leftParen->pos().x() + leftParen->ldata()->bbox().x() + leftParen->ldata()->thickness;
const double rightParenX = rightParen->pos().x() + rightParen->ldata()->bbox().x() + rightParen->width()
- rightParen->ldata()->thickness;

const double leftParenToItem = itemLeftX - leftParenX;
const double itemToRightParen = rightParenX - itemRightX;
const double parenToItemDist = (leftParenToItem + itemToRightParen) / 2;

leftParen->mutldata()->moveX(-std::abs(parenToItemDist - leftParenToItem));
rightParen->mutldata()->moveX(-std::abs(itemToRightParen - parenToItemDist));
}
2 changes: 2 additions & 0 deletions src/engraving/rendering/score/segmentlayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class SegmentLayout
static void computeChordsUp(const Segment& segment, track_idx_t startTrack, track_idx_t endTrack, const LayoutContext& ctx);

static void layoutChordsStem(const Segment& segment, track_idx_t startTrack, track_idx_t endTrack, const LayoutContext& ctx);

static void placeParentheses(const Segment* segment, staff_idx_t staffIdx);
};
}

Expand Down
15 changes: 2 additions & 13 deletions src/engraving/rendering/score/tlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4510,7 +4510,6 @@ void TLayout::layoutPalmMuteSegment(PalmMuteSegment* item, LayoutContext& ctx)

void TLayout::layoutParenthesis(Parenthesis* item, LayoutContext& ctx)
{
LOGI() << "==> layoutParenthesis: " << item->tick().toString() << " dir: " << (int)item->direction();
Parenthesis::LayoutData* ldata = item->mutldata();
ldata->setPos(PointF());
ldata->clearShape();
Expand Down Expand Up @@ -4543,7 +4542,8 @@ void TLayout::layoutParenthesis(Parenthesis* item, LayoutContext& ctx)

const double heightInSpatium = height / spatium;
const double shoulderYOffset = 0.2 * height;
const double thickness = height / 60 * mag;
const double thickness = height / 60 * mag; // 0.1sp for a height of 6sp
ldata->thickness.set_value(thickness);
const double shoulderX = 0.2 * height * mag;

PointF start = PointF(0.0, startY);
Expand Down Expand Up @@ -4591,17 +4591,6 @@ void TLayout::layoutParenthesis(Parenthesis* item, LayoutContext& ctx)

item->mutldata()->setShape(shape);

if (!leftBracket) {
// Space against existing segment shape
double minDist = HorizontalSpacing::minHorizontalDistance(seg->staffShape(item->staffIdx()),
item->shape().translated(start), item->spatium());
start.setX(minDist);
} else {
// Space following segment shape against this
double minDist = HorizontalSpacing::minHorizontalDistance(item->shape().translated(start),
seg->staffShape(item->staffIdx()), item->spatium());
start.setX(-minDist);
}
item->setPos(start);
}

Expand Down
2 changes: 1 addition & 1 deletion src/engraving/style/styledef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1788,7 +1788,7 @@ const std::array<StyleDef::StyleValue, size_t(Sid::STYLES)> StyleDef::styleValue
styleDef(useParensRepeatCourtesiesAfterCancelling, true),
styleDef(showCourtesiesAfterCancellingOtherJumps, true),
styleDef(useParensOtherJumpCourtesiesAfterCancelling, true),
styleDef(smallParens, false),
styleDef(smallParens, true),
} };

#undef styleDef

0 comments on commit beaed54

Please sign in to comment.