diff --git a/src/engraving/dom/clef.cpp b/src/engraving/dom/clef.cpp index 5623fc2198027..996be14734d65 100644 --- a/src/engraving/dom/clef.cpp +++ b/src/engraving/dom/clef.cpp @@ -479,6 +479,11 @@ void Clef::undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps) } } +bool Clef::isMidMeasureClef() const +{ + return segment() && segment()->rtick().isNotZero(); +} + void Clef::manageExclusionFromParts(bool exclude) { if (exclude) { diff --git a/src/engraving/dom/clef.h b/src/engraving/dom/clef.h index ae6b888e1d573..0a4d8617037be 100644 --- a/src/engraving/dom/clef.h +++ b/src/engraving/dom/clef.h @@ -146,6 +146,8 @@ class Clef final : public EngravingItem bool isHeader() const { return m_isHeader; } void setIsHeader(bool val) { m_isHeader = val; } + bool isMidMeasureClef() const; + bool canBeExcludedFromOtherParts() const override { return !isHeader(); } void manageExclusionFromParts(bool exclude) override; diff --git a/src/engraving/dom/textbase.cpp b/src/engraving/dom/textbase.cpp index b1da7a2480696..22ecf74550e63 100644 --- a/src/engraving/dom/textbase.cpp +++ b/src/engraving/dom/textbase.cpp @@ -44,6 +44,7 @@ #include "barline.h" #include "box.h" +#include "dynamic.h" #include "instrumentname.h" #include "measure.h" #include "mscore.h" @@ -1058,7 +1059,8 @@ void TextBlock::layout(const TextBase* t) for (auto fi = m_fragments.begin(); fi != m_fragments.end(); ++fi) { TextFragment& f = *fi; f.pos.setX(x); - FontMetrics fm(f.font(t)); + Font fragmentFont = f.font(t); + FontMetrics fm(fragmentFont); if (f.format.valign() != VerticalAlignment::AlignNormal) { double voffset = fm.xHeight() / subScriptSize; // use original height if (f.format.valign() == VerticalAlignment::AlignSubScript) { @@ -1078,7 +1080,20 @@ void TextBlock::layout(const TextBase* t) x += w; } - m_shape.add(fm.tightBoundingRect(f.text).translated(f.pos), t); + RectF textBRect = fm.tightBoundingRect(f.text).translated(f.pos); + bool useDynamicSymShape = fragmentFont.type() == Font::Type::MusicSymbol && t->isDynamic(); + if (useDynamicSymShape) { + const Dynamic* dyn = toDynamic(t); + SymId symId = TConv::symId(dyn->dynamicType()); + if (symId != SymId::noSym) { + m_shape.add(dyn->symShapeWithCutouts(symId).translated(f.pos)); + } else { + m_shape.add(textBRect, t); + } + } else { + m_shape.add(textBRect, t); + } + Font font = f.font(t); if (font.type() == Font::Type::MusicSymbol || font.type() == Font::Type::MusicSymbolText) { // SEMI-HACK: Music fonts can have huge linespacing because of tall symbols, so instead of using the diff --git a/src/engraving/rendering/dev/horizontalspacing.cpp b/src/engraving/rendering/dev/horizontalspacing.cpp index 04d130cb6e6e3..e46d63b36e74c 100644 --- a/src/engraving/rendering/dev/horizontalspacing.cpp +++ b/src/engraving/rendering/dev/horizontalspacing.cpp @@ -255,13 +255,13 @@ void HorizontalSpacing::spaceRightAlignedSegments(Measure* m, double segmentShap // Compute spacing for (Segment* raSegment : rightAlignedSegments) { // 1) right-align the segment against the following ones - double minDistAfter = -DBL_MAX; + double minDistAfter = 0.0; for (Segment* seg = raSegment->nextActive(); seg; seg = seg->nextActive()) { double xDiff = seg->x() - raSegment->x(); double minDist = minHorizontalCollidingDistance(raSegment, seg, segmentShapeSqueezeFactor); minDistAfter = std::max(minDistAfter, minDist - xDiff); } - if (minDistAfter != -DBL_MAX && raSegment->prevActive()) { + if (raSegment->prevActive()) { Segment* prevSegment = raSegment->prevActive(); prevSegment->setWidth(prevSegment->width() - minDistAfter); prevSegment->setWidthOffset(prevSegment->widthOffset() - minDistAfter); @@ -539,6 +539,10 @@ bool HorizontalSpacing::isNeverKernable(const EngravingItem* item) switch (type) { case ElementType::CLEF: + if (toClef(item)->isMidMeasureClef()) { + return false; + } + // fall through case ElementType::TIMESIG: case ElementType::KEYSIG: case ElementType::BAR_LINE: diff --git a/src/engraving/rendering/dev/tlayout.cpp b/src/engraving/rendering/dev/tlayout.cpp index 945d06af5c292..103394a593e02 100644 --- a/src/engraving/rendering/dev/tlayout.cpp +++ b/src/engraving/rendering/dev/tlayout.cpp @@ -1794,10 +1794,15 @@ void TLayout::layoutClef(const Clef* item, Clef::LayoutData* ldata, const Layout } // clefs on palette or at start of system/measure are left aligned // other clefs are right aligned - RectF r(item->symBbox(ldata->symId)); - double x = item->segment() && item->segment()->rtick().isNotZero() ? -r.right() : 0.0; + Shape shape(item->symShapeWithCutouts(ldata->symId)); + bool isMidMeasureClef = item->isMidMeasureClef(); + double x = isMidMeasureClef ? -shape.right() : 0.0; ldata->setPos(PointF(x, yoff * _spatium + (stepOffset * 0.5 * _spatium))); - ldata->setBbox(r); + if (item->isMidMeasureClef()) { + ldata->setShape(shape); + } else { + ldata->setBbox(item->symBbox(ldata->symId)); + } } void TLayout::layoutCapo(const Capo* item, Capo::LayoutData* ldata, const LayoutContext&)