On ping-pong-ing layout

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

On ping-pong-ing layout

Maurizio M. Gavioli
I'll take the issue http://musescore.org/en/node/30941 as an example (but other examples exist and more or less anybody met this anomaly once) and specifically the sample score posted in the thread last comment ( http://musescore.org/en/node/30941#comment-129056 ):

I think (part of?) the problem resides in the Score::layoutSystem() function (file libmscore/layout.cpp); it uses Measure::minWidth1() and Measure::minWidth2() to compute the measure width, accumulate them into a total width and stop when the system width is exceeded.

A measure might require courtesy elements after itself (clef, key sig., time sig.), if system-final, but obviously does not if not system-final. Occasionally, the bare width of the measure does fit in the system, but the width of the measure + court. elements does not. This happens with measure 7 of the sample score quoted above.

Measure::minWidth1() and Measure::minWidth2() do not take any cautionary / courtesy element at the end of the system into account to compute the measure width; nor should they, as these functions are agnostic about the context the measure is in.

Also Score::layoutSystem() does not look for courtesy elements: it only accumulates measure bare widths against the total system width. Courtesy elements are added afterwards by Score::layoutSystemRow(), once Score::layoutSystem() returns. At this point, the measures belonging to the systems are defined and Score::layoutSystemRow() 'squeezes' courtesy elements in, without noticing this exceeds the system width.

At next layout, the system final courtesy elements will be there and will be accounted for, resulting in the last system measure being moved to the next system (which in turns removes the courtesy elements, no longer needed)... and so on...

I see two possible strategies:

1) Score::layoutSystem() checks for potential courtesy elements before adding another measure to the system.

2) Score::layoutSystemRow() checks for available room before adding the courtesy elements it sees needed and removes the last system measure if they do not fit.

Any suggestion? Anyone volunteering to pick up the task?

Thanks,

M.
Reply | Threaded
Open this post in threaded view
|

Re: On ping-pong-ing layout

Marc Sabatella
Thanks for looking into this further!

> *Measure::minWidth1()* and *Measure::minWidth2()* do not take any cautionary
> / courtesy element at the end of the system into account to compute the
> measure width; nor should they, as these functions are agnostic about the
> context the measure is in.

Agreed.  If they happen to already contain the element, they should
include it in the calculation, but it shouldn't be manufactured here.  
However, see below.

> Also *Score::layoutSystem()* does not look for courtesy elements: it only
> accumulates measure bare widths against the total system width. Courtesy
> elements are added afterwards by *Score::layoutSystemRow()*, once
> *Score::layoutSystem()* returns. At this point, the measures belonging to
> the systems are defined and *Score::layoutSystemRow()* 'squeezes' courtesy
> elements in, without noticing this exceeds the system width.

That's exactly what that example looks like to me, thanks for confirming!

> I see two possible strategies:
>
> 1) *Score::layoutSystem()* checks for potential courtesy elements before
> adding another measure to the system.
>
> 2) *Score::layoutSystemRow()* checks for available room before adding the
> courtesy elements it sees needed and removes the last system measure if they
> do not fit.

I don't know much about how layout works on this "high" level - I've
been more concerned with finer details.

My gut feel is that #1 makes more sense, because if layoutSystemRow(0
decides it needs to remove a measure from a system, it is going to need
to call layoutSystem() again on every system from then on, and this
process could potentially go on and on.  I think I'd rather layoutSystem
get the calculation "right" the first time - even if that means being a
bit conservative.  Not sure it would, but I'd be willing to live with it.

For example, it appears to me that layoutSystem() is currently unaware
of the possible need to add courtesy signatures beyond whatever might
already have been been generated as part of a measure.  I guess this
also means it might initially overestimate the size of a measure if it
turns out the previously-generated courtesy element is no longer
needed?  If so, maybe there could an additional parameter passed to
minWidth() and/or minWidth2() to tell it to ignore courtesy elements,
and this could be used for the initial calls to those functions.

But I am also a little concerned about adding a lot of complex
courtesy-signature-handling code to layoutSystem that would be
essentially duplicated in layoutSystemRow - plenty of chances for these
calculations to be out of sync.  Perhaps it would be possible to
refactor that somehow.

Anyhow, if people think this is on the right track, or have better ideas
they can explain, I'm willing to give it a shot.  I should mention that
school started for me yesterday, so I do need to be a bit more careful
about what I take on.  Which is to say, I'd be more than happy to see
someone else tackle this.  But this kind of thing has long bothered me
and it would definitely be worth it to me to try to take care of it.

Marc


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
Mscore-developer mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mscore-developer
Reply | Threaded
Open this post in threaded view
|

Re: On ping-pong-ing layout

Maurizio M. Gavioli
Marc Sabatella wrote
Thanks for looking into this further! [...]

> I see two possible strategies:
>
> 1) *Score::layoutSystem()* checks for potential courtesy elements before
> adding another measure to the system.
>
> 2) *Score::layoutSystemRow()* checks for available room before adding the
> courtesy elements it sees needed and removes the last system measure if they
> do not fit.

[...] My gut feel is that #1 makes more sense, because if layoutSystemRow(0 decides it needs to remove a measure from a system, it is going to need to call layoutSystem() again on every system from then on, and this process could potentially go on and on.  I think I'd rather layoutSystem get the calculation "right" the first time - even if that means being a bit conservative.  Not sure it would, but I'd be willing to live with it. [...]
Precisely along these lines, further investigation unearthed a function Score::cautionaryWidth() in layout.cpp, which is apparently supposed to do exactly that: detect and compute the width of cautionary/courtesy elements after a measure. A TODO note in Score::layoutSystem() hints it should be used there, but in fact it is not (it is actually not used at all).

Anybody knows why? Is Score::cautionaryWidth() still unfinished or wrong? Is an old lead now abandoned?

Thanks,

M.
Reply | Threaded
Open this post in threaded view
|

Re: On ping-pong-ing layout

Marc Sabatella
In reply to this post by Maurizio M. Gavioli
On 09/04/2014 04:22 AM, Maurizio M. Gavioli wrote:
> I'll take the issue http://musescore.org/en/node/30941 as an example (but
> other examples exist and more or less anybody met this anomaly once) and
> specifically the sample score posted in the thread last comment (
> http://musescore.org/en/node/30941#comment-129056 )

FWIW, there is now a separate issue filed that I believe shows this
happening with a very simple test score:

http://musescore.org/en/node/36256

Would be nice to address this.  First step is probably to find out if
cautionaryWidth() has any chance of being usable here, as you had asked
earlier.

Marc


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://p.sf.net/sfu/Zoho
_______________________________________________
Mscore-developer mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mscore-developer