Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #include "measureread.h"
23 :
24 : #include "translation.h"
25 :
26 : #include "../dom/ambitus.h"
27 : #include "../dom/anchors.h"
28 : #include "../dom/barline.h"
29 : #include "../dom/beam.h"
30 : #include "../dom/breath.h"
31 : #include "../dom/chord.h"
32 : #include "../dom/dynamic.h"
33 : #include "../dom/expression.h"
34 : #include "../dom/factory.h"
35 : #include "../dom/fermata.h"
36 : #include "../dom/fret.h"
37 : #include "../dom/keysig.h"
38 : #include "../dom/location.h"
39 : #include "../dom/measure.h"
40 : #include "../dom/measurenumber.h"
41 : #include "../dom/measurerepeat.h"
42 : #include "../dom/mmrest.h"
43 : #include "../dom/mmrestrange.h"
44 : #include "../dom/score.h"
45 : #include "../dom/segment.h"
46 : #include "../dom/spacer.h"
47 : #include "../dom/staff.h"
48 : #include "../dom/stafflines.h"
49 : #include "../dom/stafftext.h"
50 : #include "../dom/system.h"
51 : #include "../dom/systemdivider.h"
52 : #include "../dom/timesig.h"
53 : #include "../dom/tuplet.h"
54 : #include "../dom/harmony.h"
55 : #include "../dom/fret.h"
56 : #include "../dom/tremolobar.h"
57 : #include "../dom/tempotext.h"
58 : #include "../dom/image.h"
59 :
60 : #include "tread.h"
61 :
62 : #include "log.h"
63 :
64 : using namespace mu::engraving;
65 : using namespace mu::engraving::read410;
66 :
67 1737 : void MeasureRead::readMeasure(Measure* measure, XmlReader& e, ReadContext& ctx, int staffIdx)
68 : {
69 1737 : IF_ASSERT_FAILED(ctx.isSameScore(measure)) {
70 0 : return;
71 : }
72 :
73 1737 : ctx.setCurrentMeasure(measure);
74 1737 : int nextTrack = staffIdx * VOICES;
75 1737 : ctx.setTrack(nextTrack);
76 :
77 1737 : for (int n = int(measure->mstaves().size()); n <= staffIdx; ++n) {
78 0 : Staff* staff = ctx.staff(n);
79 0 : MStaff* s = new MStaff;
80 0 : s->setLines(Factory::createStaffLines(measure));
81 0 : s->lines()->setTrack(n * VOICES);
82 0 : s->lines()->setVisible(!staff->isLinesInvisible(measure->tick()));
83 0 : measure->mstaves().push_back(s);
84 : }
85 :
86 1737 : bool irregular = false;
87 1737 : if (e.hasAttribute("len")) {
88 6 : bool ok = true;
89 6 : measure->setTicks(Fraction::fromString(e.attribute("len"), &ok));
90 6 : if (!ok || measure->ticks() < Fraction(1, 128)) {
91 0 : e.raiseError(muse::mtrc("engraving", "MSCX error at byte offset %1: invalid measure length: %2")
92 0 : .arg(e.byteOffset()).arg(e.attribute("len")));
93 0 : return;
94 : }
95 6 : irregular = true;
96 : }
97 :
98 4134 : while (e.readNextStartElement()) {
99 2397 : const AsciiStringView tag(e.name());
100 :
101 2397 : if (tag == "voice") {
102 1797 : ctx.setTrack(nextTrack++);
103 1797 : ctx.setTick(measure->tick());
104 1797 : readVoice(measure, e, ctx, staffIdx, irregular);
105 600 : } else if (tag == "Marker" || tag == "Jump") {
106 29 : EngravingItem* el = Factory::createItemByName(tag, measure);
107 29 : el->setTrack(ctx.track());
108 29 : TRead::readItem(el, e, ctx);
109 29 : if (el->systemFlag() && el->isTopSystemObject()) {
110 27 : el->setTrack(0); // original system object always goes on top
111 : }
112 29 : measure->add(el);
113 571 : } else if (tag == "stretch") {
114 0 : double val = e.readDouble();
115 0 : if (val < 0.0) {
116 0 : val = 0;
117 : }
118 0 : measure->setUserStretch(val);
119 571 : } else if (tag == "noOffset") {
120 0 : measure->setMeasureNumberOffset(e.readInt());
121 571 : } else if (tag == "measureNumberMode") {
122 0 : measure->setMeasureNumberMode(MeasureNumberMode(e.readInt()));
123 571 : } else if (tag == "irregular") {
124 0 : measure->setExcludeFromNumbering(e.readBool());
125 571 : } else if (tag == "breakMultiMeasureRest") {
126 0 : measure->setBreakMultiMeasureRest(e.readBool());
127 571 : } else if (tag == "startRepeat") {
128 13 : measure->setRepeatStart(true);
129 13 : e.readNext();
130 558 : } else if (tag == "endRepeat") {
131 25 : measure->setRepeatCount(e.readInt());
132 25 : measure->setRepeatEnd(true);
133 533 : } else if (tag == "vspacer" || tag == "vspacerDown") {
134 0 : if (!measure->mstaves()[staffIdx]->vspacerDown()) {
135 0 : Spacer* spacer = Factory::createSpacer(measure);
136 0 : spacer->setSpacerType(SpacerType::DOWN);
137 0 : spacer->setTrack(staffIdx * VOICES);
138 0 : measure->add(spacer);
139 : }
140 0 : measure->mstaves()[staffIdx]->vspacerDown()->setGap(Spatium(e.readDouble()));
141 533 : } else if (tag == "vspacerFixed") {
142 0 : if (!measure->mstaves()[staffIdx]->vspacerDown()) {
143 0 : Spacer* spacer = Factory::createSpacer(measure);
144 0 : spacer->setSpacerType(SpacerType::FIXED);
145 0 : spacer->setTrack(staffIdx * VOICES);
146 0 : measure->add(spacer);
147 : }
148 0 : measure->mstaves()[staffIdx]->vspacerDown()->setGap(Spatium(e.readDouble()));
149 533 : } else if (tag == "vspacerUp") {
150 0 : if (!measure->mstaves()[staffIdx]->vspacerUp()) {
151 0 : Spacer* spacer = Factory::createSpacer(measure);
152 0 : spacer->setSpacerType(SpacerType::UP);
153 0 : spacer->setTrack(staffIdx * VOICES);
154 0 : measure->add(spacer);
155 : }
156 0 : measure->mstaves()[staffIdx]->vspacerUp()->setGap(Spatium(e.readDouble()));
157 533 : } else if (tag == "visible") {
158 0 : measure->mstaves()[staffIdx]->setVisible(e.readInt());
159 533 : } else if ((tag == "slashStyle") || (tag == "stemless")) {
160 0 : measure->mstaves()[staffIdx]->setStemless(e.readInt());
161 533 : } else if (tag == "measureRepeatCount") {
162 10 : measure->setMeasureRepeatCount(e.readInt(), staffIdx);
163 523 : } else if (tag == "SystemDivider") {
164 0 : SystemDivider* sd = new SystemDivider(ctx.dummy());
165 0 : TRead::read(sd, e, ctx);
166 : //! TODO Looks like a bug.
167 : //! The SystemDivider parent must be System
168 : //! there is a method: `System* system() const { return (System*)parent(); }`,
169 : //! but when we add it to Measure, the parent will be rewritten.
170 0 : measure->add(sd);
171 523 : } else if (tag == "multiMeasureRest") {
172 5 : measure->setMMRestCount(e.readInt());
173 : // set tick to previous measure
174 5 : measure->setTick(ctx.lastMeasure()->tick());
175 5 : ctx.setTick(ctx.lastMeasure()->tick());
176 518 : } else if (tag == "MeasureNumber") {
177 0 : MeasureNumber* noText = new MeasureNumber(measure);
178 0 : TRead::read(noText, e, ctx);
179 0 : noText->setTrack(ctx.track());
180 0 : measure->add(noText);
181 518 : } else if (tag == "MMRestRange") {
182 0 : MMRestRange* range = new MMRestRange(measure);
183 0 : TRead::read(range, e, ctx);
184 0 : range->setTrack(ctx.track());
185 0 : measure->add(range);
186 518 : } else if (TRead::readProperties(static_cast<MeasureBase*>(measure), e, ctx)) {
187 : } else {
188 0 : e.unknown();
189 : }
190 : }
191 1737 : ctx.checkConnectors();
192 1737 : if (measure->isMMRest()) {
193 5 : Measure* lm = ctx.lastMeasure();
194 5 : ctx.setTick(lm->endTick());
195 : }
196 1737 : ctx.setCurrentMeasure(nullptr);
197 :
198 1737 : measure->connectTremolo();
199 : }
200 :
201 1797 : void MeasureRead::readVoice(Measure* measure, XmlReader& e, ReadContext& ctx, int staffIdx, bool irregular)
202 : {
203 1797 : Segment* segment = nullptr;
204 1797 : std::vector<Chord*> graceNotes;
205 1797 : Beam* startingBeam = nullptr;
206 1797 : Tuplet* tuplet = nullptr;
207 1797 : Fermata* fermata = nullptr;
208 :
209 1797 : Staff* staff = ctx.staff(staffIdx);
210 1797 : Fraction timeStretch(staff->timeStretch(measure->tick()));
211 :
212 6757 : while (e.readNextStartElement()) {
213 4960 : const AsciiStringView tag(e.name());
214 :
215 4960 : if (tag == "location") {
216 31 : Location loc = Location::relative();
217 31 : TRead::read(&loc, e, ctx);
218 31 : ctx.setLocation(loc);
219 31 : if (loc.isTimeTick()) {
220 19 : EditTimeTickAnchors::createTimeTickAnchor(measure, ctx.tick() - measure->tick(), track2staff(ctx.track()));
221 : }
222 4929 : } else if (tag == "tick") { // obsolete?
223 0 : LOGD() << "read midi tick";
224 0 : ctx.setTick(Fraction::fromTicks(ctx.fileDivision(e.readInt())));
225 4929 : } else if (tag == "BarLine") {
226 89 : BarLine* barLine = Factory::createBarLine(ctx.dummy());
227 89 : barLine->setTrack(ctx.track());
228 89 : TRead::read(barLine, e, ctx);
229 : //
230 : // StartRepeatBarLine: at rtick == 0, always BarLineType::START_REPEAT
231 : // BarLine: in the middle of a measure, has no semantic
232 : // EndBarLine: at the end of a measure
233 : // BeginBarLine: first segment of a measure, systemic barline
234 :
235 89 : SegmentType st = SegmentType::Invalid;
236 89 : Fraction t = ctx.tick() - measure->tick();
237 89 : if (t.isNotZero() && (t != measure->ticks())) {
238 0 : st = SegmentType::BarLine;
239 89 : } else if (barLine->barLineType() == BarLineType::START_REPEAT && t.isZero()) {
240 0 : st = SegmentType::StartRepeatBarLine;
241 89 : } else if (barLine->barLineType() == BarLineType::START_REPEAT && t == measure->ticks()) {
242 : // old version, ignore
243 0 : delete barLine;
244 0 : barLine = 0;
245 89 : } else if (t.isZero() && segment == 0) {
246 0 : st = SegmentType::BeginBarLine;
247 : } else {
248 89 : st = SegmentType::EndBarLine;
249 : }
250 89 : if (barLine) {
251 89 : segment = measure->getSegmentR(st, t);
252 89 : segment->add(barLine);
253 : }
254 89 : if (fermata) {
255 0 : segment->add(fermata);
256 0 : fermata = nullptr;
257 : }
258 4840 : } else if (tag == "Chord") {
259 2055 : Chord* chord = Factory::createChord(ctx.dummy());
260 2055 : chord->setTrack(ctx.track());
261 2055 : TRead::read(chord, e, ctx);
262 2055 : if (startingBeam) {
263 54 : startingBeam->add(chord); // also calls chord->setBeam(startingBeam)
264 54 : startingBeam = nullptr;
265 : }
266 : // if (tuplet && !chord->isGrace())
267 : // chord->readAddTuplet(tuplet);
268 2055 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
269 2055 : if (chord->noteType() != NoteType::NORMAL) {
270 30 : graceNotes.push_back(chord);
271 : } else {
272 2025 : segment->add(chord);
273 2055 : for (size_t i = 0; i < graceNotes.size(); ++i) {
274 30 : Chord* gc = graceNotes[i];
275 30 : gc->setGraceIndex(static_cast<int>(i));
276 30 : chord->add(gc);
277 : }
278 2025 : graceNotes.clear();
279 2025 : if (tuplet) {
280 284 : tuplet->add(chord);
281 : }
282 2025 : ctx.incTick(chord->actualTicks());
283 : }
284 2055 : if (fermata) {
285 2 : segment->add(fermata);
286 2 : fermata = nullptr;
287 : }
288 2785 : } else if (tag == "Rest") {
289 1383 : if (measure->isMMRest()) {
290 5 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
291 5 : MMRest* mmr = Factory::createMMRest(segment);
292 5 : mmr->setTrack(ctx.track());
293 5 : TRead::read(mmr, e, ctx);
294 5 : segment->add(mmr);
295 5 : ctx.incTick(mmr->actualTicks());
296 : } else {
297 1378 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
298 1378 : Rest* rest = Factory::createRest(segment);
299 1378 : rest->setDurationType(DurationType::V_MEASURE);
300 1378 : rest->setTicks(measure->timesig() / timeStretch);
301 1378 : rest->setTrack(ctx.track());
302 1378 : TRead::read(rest, e, ctx);
303 1378 : if (startingBeam) {
304 0 : startingBeam->add(rest); // also calls rest->setBeam(startingBeam)
305 0 : startingBeam = nullptr;
306 : }
307 :
308 1378 : segment->add(rest);
309 1378 : if (fermata) {
310 0 : segment->add(fermata);
311 0 : fermata = nullptr;
312 : }
313 :
314 1378 : if (!rest->ticks().isValid()) { // hack
315 0 : rest->setTicks(measure->timesig() / timeStretch);
316 : }
317 :
318 1378 : if (tuplet) {
319 0 : tuplet->add(rest);
320 : }
321 1378 : ctx.incTick(rest->actualTicks());
322 : }
323 1402 : } else if (tag == "Breath") {
324 4 : segment = measure->getSegment(SegmentType::Breath, ctx.tick());
325 4 : Breath* breath = Factory::createBreath(segment);
326 4 : breath->setTrack(ctx.track());
327 4 : breath->setPlacement(breath->track() & 1 ? PlacementV::BELOW : PlacementV::ABOVE);
328 4 : TRead::read(breath, e, ctx);
329 4 : segment->add(breath);
330 1398 : } else if (tag == "Spanner") {
331 201 : TRead::readSpanner(e, ctx, measure, ctx.track());
332 1197 : } else if (tag == "MeasureRepeat" || tag == "RepeatMeasure") {
333 : // 4.x 3.x
334 7 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
335 7 : MeasureRepeat* mr = Factory::createMeasureRepeat(segment);
336 7 : mr->setTrack(ctx.track());
337 7 : TRead::read(mr, e, ctx);
338 7 : if (!mr->numMeasures()) {
339 0 : mr->setNumMeasures(1); // 3.x doesn't have any other possibilities
340 : }
341 7 : if (!measure->measureRepeatCount(staffIdx)) {
342 0 : measure->setMeasureRepeatCount(1, staffIdx);
343 : }
344 7 : segment->add(mr);
345 7 : ctx.incTick(measure->ticks());
346 1190 : } else if (tag == "Clef") {
347 26 : Clef* clef = Factory::createClef(ctx.dummy());
348 26 : clef->setTrack(ctx.track());
349 26 : bool header = false;
350 26 : TRead::read(clef, e, ctx, &header);
351 26 : clef->setGenerated(false);
352 26 : if (ctx.score()->mscVersion() < 450) {
353 : // Clef segments are sorted on layout now. Previously, clef barline position could be out of sync with segment placement.
354 16 : if (ctx.tick() != Fraction(0, 1) && ctx.tick() == measure->tick()
355 16 : && !(measure->prevMeasure() && measure->prevMeasure()->repeatEnd()) && !header) {
356 0 : clef->setClefToBarlinePosition(ClefToBarlinePosition::AFTER);
357 : }
358 : }
359 :
360 26 : segment = measure->getSegment(header ? SegmentType::HeaderClef : SegmentType::Clef, ctx.tick());
361 26 : segment->add(clef);
362 1164 : } else if (tag == "TimeSig") {
363 296 : TimeSig* ts = Factory::createTimeSig(ctx.dummy());
364 296 : ts->setTrack(ctx.track());
365 296 : TRead::read(ts, e, ctx);
366 :
367 : // PRE 4.5: if time sig not at beginning of measure => courtesy time sig
368 : // 4.5+ just tag it
369 296 : Fraction currTick = ctx.tick();
370 296 : bool courtesySig = ctx.score()->mscVersion() < 450 ? currTick > measure->tick() : ts->isCourtesy();
371 296 : segment = measure->getSegment(courtesySig ? SegmentType::TimeSigAnnounce : SegmentType::TimeSig, currTick);
372 296 : segment->add(ts);
373 :
374 296 : if (!courtesySig && currTick == measure->endTick()) {
375 2 : segment->setEndOfMeasureChange(true);
376 2 : measure->setEndOfMeasureChange(true);
377 : }
378 :
379 296 : if (!courtesySig && currTick == measure->tick()) {
380 294 : timeStretch = ts->stretch().reduced();
381 294 : measure->setTimesig(ts->sig() / timeStretch);
382 :
383 294 : if (!irregular) {
384 291 : measure->setTicks(measure->timesig());
385 : }
386 : }
387 :
388 296 : if (!courtesySig && currTick > measure->tick()) {
389 2 : ctx.setTimeSigForNextMeasure(ts->sig() / ts->stretch().reduced());
390 : }
391 868 : } else if (tag == "KeySig") {
392 262 : KeySig* ks = Factory::createKeySig(ctx.dummy());
393 262 : ks->setTrack(ctx.track());
394 262 : TRead::read(ks, e, ctx);
395 :
396 : // PRE 4.5: if key sig not at beginning of measure => courtesy key sig
397 : // 4.5+ just tag it
398 262 : Fraction curTick = ctx.tick();
399 262 : bool courtesySig = ctx.score()->mscVersion() < 450 ? curTick == measure->endTick() : ks->isCourtesy();
400 262 : segment = measure->getSegment(courtesySig ? SegmentType::KeySigAnnounce : SegmentType::KeySig, curTick);
401 262 : segment->add(ks);
402 :
403 262 : if (!courtesySig && curTick == measure->endTick()) {
404 0 : segment->setEndOfMeasureChange(true);
405 0 : measure->setEndOfMeasureChange(true);
406 : }
407 :
408 262 : if (!courtesySig) {
409 262 : staff->setKey(curTick, ks->keySigEvent());
410 : }
411 606 : } else if (tag == "Text") {
412 0 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
413 0 : StaffText* t = Factory::createStaffText(segment);
414 0 : t->setTrack(ctx.track());
415 0 : TRead::read(t, e, ctx);
416 0 : if (t->empty()) {
417 0 : LOGD("==reading empty text: deleted");
418 0 : delete t;
419 : } else {
420 0 : segment->add(t);
421 : }
422 : }
423 : //----------------------------------------------------
424 : // Annotation
425 606 : else if (tag == "Dynamic") {
426 126 : segment = measure->getChordRestOrTimeTickSegment(ctx.tick());
427 126 : Dynamic* dyn = Factory::createDynamic(segment);
428 126 : dyn->setTrack(ctx.track());
429 126 : TRead::read(dyn, e, ctx);
430 126 : segment->add(dyn);
431 480 : } else if (tag == "Expression") {
432 0 : segment = measure->getChordRestOrTimeTickSegment(ctx.tick());
433 0 : Expression* expr = Factory::createExpression(segment);
434 0 : expr->setTrack(ctx.track());
435 0 : TRead::read(expr, e, ctx);
436 0 : segment->add(expr);
437 480 : } else if (tag == "Harmony") {
438 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
439 : // for symbols attached to anything but a measure
440 30 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
441 30 : Harmony* el = Factory::createHarmony(segment);
442 :
443 30 : el->setTrack(ctx.track());
444 30 : TRead::read(el, e, ctx);
445 30 : if (el->systemFlag() && el->isTopSystemObject()) {
446 0 : el->setTrack(0); // original system object always goes on top
447 : }
448 30 : if (el->chords().empty()) {
449 : // Invalid harmony
450 0 : delete el;
451 : } else {
452 30 : segment->add(el);
453 : }
454 450 : } else if (tag == "FretDiagram") {
455 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
456 : // for symbols attached to anything but a measure
457 0 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
458 0 : FretDiagram* el = Factory::createFretDiagram(segment);
459 :
460 0 : el->setTrack(ctx.track());
461 0 : TRead::read(el, e, ctx);
462 0 : if (el->systemFlag() && el->isTopSystemObject()) {
463 0 : el->setTrack(0); // original system object always goes on top
464 : }
465 0 : segment->add(el);
466 450 : } else if (tag == "TremoloBar") {
467 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
468 : // for symbols attached to anything but a measure
469 7 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
470 7 : TremoloBar* el = Factory::createTremoloBar(segment);
471 7 : el->setTrack(ctx.track());
472 7 : TRead::read(el, e, ctx);
473 7 : if (el->systemFlag() && el->isTopSystemObject()) {
474 0 : el->setTrack(0); // original system object always goes on top
475 : }
476 7 : segment->add(el);
477 443 : } else if (tag == "Symbol") {
478 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
479 : // for symbols attached to anything but a measure
480 0 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
481 0 : Symbol* el = Factory::createSymbol(segment);
482 :
483 0 : el->setTrack(ctx.track());
484 0 : TRead::read(el, e, ctx);
485 0 : if (el->systemFlag() && el->isTopSystemObject()) {
486 0 : el->setTrack(0); // original system object always goes on top
487 : }
488 0 : segment->add(el);
489 443 : } else if (tag == "Tempo") {
490 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
491 : // for symbols attached to anything but a measure
492 65 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
493 65 : TempoText* el = Factory::createTempoText(segment);
494 :
495 65 : el->setTrack(ctx.track());
496 65 : TRead::read(el, e, ctx);
497 65 : if (el->systemFlag() && el->isTopSystemObject()) {
498 65 : el->setTrack(0); // original system object always goes on top
499 : }
500 65 : segment->add(el);
501 378 : } else if (tag == "StaffText") {
502 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
503 : // for symbols attached to anything but a measure
504 67 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
505 67 : StaffText* el = Factory::createStaffText(segment);
506 67 : el->setTrack(ctx.track());
507 67 : TRead::read(el, e, ctx);
508 67 : if (el->systemFlag() && el->isTopSystemObject()) {
509 0 : el->setTrack(0); // original system object always goes on top
510 : }
511 67 : segment->add(el);
512 311 : } else if (tag == "Sticking"
513 296 : || tag == "SystemText"
514 291 : || tag == "PlayTechAnnotation"
515 284 : || tag == "Capo"
516 284 : || tag == "StringTunings"
517 284 : || tag == "RehearsalMark"
518 283 : || tag == "InstrumentChange"
519 283 : || tag == "StaffState"
520 283 : || tag == "FiguredBass"
521 607 : || tag == "HarpPedalDiagram"
522 : ) {
523 : // hack - getSegment needed because tick tags are unreliable in 1.3 scores
524 : // for symbols attached to anything but a measure
525 39 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
526 39 : EngravingItem* el = Factory::createItemByName(tag, segment);
527 :
528 39 : el->setTrack(ctx.track());
529 39 : TRead::readItem(el, e, ctx);
530 39 : if (el->systemFlag() && el->isTopSystemObject()) {
531 6 : el->setTrack(0); // original system object always goes on top
532 : }
533 39 : segment->add(el);
534 272 : } else if (tag == "Fermata") {
535 2 : fermata = Factory::createFermata(ctx.dummy());
536 2 : fermata->setTrack(ctx.track());
537 2 : fermata->setPlacement(fermata->track() & 1 ? PlacementV::BELOW : PlacementV::ABOVE);
538 2 : TRead::read(fermata, e, ctx);
539 270 : } else if (tag == "Image") {
540 0 : if (MScore::noImages) {
541 0 : e.skipCurrentElement();
542 : } else {
543 0 : segment = measure->getSegment(SegmentType::ChordRest, ctx.tick());
544 0 : Image* el = Factory::createImage(segment);
545 0 : el->setTrack(ctx.track());
546 0 : TRead::read(el, e, ctx);
547 0 : segment->add(el);
548 : }
549 : }
550 : //----------------------------------------------------
551 270 : else if (tag == "Tuplet") {
552 108 : Tuplet* oldTuplet = tuplet;
553 108 : tuplet = Factory::createTuplet(measure);
554 108 : tuplet->setTrack(ctx.track());
555 108 : tuplet->setTick(ctx.tick());
556 108 : TRead::read(tuplet, e, ctx);
557 108 : if (oldTuplet) {
558 71 : oldTuplet->add(tuplet);
559 : }
560 162 : } else if (tag == "endTuplet") {
561 108 : if (!tuplet) {
562 0 : LOGD("Measure::read: encountered <endTuplet/> when no tuplet was started");
563 0 : e.skipCurrentElement();
564 0 : continue;
565 : }
566 108 : Tuplet* oldTuplet = tuplet;
567 108 : tuplet = tuplet->tuplet();
568 108 : if (oldTuplet->elements().empty()) {
569 : // this should not happen and is a sign of input file corruption
570 0 : LOGD("Measure:read: empty tuplet in measure index=%d, input file corrupted?", ctx.currentMeasureIndex());
571 0 : if (tuplet) {
572 0 : tuplet->remove(oldTuplet);
573 : }
574 0 : delete oldTuplet;
575 : }
576 108 : e.readNext();
577 54 : } else if (tag == "Beam") {
578 54 : Beam* beam = Factory::createBeam(ctx.score());
579 54 : beam->setTrack(ctx.track());
580 54 : TRead::read(beam, e, ctx);
581 54 : if (startingBeam) {
582 0 : LOGD("The read beam was not used");
583 0 : delete startingBeam;
584 : }
585 54 : startingBeam = beam;
586 0 : } else if (tag == "Segment" && segment) {
587 0 : TRead::read(segment, e, ctx);
588 0 : } else if (tag == "Ambitus") {
589 0 : segment = measure->getSegment(SegmentType::Ambitus, ctx.tick());
590 0 : Ambitus* range = Factory::createAmbitus(segment);
591 0 : TRead::read(range, e, ctx);
592 0 : range->setTrack(trackZeroVoice(ctx.track()));
593 0 : segment->add(range);
594 : } else {
595 0 : e.unknown();
596 : }
597 : }
598 1797 : if (startingBeam) {
599 0 : LOGD("The read beam was not used");
600 0 : delete startingBeam;
601 : }
602 1797 : if (tuplet) {
603 0 : LOGD("Measure:readVoice: measure index=%d, <endTuplet/> not found", ctx.currentMeasureIndex());
604 0 : if (tuplet->elements().empty()) {
605 0 : if (tuplet->tuplet()) {
606 0 : tuplet->tuplet()->remove(tuplet);
607 : }
608 0 : delete tuplet;
609 : }
610 : }
611 1797 : if (fermata) {
612 0 : SegmentType st = (ctx.tick() == measure->endTick() ? SegmentType::EndBarLine : SegmentType::ChordRest);
613 0 : segment = measure->getSegment(st, ctx.tick());
614 0 : segment->add(fermata);
615 0 : fermata = nullptr;
616 : }
617 1797 : }
|