fixed/improved vertical position of text when scaled on HiDPI screens on Windows when running on Java 8

This commit is contained in:
Karl Tauber
2020-06-22 21:05:11 +02:00
parent 15a714faed
commit 7fb7a1ac85
4 changed files with 74 additions and 29 deletions

View File

@@ -19,7 +19,7 @@ FlatLaf Change Log
- TableHeader: Support top/bottom/left positioned sort arrow when using - TableHeader: Support top/bottom/left positioned sort arrow when using
[Glazed Lists](https://github.com/glazedlists/glazedlists). (issue #113) [Glazed Lists](https://github.com/glazedlists/glazedlists). (issue #113)
- Fixed/improved vertical position of text when scaled on HiDPI screens on - Fixed/improved vertical position of text when scaled on HiDPI screens on
Windows when running on Java 9 or later. Windows.
## 0.36 ## 0.36

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.util;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator;
@@ -115,9 +116,12 @@ public class HiDPIUtils
* This methods computes a correction value for the Y position. * This methods computes a correction value for the Y position.
*/ */
public static float computeTextYCorrection( Graphics2D g ) { public static float computeTextYCorrection( Graphics2D g ) {
if( !useTextYCorrection() || !SystemInfo.IS_WINDOWS || !SystemInfo.IS_JAVA_9_OR_LATER ) if( !useTextYCorrection() || !SystemInfo.IS_WINDOWS )
return 0; return 0;
if( !SystemInfo.IS_JAVA_9_OR_LATER )
return UIScale.getUserScaleFactor() > 1 ? -UIScale.scale( 0.625f ) : 0;
AffineTransform t = g.getTransform(); AffineTransform t = g.getTransform();
double scaleY = t.getScaleY(); double scaleY = t.getScaleY();
if( scaleY < 1.25 ) if( scaleY < 1.25 )
@@ -207,6 +211,21 @@ public class HiDPIUtils
public void drawString( AttributedCharacterIterator iterator, float x, float y ) { public void drawString( AttributedCharacterIterator iterator, float x, float y ) {
super.drawString( iterator, x, y + yCorrection ); 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 );
}
}; };
} }
} }

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.testing;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -39,6 +40,7 @@ public class FlatPaintingStringTest
extends JPanel extends JPanel
{ {
public static void main( String[] args ) { public static void main( String[] args ) {
System.setProperty( "flatlaf.uiScale", "1x" );
System.setProperty( "sun.java2d.uiScale", "1x" ); System.setProperty( "sun.java2d.uiScale", "1x" );
SwingUtilities.invokeLater( () -> { SwingUtilities.invokeLater( () -> {
@@ -54,26 +56,34 @@ public class FlatPaintingStringTest
FlatPaintingStringTest() { FlatPaintingStringTest() {
initComponents(); initComponents();
if( !SystemInfo.IS_JAVA_9_OR_LATER ) {
add( new JLabel( "requires Java 9 or later" ) );
return;
}
add( new JLabel() ); add( new JLabel() );
add( new JLabel( "none" ) ); add( new JLabel( "none" ) );
add( new JLabel( "flatlaf" ) ); add( new JLabel( "flatlaf" ) );
add( new JLabel( "0.25*scale" ) ); add( new JLabel( "0.25*scale" ) );
add( new JLabel( "0.5*scale" ) ); add( new JLabel( "0.5*scale" ) );
add( new JLabel( "0.25" ) ); if( SystemInfo.IS_JAVA_9_OR_LATER ) {
add( new JLabel( "0.5" ) ); add( new JLabel( "0.25" ) );
add( new JLabel( "0.625" ) ); add( new JLabel( "0.5" ) );
add( new JLabel( "0.75" ) ); add( new JLabel( "0.625" ) );
add( new JLabel( "0.875" ) ); 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 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 oneQSysScale = (g, scaleFactor) -> -(0.25f * scaleFactor);
YCorrectionFunction halfSysScale = (g, scaleFactor) -> -(0.5f * 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 oneQ = (g, scaleFactor) -> -0.25f;
YCorrectionFunction half = (g, scaleFactor) -> -0.5f; YCorrectionFunction half = (g, scaleFactor) -> -0.5f;
YCorrectionFunction fiveEights = (g, scaleFactor) -> -0.625f; YCorrectionFunction fiveEights = (g, scaleFactor) -> -0.625f;
@@ -89,19 +99,28 @@ public class FlatPaintingStringTest
add( scaleFactor, flatlaf ); add( scaleFactor, flatlaf );
add( scaleFactor, oneQSysScale ); add( scaleFactor, oneQSysScale );
add( scaleFactor, halfSysScale ); add( scaleFactor, halfSysScale );
add( scaleFactor, oneQ ); if( SystemInfo.IS_JAVA_9_OR_LATER ) {
add( scaleFactor, half ); add( scaleFactor, oneQ );
add( scaleFactor, fiveEights ); add( scaleFactor, half );
add( scaleFactor, threeQ ); add( scaleFactor, fiveEights );
add( scaleFactor, sevenEights ); add( scaleFactor, threeQ );
add( scaleFactor, sevenEights );
} else {
add( scaleFactor, fiveEightsQSysScale );
add( scaleFactor, threeQSysScale );
add( scaleFactor, sevenEightsSysScale );
}
} }
} }
private void add( float scaleFactor, YCorrectionFunction correctionFunction ) { private void add( float scaleFactor, YCorrectionFunction correctionFunction ) {
add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" ); if( SystemInfo.IS_JAVA_9_OR_LATER ) {
add( new Painter( scaleFactor, correctionFunction, 0.25f ), "gapx 0 0" ); add( new Painter( scaleFactor, correctionFunction, 0 ), "split 4, gapx 0 0" );
add( new Painter( scaleFactor, correctionFunction, 0.5f ), "gapx 0 0" ); add( new Painter( scaleFactor, correctionFunction, 0.25f ), "gapx 0 0" );
add( new Painter( scaleFactor, correctionFunction, 0.75f ), "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() { private void initComponents() {
@@ -114,7 +133,7 @@ public class FlatPaintingStringTest
// columns // columns
"[fill]", "[fill]",
// rows // rows
"[fill]")); "[top]"));
// JFormDesigner - End of component initialization //GEN-END:initComponents // JFormDesigner - End of component initialization //GEN-END:initComponents
} }
@@ -139,7 +158,12 @@ public class FlatPaintingStringTest
this.scaleFactor = scaleFactor; this.scaleFactor = scaleFactor;
this.correctionFunction = correctionFunction; this.correctionFunction = correctionFunction;
this.yOffset = yOffset; 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 @Override
@@ -158,7 +182,7 @@ public class FlatPaintingStringTest
FlatUIUtils.setRenderingHints( g2 ); FlatUIUtils.setRenderingHints( g2 );
// simulate component y position at a fraction // simulate component y position at a fraction
if( scaleFactor > 1 ) if( scaleFactor > 1 && SystemInfo.IS_JAVA_9_OR_LATER )
g2.translate( 0, yOffset ); g2.translate( 0, yOffset );
int width = getWidth(); int width = getWidth();
@@ -173,7 +197,8 @@ public class FlatPaintingStringTest
// g.drawLine( 0, 0, width2, 0 ); // g.drawLine( 0, 0, width2, 0 );
// g.drawLine( 0, height2 - 1, width2, height2 - 1 ); // 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; int topline = height2 - baseline - 1;
g.setColor( Color.red ); g.setColor( Color.red );
@@ -185,7 +210,8 @@ public class FlatPaintingStringTest
g.translate( insets.left, 0 ); g.translate( insets.left, 0 );
// scale // scale
((Graphics2D)g).scale( scaleFactor, scaleFactor ); if( SystemInfo.IS_JAVA_9_OR_LATER )
((Graphics2D)g).scale( scaleFactor, scaleFactor );
// compute Y correction // compute Y correction
float yCorrection = correctionFunction.computeTextYCorrection( g2, scaleFactor ); float yCorrection = correctionFunction.computeTextYCorrection( g2, scaleFactor );
@@ -217,7 +243,7 @@ public class FlatPaintingStringTest
} }
private int scale( int value ) { private int scale( int value ) {
return Math.round( value * scaleFactor ); return SystemInfo.IS_JAVA_9_OR_LATER ? Math.round( value * scaleFactor ) : value;
} }
} }
} }

View File

@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3" "$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[fill]" "$columnConstraints": "[fill]"
"$rowConstraints": "[fill]" "$rowConstraints": "[top]"
} ) { } ) {
name: "this" name: "this"
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE "border": sfield com.jformdesigner.model.FormObject NULL_VALUE