Changed the demo to use a 1px align at the right, at some sizes the margin is 0px / 2px
latest tip, develop
Its due the the same issue with the other previous issue, the coordinates should be always rounded from absolute coordinates (set bottom-right, not width-height)
My suspicion is that we’re falling foul of of some rounding error where we’re very close to a .5 boundary - where the centre of the 1px white line is at an integer position.
Just an idea, shoudn‘t the coordinats always rounded down?
Because components are integer based, the responsible pixel between 0.000 and 0.999 is 0 (which fills the whole pixel), and calculated coordinates beginning with 0.000.
I was about to report his as a bug, but it seems now like it’s intensional?
I have a FlexItem with a width of 4.99999952f as the result of a lossy-calculation (comes from calculating 10% of 50) which I would expect to be rounded to 5. However because of this patch to always round-down, my component is given a width of 4. I was left scratching my head for long time as to why 10% of 50 was 4 - thought I was going mad.
Could someone shed some light on why always rounding-down is the correct solution? I don’t really understand why that’s preferable over rounding to the nearest whole number?
The FlexBox and Grid algorithms, as they are implemented using floating point numbers, are pretty efficient in that they can lay out items consistently with a large number of parameters, while not having different implementations for different use cases.
You could argue that it’s a weakness of theirs that final, integer positions are only accurate to ±0.5 pixels [1], and linear sizes to ±1 pixels, since you get them by summing two positions.
Always rounding down vs. rounding to the nearest integer are no different in this matter. If you modify the FlexBoxDemo to use the once proposed roundToIntAccurate() you will see that the width of columns will still not always be equal to each other and you can still see something almost 5 wide get rounded down to 4.
An alternative approach would be to calculate positions and sizes such as x = roundToInt (position.getX()); right = x + roundToInt (position.getWidth());
which would make FlexItem sizes ±0.5 pixels accurate at the cost of the right edge now having the larger error. That would also make the issue with the 1 px margins manifest again, so that alternative seems worse.
The reason I think rounding down is preferable is that it’s cheaper and more predictable. The integral part is stored accurately up to a pretty large number in terms of UI sizes, and then you won’t have to wonder how it will be rounded.
[1]: Or in the case of always rounding down an error between (-1, 0]
Thanks for taking the time to explain this @attila!
In my particular use case I found that using doubles rather than floats to do that 10% of 50 calculation removed the precision error.
I always prefer for any oddities like this to be handled internally by the API, rather than the client having to do things in a way that doesn’t always make the intent obvious… but I can see how in this case the rounding-down is the better approach from JUCE’s POV so I can live with that