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 "staffrw.h"
23 :
24 : #include "rw/write/twrite.h"
25 :
26 : #include "dom/factory.h"
27 : #include "dom/box.h"
28 : #include "dom/measure.h"
29 : #include "dom/score.h"
30 :
31 : #include "measurerw.h"
32 : #include "tread.h"
33 :
34 : #include "log.h"
35 :
36 : using namespace mu::engraving;
37 : using namespace mu::engraving::read400;
38 :
39 878 : void StaffRead::readStaff(Score* score, XmlReader& e, ReadContext& ctx)
40 : {
41 878 : int staff = e.intAttribute("id", 1) - 1;
42 878 : int measureIdx = 0;
43 878 : ctx.setCurrentMeasureIndex(0);
44 878 : ctx.setTick(Fraction(0, 1));
45 878 : ctx.setTrack(staff * VOICES);
46 :
47 878 : if (staff == 0) {
48 4937 : while (e.readNextStartElement()) {
49 4434 : const AsciiStringView tag(e.name());
50 :
51 4434 : if (tag == "Measure") {
52 3924 : Measure* measure = Factory::createMeasure(ctx.score());
53 3924 : measure->setTick(ctx.tick());
54 3924 : ctx.setCurrentMeasureIndex(measureIdx++);
55 : //
56 : // inherit timesig from previous measure
57 : //
58 3924 : Measure* m = ctx.lastMeasure(); // measure->prevMeasure();
59 3924 : Fraction f(m ? m->timesig() : Fraction(4, 4));
60 3924 : measure->setTicks(f);
61 3924 : measure->setTimesig(f);
62 :
63 3924 : MeasureRead::readMeasure(measure, e, ctx, staff);
64 3924 : measure->checkMeasure(staff);
65 3924 : if (!measure->isMMRest()) {
66 3894 : score->measures()->append(measure);
67 3894 : if (m && m->mmRest()) {
68 29 : m->mmRest()->setNext(measure);
69 : }
70 3894 : score->checkSpanner(ctx.tick(), ctx.tick() + measure->ticks(), /*removeOrphans*/ false);
71 3894 : ctx.setLastMeasure(measure);
72 3894 : ctx.setTick(measure->tick() + measure->ticks());
73 : } else {
74 : // this is a multi measure rest
75 : // always preceded by the first measure it replaces
76 30 : Measure* m1 = ctx.lastMeasure();
77 :
78 30 : if (m1) {
79 30 : m1->setMMRest(measure);
80 30 : measure->setTick(m1->tick());
81 30 : measure->setPrev(m1->prev());
82 : }
83 : }
84 510 : } else if (tag == "HBox" || tag == "VBox" || tag == "TBox" || tag == "FBox") {
85 510 : MeasureBase* mb = toMeasureBase(Factory::createItemByName(tag, ctx.dummy()));
86 510 : mb->setTick(ctx.tick());
87 510 : score->measures()->append(mb);
88 510 : 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 375 : Measure* measure = score->firstMeasure();
97 1563 : while (e.readNextStartElement()) {
98 1188 : const AsciiStringView tag(e.name());
99 :
100 1188 : if (tag == "Measure") {
101 1188 : 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 1188 : ctx.setTick(measure->tick());
108 1188 : ctx.setCurrentMeasureIndex(measureIdx++);
109 1188 : MeasureRead::readMeasure(measure, e, ctx, staff);
110 1188 : measure->checkMeasure(staff);
111 1188 : if (measure->isMMRest()) {
112 0 : measure = ctx.lastMeasure()->nextMeasure();
113 : } else {
114 1188 : ctx.setLastMeasure(measure);
115 1188 : if (measure->mmRest()) {
116 0 : measure = measure->mmRest();
117 : } else {
118 1188 : 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 878 : }
|