Page Settings: switching to inches distorts staff space

• May 13, 2018 - 03:21

Tested in version 2.1 and 3.0. Steps to reproduce:
1) create a new score of any kind
2) go to Layout/Page Settings... and verify that the Staff space (sp) value is 1.764
3) switch Units from mm to in
4) click OK
5) open the Layout/Page Settings dialog again
6) switch the Unit to mm, and now the Staff space value is 1.753

It may seem like a small difference, but it makes a big difference. Clearly it is what happened in this issue:
https://musescore.org/en/node/16630

I imagine this is a rounding error of some kind. It also rings a bell, like I submitted this same bug a few years ago. I can't remember how it was resolved.
edit - Yes, definitely a rounding error when rounding the staff space value to 3 decimal places for inches. I just did the math. You can round the display for inches, but you cannot round the internal number or it will modify the staff space value inadvertently. You have to keep it all at 4 decimal places, at least 4 decimal places.
edit - I just changed my branch to use 5 decimals, but the mm value starts at 1.76400. It is being rounded elsewhere from 1.76388889. This is funky! Rounding really screws this up. Maybe there is no solution for this, and there was no solution a few years ago when this came up. That's probably one of the reasons why I tried to make Points/Pixels an available unit in this dialog, so that the spatium could be kept at exactly 25.000.

If this is not fixable, then I will submit an issue to increase the page width max to be greater than its current value of 2,000. If maintaining a clean spatium value requires using mm units, then I and others need pages wider then 2,000mm in order to do piano-roll-style horizontally scrolling scores. I have set my branch's max to 20,000 in the Width spinbox on the pagesettings.ui. That seems like a reasonable max at this time, though it could definitely go as high as 99,999, keeping it at 5 digits. I don't think 9,999 is enough, though it will probably suffice for now if you want to limit it to 4 digits to the left of the decimal.


Comments

This comment applies to version 3.0 only.
A further problem: once you have switched units to inches, you can never get the spatium value back to exactly 25.000. Resetting units to millimeter and setting the staff space manually back to 1.764 creates a small rounding error too: 25.002
I am about to recreate an entire score via copy/paste because of this. There's no other way.

Actually, any time you click the Apply or OK buttons, you create this rounding error. The code sets the spatium to the rounded spinbox value * a conversion factor. So even adjusting margins, even pressing OK instead of Cancel causes this:
https://github.com/musescore/MuseScore/blob/396687ce6ad95b9461154b1ee56…

Before the DPI_F = 5 change, this is 5x less of an issue, and if the spatium itself is being rounded to 3 decimals you get exactly 5.000. That's why I say this is not a problem in version 2, though if there's no rounding on the spatium, then it is an issue, just 5x smaller. I don't feel like setting up a version 2 debug build to actually see the spatium value, so I can't be sure.

I am looking at the resulting issues in SVG exports. The clearest example I have is staff lines spacing unevenly. I create a Treble Clef template-based new score, copy in a couple of pages worth of a single staff, then SVG Export it. All the staff lines are evenly spaced. Then I switch to inches and back to millimeters, adjust the staff space back to 1.764 and SVG Export again. Voilà, some of the staff lines are unevenly spaced. The farther down the page you go, the more uneven they get. SVG Export does some rounding on coordinates too, because it reduces file size and load time, and 2 or 3 decimals is the most you'll ever need. Rounding is useful! But it's best when only applied to final results, not a multiplier.

If you need a clean spatium value, you must never change the units or the staff space value in Page Settings. Just leave the default. Maybe I'm in the minority, in terms of people who care about this level of precision, but it seems that there ought to be a way to resolve this without too much work, and I'm certainly willing to chip in.

The root cause of this issue is QDoubleSpinBox() storing a double as a string. This means setting a value in the spinbox and reading it back you will see two different numbers. E.g. the default spatium is 25, converted in mm it is 1.76389mm. When you put this in the spatiumEntry spinbox and read it back you will get the value 1.764mm, resulting in a spatium of 25.0016. The same is seen for page sizes.
As a matter of fact there is no need to switch to inches and/or mm, just a simple OK or Apply will do because this will read the values from the spinboxes, regardless these are really changed or not.
To solve this issue the code should read the values from spinboxes only when they are really changed. Since the QT spinboxes don't track this we have to do it ourselves. Which isn't a big task by the way.

In reply to by njvdberg

In the end, for the purposes of not changing too much in the code or the file format, the solution I arrived at was not to fix this core issue, but to deal only with the rounding of the default spatium value, which can be handled by a few specific cases of rounded values. I abandoned my PR path because I got busy with other stuff and because it was a lot of work to break up my EPIC PR into chunks.
If you want to continue on this path, I'd be glad to help you...
As for this specific issue, I believe my PRs solved it, though I'd have to go back and test them.

In reply to by njvdberg

I mean all my PRs on this subject from last year, especially that last one. And yes, you are having the same problem as the reviewers, which is why I struggled to get the PR accepted. They wanted a series of very isolated PRs, which makes sense for reviewing it, but not so much for coding it. Anyway, I got pulled away and was able to function with my last rebase, so there I remain for the moment.
Unfortunately the pagesettings.cpp file really needs a major rewrite, which is what I did. There is a lot of unnecessary churning on value changes in the widgets, for example.
You might build the branch for that last PR and see how the dialog works relative to the current dialog in master, if you want to get into it.

In reply to by sideways

As a matter of fact, I also prefer smaller, dedicated PR's. Just step by step so if something goes wrong, it is easier to trace and correct. Especially a rewrite of any piece of code I'll prefer to have the rewrite only. At least it is possible to test the rewrite didn't cause any problems :-).

WhenI look at void PageSettings::spatiumChanged(double val) in PR4906, it seems to me it is not solving the issue but simply repairing it for the default spatium. But when another spatium is chosen, changing the units (and most likely also just applying the form) will introduce the issue again but now there is no way to repair it.
Therefor my approach would be: If any value hasn't been changed, don't write the value back to the score. That's the only way which prevents this kind of rounding issues. I'll make a small PR demonstrating what I mean.

In reply to by njvdberg

My PR checks for values changed at the end, when you commit to changing the values, not when you change a single value. See here in applyToScore(): https://github.com/musescore/MuseScore/blob/26aa4b89e810e286385d3645a65…

If that's the issue, the application of the value to the score, putting it all in applyToScore() makes the most sense. Less churn during user changes. The only thing that needs to change immediately is the preview score that displays inside the dialog.

Do you still have an unanswered question? Please log in first to post your question.