Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 41 additions & 31 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,8 @@ static void distributeStaves(Page* page)
if (!sysStaff->show())
continue;

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

if (newSystem) {
vgd->addSpaceBetweenSections();
Expand Down Expand Up @@ -1647,13 +1647,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 +1688,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 +1699,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,24 +5106,28 @@ LayoutContext::~LayoutContext()

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

VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *sst, const Spacer* spacer, qreal y)
VerticalGapData::VerticalGapData(bool first, System *sys, Staff *st, SysStaff *sst, Spacer* nextSpacer, qreal y)
: _fixedHeight(first), system(sys), sysStaff(sst), staff(st)
{
if (_fixedHeight) {
_normalisedSpacing = system->score()->styleP(Sid::staffUpperBorder);
_maxActualSpacing = _normalisedSpacing;
}
else {
_normalisedSpacing = system->y() + (sysStaff ? sysStaff->y() : 0.0) - y;
_maxActualSpacing = system->score()->styleP(Sid::maxStaffSpread);

Spacer* spacer { sys->upSpacer(st->idx(), nextSpacer) };

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);
_fixedSpacer = spacer->spacerType() == SpacerType::FIXED;
_normalisedSpacing = qMax(_normalisedSpacing, spacer->gap());
if (_fixedSpacer) {
_maxActualSpacing = _normalisedSpacing;
}
}
}
}
Expand All @@ -5146,8 +5152,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 +5166,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 +5193,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 +5230,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 +5252,7 @@ qreal VerticalGapData::addSpacing(qreal step)

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

//---------------------------------------------------------
Expand All @@ -5265,8 +5271,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 +5296,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 +5320,4 @@ qreal VerticalGapDataList::smallest(qreal limit) const
}
return vdp ? vdp->spacing() : 0.0;
}

}
3 changes: 2 additions & 1 deletion libmscore/layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Page;
class VerticalGapData {
private:
bool _fixedHeight { false };
bool _fixedSpacer { false };
qreal _factor { 1.0 };
qreal _normalisedSpacing { 0.0 };
qreal _maxActualSpacing { 0.0 };
Expand All @@ -41,7 +42,7 @@ class VerticalGapData {
SysStaff* sysStaff { nullptr };
Staff* staff { nullptr };

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

void addSpaceBetweenSections();
void addSpaceAroundVBox(bool above);
Expand Down
67 changes: 59 additions & 8 deletions libmscore/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,29 +1540,80 @@ 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());
}
}
}
return dist;
}

//---------------------------------------------------------
// upSpacer
// Return largest upSpacer for this system. This can
// be a downSpacer of the previous system.
//---------------------------------------------------------

Spacer* System::upSpacer(int staffIdx, Spacer* prevDownSpacer) const
{
if (staffIdx < 0)
return nullptr;

if (prevDownSpacer && (prevDownSpacer->spacerType() == SpacerType::FIXED))
return prevDownSpacer;

Spacer* spacer { prevDownSpacer };
for (MeasureBase* mb : measures()) {
if (!(mb && mb->isMeasure()))
continue;
Spacer* sp { toMeasure(mb)->vspacerUp(staffIdx)} ;
if (sp) {
if (!spacer || ((spacer->spacerType() == SpacerType::UP) && (sp->gap() > spacer->gap()))) {
spacer = sp;
}
continue;
}
}
return spacer;
}

//---------------------------------------------------------
// downSpacer
// Return the largest downSpacer for this system.
//---------------------------------------------------------

Spacer* System::downSpacer(int staffIdx) const
{
if (staffIdx < 0)
return nullptr;

Spacer* spacer { nullptr };
for (MeasureBase* mb : measures()) {
if (!(mb && mb->isMeasure()))
continue;
Spacer* sp { toMeasure(mb)->vspacerDown(staffIdx) };
if (sp) {
if (sp->spacerType() == SpacerType::FIXED) {
return sp;
}
else {
if (!spacer || (sp->gap() > spacer->gap()))
spacer = sp;
}
}
}
return spacer;
}

//---------------------------------------------------------
// firstNoteRestSegmentX
// in System() coordinates
Expand Down
12 changes: 6 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 @@ -188,12 +187,13 @@ class System final : public Element {
qreal minTop() const;
qreal minBottom() const;
qreal spacerDistance(bool up) const;
Spacer* upSpacer(int staffIdx, Spacer* prevDownSpacer) const;
Spacer* downSpacer(int staffIdx) const;

qreal firstNoteRestSegmentX(bool leading = false);

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