Bug 412447

Summary: Scaling-Level as multiple of 0.25
Product: [Plasma] KScreen Reporter: Christoph Cullmann <cullmann>
Component: kcmAssignee: Nate Graham <nate>
Status: RESOLVED FIXED    
Severity: normal CC: cfeck, cullmann, nate
Priority: NOR    
Version: git   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 5.18.0

Description Christoph Cullmann 2019-09-29 12:48:15 UTC
I would propose to change the minimal scale factor step to 0.25.

At the moment the minimal step is 0.1, which is very bad given that leads to rounding artifacts everywhere (0.1 is not even something one can properly represent as a floating point value).

Windows normally allows only 0.25 steps (or there 25% steps), too, to avoid such issues.

If one wants a even smaller step size, please always some 2^-x step, like 0.125 or such.

To see the issues, just try e.g. KWrite with some 1.1 scale, I have even artifacts in the menus.
Comment 1 Nate Graham 2019-09-29 15:07:25 UTC
This comes up a bit, and I don't disagree. Certainly we have a problem right now of the important 1.25x and 1.75x scale factors being unreachable in the UI because our minimum increment is 0.1. We should fix that somehow. I see three options:

- Make the increment 0.25 (drawbacks: you lose the ability to set 0.1x, 0.2x, 0.4x etc)

- Make the increment 0.5 (drawbacks: the slider would have a ton of values; might be too many)

- Make the default increment 0.25, but add an advanced scaling mode that allows the user to enter an arbitrary value (drawback: complicated UI; provides more ways for people to shoot themselves in the foot)

Thoughts?
Comment 2 Christoph Cullmann 2019-09-29 17:00:57 UTC
I would prefer to just have 0.25 as minimal step.

10% zoom looks for me strange anyways, you can just alter your font sizes a bit and you will have this effect in a much more usable way. (without any artifacts)
Comment 3 Dominik Haumann 2019-09-29 19:23:23 UTC
I think Christoph's point is exactly about NOT allowing these 0.1 increments. Say we optimize it in such a way that we have the 2^-n steps (e.g. 0.125, or 0.25), then these values at least can be represented as floating point value. Adding an advanced mode that again lets the user to break things is not a good idea, is it?

So +1 for the 0.25 steps.
Comment 4 Christoph Feck 2019-09-30 00:35:53 UTC
What exactly is the difference you are trying to solve with this proposal? The Kate issue you mentioned (and worked around with trying to find a font size that gets an integer upscaled result) doesn't sound plausible. For example, if you scale e.g. 22 pixels (common icon size) up by 1.25 or 1.4, you still get a fractional result in either case.

I agree that limiting to only a single fractional digit is wrong, but not being able to set finer scaling ratios than 0.25 is not something I feel comfortable.
Comment 5 Christoph Cullmann 2019-09-30 03:43:34 UTC
The main issue is:

0.1 is no floating point value you can represent on a machine.

With factors like 1.1, you get rounding artifacts everywhere.
Even if you scale something trivial like a 10 pixel UI element with that, you will never get a non-fractional real pixel height even if you repeat this 10 times.

With 0.25 or 0.5 you at least have some floating point value that will not lead to such strange rounding issues.

https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

It has a reason that Microsoft per default only allows such levels and hides the others behind some "now all is broken" text.

Beside that, before the rise of HiDPI, for such minimal DPI differences, one just adjusted the fonts, no need to render 1 pixel lines as 1.1 pixel. I just don't even see the use-case for allowing per default such fine-grained zooming, beside that it breaks the rendering of close to everything.

If I try that here, I have rendering artifacts everywhere, from the standard menus to toolbars...
Comment 6 Nate Graham 2019-09-30 20:22:46 UTC
https://phabricator.kde.org/D24321
Comment 7 Nate Graham 2019-10-02 14:57:02 UTC
Git commit 7a9387ed727c4538cb8dc3690faeaec8368b0702 by Nate Graham.
Committed on 02/10/2019 at 14:56.
Pushed by ngraham into branch 'master'.

[KCM] Scale more coarsely with the slider, but more finely with a spinbox

Summary:
Right now we have a problem in that the important scale factors of 1.25 and 1.75 are
not reachable using the UI. However just reducing the slider increment to 0.05 would
result in way too many slider values. Instead, this patch implements the following:
- The slider goes by increments of 0.25
- There's a spinbox beside the slider that allows the user to set the scale factor by 0.05 increments
- On X11 with global scaling, the user is shown a warning message when using scale factors that are not a multiple of 0.25

This way the commonly-used scale factors are more accessible, but finer values are
made available to people who really need them and are likely to go poking around.
FIXED-IN: 5.18.0

Test Plan: {F7489713}

Reviewers: #vdg, #plasma, romangg, ndavis

Reviewed By: #vdg, #plasma, romangg, ndavis

Subscribers: dhaumann, davidedmundson, ouwerkerk, GB_2, ndavis, cullmann, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D24321

M  +22   -3    kcm/package/contents/ui/OutputPanel.qml
M  +40   -4    kcm/package/contents/ui/Panel.qml
M  +1    -1    kcm/package/contents/ui/main.qml
M  +2    -2    kded/output.cpp

https://commits.kde.org/kscreen/7a9387ed727c4538cb8dc3690faeaec8368b0702
Comment 8 Christoph Cullmann 2019-10-02 17:43:27 UTC
Thanks already for this nice improvement.

I still think that some minimal factor of 0.0625 would be preferable, this would make the rounding on output unnecessary, too.
Comment 9 Christoph Feck 2019-10-02 17:47:16 UTC
Would it work if we internally round it before storing? E.g. f = qRound(f * 32) / 32. For displaying, it would use f = qRound(f * 20) / 20. Some testing would be needed to confirm this mapping is bijective, otherwise use 64 instead of 32.
Comment 10 Christoph Cullmann 2019-10-02 17:47:37 UTC
Btw., to see the concrete benefit, try out the following:

export QT_SCALE_FACTOR=1.1

use current master version of frameworks + kwrite, open a file, select many lines and then scale the font up and down

In some scale factor always every X lines a artifact will exist.

Try the same with

export QT_SCALE_FACTOR=1.0625

=> I don't get artifacts in any zoom ratio.

The same can be observed with other x * 0.05 scales vs x * 0.0625.

Perhaps these artifacts can be resolved some when in Qt, perhaps not, in any case, by changing the step width for the "expert" mode just a little bit, we can avoid artifacts in most cases and the only drawback is one digit more in the expert mode.

On the other side you can remove the rounding code internally, as there is nothing to round as the x * 0.0625 things will create no rounding errors for the 0-10 something range we use.
Comment 11 Christoph Cullmann 2019-10-02 17:48:50 UTC
> Would it work if we internally round it before storing? E.g. f = qRound(f * 32) / 32. For displaying, it would use f = qRound(f * 20) / 20. Some testing would be needed to confirm this mapping is bijective, otherwise use 64 instead of 32.

An alternate solution is to round it down some 1/16 multiple during output export in kded. But I as user would be a bit suprised to find out my 1.35 I configured in the "expert" field got adjusted.

(thought for me that would still be better than artifacts)
Comment 12 Christoph Cullmann 2019-10-02 17:56:04 UTC
This would be the output code change:

// round to the nearest 1/16 multiple
const double minimalScaleStep = (1. / 16.);
info[QStringLiteral("scale")] = qRound(output->scale() / minimalScaleStep) * minimalScaleStep;
Comment 13 Christoph Cullmann 2019-10-02 17:59:27 UTC
Btw., if you want to read up why such 0.1 or 0.05 things create issues for computation, take e.g. a look at https://docs.python.org/3/tutorial/floatingpoint.html

Actually a good explanation why you get very strange results with such numbers.
And yes, if you look at all your computation everywhere in the code you might be able to circumvent the rounding issues in the most places, thought this seems not realistic to solve for all the stuff we have in the close future.
Comment 14 Nate Graham 2019-10-02 18:31:26 UTC
(In reply to Christoph Cullmann from comment #10)
> Btw., to see the concrete benefit, try out the following:
> 
> export QT_SCALE_FACTOR=1.1
> 
> use current master version of frameworks + kwrite, open a file, select many
> lines and then scale the font up and down
> 
> In some scale factor always every X lines a artifact will exist.
> 
> Try the same with
> 
> export QT_SCALE_FACTOR=1.0625
> 
> => I don't get artifacts in any zoom ratio.
> 
> The same can be observed with other x * 0.05 scales vs x * 0.0625.
I can confirm this.
Comment 15 Nate Graham 2019-10-16 14:50:08 UTC
Git commit 2b23256b0a47526715e98352fe3a12db520c306f by Nate Graham.
Committed on 16/10/2019 at 14:50.
Pushed by ngraham into branch 'master'.

[KCM] Limit scale factor increment to 6.25% on X11

Summary:
Because of the nature of floating point math and various Qt and X11 bugs, limiting the
scale factor increment to 0.0625 (6.25% in percentage form) will improve the display in
many apps.

For more information, see the discussions in https://bugreports.qt.io/browse/QTBUG-66036 and
the following bug reports:
Related: bug 390451, bug 373232

Depends on D24370
Depends on D24371

Test Plan: {F7500922}

Reviewers: #plasma, romangg, mart

Reviewed By: #plasma, romangg, mart

Subscribers: cullmann, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D24373

M  +9    -4    kcm/package/contents/ui/Panel.qml
M  +2    -2    kded/output.cpp

https://commits.kde.org/kscreen/2b23256b0a47526715e98352fe3a12db520c306f