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) 2023 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 "verticalgapdata.h"
23 :
24 : #include "realfn.h"
25 :
26 : #include "dom/spacer.h"
27 : #include "dom/staff.h"
28 : #include "dom/system.h"
29 :
30 : #include "style/style.h"
31 :
32 : using namespace mu::engraving;
33 : using namespace mu::engraving::rendering::score;
34 :
35 9801 : VerticalGapData::VerticalGapData(const MStyle* style, bool first, System* sys, const Staff* st, SysStaff* sst, Spacer* nextSpacer, double y)
36 9801 : : style(style), system(sys), sysStaff(sst), staff(st), m_fixedHeight(first)
37 : {
38 9801 : if (m_fixedHeight) {
39 3110 : m_normalisedSpacing = style->styleAbsolute(Sid::staffUpperBorder);
40 3110 : m_maxActualSpacing = m_normalisedSpacing;
41 : } else {
42 6691 : m_normalisedSpacing = system->y() + (sysStaff ? sysStaff->bbox().y() : 0.0) - y;
43 6691 : m_maxActualSpacing = style->styleAbsolute(Sid::maxStaffSpread);
44 :
45 6691 : Spacer* spacer { staff ? system->upSpacer(staff->idx(), nextSpacer) : nullptr };
46 :
47 6691 : if (spacer) {
48 2 : m_fixedSpacer = spacer->spacerType() == SpacerType::FIXED;
49 2 : m_normalisedSpacing = std::max(m_normalisedSpacing, spacer->absoluteGap());
50 2 : if (m_fixedSpacer) {
51 2 : m_maxActualSpacing = m_normalisedSpacing;
52 : }
53 : }
54 : }
55 9801 : }
56 :
57 : //---------------------------------------------------------
58 : // updateFactor
59 : //---------------------------------------------------------
60 :
61 6883 : void VerticalGapData::updateFactor(double factor)
62 : {
63 6883 : if (m_fixedHeight) {
64 1838 : return;
65 : }
66 5045 : double f = std::max(factor, m_factor);
67 5045 : m_normalisedSpacing *= m_factor / f;
68 5045 : m_factor = f;
69 : }
70 :
71 : //---------------------------------------------------------
72 : // addSpaceBetweenSections
73 : //---------------------------------------------------------
74 :
75 5355 : void VerticalGapData::addSpaceBetweenSections()
76 : {
77 5355 : updateFactor(style->styleD(Sid::spreadSystem));
78 5355 : if (!(m_fixedHeight | m_fixedSpacer)) {
79 3817 : m_maxActualSpacing = style->styleAbsolute(Sid::maxSystemSpread) / m_factor;
80 : }
81 5355 : }
82 :
83 : //---------------------------------------------------------
84 : // addSpaceAroundVBox
85 : //---------------------------------------------------------
86 :
87 3168 : void VerticalGapData::addSpaceAroundVBox(bool above)
88 : {
89 3168 : m_fixedHeight = true;
90 3168 : m_factor = 1.0;
91 3168 : m_normalisedSpacing = above ? style->styleAbsolute(Sid::frameSystemDistance) : style->styleAbsolute(Sid::systemFrameDistance);
92 3168 : m_maxActualSpacing = m_normalisedSpacing / m_factor;
93 3168 : }
94 :
95 : //---------------------------------------------------------
96 : // addSpaceAroundNormalBracket
97 : //---------------------------------------------------------
98 :
99 465 : void VerticalGapData::addSpaceAroundNormalBracket()
100 : {
101 465 : updateFactor(style->styleD(Sid::spreadSquareBracket));
102 465 : }
103 :
104 : //---------------------------------------------------------
105 : // addSpaceAroundCurlyBracket
106 : //---------------------------------------------------------
107 :
108 1063 : void VerticalGapData::addSpaceAroundCurlyBracket()
109 : {
110 1063 : updateFactor(style->styleD(Sid::spreadCurlyBracket));
111 1063 : }
112 :
113 : //---------------------------------------------------------
114 : // insideCurlyBracket
115 : //---------------------------------------------------------
116 :
117 686 : void VerticalGapData::insideCurlyBracket()
118 : {
119 686 : m_maxActualSpacing = style->styleAbsolute(Sid::maxAkkoladeDistance) / m_factor;
120 686 : }
121 :
122 : //---------------------------------------------------------
123 : // factor
124 : //---------------------------------------------------------
125 :
126 61129 : double VerticalGapData::factor() const
127 : {
128 61129 : return m_factor;
129 : }
130 :
131 : //---------------------------------------------------------
132 : // spacing
133 : // return normalised spacing
134 : //---------------------------------------------------------
135 :
136 108244 : double VerticalGapData::spacing() const
137 : {
138 108244 : return m_normalisedSpacing + m_addedNormalisedSpace;
139 : }
140 :
141 : //---------------------------------------------------------
142 : // addedSpace
143 : //---------------------------------------------------------
144 :
145 12593 : double VerticalGapData::actualAddedSpace() const
146 : {
147 12593 : return m_addedNormalisedSpace * factor();
148 : }
149 :
150 : //---------------------------------------------------------
151 : // addSpacing
152 : //---------------------------------------------------------
153 :
154 25568 : double VerticalGapData::addSpacing(double step)
155 : {
156 25568 : if (m_fixedHeight | m_fixedSpacer) {
157 7014 : return 0.0;
158 : }
159 18554 : if (m_normalisedSpacing >= m_maxActualSpacing) {
160 58 : m_normalisedSpacing = m_maxActualSpacing;
161 58 : step = 0.0;
162 : } else {
163 18496 : double newSpacing { m_normalisedSpacing + m_addedNormalisedSpace + step };
164 18496 : if ((newSpacing >= m_maxActualSpacing)) {
165 2839 : step = m_maxActualSpacing - m_normalisedSpacing - m_addedNormalisedSpace;
166 : }
167 : }
168 18554 : m_addedNormalisedSpace += step;
169 18554 : m_lastStep = step;
170 18554 : return step;
171 : }
172 :
173 : //---------------------------------------------------------
174 : // isFixedHeight
175 : //---------------------------------------------------------
176 :
177 95923 : bool VerticalGapData::isFixedHeight() const
178 : {
179 95923 : return m_fixedHeight || muse::RealIsNull(m_normalisedSpacing - m_maxActualSpacing);
180 : }
181 :
182 : //---------------------------------------------------------
183 : // undoLastAddSpacing
184 : //---------------------------------------------------------
185 :
186 0 : void VerticalGapData::undoLastAddSpacing()
187 : {
188 0 : m_addedNormalisedSpace -= m_lastStep;
189 0 : m_lastStep = 0.0;
190 0 : }
191 :
192 : //---------------------------------------------------------
193 : // addFillSpacing
194 : //---------------------------------------------------------
195 :
196 17851 : double VerticalGapData::addFillSpacing(double step, double maxFill)
197 : {
198 17851 : if (m_fixedSpacer) {
199 32 : return 0.0;
200 : }
201 17819 : double actStep { ((step + m_fillSpacing / m_factor) > maxFill) ? (maxFill - m_fillSpacing / m_factor) : step };
202 17819 : double res = addSpacing(actStep);
203 17819 : m_fillSpacing += res * m_factor;
204 17819 : return res;
205 : }
206 :
207 0 : void VerticalGapData::setNormalisedSpacing(double newNormalisedSpacing)
208 : {
209 0 : m_normalisedSpacing = newNormalisedSpacing;
210 0 : }
211 :
212 : //---------------------------------------------------------
213 : // deleteAll
214 : //---------------------------------------------------------
215 :
216 3108 : void VerticalGapDataList::deleteAll()
217 : {
218 12877 : for (auto vsd : *this) {
219 9769 : delete vsd;
220 : }
221 3108 : }
222 :
223 : //---------------------------------------------------------
224 : // sumStretchFactor
225 : //---------------------------------------------------------
226 :
227 7404 : double VerticalGapDataList::sumStretchFactor() const
228 : {
229 7404 : double sum { 0.0 };
230 52697 : for (VerticalGapData* vsd : *this) {
231 45293 : if (!vsd->isFixedHeight()) {
232 33931 : sum += vsd->factor();
233 : }
234 : }
235 7404 : return sum;
236 : }
237 :
238 : //---------------------------------------------------------
239 : // smallest
240 : //---------------------------------------------------------
241 :
242 7854 : double VerticalGapDataList::smallest(double limit) const
243 : {
244 7854 : VerticalGapData* vdp { nullptr };
245 58484 : for (VerticalGapData* vgd : *this) {
246 50630 : if (vgd->isFixedHeight()) {
247 12976 : continue;
248 : }
249 37654 : if ((std::ceil(limit) == std::ceil(vgd->spacing()))) {
250 12240 : continue;
251 : }
252 25414 : if (!vdp || (vgd->spacing() < vdp->spacing())) {
253 8380 : vdp = vgd;
254 : }
255 : }
256 7854 : return vdp ? vdp->spacing() : 0.0;
257 : }
|