Skip to content

Commit

Permalink
Merge pull request #24011 from mike-spa/reimplementLedgerLines
Browse files Browse the repository at this point in the history
Reimplement ledger lines
  • Loading branch information
RomanPudashkin authored Aug 14, 2024
2 parents 1e8c2f5 + de9383d commit 4f2b9e2
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 95 deletions.
60 changes: 37 additions & 23 deletions src/engraving/dom/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ std::vector<int> Chord::noteDistances() const
Chord::Chord(Segment* parent)
: ChordRest(ElementType::CHORD, parent)
{
m_ledgerLines = 0;
m_stem = 0;
m_hook = 0;
m_stemDirection = DirectionV::AUTO;
Expand All @@ -285,7 +284,6 @@ Chord::Chord(const Chord& c, bool link)
if (link) {
score()->undo(new Link(this, const_cast<Chord*>(&c)));
}
m_ledgerLines = 0;

for (Note* onote : c.m_notes) {
Note* nnote = Factory::copyNote(*onote, link);
Expand Down Expand Up @@ -426,11 +424,7 @@ Chord::~Chord()
delete m_stemSlash;
delete m_stem;
delete m_hook;
for (LedgerLine* ll = m_ledgerLines; ll;) {
LedgerLine* llNext = ll->next();
delete ll;
ll = llNext;
}
muse::DeleteAll(m_ledgerLines);
muse::DeleteAll(m_graceNotes);
muse::DeleteAll(m_notes);
}
Expand Down Expand Up @@ -918,7 +912,7 @@ double Chord::maxHeadWidth() const
// addLedgerLines
//---------------------------------------------------------

void Chord::addLedgerLines()
void Chord::updateLedgerLines()
{
// initialize for palette
track_idx_t track = 0; // the track lines belong to
Expand Down Expand Up @@ -957,6 +951,7 @@ void Chord::addLedgerLines()
// notes are scanned twice from outside (bottom or top) toward the staff
// each pass stops at the first note without ledger lines
size_t n = m_notes.size();
std::vector<LedgerLineData> ledgerLineData;
for (size_t j = 0; j < 2; j++) { // notes are scanned twice...
int from, delta;
std::vector<LedgerLineData> vecLines;
Expand Down Expand Up @@ -1053,22 +1048,24 @@ void Chord::addLedgerLines()
}
}
if (minLine < 0 || maxLine > lineBelow) {
double _spatium = spatium();
double stepDistance = lineDistance * 0.5;
for (auto lld : vecLines) {
LedgerLine* h = new LedgerLine(score()->dummy());
h->setParent(this);
h->setTrack(track);
h->setVisible(lld.visible && staffVisible);
h->setLen(lld.maxX - lld.minX);
h->setPos(lld.minX, lld.line * _spatium * stepDistance);
h->setNext(m_ledgerLines);
m_ledgerLines = h;
}
ledgerLineData.insert(ledgerLineData.end(), vecLines.begin(), vecLines.end());
}
}

for (LedgerLine* ll = m_ledgerLines; ll; ll = ll->next()) {
double _spatium = spatium();
double stepDistance = lineDistance * 0.5;
resizeLedgerLinesTo(ledgerLineData.size());
for (size_t i = 0; i < ledgerLineData.size(); ++i) {
LedgerLineData lld = ledgerLineData[i];
LedgerLine* h = m_ledgerLines[i];
h->setParent(this);
h->setTrack(track);
h->setVisible(lld.visible && staffVisible);
h->setLen(lld.maxX - lld.minX);
h->setPos(lld.minX, lld.line * _spatium * stepDistance);
}

for (LedgerLine* ll : m_ledgerLines) {
renderer()->layoutItem(ll);
}
}
Expand Down Expand Up @@ -1155,7 +1152,7 @@ void Chord::processSiblings(std::function<void(EngravingItem*)> func, bool inclu
func(m_tremoloSingleChord);
}
if (includeTemporarySiblings) {
for (LedgerLine* ll = m_ledgerLines; ll; ll = ll->next()) {
for (LedgerLine* ll : m_ledgerLines) {
func(ll);
}
}
Expand Down Expand Up @@ -1552,6 +1549,23 @@ Chord* Chord::next() const
return nullptr;
}

void Chord::resizeLedgerLinesTo(size_t newSize)
{
int ledgerLineCountDiff = newSize - m_ledgerLines.size();
if (ledgerLineCountDiff > 0) {
for (int i = 0; i < ledgerLineCountDiff; ++i) {
m_ledgerLines.push_back(new LedgerLine(score()->dummy()));
}
} else {
for (int i = 0; i < std::abs(ledgerLineCountDiff); ++i) {
delete m_ledgerLines.back();
m_ledgerLines.pop_back();
}
}

assert(m_ledgerLines.size() == newSize);
}

void Chord::setBeamExtension(double extension)
{
if (m_stem) {
Expand Down Expand Up @@ -1812,7 +1826,7 @@ void Chord::scanElements(void* data, void (* func)(void*, EngravingItem*), bool
}
const Staff* st = staff();
if ((st && st->showLedgerLines(tick())) || !st) { // also for palette
for (LedgerLine* ll = m_ledgerLines; ll; ll = ll->next()) {
for (LedgerLine* ll : m_ledgerLines) {
func(data, ll);
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/engraving/dom/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ class Chord final : public ChordRest
bool isUiItem() const { return m_isUiItem; }
void setIsUiItem(bool val) { m_isUiItem = val; }

LedgerLine* ledgerLines() { return m_ledgerLines; }
const LedgerLine* ledgerLines() const { return m_ledgerLines; }
void setLedgerLine(LedgerLine* l) { m_ledgerLines = l; }
void addLedgerLines();
const std::vector<LedgerLine*>& ledgerLines() const { return m_ledgerLines; }
void resizeLedgerLinesTo(size_t newSize);
void updateLedgerLines();

double defaultStemLength() const { return m_defaultStemLength; }
void setDefaultStemLength(double l) { m_defaultStemLength = l; }
Expand Down Expand Up @@ -352,7 +351,7 @@ class Chord final : public ChordRest
void processSiblings(std::function<void(EngravingItem*)> func, bool includeTemporarySiblings) const;

std::vector<Note*> m_notes; // sorted to decreasing line step
LedgerLine* m_ledgerLines = nullptr; // single linked list
std::vector<LedgerLine*> m_ledgerLines;

Stem* m_stem = nullptr;
Hook* m_hook = nullptr;
Expand Down
1 change: 0 additions & 1 deletion src/engraving/dom/ledgerline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ LedgerLine::LedgerLine(EngravingItem* s)
{
setSelectable(false);
m_len = 0.;
m_next = 0;
}

LedgerLine::~LedgerLine()
Expand Down
3 changes: 0 additions & 3 deletions src/engraving/dom/ledgerline.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class LedgerLine final : public EngravingItem
bool vertical() const { return m_vertical; }

double measureXPos() const;
LedgerLine* next() const { return m_next; }
void setNext(LedgerLine* l) { m_next = l; }

void spatiumChanged(double /*oldValue*/, double /*newValue*/) override;

Expand All @@ -72,7 +70,6 @@ class LedgerLine final : public EngravingItem
private:

double m_len = 0.0;
LedgerLine* m_next = nullptr;
bool m_vertical = false;
};
} // namespace mu::engraving
Expand Down
6 changes: 2 additions & 4 deletions src/engraving/dom/scoretree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,8 @@ EngravingObjectList Chord::scanChildren() const
children.push_back(m_stemSlash);
}

LedgerLine* ledgerLines = m_ledgerLines;
while (ledgerLines) {
children.push_back(ledgerLines);
ledgerLines = ledgerLines->next();
for (LedgerLine* ledg : m_ledgerLines) {
children.push_back(ledg);
}

for (EngravingObject* child : ChordRest::scanChildren()) {
Expand Down
4 changes: 1 addition & 3 deletions src/engraving/rendering/dev/accidentalslayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,8 @@ void AccidentalsLayout::createChordsShape(AccidentalsLayoutContext& ctx)

for (const Chord* chord : ctx.chords) {
PointF chordPos = keepAccidentalsCloseToChord(chord) ? PointF() : chord->pos();
const LedgerLine* ledger = chord->ledgerLines();
while (ledger) {
for (const LedgerLine* ledger : chord->ledgerLines()) {
ctx.chordsShape.add(ledger->shape().translate(ledger->pos() + chordPos));
ledger = ledger->next();
}
for (const Note* note : chord->notes()) {
SymId noteSym = note->ldata()->cachedNoteheadSym;
Expand Down
33 changes: 7 additions & 26 deletions src/engraving/rendering/dev/chordlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,6 @@ void ChordLayout::layoutTablature(Chord* item, LayoutContext& ctx)
layoutTablature(c, ctx);
}

while (item->ledgerLines()) {
LedgerLine* l = item->ledgerLines()->next();
delete item->ledgerLines();
item->setLedgerLine(l);
}

double lll = 0.0; // space to leave at left of chord
double rrr = 0.0; // space to leave at right of chord
Note* upnote = item->upNote();
Expand Down Expand Up @@ -434,20 +428,16 @@ void ChordLayout::layoutTablature(Chord* item, LayoutContext& ctx)

// create ledger lines, if required (in some historic styles)
if (ledgerLines > 0) {
// there seems to be no need for widening 'ledger lines' beyond fret mark widths; more 'on the field'
// tests and usage will show if this depends on the metrics of the specific fonts used or not.
// double extraLen = style().styleS(Sid::ledgerLineLength).val() * _spatium;
item->resizeLedgerLinesTo(ledgerLines);
double extraLen = 0;
double llX = stemX - (headWidth + extraLen) * 0.5;
for (int i = 0; i < ledgerLines; i++) {
LedgerLine* ldgLin = new LedgerLine(ctx.mutDom().dummyParent());
LedgerLine* ldgLin = item->ledgerLines()[i];
ldgLin->setParent(item);
ldgLin->setTrack(item->track());
ldgLin->setVisible(item->visible());
ldgLin->setLen(headWidth + extraLen);
ldgLin->setPos(llX, llY);
ldgLin->setNext(item->ledgerLines());
item->setLedgerLine(ldgLin);
TLayout::layoutLedgerLine(ldgLin, ctx);
llY += lineDist / ledgerLines;
}
Expand Down Expand Up @@ -2546,19 +2536,10 @@ void ChordLayout::layoutChords3(const std::vector<Chord*>& chords,

void ChordLayout::layoutLedgerLines(const std::vector<Chord*>& chords)
{
auto redoLedgerLines = [] (Chord* item) {
while (item->ledgerLines()) {
LedgerLine* l = item->ledgerLines()->next();
delete item->ledgerLines();
item->setLedgerLine(l);
}
item->addLedgerLines();
};

for (Chord* item : chords) {
redoLedgerLines(item);
item->updateLedgerLines();
for (Chord* grace : item->graceNotes()) {
redoLedgerLines(grace);
grace->updateLedgerLines();
}
}
}
Expand Down Expand Up @@ -3274,8 +3255,8 @@ void ChordLayout::layoutNote2(Note* item, LayoutContext& ctx)
e->mutldata()->setMag(item->mag());
Shape noteShape = item->shape();
noteShape.remove_if([e](ShapeElement& s) { return s.item() == e || s.item()->isBend(); });
LedgerLine* ledger = item->line() < -1 || item->line() > item->staff()->lines(item->tick())
? chord->ledgerLines() : nullptr;
LedgerLine* ledger = (item->line() < -1 || item->line() > item->staff()->lines(item->tick())) && !chord->ledgerLines().empty()
? chord->ledgerLines().front() : nullptr;
if (ledger) {
noteShape.add(ledger->shape().translate(ledger->pos() - item->pos()));
}
Expand Down Expand Up @@ -3493,7 +3474,7 @@ void ChordLayout::fillShape(const Chord* item, ChordRest::LayoutData* ldata)

shape.add(chordRestShape(item)); // add lyrics

for (const LedgerLine* l = item->ledgerLines(); l; l = l->next()) {
for (const LedgerLine* l : item->ledgerLines()) {
shape.add(l->shape().translate(l->pos() - l->staffOffset()));
}

Expand Down
8 changes: 4 additions & 4 deletions src/engraving/rendering/dev/slurtielayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ void SlurTieLayout::adjustX(TieSegment* tieSegment, SlurTiePos& sPos, Grip start
void SlurTieLayout::adjustXforLedgerLines(TieSegment* tieSegment, bool start, Chord* chord, Note* note,
const PointF& chordSystemPos, double padding, double& resultingX)
{
if (tieSegment->tie()->isInside() || !chord->ledgerLines()) {
if (tieSegment->tie()->isInside() || chord->ledgerLines().empty()) {
return;
}

Expand All @@ -1660,7 +1660,7 @@ void SlurTieLayout::adjustXforLedgerLines(TieSegment* tieSegment, bool start, Ch

bool ledgersAbove = false;
bool ledgersBelow = false;
for (LedgerLine* ledger = chord->ledgerLines(); ledger; ledger = ledger->next()) {
for (LedgerLine* ledger : chord->ledgerLines()) {
if (ledger->y() < 0.0) {
ledgersAbove = true;
} else {
Expand Down Expand Up @@ -1697,7 +1697,7 @@ void SlurTieLayout::adjustYforLedgerLines(TieSegment* tieSegment, SlurTiePos& sP
}

Chord* chord = note->chord();
if (!chord->ledgerLines()) {
if (chord->ledgerLines().empty()) {
return;
}
PointF chordSystemPos = chord->pos() + chord->segment()->pos() + chord->segment()->measure()->pos();
Expand All @@ -1706,7 +1706,7 @@ void SlurTieLayout::adjustYforLedgerLines(TieSegment* tieSegment, SlurTiePos& sP
int upSign = tie->up() ? -1 : 1;
double margin = 0.4 * spatium;

for (LedgerLine* ledger = chord->ledgerLines(); ledger; ledger = ledger->next()) {
for (LedgerLine* ledger : chord->ledgerLines()) {
PointF ledgerPos = ledger->pos() + chordSystemPos;
double yDiff = upSign * (ledgerPos.y() - tiePoint.y());
bool collision = yDiff > 0 && yDiff < margin;
Expand Down
29 changes: 7 additions & 22 deletions src/engraving/rendering/stable/chordlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ void ChordLayout::layoutPitched(Chord* item, LayoutContext& ctx)

double chordX = (item->noteType() == NoteType::NORMAL) ? item->ldata()->pos().x() : 0.0;

while (item->ledgerLines()) {
LedgerLine* l = item->ledgerLines()->next();
delete item->ledgerLines();
item->setLedgerLine(l);
}

double lll = 0.0; // space to leave at left of chord
double rrr = 0.0; // space to leave at right of chord
double lhead = 0.0; // amount of notehead to left of chord origin
Expand Down Expand Up @@ -169,7 +163,7 @@ void ChordLayout::layoutPitched(Chord* item, LayoutContext& ctx)
// create ledger lines
//-----------------------------------------

item->addLedgerLines();
item->updateLedgerLines();

// If item has an arpeggio: mark chords which are part of the arpeggio
if (item->arpeggio()) {
Expand Down Expand Up @@ -335,12 +329,6 @@ void ChordLayout::layoutTablature(Chord* item, LayoutContext& ctx)
layoutTablature(c, ctx);
}

while (item->ledgerLines()) {
LedgerLine* l = item->ledgerLines()->next();
delete item->ledgerLines();
item->setLedgerLine(l);
}

double lll = 0.0; // space to leave at left of chord
double rrr = 0.0; // space to leave at right of chord
Note* upnote = item->upNote();
Expand Down Expand Up @@ -425,20 +413,16 @@ void ChordLayout::layoutTablature(Chord* item, LayoutContext& ctx)

// create ledger lines, if required (in some historic styles)
if (ledgerLines > 0) {
// there seems to be no need for widening 'ledger lines' beyond fret mark widths; more 'on the field'
// tests and usage will show if this depends on the metrics of the specific fonts used or not.
// double extraLen = style().styleS(Sid::ledgerLineLength).val() * _spatium;
item->resizeLedgerLinesTo(ledgerLines);
double extraLen = 0;
double llX = stemX - (headWidth + extraLen) * 0.5;
for (int i = 0; i < ledgerLines; i++) {
LedgerLine* ldgLin = new LedgerLine(ctx.mutDom().dummyParent());
LedgerLine* ldgLin = item->ledgerLines()[i];
ldgLin->setParent(item);
ldgLin->setTrack(item->track());
ldgLin->setVisible(item->visible());
ldgLin->setLen(headWidth + extraLen);
ldgLin->setPos(llX, llY);
ldgLin->setNext(item->ledgerLines());
item->setLedgerLine(ldgLin);
TLayout::layoutLedgerLine(ldgLin, ctx);
llY += lineDist / ledgerLines;
}
Expand Down Expand Up @@ -3499,8 +3483,9 @@ void ChordLayout::layoutNote2(Note* item, LayoutContext& ctx)
e->mutldata()->setMag(item->mag());
Shape noteShape = item->shape();
noteShape.remove_if([e](ShapeElement& s) { return s.item() == e || s.item()->isBend(); });
LedgerLine* ledger = item->line() < -1 || item->line() > item->staff()->lines(item->tick())
? item->chord()->ledgerLines() : nullptr;
LedgerLine* ledger = (item->line() < -1 || item->line() > item->staff()->lines(item->tick()))
&& !item->chord()->ledgerLines().empty()
? item->chord()->ledgerLines().front() : nullptr;
if (ledger) {
noteShape.add(ledger->shape().translate(ledger->pos() - item->pos()));
}
Expand Down Expand Up @@ -3729,7 +3714,7 @@ void ChordLayout::fillShape(const Chord* item, ChordRest::LayoutData* ldata, con

shape.add(chordRestShape(item, conf)); // add lyrics

for (const LedgerLine* l = item->ledgerLines(); l; l = l->next()) {
for (const LedgerLine* l : item->ledgerLines()) {
shape.add(l->shape().translate(l->pos()));
}

Expand Down
Loading

0 comments on commit 4f2b9e2

Please sign in to comment.