fix #315636: no space between barline and note with invisible signature

Resolves: https://musescore.org/en/node/315636

When code was added to better handle invisible key or time signatures
at the beginning of a score,
this inadvertently affected spacing between barline and first note
if there were invisible key or time signature changes later.
The spacing was never actually *correct* here -
it was controlled by the key or time signature margin -
but it more or less worked and scores depended on it.

The problem is that the changes made involved
setitng the width of these invisible segments to 0
and skipping them.
Whereas previously, they got processed enough
to yield some space betwene the barline and first note.
The firx here is just to limit the effect of the previous change
so not *all* segments with all elements invisible,
but only those in system header measures,
or segments after the beginning of the measure.
Thus we continue to handle beginnings of scores and systems well,
and also courtesies at the end of measures.
But we revert to the previous behavior for key or time signatures
at the beginning of measures that are *not* headers.
Again, it wasn't ideal, but it basically worked,
nand now works again the same way.

I left TODO's in the code to indicate something
of what would need to happen to fix this "for real",
with the space controlled by barNoteDistance as the user expects,
rather than depending on the key or time signature margins.
A quick attempt to implement this led to problems
that convinced me to put it off until a larger scale rewrite
of the spacing algorithms as a whole.
This commit is contained in:
Marc Sabatella 2021-01-25 16:16:42 -07:00 committed by pereverzev_v
parent cebc85256e
commit d0fc8e9739
1 changed files with 13 additions and 2 deletions

View File

@ -4432,13 +4432,21 @@ void Measure::computeMinWidth(Segment* s, qreal x, bool isSystemHeader)
while (s) {
s->rxpos() = x;
if (!s->enabled() || !s->visible() || s->allElementsInvisible()) {
// skip disabled / invisible segments
// segments with all elements invisible are skipped,
// but only for headers or segments later in the measure -
// invisible key or time signatures at the beginning of non-header measures are treated normally here
// otherwise we would not allocate enough space for the first note
// as it is, this isn't quite right as the space will be given by key or time margins,
// not the bar to note distance
// TODO: skip these segments entirely and get the correct bar to note distance
if (!s->enabled() || !s->visible() || ((header() || s->rtick().isNotZero()) && s->allElementsInvisible())) {
s->setWidth(0);
s = s->next();
continue;
}
Segment* ns = s->nextActive();
while (ns && ns->allElementsInvisible())
while (ns && ((header() || ns->rtick().isNotZero()) && ns->allElementsInvisible()))
ns = ns->nextActive();
// end barline might be disabled
// but still consider it for spacing of previous segment
@ -4520,6 +4528,9 @@ void Measure::computeMinWidth()
//
// skip disabled segment
//
// TODO: skip segments with all elements invisible also
// this will eventually allow us to calculate correct bar to note distance
// even if there is an invisible key or time signature present
for (s = first(); s && !s->enabled(); s = s->next()) {
s->rxpos() = 0;
s->setWidth(0);