diff --git a/src/engraving/dom/stringdata.cpp b/src/engraving/dom/stringdata.cpp index 7a8fa6cebad11..461abaa357130 100644 --- a/src/engraving/dom/stringdata.cpp +++ b/src/engraving/dom/stringdata.cpp @@ -92,7 +92,7 @@ void StringData::set(const StringData& src) // from highest (0) to lowest (strings()-1) //--------------------------------------------------------- -bool StringData::convertPitch(int pitch, Staff* staff, int* string, int* fret) const +bool StringData::convertPitch(int pitch, const Staff* staff, int* string, int* fret) const { return convertPitch(pitch, pitchOffsetAt(staff), string, fret); } @@ -105,7 +105,7 @@ bool StringData::convertPitch(int pitch, Staff* staff, int* string, int* fret) c // Note: frets above max fret are accepted. //--------------------------------------------------------- -int StringData::getPitch(int string, int fret, Staff* staff) const +int StringData::getPitch(int string, int fret, const Staff* staff) const { return getPitch(string, fret, pitchOffsetAt(staff)); } @@ -117,7 +117,7 @@ int StringData::getPitch(int string, int fret, Staff* staff) const // Returns INVALID_FRET_INDEX if not possible //--------------------------------------------------------- -int StringData::fret(int pitch, int string, Staff* staff) const +int StringData::fret(int pitch, int string, const Staff* staff) const { return fret(pitch, string, pitchOffsetAt(staff)); } @@ -303,7 +303,7 @@ int StringData::frettedStrings() const // For string data calculations, pitch offset may depend on transposition, capos and, possibly, ottavas. //--------------------------------------------------------- -int StringData::pitchOffsetAt(Staff* staff) +int StringData::pitchOffsetAt(const Staff* staff) { return -(staff ? staff->part()->instrument()->transpose().chromatic : 0); } diff --git a/src/engraving/dom/stringdata.h b/src/engraving/dom/stringdata.h index 14c08708a173e..4783fbc00cfd8 100644 --- a/src/engraving/dom/stringdata.h +++ b/src/engraving/dom/stringdata.h @@ -60,11 +60,11 @@ class StringData bool isNull() const; void set(const StringData& src); - bool convertPitch(int pitch, Staff* staff, int* string, int* fret) const; - int fret(int pitch, int string, Staff* staff) const; + bool convertPitch(int pitch, const Staff* staff, int* string, int* fret) const; + int fret(int pitch, int string, const Staff* staff) const; void fretChords(Chord* chord) const; - int getPitch(int string, int fret, Staff* staff) const; - static int pitchOffsetAt(Staff* staff); + int getPitch(int string, int fret, const Staff* staff) const; + static int pitchOffsetAt(const Staff* staff); size_t strings() const { return m_stringTable.size(); } int frettedStrings() const; const std::vector& stringList() const { return m_stringTable; } diff --git a/src/engraving/rendering/dev/tlayout.cpp b/src/engraving/rendering/dev/tlayout.cpp index 9b2e8ba6f05f2..1574f8b8a2766 100644 --- a/src/engraving/rendering/dev/tlayout.cpp +++ b/src/engraving/rendering/dev/tlayout.cpp @@ -86,6 +86,7 @@ #include "dom/ledgerline.h" #include "dom/letring.h" #include "dom/line.h" +#include "dom/linkedobjects.h" #include "dom/lyrics.h" #include "dom/marker.h" @@ -4284,6 +4285,58 @@ void TLayout::layoutNote(const Note* item, Note::LayoutData* ldata) } const Staff* st = item->staff(); + auto tick = item->chord()->segment()->tick(); + auto stringData = item->staff()->part()->instrument(tick)->stringData(); + auto scoreElement = item->links() ? item->links()->mainElement() : nullptr; + Note* staffNote = nullptr; + size_t maxStrings = stringData->strings(); + int updatedString = item->string(); + int updatedFret = item->fret(); + if (scoreElement && scoreElement->isNote()) { + staffNote = toNote(scoreElement); + if (staffNote) { + // Handle String Text: + for (auto& e : staffNote->el()) { + if (e->isFingering()) { + if (auto fingering = toFingering(e)) { + if (fingering->textStyleType() == TextStyleType::STRING_NUMBER) { + int whichString = fingering->plainText().toInt(); + if (whichString <= maxStrings && whichString >= 0) { + updatedString = whichString; // E.g: 1-6 + updatedString -= 1; // E.g: 0-5 (internal representation) + updatedFret = stringData->fret(item->pitch(), updatedString, st); + } + } + } + } + } + const_cast(item)->setString(updatedString); + const_cast(item)->setFret(updatedFret); + } + } + + // Handle Capo Text: + // (Can be on either clef or tab staff) + Staff* clefStaff = staffNote ? staffNote->staff() : nullptr; + const Staff* tabStaff = item->staff(); + const Staff* staff = clefStaff ? clefStaff : tabStaff; + int capoPosition = staff->capo(tick).fretPosition; + if (capoPosition > 0) { + while (updatedFret < capoPosition) { + updatedString += 1; + updatedFret = stringData->fret(item->pitch(), updatedString, tabStaff); + if (updatedFret < 0 || updatedString > maxStrings) { + updatedFret = -1; + updatedString = item->string(); + break; + } else if (updatedFret < capoPosition) { + continue; + } + } + const_cast(item)->setString(updatedString); + const_cast(item)->setFret(updatedFret); + } + const StaffType* tab = st->staffTypeForElement(item); // not complete but we need systems to be laid out to add parenthesis if (item->fixed()) { @@ -4293,6 +4346,8 @@ void TLayout::layoutNote(const Note* item, Note::LayoutData* ldata) if (item->negativeFretUsed()) { const_cast(item)->setFretString(u"-" + item->fretString()); + } else if (item->fret() < 0) { + const_cast(item)->setFretString(u"?"); } if (item->displayFret() == Note::DisplayFretOption::ArtificialHarmonic) {