Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 312723

Summary: Fonts broken on Export to Image and Printing
Product: [Modeling] GMF-Runtime Reporter: Anthony Hunter <ahunter.eclipse>
Component: GeneralAssignee: Alex Boyko <aboyko>
Status: RESOLVED FIXED QA Contact: Alex Boyko <aboyko>
Severity: normal    
Priority: P3 CC: aboyko, ansgar.radermacher, bernd.wiswedel, laurent.redor, p.beauvoir, pierre-charles.david, robert
Version: 1.4.2   
Target Milestone: 1.13.1   
Hardware: PC   
OS: Linux   
See Also: https://git.eclipse.org/r/151700
https://git.eclipse.org/c/gmf-runtime/org.eclipse.gmf-runtime.git/commit/?id=2d71b27e2d536c459ae115f92f2b9a5790454078
https://bugs.eclipse.org/bugs/show_bug.cgi?id=530291
https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/178404
https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/182337
https://git.eclipse.org/c/gmf-runtime/org.eclipse.gmf-runtime.git/commit/?id=32ef796e0d8bf78e666ff7c3d8cc5b52b9fbb7c3
https://git.eclipse.org/c/gmf-runtime/org.eclipse.gmf-runtime.git/commit/?id=7241e5d2b964bc26945fe30c8212e2854ea49eb5
Whiteboard:
Bug Depends on:    
Bug Blocks: 392902    
Attachments:
Description Flags
Example geoshapes diagram
none
Example geoshapes diagram exported to image file with chopped fonts
none
test patch for Ubuntu
none
Example geoshapes diagram exported to image file with better fonts
none
test patch
none
Broken SVG export from Sirius before the patch
none
Fixed SVG export from Sirius with the patch applied
none
KNIME: SVG after the patch is applied (fonts too large)
bernd.wiswedel: review?
KNIME: Before the patch fonts were OK none

Description Anthony Hunter CLA 2010-05-12 17:36:11 EDT
See the attachments. I am on Ubuntu Linux where this problem occurs. 

Take a GMF Geoshapes diagram example.
Create a few shapes with different font sizes.
I used Times New Roman and Arial, 10, 24 and 72 points

Print or export to image as a PNG file.

The fonts are chopped both on the top and bottom.

This error has been around since Ganymede.
Comment 1 Anthony Hunter CLA 2010-05-12 17:37:08 EDT
Created attachment 168279 [details]
Example geoshapes diagram
Comment 2 Anthony Hunter CLA 2010-05-12 17:37:32 EDT
Created attachment 168280 [details]
Example geoshapes diagram exported to image file with chopped fonts
Comment 3 Alex Boyko CLA 2010-05-14 16:02:23 EDT
Truncated text on the top/bottom appears only on during image export, printing, correct? The diagram shows up ok?
This may mean that there is something not good with our AWT graphics implementation in the non-Win32 case.
I'll take a look at this on RedHat. Think exporting to JPG, GIF, BMP might be ok.
Comment 4 Anthony Hunter CLA 2010-05-14 17:13:38 EDT
Correct, on screen is fine, off screen is the problem.

You are also correct, JPG, GIF, and BMP do not have a problem.

SVG, JPEG, PNG, and PDF have the issue with export to image.
Comment 5 Alex Boyko CLA 2010-05-14 18:30:43 EDT
Couldn't reproduce this with RHEL5 (RadHat). Text is not clipped, the image looks exactly like the diagram.
Will try SLED10 (SUSE) next.
Comment 6 Alex Boyko CLA 2010-05-17 19:01:21 EDT
Can reproduce on SLED10. The image is not like the one attached here though. Only the width is clipped, i.e can't see the numbers.
Anyway the problem as far as I see it is that AWT fonts on some Linux platforms are swapped with defaults for some reason. If you look carefully at SWT generated JPG and AWT generated PNG then you'll that New Roman shows up fine on JPG, but it's not New Roman on the PNG image.
Comment 7 Alex Boyko CLA 2010-05-18 11:02:27 EDT
Created attachment 168945 [details]
test patch for Ubuntu

Anthony,

I looked carefully at the screen-shot you attached. For you the fonts are not swapped - they are just larger. I noticed that with SLED 10 fonts on AWT graphics are set larger than they should be. The cause is in GraphicsToGraphics2DAdaptor. Can you try the patch I attached on Ubuntu? Think it may make it work on Ubuntu.
Comment 8 Anthony Hunter CLA 2010-05-18 17:22:21 EDT
Created attachment 169026 [details]
Example geoshapes diagram exported to image file with better fonts

Hi Alex, here is the diagram with your patch. I say the export to image support is better.
Comment 9 Anthony Hunter CLA 2010-05-18 17:24:42 EDT
good to commit for RC1
Comment 10 Alex Boyko CLA 2010-05-18 17:57:38 EDT
That was a hack fix.

We need to fix it as specfied here:
Q: Why does (eg) a 10 pt font in Java applications appear to have a different size from the same font at 10pt in a native application?

A: Conversion from the size in points into device pixels depends on device resolution as reported by the platform APIs. Java 2D defaults to assuming 72 dpi. Platform defaults vary. Mac OS also uses 72 dpi. Linux desktops based on GTK (Gnome) or Qt (KDE) typically default to 96 dpi and let the end-user customise what they want to use. Windows defaults to 96 dpi (VGA resolution) and also offers 120 dpi (large fonts size) and lets users further specify a custom resolution. So a couple of things can now be seen

    * The DPI reported by platform APIs likely has no correspondence to the true DPI

of the display device

    * Its unlikely that Java 2D's default matches the platform default.

So a typical results is that for Window's default 96 DPI that a 10 pt font in a Java application is 72/96 of the size of the native counterpart.

Note that Swing's Windows and GTK L&Fs do scale fonts based on the system DPI to match the desktop. If you want to do the same in your application you can call java.awt.Toolkit.getScreenResolution() and use this to apply a simple scale to the size you specify for fonts. 

http://webcache.googleusercontent.com/search?q=cache:0z36TGFtod0J:java.sun.com/products/java-media/2D/reference/faqs/index.html+AWT+DPI+from+buffered+image&cd=1&hl=en&ct=clnk&gl=ca

I'll provide another patch soon.
Comment 11 Anthony Hunter CLA 2010-05-18 21:44:12 EDT
OK, since RC1 is today this can go into RC2.
Comment 12 Alex Boyko CLA 2010-05-18 23:34:27 EDT
Created attachment 169046 [details]
test patch

Lets try getting platform DPI with AWT instead of SWT. Perhaps SWT doesn't do it correctly for Ubuntu.
Comment 13 Eclipse Webmaster CLA 2010-07-16 23:38:28 EDT
[target cleanup] 2.3 RC was the original target milestone for this
bug
Comment 14 Eclipse Webmaster CLA 2010-07-19 21:58:54 EDT
[GMF Restructure] Bug 319140 : product GMF and component
Runtime was the original product and component for this bug
Comment 15 Ansgar Radermacher CLA 2013-04-15 08:34:31 EDT
This error also affects Papyrus image export on non-Windows machines. I tried the proposed patch (that has apparently never commited). It does not change the resulting SVG file, since Toolkit.getDefaultToolkit().getScreenResolution() and DisplayUtils.getDisplay().getDPI().x actually return the same result (75 dpi) on my machine. This result is also the same that is reported by xdpyinfo:

screen #0:
  dimensions:    2560x1440 pixels (862x485 millimeters)
  resolution:    75x75 dots per inch
  depths (7):    24, 1, 4, 8, 15, 16, 32

I.e. the value is "right", but fonts are smaller compared with the fonts I see on the screen. This means that the font scaling for the screen uses apparently a hardcoded DPI (96) which may make sense to keep diagrams portable. In this case, we would need to use the same hardcoded DPI for the output.
Alternatively, we may use the "right" DPI, but also scale coordinates accordingly.

If I hardcode the windows default of 96 DPI into the code in GraphicsToGraphics2DAdaptor, the results are the same on Linux and Windows. For instance, Papyrus uses a 9pt font by default, the font in the produced SVG file has 12pt size (9 x 96/72).
Comment 16 Ansgar Radermacher CLA 2013-04-15 14:54:24 EDT
I think, the question whether the DPI is correct with respect to the display device is quite irrelevant, since
- the produced SVG or PDF file is likely to be integrated into other documents, printed, etc, i.e. there is no point in adapting it to the screen.

- these two vector formats are scalable anyway.

Thus, I propose to hardcode the windows DPI default to assure consistent handling
Comment 17 Anthony Hunter CLA 2013-04-16 10:37:51 EDT
Agreed that the last patch attached by Alex still does not solve the issue on Ubuntu for SVG.

When you say "to hardcode the windows DPI default", I am not sure how you did that, since that did not seem to work for me. Can you attach a patch what did work?
Comment 18 Ansgar Radermacher CLA 2013-04-16 10:57:56 EDT
Well, it's really quite ugly, I just put the values directly into the code:

file is src/org/eclipse/gmf/runtime/draw2d/ui/render/awt/internal/graphics/GraphicsToGraphics2DAdaptor.java, method setFont

float fsize = (float) height
	// * (float) DisplayUtils.getDisplay().getDPI().x
	* 96.0f / 72.0f;	// default DPI on windows / default DPI of AWT
// don't round, font might be too big (and text may get clipped)
// height = Math.round(fsize);
height = (int) fsize;


Thus, we are using a fixed constant (4/3) for font scaling. I guess something similar is happening when the font size is calculating for rendering to the screen or bitmap formats (though I haven't looked that up).
I also changed the code that calculates the font height: I just casted to int instead of rounding, since it's safer if the font is a too small compared to too big (since it would get clipped).
Comment 19 Eclipse Genie CLA 2019-10-28 09:54:39 EDT
New Gerrit change created: https://git.eclipse.org/r/151700
Comment 20 Ansgar Radermacher CLA 2019-10-28 10:11:17 EDT
As we still have this issue with Papyrus (see for instance https://www.eclipse.org/forums/index.php/m/1780888/?srch=dpi#msg_1780888 or https://www.eclipse.org/forums/index.php/t/1101040/), I pushed my patch to gerrit. I'm not 100% sure, if there are side effects - at least I did not remark any in the context of Papyrus.
Comment 21 Pierre-Charles David CLA 2019-11-06 03:07:23 EST
Created attachment 280518 [details]
Broken SVG export from Sirius before the patch
Comment 22 Pierre-Charles David CLA 2019-11-06 03:07:51 EST
Created attachment 280519 [details]
Fixed SVG export from Sirius with the patch applied
Comment 24 Pierre-Charles David CLA 2020-02-20 11:27:23 EST
*** Bug 270756 has been marked as a duplicate of this bug. ***
Comment 25 Bernd Wiswedel CLA 2020-11-01 15:39:58 EST
Created attachment 284626 [details]
KNIME: SVG after the patch is applied (fonts too large)


At KNIME we use org.eclipse.gmf.runtime.draw2d.ui.render.awt to create SVGs from KNIME workflows. After an upgrade to the 2020-03 eclipse version we noticed that on MacOSX the fonts in the SVGs are too large. The SVG attached here shows the behavior. Going to attach another SVG from an older Eclipse version.
(The jar used here is org.eclipse.gmf.runtime.draw2d.ui.render.awt_1.8.0.201912020813.jar)
Comment 26 Bernd Wiswedel CLA 2020-11-01 15:41:47 EST
Created attachment 284627 [details]
KNIME: Before the patch fonts were OK

This attachment shows the SVG as generated using Eclipse 4.7 (don't recall the yyyy-MM version). The jar of gmf.runtime is: org.eclipse.gmf.runtime.draw2d.ui.render.awt_1.8.0.201706061437.jar
Comment 27 Bernd Wiswedel CLA 2020-11-01 15:56:49 EST
A couple more observations:

As noted in comment #10 MacOS, Linux and Windows report different DPI values (it seems 72 on Mac, on (my) Linux it's 96). So if I look at the change in comment #23 (git change) on Mac there is now also an unconditional scaling taking place and the font size used in Draw2D and GEF world are always scaled to 96/72, which explains the font sizes now being too large. I'd like to note that we don't see this problem on Windows or Linux (at least the instances we have access to) where font size is correctly "calculated".


Although there was a change that ended up on master and in a release this ticket is still in status "NEW".

The version numbers in pom.xml (1.8.0.qualifier) and MANIFEST.MF (1.13.0-SNAPSHOT) are out of sync ([1] vs [2]).

[1] https://git.eclipse.org/r/plugins/gitiles/gmf-runtime/org.eclipse.gmf-runtime/+/refs/heads/master/org.eclipse.gmf.runtime.draw2d.ui.render.awt/META-INF/MANIFEST.MF
[2] https://git.eclipse.org/r/plugins/gitiles/gmf-runtime/org.eclipse.gmf-runtime/+/refs/heads/master/org.eclipse.gmf.runtime.draw2d.ui.render.awt/pom.xml

This now presents a regression (at least in our product). What are the odds we can revert the change?
Comment 28 Phil Beauvoir CLA 2021-03-23 16:12:53 EDT
The following change does not work on Mac:

float fsize = (float) height
	// * (float) DisplayUtils.getDisplay().getDPI().x
	* 96.0f / 72.0f;	// default DPI on windows / default DPI of AWT

The fonts are too big.

You should revert that change.
Comment 29 Ansgar Radermacher CLA 2021-03-24 11:50:19 EDT
On Linux, the situation seems to be the opposite (at least on my machine). Before the patch, fonts were either to big or too small, depending on the display DPI. Now, they work fine. Thus, instead of reverting the patch, I'd prefer to either have OS specific code or further investigate why the code behaves differently on MacOS and Linux that both use GTK.


(In reply to Phil Beauvoir from comment #28)
> The following change does not work on Mac:
> 
> float fsize = (float) height
> 	// * (float) DisplayUtils.getDisplay().getDPI().x
> 	* 96.0f / 72.0f;	// default DPI on windows / default DPI of AWT
> 
> The fonts are too big.
> 
> You should revert that change.
Comment 30 Phil Beauvoir CLA 2021-03-24 12:01:46 EDT
A fixed value of 96 DPI simply doesn't work on Mac because Mac uses 72 DPI therefore all fonts are rendered too large.
Comment 31 Phil Beauvoir CLA 2021-03-24 12:57:00 EDT
Be aware that there are two parts to this hack. The first part uses a fixed DPI of 96 and means that font sizes are incorrect on any device where DPI is not 96 and the second part (integer rounding) ensures a better fit of fonts on higher resolutions:

// height = Math.round(fsize);
height = (int) fsize;

This second part seems reasonable, but the first part of the hack using 96 DPI just plain breaks things on Mac.

> why the code behaves differently on MacOS and Linux that both use GTK.

I think you made a mistake in that sentence, macOS doesn't use GTK.
Comment 32 Ansgar Radermacher CLA 2021-03-25 04:57:16 EDT
Sorry, of course MacOS uses cocoa. I'm chiefly working on Papyrus, i.e. also mainly a user (and not developer) of GMF runtime.
When I proposed the patch, I found it very strange that the SVG export scaled a font based on the current display DPI (and observed too big fonts or too small fonts, depending on the connected screen). I also observed that apparently the getDPI() function on Windows always returned 96 (see https://stackoverflow.com/questions/645352/is-the-number-of-pixels-per-inch-standard-on-all-windows-pc-displays-logpixels) whereas it returned the actual DPI in GTK. This motivated me for the patch, but it was not tested on MacOS. 

(In reply to Phil Beauvoir from comment #31)
> Be aware that there are two parts to this hack. The first part uses a fixed
> DPI of 96 and means that font sizes are incorrect on any device where DPI is
> not 96 and the second part (integer rounding) ensures a better fit of fonts
> on higher resolutions:
> 
> // height = Math.round(fsize);
> height = (int) fsize;
> 
> This second part seems reasonable, but the first part of the hack using 96
> DPI just plain breaks things on Mac.
> 
> > why the code behaves differently on MacOS and Linux that both use GTK.
> 
> I think you made a mistake in that sentence, macOS doesn't use GTK.
Comment 33 Phil Beauvoir CLA 2021-03-25 05:08:53 EDT
(In reply to Ansgar Radermacher from comment #32)
> I also observed that
> apparently the getDPI() function on Windows always returned 96 (see
> https://stackoverflow.com/questions/645352/is-the-number-of-pixels-per-inch-
> standard-on-all-windows-pc-displays-logpixels) whereas it returned the
> actual DPI in GTK.

On Windows, if scaling is set to 150% it will return 144 DPI.

To be clear, we use a standalone copy of GraphicsToGraphics2DAdaptor.java (and GDIFont.java)[0] which came via Graphiti in our RCP application, Archi[1], to support SVG export of Draw2D/GEF3 images.

We've tested this on various configuration of Windows, Linux and Mac at different scalings and found that the only consistent method is the original method of dividing the reported DPI by 72 as in the original code.


[0] https://github.com/archimatetool/archi/blob/master/com.archimatetool.export.svg/src/com/archimatetool/export/svg/graphiti/GraphicsToGraphics2DAdaptor.java
[1] https://www.archimatetool.com
Comment 34 Ansgar Radermacher CLA 2021-03-25 05:41:58 EDT
So, it seems that you used the original code on Linux and had no font scaling issues during the export, right? In Papyrus, we always had (and still have) the different problem that fonts on the screen are smaller than on Windows, i.e. the same model renders differently on both platforms.

> We've tested this on various configuration of Windows, Linux and Mac at
> different scalings and found that the only consistent method is the original
> method of dividing the reported DPI by 72 as in the original code.
Comment 35 Phil Beauvoir CLA 2021-03-25 05:53:44 EDT
(In reply to Ansgar Radermacher from comment #34)
> ...In Papyrus, we always had (and
> still have) the different problem that fonts on the screen are smaller than
> on Windows, i.e. the same model renders differently on both platforms.


This is an issue with different DPIs. Fonts are different sizes on screen on Windows and Mac because of the 96 DPI on Windows and 72 DPI on Mac. So Arial 10 on Mac is rendered smaller on screen than on Windows. We don't change that when exporting to SVG.
Comment 36 Ansgar Radermacher CLA 2021-03-26 04:04:53 EDT
I did some testing with my current Eclipse version (2020-12, I've not yet migrated to 2021-03). Apparently, some things have changed both on Linux and on the SWT side:
- Linux always reports 96 dpi using xdpyinfo, regardless of the correct screen dimensions received via EDID. It only calculates the real DPI, if the user explicitly provides the screen dimension in the monitor section of the xorg configuration file.
- Even if the system DPI differs from 96 (I've added screen dimensions to the monitor section for testing), SWT/GTK currently always reports 96. I guess, this is the reaction to problems independent of this patch when switching between monitors with different DPIs, see bug 539821.

This means, that the patch seems to be no longer necessary for Linux and can be reverted. Pierre-Charles, can you please confirm and eventually revert the patch.

(In reply to Phil Beauvoir from comment #33)
> We've tested this on various configuration of Windows, Linux and Mac at
> different scalings and found that the only consistent method is the original
> method of dividing the reported DPI by 72 as in the original code.
Comment 37 Phil Beauvoir CLA 2021-03-26 05:27:45 EDT
(In reply to Ansgar Radermacher from comment #36)
> This means, that the patch seems to be no longer necessary for Linux and can
> be reverted. Pierre-Charles, can you please confirm and eventually revert
> the patch.

This part of the patch might still be useful:

height = (int) fsize;

In our usage of GraphicsToGraphics2DAdaptor.java text was clipped with some fonts because of rounding the calculated float height value upwards instead of downwards.
Comment 38 Eclipse Genie CLA 2021-03-26 06:02:53 EDT
New Gerrit change created: https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/178404
Comment 39 Pierre-Charles David CLA 2021-04-06 04:22:54 EDT
(In reply to Ansgar Radermacher from comment #36)
> This means, that the patch seems to be no longer necessary for Linux and can
> be reverted. Pierre-Charles, can you please confirm and eventually revert
> the patch.

I've tested under Linux, with the hard-coded 96 DPI and with the call to SWT, and I always get the correct result when exporting a Sirius diagram as SVG. What's strange is that I tested on both 2020-12 and 2020-03 and the result is always fine, while I'm pretty sure I had the original issue at the time (see https://projects.eclipse.org/sites/default/files/release/screenshot/improved-svg-export.png taken at the time for our release notes).

I don't have access to a mac at the moment, I'll try to test there soon (hopefully tomorrow), 

If the new patch (https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/178404) works on all platforms (Windows, macOS, Linux) on current Eclipse target platforms, I'll probably merge it, but there are many parameters that could possibly impact this, now or in the future (OS, Eclipse/SWT version, actual screen size/resolution, OS-level zoom setting, GTK version for Linux, X11/Wayland...) that I'm tempted to introduce a system property (say, org.eclipse.gmf.runtime.draw2d.ui.render.dpi) that could be used to override the value without patching/releasing a new GMF, just in case.

I had a GMF Runtime 1.13.1rc1 ready to be released (just needed to find the time to do it), I'll postpone it to get this included.
Comment 40 Eclipse Genie CLA 2021-06-22 05:25:40 EDT
New Gerrit change created: https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/182337
Comment 42 Pierre-Charles David CLA 2021-06-22 08:58:26 EDT
I've merged a slightly modified version of Ansgar's patch on the maintenance branch for 1.13.1: https://git.eclipse.org/r/c/gmf-runtime/org.eclipse.gmf-runtime/+/182337

The DPI used is now determined by:

  Integer.getInteger("org.eclipse.gmf.runtime.draw2d.ui.render.dpi", DisplayUtils.getDisplay().getDPI().x)

So by default it reverts to using the display's DPI as before, but all the parameters than can impact the result and that I can not test, this can be overridden by a system property if needed.

I'll release version 1.13.1 with that, and report the fix on master for the upcoming version 1.14.