Skip to content

Commit

Permalink
Reimplement spacers in vertical staves adjustment to make sure all sp…
Browse files Browse the repository at this point in the history
…acers are taken into account.
  • Loading branch information
njvdberg committed Mar 10, 2021
1 parent 0e9870b commit 7f33d6b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 43 deletions.
90 changes: 61 additions & 29 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,7 @@ static void distributeStaves(Page* page)
qreal prevYBottom { page->tm() };
qreal yBottom { 0.0 };
bool vbox { false };
Spacer* activeSpacer { nullptr };
Spacer* nextSpacer { nullptr };
bool transferNormalBracket { false };
bool transferCurlyBracket { false };
for (System* system : page->systems()) {
Expand Down Expand Up @@ -1614,8 +1614,32 @@ static void distributeStaves(Page* page)
if (!sysStaff->show())
continue;

Spacer* activeSpacer { nextSpacer };
nextSpacer = nullptr ;
for (MeasureBase* mb : system->measures()) {
if (!(mb && mb->isMeasure()))
continue;
Measure* m = toMeasure(mb);
Spacer* sp = m->vspacerUp(staff->idx());
if (sp) {
if (!activeSpacer || ((activeSpacer->spacerType() == SpacerType::UP) && (sp->gap() > activeSpacer->gap()))) {
activeSpacer = sp;
}
continue;
}
sp = m->vspacerDown(staff->idx());
if (sp) {
if (sp->spacerType() == SpacerType::FIXED) {
nextSpacer = sp;
}
else {
if (!nextSpacer || (sp->gap() > nextSpacer->gap()))
nextSpacer = sp;
}
}
}

VerticalGapData* vgd = new VerticalGapData(!ngaps++, system, staff, sysStaff, activeSpacer, prevYBottom);
activeSpacer = nullptr;

if (newSystem) {
vgd->addSpaceBetweenSections();
Expand Down Expand Up @@ -1647,13 +1671,12 @@ static void distributeStaves(Page* page)
transferNormalBracket = endNormalBracket >= 0;
transferCurlyBracket = endCurlyBracket >= 0;
}
activeSpacer = system->getActiveSpacer();
}
--ngaps;

qreal spaceLeft { page->height() - page->bm() - score->styleP(Sid::staffLowerBorder) - yBottom };
if (activeSpacer)
spaceLeft -= activeSpacer->gap();
if (nextSpacer && (nextSpacer->spacerType() == SpacerType::DOWN))
spaceLeft -= nextSpacer->gap();
if (spaceLeft <= 0.0)
return;

Expand Down Expand Up @@ -1689,8 +1712,9 @@ static void distributeStaves(Page* page)
}
if ((spaceLeft - addedSpace) <= 0.0)
{
for (VerticalGapData* vgd : modified)
for (VerticalGapData* vgd : modified) {
vgd->undoLastAddSpacing();
}
ngaps = 0;
}
else {
Expand All @@ -1699,17 +1723,19 @@ static void distributeStaves(Page* page)
}

// If there is still space left, distribute the space of the staves.
// However, there is a limit on how much space is added per gap.
const qreal maxPageFill { score->styleP(Sid::maxPageFillSpread) };
spaceLeft = qMin(maxPageFill * vgdl.length(), spaceLeft);
pass = 0;
ngaps = 1;
while (!almostZero(spaceLeft) && !almostZero(maxPageFill) && (ngaps > 0) && (++pass < maxPasses)) {
ngaps = 0;
qreal addedSpace { 0.0 };
qreal step {spaceLeft / vgdl.sumStretchFactor() };
for (VerticalGapData* vgd : vgdl) {
qreal step = spaceLeft / vgdl.sumStretchFactor();
step = vgd->addFillSpacing(step, maxPageFill);
if (!almostZero(step)) {
addedSpace += step * vgd->factor();
qreal res { vgd->addFillSpacing(step, maxPageFill) };
if (!almostZero(res)) {
addedSpace += res * vgd->factor();
++ngaps;
}
}
Expand Down Expand Up @@ -5104,6 +5130,7 @@ LayoutContext::~LayoutContext()

//---------------------------------------------------------
// VerticalStretchData
// defines a gap ABOVE the staff.
//---------------------------------------------------------

VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *sst, const Spacer* spacer, qreal y)
Expand All @@ -5114,14 +5141,15 @@ VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *s
_maxActualSpacing = _normalisedSpacing;
}
else {
_normalisedSpacing = system->y() + (sysStaff ? sysStaff->y() : 0.0) - y;
_maxActualSpacing = system->score()->styleP(Sid::maxStaffSpread);
if (spacer) {
_fixedHeight = true;
_normalisedSpacing = spacer->gap();
_maxActualSpacing = _normalisedSpacing;
}
else {
_normalisedSpacing = system->y() + (sysStaff ? sysStaff->y() : 0.0) - y;
_maxActualSpacing = system->score()->styleP(Sid::maxStaffSpread);
_hasSpacer = true;
_fixedSpacer = spacer->spacerType() == SpacerType::FIXED;
_normalisedSpacing = qMax(_normalisedSpacing, spacer->gap());
if (_fixedSpacer) {
_maxActualSpacing = _normalisedSpacing;
}
}
}
}
Expand All @@ -5146,8 +5174,8 @@ void VerticalGapData::updateFactor(qreal factor)
void VerticalGapData::addSpaceBetweenSections()
{
updateFactor(system->score()->styleD(Sid::spreadSystem));
if (!_fixedHeight)
_maxActualSpacing = qMax(_maxActualSpacing, system->score()->styleP(Sid::maxSystemSpread));
if (!(_fixedHeight | _fixedSpacer))
_maxActualSpacing = system->score()->styleP(Sid::maxSystemSpread) / _factor;
}

//---------------------------------------------------------
Expand All @@ -5160,7 +5188,7 @@ void VerticalGapData::addSpaceAroundVBox(bool above)
_factor = 1.0;
const Score* score { system->score() };
_normalisedSpacing = above ? score->styleP(Sid::frameSystemDistance) : score->styleP(Sid::systemFrameDistance);
_maxActualSpacing = _normalisedSpacing;
_maxActualSpacing = _normalisedSpacing / _factor;
}

//---------------------------------------------------------
Expand All @@ -5187,7 +5215,7 @@ void VerticalGapData::addSpaceAroundCurlyBracket()

void VerticalGapData::insideCurlyBracket()
{
_maxActualSpacing = system->score()->styleP(Sid::maxAkkoladeDistance);
_maxActualSpacing = system->score()->styleP(Sid::maxAkkoladeDistance) / _factor;
}

//---------------------------------------------------------
Expand Down Expand Up @@ -5224,9 +5252,9 @@ qreal VerticalGapData::actualAddedSpace() const

qreal VerticalGapData::addSpacing(qreal step)
{
if (_fixedHeight)
if (_fixedHeight | _fixedSpacer)
return 0.0;
if ((_normalisedSpacing >= _maxActualSpacing)) {
if (_normalisedSpacing >= _maxActualSpacing) {
_normalisedSpacing = _maxActualSpacing;
step = 0.0;
}
Expand All @@ -5246,7 +5274,7 @@ qreal VerticalGapData::addSpacing(qreal step)

bool VerticalGapData::isFixedHeight() const
{
return _fixedHeight;
return _fixedHeight || almostZero(_normalisedSpacing - _maxActualSpacing);
}

//---------------------------------------------------------
Expand All @@ -5265,8 +5293,11 @@ void VerticalGapData::undoLastAddSpacing()

qreal VerticalGapData::addFillSpacing(qreal step, qreal maxFill)
{
qreal res = addSpacing(qMin(maxFill - _fillSpacing, step));
_fillSpacing += res;
if (_fixedSpacer)
return 0.0;
qreal actStep { ((step + _fillSpacing / _factor) > maxFill) ? (maxFill - _fillSpacing / _factor) : step};
qreal res = addSpacing(actStep);
_fillSpacing += res * _factor;
return res;
}

Expand All @@ -5287,8 +5318,10 @@ void VerticalGapDataList::deleteAll()
qreal VerticalGapDataList::sumStretchFactor() const
{
qreal sum { 0.0 };
for (VerticalGapData* vsd : *this)
sum += vsd->factor();
for (VerticalGapData* vsd : *this) {
if (!vsd->isFixedHeight())
sum += vsd->factor();
}
return sum;
}

Expand All @@ -5309,5 +5342,4 @@ qreal VerticalGapDataList::smallest(qreal limit) const
}
return vdp ? vdp->spacing() : 0.0;
}

}
2 changes: 2 additions & 0 deletions libmscore/layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Page;
class VerticalGapData {
private:
bool _fixedHeight { false };
bool _hasSpacer { false };
bool _fixedSpacer { false };
qreal _factor { 1.0 };
qreal _normalisedSpacing { 0.0 };
qreal _maxActualSpacing { 0.0 };
Expand Down
10 changes: 2 additions & 8 deletions libmscore/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,23 +1540,17 @@ qreal System::spacerDistance(bool up) const
if (staff < 0)
return 0.0;
qreal dist = 0.0;
activeSpacer = nullptr;
for (MeasureBase* mb : measures()) {
if (mb->isMeasure()) {
Measure* m = toMeasure(mb);
Spacer* sp = up ? m->vspacerUp(staff) : m->vspacerDown(staff);
if (sp) {
if (sp->spacerType() == SpacerType::FIXED) {
activeSpacer = sp;
dist = sp->gap();
break;
}
else {
if (sp->gap() > dist) {
activeSpacer = sp;
dist = sp->gap();
}
}
else
dist = qMax(dist, sp->gap());
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions libmscore/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,10 @@ class System final : public Element {
QList<Bracket*> _brackets;
QList<SpannerSegment*> _spannerSegments;

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

int firstVisibleSysStaff() const;
int lastVisibleSysStaff() const;
Expand Down Expand Up @@ -193,7 +192,6 @@ class System final : public Element {

void moveBracket(int staffIdx, int srcCol, int dstCol);
bool hasFixedDownDistance() const { return fixedDownDistance; }
Spacer* getActiveSpacer() const { return activeSpacer; }
int firstVisibleStaff() const;
int nextVisibleStaff(int) const;
qreal distance() const { return _distance; }
Expand Down

0 comments on commit 7f33d6b

Please sign in to comment.