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