From 7fb7a1ac8555a601f27fb367ae57ae4f86843d1a Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 22 Jun 2020 21:05:11 +0200 Subject: [PATCH] fixed/improved vertical position of text when scaled on HiDPI screens on Windows when running on Java 8 --- CHANGELOG.md | 2 +- .../com/formdev/flatlaf/util/HiDPIUtils.java | 21 ++++- .../testing/FlatPaintingStringTest.java | 78 ++++++++++++------- .../testing/FlatPaintingStringTest.jfd | 2 +- 4 files changed, 74 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc8c5f33..5ac56367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ FlatLaf Change Log - TableHeader: Support top/bottom/left positioned sort arrow when using [Glazed Lists](https://github.com/glazedlists/glazedlists). (issue #113) - Fixed/improved vertical position of text when scaled on HiDPI screens on - Windows when running on Java 9 or later. + Windows. ## 0.36 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/HiDPIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/HiDPIUtils.java index 71dbc156..93b417a6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/HiDPIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/HiDPIUtils.java @@ -18,6 +18,7 @@ package com.formdev.flatlaf.util; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.text.AttributedCharacterIterator; @@ -115,9 +116,12 @@ public class HiDPIUtils * This methods computes a correction value for the Y position. */ public static float computeTextYCorrection( Graphics2D g ) { - if( !useTextYCorrection() || !SystemInfo.IS_WINDOWS || !SystemInfo.IS_JAVA_9_OR_LATER ) + if( !useTextYCorrection() || !SystemInfo.IS_WINDOWS ) return 0; + if( !SystemInfo.IS_JAVA_9_OR_LATER ) + return UIScale.getUserScaleFactor() > 1 ? -UIScale.scale( 0.625f ) : 0; + AffineTransform t = g.getTransform(); double scaleY = t.getScaleY(); if( scaleY < 1.25 ) @@ -207,6 +211,21 @@ public class HiDPIUtils public void drawString( AttributedCharacterIterator iterator, float x, float y ) { super.drawString( iterator, x, y + yCorrection ); } + + @Override + public void drawChars( char[] data, int offset, int length, int x, int y ) { + super.drawChars( data, offset, length, x, Math.round( y + yCorrection ) ); + } + + @Override + public void drawBytes( byte[] data, int offset, int length, int x, int y ) { + super.drawBytes( data, offset, length, x, Math.round( y + yCorrection ) ); + } + + @Override + public void drawGlyphVector( GlyphVector g, float x, float y ) { + super.drawGlyphVector( g, x, y + yCorrection ); + } }; } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.java index 1cd5a9e5..60c6246b 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.java @@ -18,6 +18,7 @@ package com.formdev.flatlaf.testing; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; @@ -39,6 +40,7 @@ public class FlatPaintingStringTest extends JPanel { public static void main( String[] args ) { + System.setProperty( "flatlaf.uiScale", "1x" ); System.setProperty( "sun.java2d.uiScale", "1x" ); SwingUtilities.invokeLater( () -> { @@ -54,26 +56,34 @@ public class FlatPaintingStringTest FlatPaintingStringTest() { initComponents(); - if( !SystemInfo.IS_JAVA_9_OR_LATER ) { - add( new JLabel( "requires Java 9 or later" ) ); - return; - } - add( new JLabel() ); add( new JLabel( "none" ) ); add( new JLabel( "flatlaf" ) ); add( new JLabel( "0.25*scale" ) ); add( new JLabel( "0.5*scale" ) ); - add( new JLabel( "0.25" ) ); - add( new JLabel( "0.5" ) ); - add( new JLabel( "0.625" ) ); - add( new JLabel( "0.75" ) ); - add( new JLabel( "0.875" ) ); + if( SystemInfo.IS_JAVA_9_OR_LATER ) { + add( new JLabel( "0.25" ) ); + add( new JLabel( "0.5" ) ); + add( new JLabel( "0.625" ) ); + add( new JLabel( "0.75" ) ); + add( new JLabel( "0.875" ) ); + } else { + add( new JLabel( "0.625*scale" ) ); + add( new JLabel( "0.75*scale" ) ); + add( new JLabel( "0.875*scale" ) ); + } YCorrectionFunction none = (g, scaleFactor) -> 0; - YCorrectionFunction flatlaf = (g, scaleFactor) -> HiDPIUtils.computeTextYCorrection( g ); + YCorrectionFunction flatlaf = (g, scaleFactor) -> { + return SystemInfo.IS_JAVA_9_OR_LATER + ? HiDPIUtils.computeTextYCorrection( g ) + : (scaleFactor > 1 ? -(0.625f * scaleFactor) : 0); + }; YCorrectionFunction oneQSysScale = (g, scaleFactor) -> -(0.25f * scaleFactor); YCorrectionFunction halfSysScale = (g, scaleFactor) -> -(0.5f * scaleFactor); + YCorrectionFunction fiveEightsQSysScale = (g, scaleFactor) -> -(0.625f * scaleFactor); + YCorrectionFunction threeQSysScale = (g, scaleFactor) -> -(0.75f * scaleFactor); + YCorrectionFunction sevenEightsSysScale = (g, scaleFactor) -> -(0.875f * scaleFactor); YCorrectionFunction oneQ = (g, scaleFactor) -> -0.25f; YCorrectionFunction half = (g, scaleFactor) -> -0.5f; YCorrectionFunction fiveEights = (g, scaleFactor) -> -0.625f; @@ -89,19 +99,28 @@ public class FlatPaintingStringTest add( scaleFactor, flatlaf ); add( scaleFactor, oneQSysScale ); add( scaleFactor, halfSysScale ); - add( scaleFactor, oneQ ); - add( scaleFactor, half ); - add( scaleFactor, fiveEights ); - add( scaleFactor, threeQ ); - add( scaleFactor, sevenEights ); + if( SystemInfo.IS_JAVA_9_OR_LATER ) { + add( scaleFactor, oneQ ); + add( scaleFactor, half ); + add( scaleFactor, fiveEights ); + add( scaleFactor, threeQ ); + add( scaleFactor, sevenEights ); + } else { + add( scaleFactor, fiveEightsQSysScale ); + add( scaleFactor, threeQSysScale ); + add( scaleFactor, sevenEightsSysScale ); + } } } private void add( float scaleFactor, YCorrectionFunction correctionFunction ) { - add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" ); - add( new Painter( scaleFactor, correctionFunction, 0.25f ), "gapx 0 0" ); - add( new Painter( scaleFactor, correctionFunction, 0.5f ), "gapx 0 0" ); - add( new Painter( scaleFactor, correctionFunction, 0.75f ), "gapx 0 0" ); + if( SystemInfo.IS_JAVA_9_OR_LATER ) { + add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" ); + add( new Painter( scaleFactor, correctionFunction, 0.25f ), "gapx 0 0" ); + add( new Painter( scaleFactor, correctionFunction, 0.5f ), "gapx 0 0" ); + add( new Painter( scaleFactor, correctionFunction, 0.75f ), "gapx 0 0" ); + } else + add( new Painter( scaleFactor, correctionFunction, 0 ) ); } private void initComponents() { @@ -114,7 +133,7 @@ public class FlatPaintingStringTest // columns "[fill]", // rows - "[fill]")); + "[top]")); // JFormDesigner - End of component initialization //GEN-END:initComponents } @@ -139,7 +158,12 @@ public class FlatPaintingStringTest this.scaleFactor = scaleFactor; this.correctionFunction = correctionFunction; this.yOffset = yOffset; - setBorder( new EmptyBorder( 2, 4, 2, 0 ) ); + setBorder( new EmptyBorder( 2, 0, 2, 0 ) ); + + if( !SystemInfo.IS_JAVA_9_OR_LATER ) { + Font font = getFont(); + setFont( font.deriveFont( (float) Math.round( font.getSize() * scaleFactor ) ) ); + } } @Override @@ -158,7 +182,7 @@ public class FlatPaintingStringTest FlatUIUtils.setRenderingHints( g2 ); // simulate component y position at a fraction - if( scaleFactor > 1 ) + if( scaleFactor > 1 && SystemInfo.IS_JAVA_9_OR_LATER ) g2.translate( 0, yOffset ); int width = getWidth(); @@ -173,7 +197,8 @@ public class FlatPaintingStringTest // g.drawLine( 0, 0, width2, 0 ); // g.drawLine( 0, height2 - 1, width2, height2 - 1 ); - int baseline = (int) Math.round( (insets.top + fm.getAscent()) * scaleFactor2 * scaleFactor ) - 1; + int baseline = (int) Math.round( (insets.top + fm.getAscent()) * scaleFactor2 + * (SystemInfo.IS_JAVA_9_OR_LATER ? scaleFactor : 1f) ) - 1; int topline = height2 - baseline - 1; g.setColor( Color.red ); @@ -185,7 +210,8 @@ public class FlatPaintingStringTest g.translate( insets.left, 0 ); // scale - ((Graphics2D)g).scale( scaleFactor, scaleFactor ); + if( SystemInfo.IS_JAVA_9_OR_LATER ) + ((Graphics2D)g).scale( scaleFactor, scaleFactor ); // compute Y correction float yCorrection = correctionFunction.computeTextYCorrection( g2, scaleFactor ); @@ -217,7 +243,7 @@ public class FlatPaintingStringTest } private int scale( int value ) { - return Math.round( value * scaleFactor ); + return SystemInfo.IS_JAVA_9_OR_LATER ? Math.round( value * scaleFactor ) : value; } } } diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.jfd index 4f04dbeb..c5fb3d83 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatPaintingStringTest.jfd @@ -9,7 +9,7 @@ new FormModel { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "insets dialog,hidemode 3" "$columnConstraints": "[fill]" - "$rowConstraints": "[fill]" + "$rowConstraints": "[top]" } ) { name: "this" "border": sfield com.jformdesigner.model.FormObject NULL_VALUE