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