-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Segment-based horizontal spacing #25099
Conversation
009f6bb
to
955469d
Compare
return 0.0; | ||
case SegmentType::ChordRest: | ||
{ | ||
Shape leftBarrier(RectF(0.0, -0.5 * DBL_MAX, 0.0, DBL_MAX)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-0.5 * DBL_MAX
Could you explain the purpose of this? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit hacky, but it's also a simple way of ensuring that nothing can cross the left margin of the system (and it was done this way since forever). We basically compute minLeft
against a "barrier" rectangle of infinite height (but our infinite is actually DBL_MAX, and if we want our rectangle to have height = DBL_MAX we let it start from -0.5 * DBL_MAX so it will extend to both large negative and large positive y).
@mike-spa great job! We should also do some performance tests (compare layout time on large scores). @DmitryArefiev FYI |
@RomanPudashkin @DmitryArefiev I've already done some performance testing using our built in profiler and the results show significant improvements (see PR description). It's probably not going to be noticeable by the end user, but it's still a good step |
@RomanPudashkin all done! |
Wonderful! Been waiting a long time for this one. Can't wait to test it out. Thank you! |
Resolves: #17423
Resolves: #23507 (no idea what caused this, but it appears that among the many changes I've made this issue has gone away)
Musescore's horizontal spacing algorithms have always worked on a strictly measure-by-measure basis. Essentially, each measure is treated as an individual block which computes its own internal spacing (the main calculations taking place in
MeasureLayout::computeWidth
) , and systems are formed by adding these blocks one after the other. My original spacing improvements worked around this issue in many different ways, but they didn't change the fundamental fact that measures are still spaced separately. This was always going to be inadequate for our future needs, but the immediate necessity is that it makes it impossible to let lyrics cross bar lines, because we can't check for collisions beyond measure boundaries.This PR implements a Segment-based (as opposed to measure-based) horizontal spacing approach. The core calculations now happen in
HorizontalSpacing::spaceSegments
, where segments are spaced in system-coordinates as if measures didn't exist, and then we use the resulting segment positions to establish measures widths and positions inHorizontalSpacing::setPositionsAndWidths
.The new system supports all the previous measure-based functionality, including: the fact that systems are still filled one measure at a time, so also their width (and therefore the line-breaking decisions) are updated one measure at a time (this is why I have
HorizontalSpacing::updateSpacingForLastAddedMeasure
alongsideHorizontalSpacing::computeSpacingForFullSystem
); the fact that measures can have individual stretch applied; styled parameters such as minimum measure width; etc.Rethinking the system as a whole allowed a series of further improvements.
HorizontalSpacing::stopCheckingPreviousSegments
, we now make smarter decisions on how many segments we go back to look for collisions (before, we stopped at measure boundaries, but that's not relevant anymore). This strongly reduces the total number of segment-to-segment collision checks we do (from 340.000 to less than 100.000 in one big file I've tested), which also has significant performance benefits.Before:
After: