8143064: Icons are not properly rendered with Windows L&F on HiDPI display

Reviewed-by: ssadetsky
This commit is contained in:
Alexander Scherbatiy 2016-07-13 21:37:17 +03:00
parent 68aae8c142
commit b172f7afd8
2 changed files with 96 additions and 9 deletions

View File

@ -25,6 +25,7 @@
package sun.swing;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.util.*;
@ -99,9 +100,7 @@ public abstract class CachedPainter {
}
}
private void paint0(Component c, Graphics g, int x,
int y, int w, int h, Object... args) {
Object key = getClass();
private Image getImage(Object key, Component c, int w, int h, Object... args) {
GraphicsConfiguration config = getGraphicsConfiguration(c);
ImageCache cache = getCache(key);
Image image = cache.getImage(key, config, w, h, args);
@ -133,14 +132,40 @@ public abstract class CachedPainter {
g2.dispose();
}
// Render to the passed in Graphics
paintImage(c, g, x, y, w, h, image, args);
// If we did this 3 times and the contents are still lost
// assume we're painting to a VolatileImage that is bogus and
// give up. Presumably we'll be called again to paint.
} while ((image instanceof VolatileImage) &&
((VolatileImage)image).contentsLost() && ++attempts < 3);
return image;
}
private void paint0(Component c, Graphics g, int x,
int y, int w, int h, Object... args) {
Object key = getClass();
GraphicsConfiguration config = getGraphicsConfiguration(c);
ImageCache cache = getCache(key);
Image image = cache.getImage(key, config, w, h, args);
if (image == null) {
double sx = 1;
double sy = 1;
if (g instanceof Graphics2D) {
AffineTransform tx = ((Graphics2D) g).getTransform();
sx = tx.getScaleX();
sy = tx.getScaleY();
}
image = new PainterMultiResolutionCachedImage(sx, sy, w, h);
cache.setImage(key, config, w, h, args, image);
}
if (image instanceof PainterMultiResolutionCachedImage) {
((PainterMultiResolutionCachedImage) image).setParams(c, args);
}
// Render to the passed in Graphics
paintImage(c, g, x, y, w, h, image, args);
}
/**
@ -210,4 +235,62 @@ public abstract class CachedPainter {
}
return c.getGraphicsConfiguration();
}
}
class PainterMultiResolutionCachedImage extends AbstractMultiResolutionImage {
private final double scaleX;
private final double scaleY;
private final int baseWidth;
private final int baseHeight;
private Component c;
private Object[] args;
public PainterMultiResolutionCachedImage(double scaleX, double scaleY,
int baseWidth, int baseHeight) {
this.scaleX = scaleX;
this.scaleY = scaleY;
this.baseWidth = baseWidth;
this.baseHeight = baseHeight;
}
public void setParams(Component c, Object[] args) {
this.c = c;
this.args = args;
}
@Override
public int getWidth(ImageObserver observer) {
return baseWidth;
}
@Override
public int getHeight(ImageObserver observer) {
return baseHeight;
}
@Override
public Image getResolutionVariant(double destWidth, double destHeight) {
int w = (int) Math.ceil(destWidth);
int h = (int) Math.ceil(destHeight);
return getImage(this, c, w, h, args);
}
@Override
protected Image getBaseImage() {
return getResolutionVariant(baseWidth, baseHeight);
}
@Override
public java.util.List<Image> getResolutionVariants() {
if (scaleX == 1 && scaleY == 1) {
return Arrays.asList(getResolutionVariant(baseWidth, baseHeight));
}
return Arrays.asList(
getResolutionVariant(baseWidth, baseHeight),
getResolutionVariant(scaleX * baseWidth, scaleY * baseHeight)
);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,9 +26,10 @@ import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/* @test
* @bug 8031573 8040279
* @bug 8031573 8040279 8143064
* @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered
* in high resolution on Retina
* @author Alexander Scherbatiy
@ -39,6 +40,9 @@ public class bug8031573 extends JApplet {
@Override
public void init() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeAndWait(new Runnable() {
@Override