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 "staffread.h"
23 :
24 : #include "dom/factory.h"
25 : #include "dom/measure.h"
26 : #include "dom/score.h"
27 :
28 : #include "measureread.h"
29 : #include "tread.h"
30 :
31 : #include "log.h"
32 :
33 : using namespace mu::engraving;
34 : using namespace mu::engraving::read410;
35 :
36 300 : void StaffRead::readStaff(Score* score, XmlReader& e, ReadContext& ctx)
37 : {
38 300 : int staff = e.intAttribute("id", 1) - 1;
39 300 : int measureIdx = 0;
40 300 : ctx.setCurrentMeasureIndex(0);
41 300 : ctx.setTick(Fraction(0, 1));
42 300 : ctx.setTrack(staff * VOICES);
43 :
44 300 : if (staff == 0) {
45 1294 : while (e.readNextStartElement()) {
46 1107 : const AsciiStringView tag(e.name());
47 :
48 1107 : if (tag == "Measure") {
49 1047 : Measure* measure = Factory::createMeasure(ctx.score());
50 1047 : measure->setTick(ctx.tick());
51 1047 : ctx.setCurrentMeasureIndex(measureIdx++);
52 : //
53 : // inherit timesig from previous measure
54 : //
55 1047 : Measure* m = ctx.lastMeasure(); // measure->prevMeasure();
56 1047 : Fraction timeSigForThisMeasure = ctx.timeSigForNextMeasure();
57 1047 : Fraction f(timeSigForThisMeasure != Fraction(0, 1) ? ctx.timeSigForNextMeasure() : m ? m->timesig() : Fraction(4, 4));
58 1047 : measure->setTicks(f);
59 1047 : measure->setTimesig(f);
60 :
61 1047 : MeasureRead::readMeasure(measure, e, ctx, staff);
62 1047 : measure->checkMeasure(staff);
63 1047 : if (!measure->isMMRest()) {
64 1043 : score->measures()->append(measure);
65 1043 : if (m && m->mmRest()) {
66 4 : m->mmRest()->setNext(measure);
67 : }
68 1043 : score->checkSpanner(ctx.tick(), ctx.tick() + measure->ticks(), /*removeOrphans*/ false);
69 1043 : ctx.setLastMeasure(measure);
70 1043 : ctx.setTick(measure->endTick());
71 1043 : if (timeSigForThisMeasure != Fraction(0, 1) && ctx.timeSigForNextMeasure() == timeSigForThisMeasure) {
72 2 : ctx.setTimeSigForNextMeasure(Fraction(0, 1));
73 : }
74 : } else {
75 : // this is a multi measure rest
76 : // always preceded by the first measure it replaces
77 4 : Measure* m1 = ctx.lastMeasure();
78 :
79 4 : if (m1) {
80 4 : m1->setMMRest(measure);
81 4 : measure->setTick(m1->tick());
82 4 : measure->setPrev(m1->prev());
83 : }
84 : }
85 60 : } else if (tag == "HBox" || tag == "VBox" || tag == "TBox" || tag == "FBox") {
86 60 : MeasureBase* mb = toMeasureBase(Factory::createItemByName(tag, ctx.dummy()));
87 60 : mb->setTick(ctx.tick());
88 60 : score->measures()->append(mb);
89 : // This default value needs initialising after being added to the score, as it depends on whether this is the title frame
90 60 : if (mb->score()->mscVersion() >= 440) {
91 24 : mb->setSizeIsSpatiumDependent(mb->propertyDefault(Pid::SIZE_SPATIUM_DEPENDENT).toBool());
92 : }
93 :
94 60 : TRead::readItem(mb, e, ctx);
95 0 : } else if (tag == "tick") {
96 0 : ctx.setTick(Fraction::fromTicks(ctx.fileDivision(e.readInt())));
97 : } else {
98 0 : e.unknown();
99 : }
100 : }
101 : } else {
102 113 : Measure* measure = score->firstMeasure();
103 803 : while (e.readNextStartElement()) {
104 690 : const AsciiStringView tag(e.name());
105 :
106 690 : if (tag == "Measure") {
107 690 : if (measure == 0) {
108 0 : LOGD("Score::readStaff(): missing measure!");
109 0 : measure = Factory::createMeasure(ctx.score());
110 0 : measure->setTick(ctx.tick());
111 0 : score->measures()->append(measure);
112 : }
113 690 : ctx.setTick(measure->tick());
114 690 : ctx.setCurrentMeasureIndex(measureIdx++);
115 690 : MeasureRead::readMeasure(measure, e, ctx, staff);
116 690 : measure->checkMeasure(staff);
117 690 : if (measure->isMMRest()) {
118 1 : measure = ctx.lastMeasure()->nextMeasure();
119 : } else {
120 689 : ctx.setLastMeasure(measure);
121 689 : if (measure->mmRest()) {
122 1 : measure = measure->mmRest();
123 : } else {
124 688 : measure = measure->nextMeasure();
125 : }
126 : }
127 0 : } else if (tag == "tick") {
128 0 : ctx.setTick(Fraction::fromTicks(ctx.fileDivision(e.readInt())));
129 : } else {
130 0 : e.unknown();
131 : }
132 : }
133 : }
134 300 : }
|