Skip to content

Commit

Permalink
Merge pull request #22434 from mike-spa/lyricsRevampAndNewOptions
Browse files Browse the repository at this point in the history
Lyrics revamp and new options
  • Loading branch information
RomanPudashkin authored May 15, 2024
2 parents b38394f + b5fbd42 commit fdf6726
Show file tree
Hide file tree
Showing 41 changed files with 2,103 additions and 2,280 deletions.
2 changes: 1 addition & 1 deletion src/engraving/compat/engravingcompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void EngravingCompat::correctPedalEndPoints(MasterScore* score)
for (auto pair : score->spanner()) {
Spanner* spanner = pair.second;
if (spanner->isPedal() && toPedal(spanner)->endHookType() == HookType::HOOK_45) {
ChordRest* endCR = score->findCRinStaff(spanner->tick2(), track2staff(spanner->track()));
ChordRest* endCR = score->findChordRestEndingBeforeTickInStaff(spanner->tick2(), track2staff(spanner->track()));
if (endCR) {
for (EngravingObject* item : spanner->linkList()) {
toSpanner(item)->setTick2(endCR->tick());
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/chordtextlinebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ ChordTextLineBase::ChordTextLineBase(const ElementType& type, EngravingItem* par

void ChordTextLineBase::doComputeEndElement()
{
setEndElement(score()->findCRinStaff(tick2(), track2staff(track2())));
setEndElement(score()->findChordRestEndingBeforeTickInStaff(tick2(), track2staff(track2())));
}
}
1 change: 0 additions & 1 deletion src/engraving/dom/engravingitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ enum class KerningType
NON_KERNING,
LIMITED_KERNING,
SAME_VOICE_LIMIT,
KERNING_UNTIL_ORIGIN,
ALLOW_COLLISION,
NOT_SET,
};
Expand Down
45 changes: 10 additions & 35 deletions src/engraving/dom/lyrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,6 @@ void Lyrics::scanElements(void* data, void (* func)(void*, EngravingItem*), bool
_separator->scanElements(data, func, all); */
}

//---------------------------------------------------------
// layout2
// compute vertical position
//---------------------------------------------------------

void Lyrics::layout2(int nAbove)
{
LayoutData* ldata = mutldata();
double lh = lineSpacing() * style().styleD(Sid::lyricsLineHeight);

if (placeBelow()) {
double yo = segment()->measure()->system()->staff(staffIdx())->bbox().height();
ldata->setPosY(lh * (m_no - nAbove) + yo - chordRest()->y());
ldata->move(styleValue(Pid::OFFSET, Sid::lyricsPosBelow).value<PointF>());
} else {
ldata->setPosY(-lh * (nAbove - m_no - 1) - chordRest()->y());
ldata->move(styleValue(Pid::OFFSET, Sid::lyricsPosAbove).value<PointF>());
}
}

//---------------------------------------------------------
// paste
//---------------------------------------------------------
Expand Down Expand Up @@ -509,6 +489,16 @@ void Lyrics::triggerLayout() const
}
}

double Lyrics::yRelativeToStaff() const
{
return pos().y() + chordRest()->pos().y();
}

void Lyrics::setYRelativeToStaff(double y)
{
mutldata()->setPosY(y - chordRest()->pos().y());
}

//---------------------------------------------------------
// forAllLyrics
//---------------------------------------------------------
Expand Down Expand Up @@ -545,21 +535,6 @@ void Lyrics::undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps
}
TextBase::undoChangeProperty(id, v, ps);
return;
} else if (id == Pid::AUTOPLACE && v.toBool() != autoplace()) {
if (v.toBool()) {
// setting autoplace
// reset offset
undoResetProperty(Pid::OFFSET);
} else {
// unsetting autoplace
// rebase offset
PointF off = offset();
double y = pos().y() - propertyDefault(Pid::OFFSET).value<PointF>().y();
off.ry() = placeAbove() ? y : y - staff()->staffHeight();
undoChangeProperty(Pid::OFFSET, off, PropertyFlags::UNSTYLED);
}
TextBase::undoChangeProperty(id, v, ps);
return;
}

TextBase::undoChangeProperty(id, v, ps);
Expand Down
28 changes: 14 additions & 14 deletions src/engraving/dom/lyrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ class Lyrics final : public TextBase
Measure* measure() const { return toMeasure(explicitParent()->explicitParent()->explicitParent()); }
ChordRest* chordRest() const { return toChordRest(explicitParent()); }

void layout2(int);

void scanElements(void* data, void (* func)(void*, EngravingItem*), bool all=true) override;

int subtype() const override { return m_no; }
Expand Down Expand Up @@ -105,6 +103,9 @@ class Lyrics final : public TextBase
PropertyValue propertyDefault(Pid id) const override;
void triggerLayout() const override;

double yRelativeToStaff() const;
void setYRelativeToStaff(double y);

protected:
int m_no = 0; // row index
bool m_even = false;
Expand Down Expand Up @@ -150,8 +151,6 @@ class LyricsLine final : public SLine
bool isDash() const { return !isEndMelisma(); }
bool setProperty(Pid propertyId, const PropertyValue& v) override;

PointF linePos(Grip grip, System** system) const override;

protected:
Lyrics* m_nextLyrics = nullptr;

Expand All @@ -173,19 +172,20 @@ class LyricsLineSegment final : public LineSegment

LyricsLineSegment* clone() const override { return new LyricsLineSegment(*this); }

int numOfDashes() const { return m_numOfDashes; }
void setNumOfDashes(int val) { m_numOfDashes = val; }

double dashLength() const { return m_dashLength; }
void setDashLength(double val) { m_dashLength = val; }

// helper functions
LyricsLine* lyricsLine() const { return toLyricsLine(spanner()); }
Lyrics* lyrics() const { return lyricsLine()->lyrics(); }

protected:
int m_numOfDashes = 0;
double m_dashLength = 0.0;
double baseLineShift() const;

struct LayoutData : public LineSegment::LayoutData {
public:
const std::vector<LineF>& dashes() const { return m_dashes; }
void clearDashes() { m_dashes.clear(); }
void addDash(const LineF& dash) { m_dashes.push_back(dash); }
private:
std::vector<LineF> m_dashes;
};
DECLARE_LAYOUTDATA_METHODS(LyricsLineSegment)
};
} // namespace mu::engraving
#endif
68 changes: 14 additions & 54 deletions src/engraving/dom/lyricsline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,68 +118,18 @@ bool LyricsLine::setProperty(Pid propertyId, const engraving::PropertyValue& v)
return true;
}

PointF LyricsLine::linePos(Grip grip, System** system) const
{
if (grip == Grip::START) {
return PointF(); // Start is computed elsewhere
}

EngravingItem* endEl = endElement();
ChordRest* endCr = endEl && endEl->isChordRest() ? toChordRest(endEl) : nullptr;
if (!endCr) {
return PointF();
}

if (endCr->track() != track()) {
EngravingItem* cr = endCr->segment()->elementAt(track());
if (cr) {
endCr = toChordRest(cr);
}
}

Segment* endSeg = endCr->segment();
*system = endSeg->measure()->system();
double x = endSeg->x() + endSeg->measure()->x();
if (endCr) {
if (endCr->isChord()) {
Chord* endChord = toChord(endCr);
Note* endNote = endChord->up() ? endChord->downNote() : endChord->upNote();
x += endNote->x() + endNote->headWidth();
} else {
x += endCr->width();
}
}

return PointF(x, 0.0);
}

void LyricsLine::doComputeEndElement()
{
if (!isEndMelisma()) {
Spanner::doComputeEndElement();
return;
}

// TODO: review this hack
// lyrics endTick should already indicate the segment we want
// except for TEMP_MELISMA_TICKS case
Lyrics* l = lyrics();
Fraction tick = (l->ticks() == Lyrics::TEMP_MELISMA_TICKS) ? l->tick() : l->endTick();
Segment* s = score()->tick2segment(tick, true, SegmentType::ChordRest);
if (!s) {
LOGD("%s no end segment for tick %d", typeName(), tick.ticks());
return;
}
voice_idx_t t = trackZeroVoice(track2());
// take the first chordrest we can find;
// linePos will substitute one in current voice if available
for (voice_idx_t v = 0; v < VOICES; ++v) {
setEndElement(s->element(t + v));
if (endElement()) {
break;
}
setEndElement(score()->findChordRestEndingBeforeTickInTrack(tick2(), track()));

if (!endElement()) {
setEndElement(score()->findChordRestEndingBeforeTickInStaff(tick2(), track2staff(track())));
}
return;
}

//=========================================================
Expand All @@ -191,4 +141,14 @@ LyricsLineSegment::LyricsLineSegment(LyricsLine* sp, System* parent)
{
setGenerated(true);
}

double LyricsLineSegment::baseLineShift() const
{
if (lyricsLine()->isEndMelisma()) {
return -0.5 * lyricsLine()->lineWidth();
}

Lyrics* lyrics = lyricsLine()->lyrics();
return -style().styleD(Sid::lyricsDashYposRatio) * lyrics->fontMetrics().xHeight();
}
}
2 changes: 1 addition & 1 deletion src/engraving/dom/ottava.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,6 @@ PointF Ottava::linePos(Grip grip, System** system) const

void Ottava::doComputeEndElement()
{
setEndElement(score()->findCRinStaff(tick2(), track2staff(track())));
setEndElement(score()->findChordRestEndingBeforeTickInStaff(tick2(), track2staff(track())));
}
}
24 changes: 23 additions & 1 deletion src/engraving/dom/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4503,7 +4503,7 @@ ChordRest* Score::findCR(Fraction tick, track_idx_t track) const
// find last chord/rest on staff that ends before tick
//---------------------------------------------------------

ChordRest* Score::findCRinStaff(const Fraction& tick, staff_idx_t staffIdx) const
ChordRest* Score::findChordRestEndingBeforeTickInStaff(const Fraction& tick, staff_idx_t staffIdx) const
{
Fraction ptick = tick - Fraction::fromTicks(1);
Measure* m = tick2measureMM(ptick);
Expand Down Expand Up @@ -4545,6 +4545,28 @@ ChordRest* Score::findCRinStaff(const Fraction& tick, staff_idx_t staffIdx) cons
return 0;
}

ChordRest* Score::findChordRestEndingBeforeTickInTrack(const Fraction& tick, track_idx_t trackIdx) const
{
Measure* measure = tick2measureMM(tick - Fraction::eps());
if (!measure) {
LOGD("findCRinStaff: no measure for tick %d", tick.ticks());
return nullptr;
}

for (const Segment* segment = measure->last(); segment; segment = segment->prev()) {
EngravingItem* item = segment->elementAt(trackIdx);
if (!segment->isChordRestType() || !item) {
continue;
}
ChordRest* chordRest = toChordRest(item);
if (segment->tick() + chordRest->actualTicks() <= tick) {
return chordRest;
}
}

return nullptr;
}

//---------------------------------------------------------
// cmdNextPrevSystem
//---------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion src/engraving/dom/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,8 @@ class Score : public EngravingObject
Hairpin* addHairpin(HairpinType, ChordRest* cr1, ChordRest* cr2 = nullptr);

ChordRest* findCR(Fraction tick, track_idx_t track) const;
ChordRest* findCRinStaff(const Fraction& tick, staff_idx_t staffIdx) const;
ChordRest* findChordRestEndingBeforeTickInStaff(const Fraction& tick, staff_idx_t staffIdx) const;
ChordRest* findChordRestEndingBeforeTickInTrack(const Fraction& tick, track_idx_t trackIdx) const;
void insertTime(const Fraction& tickPos, const Fraction& tickLen);

std::shared_ptr<IEngravingFont> engravingFont() const { return m_engravingFont; }
Expand Down
24 changes: 24 additions & 0 deletions src/engraving/dom/textbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,30 @@ RectF TextBase::pageRectangle() const
return abbox();
}

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 (int 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
5 changes: 5 additions & 0 deletions src/engraving/dom/textbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ 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&);

std::vector<LineF> dragAnchorLines() const override;
Expand Down Expand Up @@ -459,6 +462,8 @@ class TextBase : public EngravingItem
size_t rows() const { return blocks.size(); }
const TextBlock& textBlock(size_t i) const { return blocks.at(i); }
TextBlock& textBlock(size_t i) { return blocks[i]; }

ld_field<Shape> highResShape = { "[TextBase] highResShape", Shape() };
};
DECLARE_LAYOUTDATA_METHODS(TextBase)

Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/trill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,6 @@ String Trill::accessibleInfo() const

void Trill::doComputeEndElement()
{
setEndElement(score()->findCRinStaff(tick2(), track2staff(track2())));
setEndElement(score()->findChordRestEndingBeforeTickInStaff(tick2(), track2staff(track2())));
}
}
19 changes: 19 additions & 0 deletions src/engraving/infrastructure/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ Shape Shape::scaled(const SizeF& mag) const
return s;
}

Shape& Shape::adjust(double xp1, double yp1, double xp2, double yp2)
{
for (ShapeElement& element : m_elements) {
element.adjust(xp1, yp1, xp2, yp2);
}
return *this;
}

Shape Shape::adjusted(double xp1, double yp1, double xp2, double yp2) const
{
Shape s;
s.m_elements.reserve(m_elements.size());
for (const ShapeElement& element : m_elements) {
s.add(element.adjusted(xp1, yp1, xp2, yp2));
}

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 @@ -144,6 +144,8 @@ class Shape
Shape translated(const PointF&) const;
Shape& scale(const SizeF&);
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;

const RectF& bbox() const;
double minVerticalDistance(const Shape&) const;
Expand Down
Loading

0 comments on commit fdf6726

Please sign in to comment.