Skip to content

Commit 23508f2

Browse files
committed
Reimplement spacers in vertical staves adjustment to make sure all spacers are taken into account.
1 parent f30fef1 commit 23508f2

File tree

4 files changed

+105
-46
lines changed

4 files changed

+105
-46
lines changed

libmscore/layout.cpp

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ static void distributeStaves(Page* page)
15751575
qreal prevYBottom { page->tm() };
15761576
qreal yBottom { 0.0 };
15771577
bool vbox { false };
1578-
Spacer* activeSpacer { nullptr };
1578+
Spacer* nextSpacer { nullptr };
15791579
bool transferNormalBracket { false };
15801580
bool transferCurlyBracket { false };
15811581
for (System* system : page->systems()) {
@@ -1614,8 +1614,8 @@ static void distributeStaves(Page* page)
16141614
if (!sysStaff->show())
16151615
continue;
16161616

1617-
VerticalGapData* vgd = new VerticalGapData(!ngaps++, system, staff, sysStaff, activeSpacer, prevYBottom);
1618-
activeSpacer = nullptr;
1617+
VerticalGapData* vgd = new VerticalGapData(!ngaps++, system, staff, sysStaff, nextSpacer, prevYBottom);
1618+
nextSpacer = system->downSpacer(staff->idx());
16191619

16201620
if (newSystem) {
16211621
vgd->addSpaceBetweenSections();
@@ -1647,13 +1647,12 @@ static void distributeStaves(Page* page)
16471647
transferNormalBracket = endNormalBracket >= 0;
16481648
transferCurlyBracket = endCurlyBracket >= 0;
16491649
}
1650-
activeSpacer = system->getActiveSpacer();
16511650
}
16521651
--ngaps;
16531652

16541653
qreal spaceLeft { page->height() - page->bm() - score->styleP(Sid::staffLowerBorder) - yBottom };
1655-
if (activeSpacer)
1656-
spaceLeft -= activeSpacer->gap();
1654+
if (nextSpacer && (nextSpacer->spacerType() == SpacerType::DOWN))
1655+
spaceLeft -= nextSpacer->gap();
16571656
if (spaceLeft <= 0.0)
16581657
return;
16591658

@@ -1689,8 +1688,9 @@ static void distributeStaves(Page* page)
16891688
}
16901689
if ((spaceLeft - addedSpace) <= 0.0)
16911690
{
1692-
for (VerticalGapData* vgd : modified)
1691+
for (VerticalGapData* vgd : modified) {
16931692
vgd->undoLastAddSpacing();
1693+
}
16941694
ngaps = 0;
16951695
}
16961696
else {
@@ -1699,17 +1699,19 @@ static void distributeStaves(Page* page)
16991699
}
17001700

17011701
// If there is still space left, distribute the space of the staves.
1702+
// However, there is a limit on how much space is added per gap.
17021703
const qreal maxPageFill { score->styleP(Sid::maxPageFillSpread) };
1704+
spaceLeft = qMin(maxPageFill * vgdl.length(), spaceLeft);
17031705
pass = 0;
17041706
ngaps = 1;
17051707
while (!almostZero(spaceLeft) && !almostZero(maxPageFill) && (ngaps > 0) && (++pass < maxPasses)) {
17061708
ngaps = 0;
17071709
qreal addedSpace { 0.0 };
1710+
qreal step {spaceLeft / vgdl.sumStretchFactor() };
17081711
for (VerticalGapData* vgd : vgdl) {
1709-
qreal step = spaceLeft / vgdl.sumStretchFactor();
1710-
step = vgd->addFillSpacing(step, maxPageFill);
1711-
if (!almostZero(step)) {
1712-
addedSpace += step * vgd->factor();
1712+
qreal res { vgd->addFillSpacing(step, maxPageFill) };
1713+
if (!almostZero(res)) {
1714+
addedSpace += res * vgd->factor();
17131715
++ngaps;
17141716
}
17151717
}
@@ -5104,24 +5106,28 @@ LayoutContext::~LayoutContext()
51045106

51055107
//---------------------------------------------------------
51065108
// VerticalStretchData
5109+
// defines a gap ABOVE the staff.
51075110
//---------------------------------------------------------
51085111

5109-
VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *sst, const Spacer* spacer, qreal y)
5112+
VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *sst, Spacer* nextSpacer, qreal y)
51105113
: _fixedHeight(first), system(sys), sysStaff(sst), staff(st)
51115114
{
51125115
if (_fixedHeight) {
51135116
_normalisedSpacing = system->score()->styleP(Sid::staffUpperBorder);
51145117
_maxActualSpacing = _normalisedSpacing;
51155118
}
51165119
else {
5120+
_normalisedSpacing = system->y() + (sysStaff ? sysStaff->y() : 0.0) - y;
5121+
_maxActualSpacing = system->score()->styleP(Sid::maxStaffSpread);
5122+
5123+
Spacer* spacer { sys->upSpacer(st->idx(), nextSpacer) };
5124+
51175125
if (spacer) {
5118-
_fixedHeight = true;
5119-
_normalisedSpacing = spacer->gap();
5120-
_maxActualSpacing = _normalisedSpacing;
5121-
}
5122-
else {
5123-
_normalisedSpacing = system->y() + (sysStaff ? sysStaff->y() : 0.0) - y;
5124-
_maxActualSpacing = system->score()->styleP(Sid::maxStaffSpread);
5126+
_fixedSpacer = spacer->spacerType() == SpacerType::FIXED;
5127+
_normalisedSpacing = qMax(_normalisedSpacing, spacer->gap());
5128+
if (_fixedSpacer) {
5129+
_maxActualSpacing = _normalisedSpacing;
5130+
}
51255131
}
51265132
}
51275133
}
@@ -5146,8 +5152,8 @@ void VerticalGapData::updateFactor(qreal factor)
51465152
void VerticalGapData::addSpaceBetweenSections()
51475153
{
51485154
updateFactor(system->score()->styleD(Sid::spreadSystem));
5149-
if (!_fixedHeight)
5150-
_maxActualSpacing = qMax(_maxActualSpacing, system->score()->styleP(Sid::maxSystemSpread));
5155+
if (!(_fixedHeight | _fixedSpacer))
5156+
_maxActualSpacing = system->score()->styleP(Sid::maxSystemSpread) / _factor;
51515157
}
51525158

51535159
//---------------------------------------------------------
@@ -5160,7 +5166,7 @@ void VerticalGapData::addSpaceAroundVBox(bool above)
51605166
_factor = 1.0;
51615167
const Score* score { system->score() };
51625168
_normalisedSpacing = above ? score->styleP(Sid::frameSystemDistance) : score->styleP(Sid::systemFrameDistance);
5163-
_maxActualSpacing = _normalisedSpacing;
5169+
_maxActualSpacing = _normalisedSpacing / _factor;
51645170
}
51655171

51665172
//---------------------------------------------------------
@@ -5187,7 +5193,7 @@ void VerticalGapData::addSpaceAroundCurlyBracket()
51875193

51885194
void VerticalGapData::insideCurlyBracket()
51895195
{
5190-
_maxActualSpacing = system->score()->styleP(Sid::maxAkkoladeDistance);
5196+
_maxActualSpacing = system->score()->styleP(Sid::maxAkkoladeDistance) / _factor;
51915197
}
51925198

51935199
//---------------------------------------------------------
@@ -5224,9 +5230,9 @@ qreal VerticalGapData::actualAddedSpace() const
52245230

52255231
qreal VerticalGapData::addSpacing(qreal step)
52265232
{
5227-
if (_fixedHeight)
5233+
if (_fixedHeight | _fixedSpacer)
52285234
return 0.0;
5229-
if ((_normalisedSpacing >= _maxActualSpacing)) {
5235+
if (_normalisedSpacing >= _maxActualSpacing) {
52305236
_normalisedSpacing = _maxActualSpacing;
52315237
step = 0.0;
52325238
}
@@ -5246,7 +5252,7 @@ qreal VerticalGapData::addSpacing(qreal step)
52465252

52475253
bool VerticalGapData::isFixedHeight() const
52485254
{
5249-
return _fixedHeight;
5255+
return _fixedHeight || almostZero(_normalisedSpacing - _maxActualSpacing);
52505256
}
52515257

52525258
//---------------------------------------------------------
@@ -5265,8 +5271,11 @@ void VerticalGapData::undoLastAddSpacing()
52655271

52665272
qreal VerticalGapData::addFillSpacing(qreal step, qreal maxFill)
52675273
{
5268-
qreal res = addSpacing(qMin(maxFill - _fillSpacing, step));
5269-
_fillSpacing += res;
5274+
if (_fixedSpacer)
5275+
return 0.0;
5276+
qreal actStep { ((step + _fillSpacing / _factor) > maxFill) ? (maxFill - _fillSpacing / _factor) : step};
5277+
qreal res = addSpacing(actStep);
5278+
_fillSpacing += res * _factor;
52705279
return res;
52715280
}
52725281

@@ -5287,8 +5296,10 @@ void VerticalGapDataList::deleteAll()
52875296
qreal VerticalGapDataList::sumStretchFactor() const
52885297
{
52895298
qreal sum { 0.0 };
5290-
for (VerticalGapData* vsd : *this)
5291-
sum += vsd->factor();
5299+
for (VerticalGapData* vsd : *this) {
5300+
if (!vsd->isFixedHeight())
5301+
sum += vsd->factor();
5302+
}
52925303
return sum;
52935304
}
52945305

@@ -5309,5 +5320,4 @@ qreal VerticalGapDataList::smallest(qreal limit) const
53095320
}
53105321
return vdp ? vdp->spacing() : 0.0;
53115322
}
5312-
53135323
}

libmscore/layout.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Page;
2828
class VerticalGapData {
2929
private:
3030
bool _fixedHeight { false };
31+
bool _fixedSpacer { false };
3132
qreal _factor { 1.0 };
3233
qreal _normalisedSpacing { 0.0 };
3334
qreal _maxActualSpacing { 0.0 };
@@ -41,7 +42,7 @@ class VerticalGapData {
4142
SysStaff* sysStaff { nullptr };
4243
Staff* staff { nullptr };
4344

44-
VerticalGapData(bool first, System* sys, Staff* st, SysStaff* sst, const Spacer* spacer, qreal y);
45+
VerticalGapData(bool first, System* sys, Staff* st, SysStaff* sst, Spacer* nextSpacer, qreal y);
4546

4647
void addSpaceBetweenSections();
4748
void addSpaceAroundVBox(bool above);

libmscore/system.cpp

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,29 +1540,77 @@ qreal System::spacerDistance(bool up) const
15401540
if (staff < 0)
15411541
return 0.0;
15421542
qreal dist = 0.0;
1543-
activeSpacer = nullptr;
15441543
for (MeasureBase* mb : measures()) {
15451544
if (mb->isMeasure()) {
15461545
Measure* m = toMeasure(mb);
15471546
Spacer* sp = up ? m->vspacerUp(staff) : m->vspacerDown(staff);
15481547
if (sp) {
15491548
if (sp->spacerType() == SpacerType::FIXED) {
1550-
activeSpacer = sp;
15511549
dist = sp->gap();
15521550
break;
15531551
}
1554-
else {
1555-
if (sp->gap() > dist) {
1556-
activeSpacer = sp;
1557-
dist = sp->gap();
1558-
}
1559-
}
1552+
else
1553+
dist = qMax(dist, sp->gap());
15601554
}
15611555
}
15621556
}
15631557
return dist;
15641558
}
15651559

1560+
//---------------------------------------------------------
1561+
// upSpacer
1562+
// Return largest upSpacer for this system. This can
1563+
// be a downSpacer of the previous system.
1564+
//---------------------------------------------------------
1565+
1566+
Spacer* System::upSpacer(int staffIdx, Spacer* prevDownSpacer) const
1567+
{
1568+
if (staffIdx < 0)
1569+
return nullptr;
1570+
1571+
Spacer* spacer { prevDownSpacer };
1572+
for (MeasureBase* mb : measures()) {
1573+
if (!(mb && mb->isMeasure()))
1574+
continue;
1575+
Spacer* sp { toMeasure(mb)->vspacerUp(staffIdx)} ;
1576+
if (sp) {
1577+
if (!spacer || ((spacer->spacerType() == SpacerType::UP) && (sp->gap() > spacer->gap()))) {
1578+
spacer = sp;
1579+
}
1580+
continue;
1581+
}
1582+
}
1583+
return spacer;
1584+
}
1585+
1586+
//---------------------------------------------------------
1587+
// downSpacer
1588+
// Return the largest downSpacer for this system.
1589+
//---------------------------------------------------------
1590+
1591+
Spacer* System::downSpacer(int staffIdx) const
1592+
{
1593+
if (staffIdx < 0)
1594+
return nullptr;
1595+
1596+
Spacer* spacer { nullptr };
1597+
for (MeasureBase* mb : measures()) {
1598+
if (!(mb && mb->isMeasure()))
1599+
continue;
1600+
Spacer* sp { toMeasure(mb)->vspacerDown(staffIdx) };
1601+
if (sp) {
1602+
if (sp->spacerType() == SpacerType::FIXED) {
1603+
return sp;
1604+
}
1605+
else {
1606+
if (!spacer || (sp->gap() > spacer->gap()))
1607+
spacer = sp;
1608+
}
1609+
}
1610+
}
1611+
return spacer;
1612+
}
1613+
15661614
//---------------------------------------------------------
15671615
// firstNoteRestSegmentX
15681616
// in System() coordinates

libmscore/system.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,10 @@ class System final : public Element {
9595
QList<Bracket*> _brackets;
9696
QList<SpannerSegment*> _spannerSegments;
9797

98-
qreal _leftMargin { 0.0 }; ///< left margin for instrument name, brackets etc.
99-
mutable bool fixedDownDistance { false };
100-
mutable Spacer* activeSpacer { nullptr };
101-
qreal _distance { 0.0 }; // temp. variable used during layout
102-
qreal _systemHeight { 0.0 };
98+
qreal _leftMargin { 0.0 }; ///< left margin for instrument name, brackets etc.
99+
mutable bool fixedDownDistance { false };
100+
qreal _distance { 0.0 }; // temp. variable used during layout
101+
qreal _systemHeight { 0.0 };
103102

104103
int firstVisibleSysStaff() const;
105104
int lastVisibleSysStaff() const;
@@ -188,12 +187,13 @@ class System final : public Element {
188187
qreal minTop() const;
189188
qreal minBottom() const;
190189
qreal spacerDistance(bool up) const;
190+
Spacer* upSpacer(int staffIdx, Spacer* prevDownSpacer) const;
191+
Spacer* downSpacer(int staffIdx) const;
191192

192193
qreal firstNoteRestSegmentX(bool leading = false);
193194

194195
void moveBracket(int staffIdx, int srcCol, int dstCol);
195196
bool hasFixedDownDistance() const { return fixedDownDistance; }
196-
Spacer* getActiveSpacer() const { return activeSpacer; }
197197
int firstVisibleStaff() const;
198198
int nextVisibleStaff(int) const;
199199
qreal distance() const { return _distance; }

0 commit comments

Comments
 (0)