Skip to content

Commit

Permalink
More code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-spa committed Jan 19, 2022
1 parent 30e06eb commit 99e637c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
13 changes: 9 additions & 4 deletions src/engraving/layout/layoutsystem.cpp
Expand Up @@ -86,8 +86,9 @@ System* LayoutSystem::collectSystem(const LayoutOptions& options, LayoutContext&
bool curTrailer = ctx.curMeasure->trailer();
MeasureBase* breakMeasure = nullptr;

Fraction minTicks = Fraction(4, 1); // Inizialize variable which stores the shortest note of the system
Fraction prevMinTicks = Fraction(4, 1);
Fraction minTicks = Fraction(10000, 1); // Initializing this variable at a random high value.
// In principle, it just needs to be longer than any possible note.
Fraction prevMinTicks = Fraction(1, 1);
bool changeMinSysTicks = false;
qreal oldStretch = 1;

Expand Down Expand Up @@ -387,8 +388,12 @@ System* LayoutSystem::collectSystem(const LayoutOptions& options, LayoutContext&
qreal stretchCoeff = 1;
qreal prevWidth = 0;
int iter = 0;
while (abs(newRest) > score->spatium() * 0.08 && iter < 200) { // spatium*0.08 is about the width of a note stem
stretchCoeff += 1.5 * newRest / curSysWidth;
static double epsilon = score->spatium() * 0.08; // For reference: this is approximately as small as the width of a note stem
static constexpr int maxIter = 200; // Limits the number of iterations, just for safety. In reality, most systems require less then 10 iterations.
static constexpr float multiplier = 1.5; // Empirically optimized value which allows the fastest convergence of the following algorithm.

while (abs(newRest) > epsilon && iter < maxIter) {
stretchCoeff += multiplier * newRest / curSysWidth;
for (MeasureBase* mb : system->measures()) {
if (mb->isMeasure()) {
Measure* m = toMeasure(mb);
Expand Down
16 changes: 8 additions & 8 deletions src/engraving/libmscore/measure.cpp
Expand Up @@ -3149,8 +3149,6 @@ QString Measure::accessibleInfo() const

void Measure::layoutMeasureElements()
{
//bbox().setWidth(targetWidth); // Doesn't seem to be needed but I keep it here just to be safe

//---------------------------------------------------
// layout individual elements
//---------------------------------------------------
Expand Down Expand Up @@ -4008,7 +4006,7 @@ static bool hasAccidental(Segment* s)
}

//---------------------------------------------------------
// Stretch formula
// durationStretch
// Computes the stretch for a given segment depending
// on its duration with respect to the shortest one.
// Three different options proposed (see documentation).
Expand All @@ -4019,7 +4017,7 @@ float Measure::durationStretch(Fraction curTicks, const Fraction minTicks) const
static constexpr qreal baseSlope = 0.647;
qreal slope = userSlope * baseSlope;
// The slope of the spacing formula is determined by the multiplication of user-defined settings and baseSlope.
// The value of baseSlope is chosen such that, for the default user settings, the curve matches the Gould.
// The value of baseSlope is chosen such that the curve matches the "ideal" one when user settings are at default.
// See documentation PDF for more detail.

static constexpr int maxMMRestWidth = 20; // At most, MM rests will be spaced "as if" they were 20 bars long.
Expand All @@ -4046,7 +4044,7 @@ float Measure::durationStretch(Fraction curTicks, const Fraction minTicks) const
//qreal str = 1 - 0.112 * slope + 0.112 * slope * qreal(curTicks.ticks()) / qreal(minTicks.ticks());
// Logarithmic spacing (MS 3.6)
//qreal str = 1.0 + 0.721 * slope * log(qreal(curTicks.ticks()) / qreal(minTicks.ticks()));
// Quadratic spacing (Gould)
// Quadratic spacing
qreal str = 1 - slope + slope * sqrt(qreal(curTicks.ticks()) / qreal(minTicks.ticks()));

if (minTicks > longNoteThreshold) {
Expand Down Expand Up @@ -4077,8 +4075,10 @@ void Measure::computeWidth(Segment* s, qreal x, bool isSystemHeader, Fraction mi
bool first = isFirstInSystem();
const Shape ls(first ? RectF(0.0, -1000000.0, 0.0, 2000000.0) : RectF(0.0, 0.0, 0.0, spatium() * 4));

qreal minNoteSpace = score()->noteHeadWidth() * 1.05;
qreal usrStretch = qMax(userStretch() * score()->styleD(Sid::measureSpacing), qreal(0.1)); // The qMax avoids stretch going to zero
qreal minNoteSpace = score()->noteHeadWidth() * 1.05; // This used to be minNoteSpace = noteHeadWidth() + minNoteDistance().
// I have removed minNoteDistance() because it was causing an unintuitive behaviour in the spacing,
// and I've substituted it with a purely empirical factor (*1.05) which obtains a similar default distance.
qreal usrStretch = std::max(userStretch() * score()->styleD(Sid::measureSpacing), qreal(0.1)); // The max() avoids stretch going to zero

while (s) {
s->rxpos() = x;
Expand Down Expand Up @@ -4119,7 +4119,7 @@ void Measure::computeWidth(Segment* s, qreal x, bool isSystemHeader, Fraction mi
// NOTE: durStretch is the spacing factor purely determined by the duration of the note.
// usrStretch is the spacing factor determined by user settings.
// stretchCoeff is the spacing factor used to justify the systems, i.e. getting the systems to fill the page.
w = qMax(w, minStretchedWidth);
w = std::max(w, minStretchedWidth);
}
}
// look back for collisions with previous segments
Expand Down
9 changes: 4 additions & 5 deletions src/engraving/libmscore/system.cpp
Expand Up @@ -1832,14 +1832,13 @@ int System::lastVisibleSysStaffOfPart(const Part* part) const

Fraction System::minSysTicks() const
{
Fraction minTicks = Fraction(10, 1); // Initializing the variable at a random high value.
Fraction minTicks = Fraction (10000, 1); // Initializing the variable at a random high value.
// In principle, it just needs to be longer than any possible note, such that the following loop
// always correctly returns the shortest note/rest of the system.
for (MeasureBase* mb : measures()) {
if (mb->isMeasure()) {
Measure* m = toMeasure(mb);
Fraction curMinTicks = m->computeTicks();
if (curMinTicks < minTicks) {
minTicks = curMinTicks;
}
minTicks = std::min(m->computeTicks(), minTicks);
}
}
return minTicks;
Expand Down

0 comments on commit 99e637c

Please sign in to comment.