Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Masking #26227

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Masking #26227

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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions src/appshell/view/appmenumodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ MenuItem* AppMenuModel::makeDiagnosticsMenu()
makeMenuItem("color-segment-shapes"),
makeMenuItem("show-skylines"),
makeMenuItem("show-system-bounding-rects"),
makeMenuItem("show-element-masks"),
makeMenuItem("show-corrupted-measures")
};

Expand Down
5 changes: 5 additions & 0 deletions src/engraving/dom/engravingitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ class EngravingItem : public EngravingObject
virtual void reset()
{
m_shape.reset();
m_mask.reset();
//! NOTE Temporary removed, have problems, need investigation
//m_pos.reset();
}
Expand Down Expand Up @@ -582,6 +583,9 @@ class EngravingItem : public EngravingObject
setBbox(r);
}

void setMask(const Shape& m) { m_mask.set_value(m); }
const Shape& mask() const { return m_mask.value(); }

OffsetChange offsetChanged() const { return autoplace.offsetChanged; }

void connectItemSnappedBefore(EngravingItem* itemBefore);
Expand Down Expand Up @@ -633,6 +637,7 @@ class EngravingItem : public EngravingObject
double m_mag = 1.0; // standard magnification (derived value)
ld_field<PointF> m_pos = "pos"; // Reference position, relative to _parent, set by autoplace
ld_field<Shape> m_shape = "shape";
ld_field<Shape> m_mask = "mask";

EngravingItem* m_itemSnappedBefore = nullptr;
EngravingItem* m_itemSnappedAfter = nullptr;
Expand Down
8 changes: 8 additions & 0 deletions src/engraving/dom/lyrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace mu::engraving {

static const ElementStyle lyricsElementStyle {
{ Sid::lyricsPlacement, Pid::PLACEMENT },
{ Sid::lyricsAvoidBarlines, Pid::AVOID_BARLINES },
};

//---------------------------------------------------------
Expand Down Expand Up @@ -388,6 +389,8 @@ PropertyValue Lyrics::getProperty(Pid propertyId) const
return m_ticks;
case Pid::VERSE:
return m_no;
case Pid::AVOID_BARLINES:
return m_avoidBarlines;
default:
return TextBase::getProperty(propertyId);
}
Expand Down Expand Up @@ -447,6 +450,9 @@ bool Lyrics::setProperty(Pid propertyId, const PropertyValue& v)
}
m_no = v.toInt();
break;
case Pid::AVOID_BARLINES:
m_avoidBarlines = v.toBool();
break;
default:
if (!TextBase::setProperty(propertyId, v)) {
return false;
Expand Down Expand Up @@ -474,6 +480,8 @@ PropertyValue Lyrics::propertyDefault(Pid id) const
return Fraction(0, 1);
case Pid::VERSE:
return 0;
case Pid::AVOID_BARLINES:
return style().styleB(Sid::lyricsAvoidBarlines);
case Pid::ALIGN:
if (isMelisma()) {
return style().styleV(Sid::lyricsMelismaAlign);
Expand Down
4 changes: 4 additions & 0 deletions src/engraving/dom/lyrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class Lyrics final : public TextBase
double yRelativeToStaff() const;
void setYRelativeToStaff(double y);

bool avoidBarlines() const { return m_avoidBarlines; }
void setAvoidBarlines(bool v) { m_avoidBarlines = v; }

protected:
int m_no = 0; // row index

Expand All @@ -116,6 +119,7 @@ class Lyrics final : public TextBase
LyricsSyllabic m_syllabic = LyricsSyllabic::SINGLE;
LyricsLine* m_separator = nullptr;
bool m_needRemoveInvalidSegments = false;
bool m_avoidBarlines = true;
};

//---------------------------------------------------------
Expand Down
24 changes: 0 additions & 24 deletions src/engraving/dom/textbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2347,30 +2347,6 @@ RectF TextBase::pageRectangle() const
return pageBoundingRect();
}

void TextBase::computeHighResShape(const FontMetrics& fontMetrics)
{
Shape& highResShape = mutldata()->highResShape.mut_value();
highResShape.clear();
highResShape.elements().reserve(m_text.size());

for (const TextBlock& block : ldata()->blocks) {
double x = 0;
for (const TextFragment& fragment : block.fragments()) {
x += fragment.pos.x();
size_t textSize = fragment.text.size();
for (size_t i = 0; i < textSize; ++i) {
Char character = fragment.text.at(i);
RectF characterBoundingRect = fontMetrics.tightBoundingRect(fragment.text.at(i));
characterBoundingRect.translate(x, 0.0);
highResShape.add(characterBoundingRect);
if (i + 1 < textSize) {
x += fontMetrics.horizontalAdvance(character);
}
}
}
}
}

//---------------------------------------------------------
// dragTo
//---------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion src/engraving/dom/textbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ class TextBase : public EngravingItem
RectF pageRectangle() const;

const Shape& highResShape() const { return ldata()->highResShape.value(); }
void computeHighResShape(const muse::draw::FontMetrics& fontMetrics);

void dragTo(EditData&);

Expand Down
2 changes: 2 additions & 0 deletions src/engraving/iengravingconfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class IEngravingConfiguration : MODULE_EXPORT_INTERFACE
bool colorSegmentShapes = false;
bool showSkylines = false;
bool showSystemBoundingRects = false;
bool showElementMasks = false;
bool showCorruptedMeasures = true;

bool anyEnabled() const
Expand All @@ -111,6 +112,7 @@ class IEngravingConfiguration : MODULE_EXPORT_INTERFACE
|| colorSegmentShapes
|| showSkylines
|| showSystemBoundingRects
|| showElementMasks
#ifndef NDEBUG
|| showCorruptedMeasures
#endif
Expand Down
30 changes: 30 additions & 0 deletions src/engraving/infrastructure/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,24 @@ Shape Shape::adjusted(double xp1, double yp1, double xp2, double yp2) const
return s;
}

Shape& Shape::pad(double p)
{
for (ShapeElement& el : m_elements) {
el.pad(p);
}
return *this;
}

Shape Shape::padded(double p) const
{
Shape s;
s.m_elements.reserve(m_elements.size());
for (const ShapeElement& el : m_elements) {
s.add(el.padded(p));
}
return s;
}

void Shape::invalidateBBox()
{
m_bbox = RectF();
Expand Down Expand Up @@ -492,6 +510,18 @@ void Shape::remove(const Shape& s)
invalidateBBox();
}

std::vector<RectF> Shape::toRects() const
{
std::vector<RectF> rects;
rects.reserve(m_elements.size());

for (const RectF& shapeEl : m_elements) {
rects.push_back(shapeEl);
}

return rects;
}

void Shape::removeInvisibles()
{
muse::remove_if(m_elements, [](ShapeElement& shapeElement) {
Expand Down
3 changes: 3 additions & 0 deletions src/engraving/infrastructure/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class Shape

const std::vector<ShapeElement>& elements() const { return m_elements; }
std::vector<ShapeElement>& elements() { return m_elements; }
std::vector<RectF> toRects() const;

std::optional<ShapeElement> find_if(const std::function<bool(const ShapeElement&)>& func) const;
std::optional<ShapeElement> find_first(ElementType type) const;
Expand All @@ -146,6 +147,8 @@ class Shape
Shape scaled(const SizeF&) const;
Shape& adjust(double xp1, double yp1, double xp2, double yp2);
Shape adjusted(double xp1, double yp1, double xp2, double yp2) const;
Shape& pad(double p);
Shape padded(double p) const;

const RectF& bbox() const;
double minVerticalDistance(const Shape&, double minHorizontalClearance = 0.0) const;
Expand Down
14 changes: 14 additions & 0 deletions src/engraving/rendering/score/debugpaint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ void DebugPaint::paintElementDebug(Painter& painter, const EngravingItem* item)
painter.drawPath(path);
}

if (item->configuration()->debuggingOptions().showElementMasks) {
PainterPath path;
path.setFillRule(PainterPath::FillRule::WindingFill);
for (const ShapeElement& el : item->ldata()->mask().elements()) {
path.addRect(el);
}

painter.setPen(Color::BLACK);
Brush brush(Color::BLACK);
brush.setStyle(BrushStyle::BDiagPattern);
painter.setBrush(brush);
painter.drawPath(path);
}

// Draw bbox
if (isDiagnosticSelected || item->configuration()->debuggingOptions().showElementBoundingRects) {
double scaling = painter.worldTransform().m11() / item->configuration()->guiScaling();
Expand Down
66 changes: 65 additions & 1 deletion src/engraving/rendering/score/horizontalspacing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ double HorizontalSpacing::computeSpacingForFullSystem(System* system, double str
bool overrideMinMeasureWidth)
{
HorizontalSpacingContext ctx;
ctx.system = system;
ctx.spatium = system->spatium();

ctx.stretchReduction = stretchReduction;
Expand Down Expand Up @@ -78,6 +79,7 @@ double HorizontalSpacing::computeSpacingForFullSystem(System* system, double str
double HorizontalSpacing::updateSpacingForLastAddedMeasure(System* system)
{
HorizontalSpacingContext ctx;
ctx.system = system;
ctx.spatium = system->spatium();
ctx.xLeftBarrier = system->leftMargin();

Expand Down Expand Up @@ -345,7 +347,9 @@ void HorizontalSpacing::spaceAgainstPreviousSegments(Segment* segment, std::vect
} else if (timeSigAboveKeySigCase) {
x = xPrevSeg + segment->minLeft(); // align to the preceding keySig
} else {
double xNonCollision = xPrevSeg + minHorizontalDistance(prevSeg, segment, ctx.squeezeFactor);
double minHorDist = minHorizontalDistance(prevSeg, segment, ctx.squeezeFactor);
minHorDist = std::max(minHorDist, spaceLyricsAgainstBarlines(prevSeg, segment, ctx));
double xNonCollision = xPrevSeg + minHorDist;
x = std::max(x, xNonCollision);
}

Expand Down Expand Up @@ -449,6 +453,7 @@ void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vector<SegmentPositio

for (size_t i = segPositions.size(); i > 1; --i) {
double systemEdge = segPositions.back().xPosInSystemCoords + segPositions.back().segment->minRight();

SegmentPosition& segPos = segPositions[i - 1];
double x = segPos.xPosInSystemCoords;
Segment* seg = segPos.segment;
Expand Down Expand Up @@ -483,6 +488,65 @@ void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vector<SegmentPositio
}
}

double HorizontalSpacing::spaceLyricsAgainstBarlines(Segment* firstSeg, Segment* secondSeg, const HorizontalSpacingContext& ctx)
{
if (!(firstSeg->isType(SegmentType::ChordRest) && secondSeg->isType(SegmentType::BarLineType))
&& !(firstSeg->isType(SegmentType::BarLineType) && secondSeg->isType(SegmentType::ChordRest))) {
return 0.0;
}

double w = 0.0;

bool crSegIsBefore = firstSeg->isChordRestType();
Segment* crSegment = crSegIsBefore ? firstSeg : secondSeg;
Segment* barlineSegment = crSegIsBefore ? secondSeg : firstSeg;

staff_idx_t nstaves = crSegment->score()->nstaves();

for (staff_idx_t staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
if (!ctx.system->staff(staffIdx)->show()) {
continue;
}

staff_idx_t nextStaff = ctx.system->nextVisibleStaff(staffIdx);
if (nextStaff == muse::nidx) {
continue;
}

BarLine* barline = toBarLine(barlineSegment->element(staff2track(staffIdx)));
if (!barline || barline->spanStaff() == 0) {
continue;
}

Shape barlineShape = barline->shape().translate(barline->pos());

track_idx_t startTrack = staff2track(staffIdx);
track_idx_t endTrack = staff2track(nextStaff) + VOICES;
for (track_idx_t track = startTrack; track < endTrack; ++track) {
ChordRest* chordRest = toChordRest(crSegment->element(track));
if (!chordRest) {
continue;
}

for (Lyrics* lyrics : chordRest->lyrics()) {
if (!(lyrics->avoidBarlines() && lyrics->visible() && lyrics->autoplace())) {
continue;
}
staff_idx_t lyricsStaffIdx = lyrics->staffIdx();
if ((lyricsStaffIdx == staffIdx && lyrics->placeBelow()) || (lyricsStaffIdx == nextStaff && lyrics->placeAbove())) {
Shape lyricsShape = lyrics->shape().translate(lyrics->pos());
double minDist = crSegIsBefore ? lyricsShape.right() + barlineShape.left() : lyricsShape.left() + barlineShape.right();
const double padding = 0.3 * lyrics->fontMetrics().xHeight();
minDist += padding;
w = std::max(w, minDist);
}
}
}
}

return w;
}

void HorizontalSpacing::checkLargeTimeSigAgainstRightMargin(std::vector<SegmentPosition>& segPositions)
{
SegmentPosition& cautionaryTSSegPos = segPositions.back();
Expand Down
1 change: 1 addition & 0 deletions src/engraving/rendering/score/horizontalspacing.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class HorizontalSpacing
static bool stopCheckingPreviousSegments(const SegmentPosition& prev, const SegmentPosition& curSegPos);
static void checkLyricsAgainstLeftMargin(Segment* segment, double& x, HorizontalSpacingContext& ctx);
static void checkLyricsAgainstRightMargin(std::vector<SegmentPosition>& segPositions);
static double spaceLyricsAgainstBarlines(Segment* firstSeg, Segment* secondSeg, const HorizontalSpacingContext& ctx);
static void checkLargeTimeSigAgainstRightMargin(std::vector<SegmentPosition>& segPositions);
static void moveRightAlignedSegments(std::vector<SegmentPosition>& placedSegments, const HorizontalSpacingContext& ctx);

Expand Down
3 changes: 1 addition & 2 deletions src/engraving/rendering/score/lyricslayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ void LyricsLayout::layout(Lyrics* item, LayoutContext& ctx)
double x = o.x() - cr->x();

TLayout::layoutBaseTextBase1(item, ctx);

item->computeHighResShape(item->fontMetrics());
TLayout::computeTextHighResShape(item, ldata);

double centerAdjust = 0.0;
double leftAdjust = 0.0;
Expand Down
Loading
Loading