Skip to content

Fixes #686 - [RichText] Add support for monitor specific scaling#687

Draft
fipro78 wants to merge 3 commits intomasterfrom
richtext_dpi_update
Draft

Fixes #686 - [RichText] Add support for monitor specific scaling#687
fipro78 wants to merge 3 commits intomasterfrom
richtext_dpi_update

Conversation

@fipro78
Copy link
Contributor

@fipro78 fipro78 commented Feb 13, 2026

This PR adds support for monitor specific scaling in the richtext widget.

It uses the new Shell#getZoom() API from the upcoming 2026-03 release, so it should not be merged until the release is done.

There is also one open topic related to conversion from a pixel value to point for the font creation.

Signed-off-by: Dirk Fauth <dirk.fauth@googlemail.com>
@@ -4,7 +4,7 @@ Bundle-Name: Nebula Rich Text Editor Examples
Bundle-SymbolicName: org.eclipse.nebula.widgets.richtext.example
Bundle-Version: 1.0.0.qualifier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should have at least some some minimal version change here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you mean the version of the richtext bundle, not the examples. Did that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change anything in any bundle you should increment that bundle's version:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nobody cares about the examples. They are not published and only used for development testing AFAIK. That is why nobody ever mentioned them in 11 years.

But ... you are completely right, and just because nobody cared so far doesn't mean it is correct. ;)
I updated the version. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't actually look at the context around this. 😁

Copy link
Contributor

@merks merks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this:

java: [ '17' ]

and this

jdk 'temurin-jdk17-latest'

need attention with your Java 21 upgrade.

@laeubi
Copy link
Contributor

laeubi commented Feb 13, 2026

There is also one open topic related to conversion from a pixel value to point for the font creation.

Last time I looked into that topic was: Don't do it... actually at Linux I can configure a custom scaling factor for fonts making anything that tries to "adjust" fonts simply fail.

Next SWT/OS lies at you (well ... it do best effort)... so you get a logical DPI not the real hardware DPI... and so on.

So the best one can do is having adapt to system font sizes and maybe add a preference for the user to define an own scaling factor.

If you need Fonts matching an exact bounds, the best is to compute it dynamically using the Font Metrics and then possibly adjust it incrementally.

@fipro78
Copy link
Contributor Author

fipro78 commented Feb 13, 2026

I think this:

java: [ '17' ]

and this

jdk 'temurin-jdk17-latest'

need attention with your Java 21 upgrade.

Thanks for the hint. As the upcoming Eclipse release requires Java 21, this needs to be adapted here also.

@laeubi
I only understand your statement partially. It doesn't really make sense to me in the context of the richtext use case. Probably because I did not clarify the use case.

With CKEditor you can edit and format text in HTML. For the text formatting, the corresponding style elements are added to the tags. And I need to convert these style informations to SWT. The font height is set in px, but Fonts in SWT need to be created with point values. So there is no existing font that would match here at that time from which I could retrieve FontMetrics. At least I would not be aware of something like that. If you have an idea how to solve this in a better way, please let me know.

@laeubi
Copy link
Contributor

laeubi commented Feb 13, 2026

I only understand your statement partially. It doesn't really make sense to me in the context of the richtext use case.

Then maybe you can give an example of where exactly this conversion is needed.

With CKEditor you can edit and format text in HTML

So far so good :-)

The font height is set in px

Where? Html supports a wide range of font size definitions including px, pt, em, ...

Fonts in SWT need to be created with point values. So there is no existing font that would match here at that time from which I could retrieve FontMetrics

If you can create Fonts you have a Display and you can create a GC and get FontMetrics from that....

Rectangle embeddedShellBounds = embeddedShell.getBounds();

String updateOnRuntime = System.getProperty("swt.autoScale.updateOnRuntime", "false"); //$NON-NLS-1$ //$NON-NLS-2$
if (!Boolean.parseBoolean(updateOnRuntime)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit that I do not understand why the distinction between monitor-specific scaling disabled/enabled has to be made here. I would expect that if you need to do something special for non-100% in monitor-specific scaling, you will probably need to do the same with monitor-specific scaling disabled at zooms of 175% and higher (but that's just a guess because I do not know why these different calculations are necessary here).

Anyway, in case the distinction is necessary, I propose to use getDisplay.isRescalingAtRuntime() instead of evaluating the system property. It should give you an even "more correct" value (as you can change the system property after the display with its shells has been created).

@fipro78
Copy link
Contributor Author

fipro78 commented Feb 13, 2026

@laeubi

The HTML is generated by CKEditor, and I don't have much influence on how it is generated. For example if a text is selected to have a size of 20, the generated HTML looks like this

<p><span style="font-size:20px">Eclipse</span></p>

In the RichTextPainter basically the HTML is parsed to generate instructions for painting. In one place the font styling is parsed, and if the font size is provided as px, it needs to be converted to points.

int pointSize = 72 * ScalingHelper.convertHorizontalPixelToDpi(pixel) / Display.getDefault().getDPI().x;

I use instructions to process the tags accordingly, and the font style is applied via span in ckeditor. So the font according to the styling is created in the SpanStylePaintInstruction

You can use the RichTextViewerExample to see it in action. With the current implementation, the selected font size in the browser reflects correctly in the viewer. At least it does on Windows with different scalings (or at least it did).

@HeikoKlare
The distinction is necessary because the Javascript returns different values than SWT. Probably because the Javascript execution does not know about the autoscaling setting. So if updateOnRuntime is false on a 150% scaling monitor, I get the 100% values from the javascript callback, but the 150% values via Shell.getBounds(). If I set updateOnRuntime to true, I get the 150% values from the javascript callback and from Shell.getBounds(). Why? I have no idea! Took me quite a while to find and handle this. I would expect that the pixel values should be the same in the browser and the shell, as the browser renders inside the shell, and therefore they have the same dimensions. But actually they don't.

Thanks for the hint about getDisplay.isRescalingAtRuntime(), I will adapt this and do some further testing.

@merks
Is there anything else I have to modify for the Java 21 update? Seems the build still fails because there is no Java 21 available.

@HeikoKlare
Copy link

If I set updateOnRuntime to true, I get the 150% values from the javascript callback and from Shell.getBounds(). Why? I have no idea! Took me quite a while to find and handle this. I would expect that the pixel values should be the same in the browser and the shell, as the browser renders inside the shell, and therefore they have the same dimensions. But actually they don't

I a quite sure this is not caused by updateOnRuntime but by the SWT autoscale mode that is (implicitly) changed when enabling updateOnRuntime. Precisely, without updateOnRuntime the autoscale mode integer is used whereas with updateOnRuntime enabled it defaults to quarter. You can see this by starting the application with -Dswt.autoScale.updateOnRuntime=false -Dswt.autoScale=quarter where you should make the same observations regarding the sizes as with updateOnRuntime enabled.
So all this is caused by the special autoscale handling of SWT that was introduced like 10 years ago, which used to only know about 100% and 200% for bounds, sizes etc. but exact scales for the fonts, which led to weird results before monitor-specific scaling was available.
And it means that with updateOnRuntime set to false, for 175% and above you should get scaled values from the Javascript as well and have to deal with them (which does not seem to be covered by the current implementation).

Related to this, the size of the shell does not look as intended to me when having updateOnRuntime set to false.

This is the size at 150%:
image

And this at 175%:
image

So the shell seems to be autoscaled to 100%/200%.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants