Skip to content

Commit

Permalink
MASKING
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-spa committed Jan 27, 2025
1 parent 5b330c5 commit 0d0fbd7
Show file tree
Hide file tree
Showing 35 changed files with 917 additions and 364 deletions.
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
18 changes: 18 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)
{
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
2 changes: 2 additions & 0 deletions src/engraving/infrastructure/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,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 RectF& bbox() const;
double minVerticalDistance(const Shape&, double minHorizontalClearance = 0.0) const;
Expand Down
67 changes: 65 additions & 2 deletions 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 @@ -448,7 +452,11 @@ void HorizontalSpacing::checkLyricsAgainstRightMargin(std::vector<SegmentPositio
int chordRestSegmentsCount = 0;

for (size_t i = segPositions.size(); i > 1; --i) {
double systemEdge = segPositions.back().xPosInSystemCoords + segPositions.back().segment->minRight();
Segment* lastSeg = segPositions.back().segment;
double systemEdge = segPositions.back().xPosInSystemCoords
+ (lastSeg->isType(SegmentType::BarLineType) ? 0.0 : lastSeg->minRight());
systemEdge -= lastSeg->style().styleMM(Sid::lyricsMinDistance);

SegmentPosition& segPos = segPositions[i - 1];
double x = segPos.xPosInSystemCoords;
Segment* seg = segPos.segment;
Expand Down Expand Up @@ -483,6 +491,61 @@ 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;
}

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

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

staff_idx_t nextStaff = ctx.system->nextVisibleStaff(staffIdx);
track_idx_t startTrack = staff2track(staffIdx);
track_idx_t endTrack = (nextStaff != muse::nidx ? staff2track(nextStaff) : startTrack) + 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

0 comments on commit 0d0fbd7

Please sign in to comment.