Skip to content

Commit fcfa166

Browse files
committed
Read/write lyric lines
1 parent 51efaf1 commit fcfa166

File tree

12 files changed

+93
-35
lines changed

12 files changed

+93
-35
lines changed

src/engraving/dom/factory.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ EngravingItem* Factory::doCreateItem(ElementType type, EngravingItem* parent)
222222
case ElementType::GUITAR_BEND: return new GuitarBend(parent->isNote() ? toNote(parent) : dummy->note());
223223
case ElementType::TREMOLOBAR: return new TremoloBar(parent);
224224
case ElementType::LYRICS: return new Lyrics(parent->isChordRest() ? toChordRest(parent) : dummy->chord());
225+
case ElementType::LYRICSLINE: return new LyricsLine(parent);
225226
case ElementType::FIGURED_BASS: return new FiguredBass(parent->isSegment() ? toSegment(parent) : dummy->segment());
226227
case ElementType::STEM: return new Stem(parent->isChord() ? toChord(parent) : dummy->chord());
227228
case ElementType::SLUR: return new Slur(parent);
@@ -247,7 +248,6 @@ EngravingItem* Factory::doCreateItem(ElementType type, EngravingItem* parent)
247248
case ElementType::PARTIAL_LYRICSLINE: return new PartialLyricsLine(parent);
248249
case ElementType::PARENTHESIS: return new Parenthesis(parent);
249250

250-
case ElementType::LYRICSLINE:
251251
case ElementType::TEXTLINE_BASE:
252252
case ElementType::TEXTLINE_SEGMENT:
253253
case ElementType::GLISSANDO_SEGMENT:
@@ -446,6 +446,9 @@ MAKE_ITEM_IMPL(LayoutBreak, MeasureBase)
446446
CREATE_ITEM_IMPL(Lyrics, ElementType::LYRICS, ChordRest, isAccessibleEnabled)
447447
COPY_ITEM_IMPL(Lyrics)
448448

449+
CREATE_ITEM_IMPL(LyricsLine, ElementType::LYRICSLINE, EngravingItem, isAccessibleEnabled)
450+
COPY_ITEM_IMPL(LyricsLine)
451+
449452
CREATE_ITEM_IMPL(Measure, ElementType::MEASURE, System, isAccessibleEnabled)
450453
COPY_ITEM_IMPL(Measure)
451454

src/engraving/dom/factory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ class Factory
129129
static Lyrics* createLyrics(ChordRest* parent, bool isAccessibleEnabled = true);
130130
static Lyrics* copyLyrics(const Lyrics& src);
131131

132+
static LyricsLine* createLyricsLine(EngravingItem* parent, bool isAccessibleEnabled = true);
133+
static LyricsLine* copyLyricsLine(const LyricsLine& src);
134+
132135
static Measure* createMeasure(System* parent, bool isAccessibleEnabled = true);
133136
static Measure* copyMeasure(const Measure& src);
134137

src/engraving/dom/lyricsline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ bool LyricsLine::setProperty(Pid propertyId, const engraving::PropertyValue& v)
119119
}
120120
break;
121121
}
122+
setGenerated(false);
122123
triggerLayout();
123124
return true;
124125
}

src/engraving/dom/utils.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,4 +1847,33 @@ std::vector<EngravingItem*> filterTargetElements(const Selection& sel, Engraving
18471847
}
18481848
return result;
18491849
}
1850+
1851+
Lyrics* searchNextLyrics(Segment* s, staff_idx_t staffIdx, int verse, PlacementV p)
1852+
{
1853+
Lyrics* l = nullptr;
1854+
const Segment* originalSeg = s;
1855+
while ((s = s->next1(SegmentType::ChordRest))) {
1856+
if (!segmentsAreAdjacentInRepeatStructure(originalSeg, s)) {
1857+
return nullptr;
1858+
}
1859+
1860+
track_idx_t strack = staffIdx * VOICES;
1861+
track_idx_t etrack = strack + VOICES;
1862+
// search through all tracks of current staff looking for a lyric in specified verse
1863+
for (track_idx_t track = strack; track < etrack; ++track) {
1864+
ChordRest* cr = toChordRest(s->element(track));
1865+
if (cr) {
1866+
// cr with lyrics found, but does it have a syllable in specified verse?
1867+
l = cr->lyrics(verse, p);
1868+
if (l) {
1869+
break;
1870+
}
1871+
}
1872+
}
1873+
if (l) {
1874+
break;
1875+
}
1876+
}
1877+
return l;
1878+
}
18501879
}

src/engraving/dom/utils.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,21 @@
2929
#include "draw/types/geometry.h"
3030

3131
namespace mu::engraving {
32-
class Score;
3332
class Chord;
3433
class ChordRest;
3534
class EngravingItem;
3635
class KeySig;
36+
class Lyrics;
37+
class Measure;
3738
class Note;
3839
class Rest;
39-
class Measure;
40+
class Score;
4041
class Score;
4142
class Segment;
4243
class Selection;
4344
class Spanner;
44-
class System;
4545
class Staff;
46+
class System;
4647
class Tuplet;
4748
class Volta;
4849
struct NoteVal;
@@ -126,4 +127,6 @@ extern bool isValidBarLineForRepeatSection(const Segment* firstSeg, const Segmen
126127
extern bool isElementInFretBox(const EngravingItem* item);
127128

128129
extern std::vector<EngravingItem*> filterTargetElements(const Selection& sel, EngravingItem* dropElement, bool& unique);
130+
131+
extern Lyrics* searchNextLyrics(Segment* s, staff_idx_t staffIdx, int verse, PlacementV p);
129132
} // namespace mu::engraving

src/engraving/rendering/score/lyricslayout.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,35 +41,6 @@ using namespace mu;
4141
using namespace mu::engraving;
4242
using namespace mu::engraving::rendering::score;
4343

44-
static Lyrics* searchNextLyrics(Segment* s, staff_idx_t staffIdx, int verse, PlacementV p)
45-
{
46-
Lyrics* l = nullptr;
47-
const Segment* originalSeg = s;
48-
while ((s = s->next1(SegmentType::ChordRest))) {
49-
if (!segmentsAreAdjacentInRepeatStructure(originalSeg, s)) {
50-
return nullptr;
51-
}
52-
53-
track_idx_t strack = staffIdx * VOICES;
54-
track_idx_t etrack = strack + VOICES;
55-
// search through all tracks of current staff looking for a lyric in specified verse
56-
for (track_idx_t track = strack; track < etrack; ++track) {
57-
ChordRest* cr = toChordRest(s->element(track));
58-
if (cr) {
59-
// cr with lyrics found, but does it have a syllable in specified verse?
60-
l = cr->lyrics(verse, p);
61-
if (l) {
62-
break;
63-
}
64-
}
65-
}
66-
if (l) {
67-
break;
68-
}
69-
}
70-
return l;
71-
}
72-
7344
void LyricsLayout::layout(Lyrics* item, LayoutContext& ctx)
7445
{
7546
if (!item->explicitParent()) { // palette & clone trick

src/engraving/rw/read460/read460.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,18 @@ bool Read460::readScoreTag(Score* score, XmlReader& e, ReadContext& ctx)
287287

288288
score->connectTies();
289289

290+
for (Spanner* sp : score->unmanagedSpanners()) {
291+
if (sp->isLyricsLine() && toLyricsLine(sp)->isDash()) {
292+
LyricsLine* line = toLyricsLine(sp);
293+
line->setNextLyrics(searchNextLyrics(line->lyrics()->segment(),
294+
line->staffIdx(),
295+
line->lyrics()->verse(),
296+
line->lyrics()->placement()
297+
));
298+
line->setTrack2(line->nextLyrics() ? line->nextLyrics()->track() : line->track());
299+
}
300+
}
301+
290302
score->m_fileDivision = Constants::DIVISION;
291303

292304
// Make sure every instrument has an instrumentId set.

src/engraving/rw/read460/tread.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ void TRead::readItem(EngravingItem* item, XmlReader& xml, ReadContext& ctx)
238238
break;
239239
case ElementType::LYRICS: read(item_cast<Lyrics*>(item), xml, ctx);
240240
break;
241+
case ElementType::LYRICSLINE: read(item_cast<LyricsLine*>(item), xml, ctx);
242+
break;
241243
case ElementType::MARKER: read(item_cast<Marker*>(item), xml, ctx);
242244
break;
243245
case ElementType::MEASURE_NUMBER: read(item_cast<MeasureNumber*>(item), xml, ctx);
@@ -3108,6 +3110,15 @@ void TRead::read(Lyrics* l, XmlReader& e, ReadContext& ctx)
31083110
}
31093111
}
31103112

3113+
void TRead::read(LyricsLine* l, XmlReader& e, ReadContext& ctx)
3114+
{
3115+
while (e.readNextStartElement()) {
3116+
if (!readProperties(static_cast<SLine*>(l), e, ctx)) {
3117+
e.unknown();
3118+
}
3119+
}
3120+
}
3121+
31113122
void TRead::read(LineSegment* l, XmlReader& e, ReadContext& ctx)
31123123
{
31133124
while (e.readNextStartElement()) {
@@ -3145,6 +3156,13 @@ bool TRead::readProperties(Lyrics* l, XmlReader& e, ReadContext& ctx)
31453156
} else if (tag == "ticks_f") {
31463157
l->setTicks(e.readFraction());
31473158
} else if (TRead::readProperty(l, tag, e, ctx, Pid::PLACEMENT)) {
3159+
} else if (tag == "LyricsLine") {
3160+
LyricsLine* ll = Factory::createLyricsLine(l);
3161+
TRead::read(ll, e, ctx);
3162+
ll->setParent(l);
3163+
ll->setTick(ctx.tick());
3164+
l->setSeparator(ll);
3165+
ctx.score()->addUnmanagedSpanner(ll);
31483166
} else if (!readProperties(static_cast<TextBase*>(l), e, ctx)) {
31493167
return false;
31503168
}
@@ -3492,7 +3510,7 @@ void TRead::read(PartialLyricsLine* p, XmlReader& xml, ReadContext& ctx)
34923510
if (tag == "isEndMelisma") {
34933511
p->setIsEndMelisma(xml.readBool());
34943512
} else if (TRead::readProperty(p, tag, xml, ctx, Pid::VERSE)) {
3495-
} else if (!readItemProperties(p, xml, ctx)) {
3513+
} else if (!readProperties(static_cast<SLine*>(p), xml, ctx)) {
34963514
xml.unknown();
34973515
}
34983516
}

src/engraving/rw/read460/tread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class LetRing;
103103
class LineSegment;
104104
class Location;
105105
class Lyrics;
106+
class LyricsLine;
106107

107108
class Marker;
108109
class MeasureBase;
@@ -261,6 +262,7 @@ class TRead
261262
static void read(LineSegment* l, XmlReader& xml, ReadContext& ctx);
262263
static void read(Location* l, XmlReader& xml, ReadContext& ctx);
263264
static void read(Lyrics* l, XmlReader& xml, ReadContext& ctx);
265+
static void read(LyricsLine* l, XmlReader& xml, ReadContext& ctx);
264266

265267
static void read(Marker* m, XmlReader& xml, ReadContext& ctx);
266268
static void read(MeasureNumber* n, XmlReader& xml, ReadContext& ctx);

src/engraving/rw/write/twrite.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ void TWrite::writeItem(const EngravingItem* item, XmlWriter& xml, WriteContext&
262262
break;
263263
case ElementType::LYRICS: write(item_cast<const Lyrics*>(item), xml, ctx);
264264
break;
265+
case ElementType::LYRICSLINE: write(item_cast<const LyricsLine*>(item), xml, ctx);
266+
break;
265267
case ElementType::MARKER: write(item_cast<const Marker*>(item), xml, ctx);
266268
break;
267269
case ElementType::MEASURE_NUMBER: write(item_cast<const MeasureNumber*>(item), xml, ctx);
@@ -2179,6 +2181,19 @@ void TWrite::write(const Lyrics* item, XmlWriter& xml, WriteContext& ctx)
21792181
writeProperty(item, xml, Pid::LYRIC_TICKS);
21802182

21812183
writeProperties(static_cast<const TextBase*>(item), xml, ctx, true);
2184+
if (item->separator() && !item->separator()->generated()) {
2185+
write(item->separator(), xml, ctx);
2186+
}
2187+
xml.endElement();
2188+
}
2189+
2190+
void TWrite::write(const LyricsLine* item, XmlWriter& xml, WriteContext& ctx)
2191+
{
2192+
if (!ctx.canWrite(item)) {
2193+
return;
2194+
}
2195+
xml.startElement(item);
2196+
writeProperties(static_cast<const SLine*>(item), xml, ctx);
21822197
xml.endElement();
21832198
}
21842199

@@ -2468,7 +2483,7 @@ void TWrite::write(const PartialLyricsLine* item, XmlWriter& xml, WriteContext&
24682483
xml.startElement(item);
24692484
writeProperty(item, xml, Pid::VERSE);
24702485
xml.tag("isEndMelisma", item->isEndMelisma());
2471-
writeItemProperties(item, xml, ctx);
2486+
writeProperties(static_cast<const SLine*>(item), xml, ctx);
24722487
xml.endElement();
24732488
}
24742489

0 commit comments

Comments
 (0)