You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sk...@apache.org on 2020/04/09 13:00:51 UTC

[netbeans] branch master updated: [NETBEANS-2543] File names clipped in Files and Projects tabs

This is an automated email from the ASF dual-hosted git repository.

skygo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 15f65fc  [NETBEANS-2543] File names clipped in Files and Projects tabs
     new 56b9146  Merge pull request #2025 from eirikbakke/NETBEANS-2543
15f65fc is described below

commit 15f65fc14730de691fcae4f7fc1bc09f46b02752
Author: Eirik Bakke <eb...@ultorg.com>
AuthorDate: Tue Mar 17 04:03:03 2020 -0400

    [NETBEANS-2543] File names clipped in Files and Projects tabs
    
    This patch fixes a bug where some file names in the "Projects" and "Files" tabs would appear truncated on fractional HiDPI scalings (e.g. 150%) on Windows. It probably also improves text measurement on an integral 200% scaling as well, possibly on MacOS as well.
    
    The problem was in org.openide.awt.HtmlRenderer and the associated HtmlRendererImpl class, which creates a fake Graphics2D object for the purposes of calculating text dimensions in getPreferredWidth. This Graphics2D object was not properly prepared with a HiDPI transform for its FontRenderContext, leading to inaccurate text measurement. Moreover, the GraphicsConfiguration was not retrieved for the correct monitor (in multi-monitor setups). These problems have been fixed.
    
    Since the scratch Graphics2D object is now specific to each monitor (each can have a different HiDPI scaling), it is now cached at the HtmlRenderer level rather than at the previous global (static) level.
    
    An alternative approach would have been to pass a FontRenderContext instead of a full Graphics2D during off-screen text measurements. This would complicate the HtmlRenderer._renderHTML method too much, however.
---
 .../src/org/openide/awt/HtmlRenderer.java          |  2 +-
 .../src/org/openide/awt/HtmlRendererImpl.java      | 69 ++++++++++++++++------
 2 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/platform/openide.awt/src/org/openide/awt/HtmlRenderer.java b/platform/openide.awt/src/org/openide/awt/HtmlRenderer.java
index 5ada2d9..493cbe1 100644
--- a/platform/openide.awt/src/org/openide/awt/HtmlRenderer.java
+++ b/platform/openide.awt/src/org/openide/awt/HtmlRenderer.java
@@ -339,7 +339,7 @@ public final class HtmlRenderer {
             // #54257 - on macosx + chinese/japanese fonts, the getStringBounds() method returns bad value
             wid = fm.stringWidth(s);
         } else {
-            wid = (int)fm.getStringBounds(s, g).getWidth();
+            wid = (int) Math.ceil(fm.getStringBounds(s, g).getWidth());
         }
 
         if (paint) {
diff --git a/platform/openide.awt/src/org/openide/awt/HtmlRendererImpl.java b/platform/openide.awt/src/org/openide/awt/HtmlRendererImpl.java
index 5da355d..4028a0f 100644
--- a/platform/openide.awt/src/org/openide/awt/HtmlRendererImpl.java
+++ b/platform/openide.awt/src/org/openide/awt/HtmlRendererImpl.java
@@ -21,6 +21,9 @@ package org.openide.awt;
 
 import java.awt.*;
 import java.awt.event.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
 
 import java.beans.PropertyChangeListener;
 import java.beans.VetoableChangeListener;
@@ -60,7 +63,7 @@ class HtmlRendererImpl extends JLabel implements HtmlRenderer.Renderer {
     //For experimentation - holding the graphics object may be the source of some
     //strange painting problems on Apple
     private static boolean noCacheGraphics = Boolean.getBoolean("nb.renderer.nocache"); //NOI18N
-    private static Reference<Graphics2D> scratchGraphics = null;
+    private ScratchGraphics cachedScratchGraphics = null;
     private boolean centered = false;
     private boolean parentFocused = false;
     private Boolean html = null;
@@ -593,28 +596,60 @@ class HtmlRendererImpl extends JLabel implements HtmlRenderer.Renderer {
         return result;
     }
 
-    /** Fetch a scratch graphics object for calculating preferred sizes while
-     * offscreen */
-    private static final Graphics2D scratchGraphics() {
-        Graphics2D result = null;
+    private static final class ScratchGraphics {
+        private final GraphicsConfiguration configuration;
+        private Reference<Graphics2D> graphics = new SoftReference<>(null);
 
-        if (scratchGraphics != null) {
-            result = scratchGraphics.get();
-
-            if (result != null) {
-                result.setClip(null); //just in case somebody did something nasty
+        public ScratchGraphics(GraphicsConfiguration configuration) {
+            if (configuration == null) {
+                throw new NullPointerException();
             }
+            this.configuration = configuration;
         }
 
-        if (result == null) {
-            result = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()
-                                        .createCompatibleImage(1, 1).createGraphics();
-            if (!noCacheGraphics) {
-                scratchGraphics = new SoftReference<>(result);
-            }
+        public boolean isConfigurationCompatible(GraphicsConfiguration other) {
+          return configuration.getColorModel().equals(other.getColorModel())
+              && configuration.getDefaultTransform().equals(other.getDefaultTransform());
         }
 
-        return result;
+        public Graphics2D getGraphics() {
+          Graphics2D result = graphics.get();
+          if (result == null) {
+              /* Equivalent to configuration.createCompatibleImage(int, int), just to show that only the
+              ColorModel field of the GraphicsConfiguration is really relevant here. */
+              ColorModel model = configuration.getColorModel();
+              WritableRaster raster = model.createCompatibleWritableRaster(1, 1);
+              BufferedImage img = new BufferedImage(model, raster, model.isAlphaPremultiplied(), null);
+              result = img.createGraphics();
+              this.graphics = new SoftReference<>(result);
+          }
+          // Restore state on every call, just in case a client modified it for some reason.
+          result.setClip(null);
+          /* NETBEANS-2543: Apply the scaling HiDPI transform. This affects font measurements, via
+                            FontRenderContext.getTransform(). */
+          result.setTransform(configuration.getDefaultTransform());
+          return result;
+        }
+    }
+
+    /** Fetch a scratch graphics object for calculating preferred sizes while
+     * offscreen */
+    private final Graphics2D scratchGraphics() {
+        GraphicsConfiguration gc = getGraphicsConfiguration();
+        if (gc == null) {
+            gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
+        }
+
+        ScratchGraphics scratchGraphics = cachedScratchGraphics;
+        if (scratchGraphics != null && scratchGraphics.isConfigurationCompatible(gc)) {
+            return scratchGraphics.getGraphics();
+        }
+
+        scratchGraphics = new ScratchGraphics(gc);
+        if (!noCacheGraphics) {
+            cachedScratchGraphics = scratchGraphics;
+        }
+        return scratchGraphics.getGraphics();
     }
 
     public @Override void setBounds(int x, int y, int w, int h) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists