Fix IconScaleTest; Add UIUtil.createImage(ScaleContext, ...)

This commit is contained in:
Anton Tarasov
2018-06-08 12:34:48 +03:00
parent e0fca0e6f1
commit eab8dd34a0
5 changed files with 68 additions and 29 deletions
@@ -94,29 +94,31 @@ public class IconScaleTest extends BareTestFixtureTestCase {
test(new RowIcon(new CachedImageIcon(new File(getIconPath()).toURI().toURL())), BaseScaleContext.create(ctx));
}
private static void test(Icon icon, BaseScaleContext ctx) {
((ScaleContextAware)icon).updateScaleContext(ctx);
private static void test(Icon icon, BaseScaleContext bctx) {
((ScaleContextAware)icon).updateScaleContext(bctx);
ScaleContext ctx = ScaleContext.create(bctx);
int usrSize = (int)Math.round(ICON_BASE_SIZE * ctx.getScale(USR_SCALE));
int devSize = (int)Math.round(usrSize * ctx.getScale(SYS_SCALE));
assertEquals("unexpected icon user width", usrSize, icon.getIconWidth());
assertEquals("unexpected icon user height", usrSize, icon.getIconHeight());
assertEquals("unexpected icon real width", devSize, ImageUtil.getRealWidth(IconUtil.toImage(icon)));
assertEquals("unexpected icon real height", devSize, ImageUtil.getRealHeight(IconUtil.toImage(icon)));
assertEquals("unexpected icon user width " + bctx, usrSize, icon.getIconWidth());
assertEquals("unexpected icon user height " + bctx, usrSize, icon.getIconHeight());
assertEquals("unexpected icon real width " + bctx, devSize, ImageUtil.getRealWidth(IconUtil.toImage(icon, ctx)));
assertEquals("unexpected icon real height " + bctx, devSize, ImageUtil.getRealHeight(IconUtil.toImage(icon, ctx)));
Icon scaledIcon = IconUtil.scale(icon, null, ICON_OBJ_SCALE);
assertNotSame("scaled instance of the icon", icon, scaledIcon);
assertEquals("ScaleContext of the original icon changed", ctx, ((ScaleContextAware)icon).getScaleContext());
assertNotSame("scaled instance of the icon " + bctx, icon, scaledIcon);
assertEquals("ScaleContext of the original icon changed " + bctx, bctx, ((ScaleContextAware)icon).getScaleContext());
int scaledUsrSize = Math.round(usrSize * ICON_OBJ_SCALE);
int scaledDevSize = Math.round(devSize * ICON_OBJ_SCALE);
assertEquals("unexpected scaled icon user width", scaledUsrSize, scaledIcon.getIconWidth());
assertEquals("unexpected scaled icon user height", scaledUsrSize, scaledIcon.getIconHeight());
assertEquals("unexpected scaled icon real width", scaledDevSize, ImageUtil.getRealWidth(IconUtil.toImage(scaledIcon)));
assertEquals("unexpected scaled icon real height", scaledDevSize, ImageUtil.getRealHeight(IconUtil.toImage(scaledIcon)));
assertEquals("unexpected scaled icon user width " + bctx, scaledUsrSize, scaledIcon.getIconWidth());
assertEquals("unexpected scaled icon user height " + bctx, scaledUsrSize, scaledIcon.getIconHeight());
assertEquals("unexpected scaled icon real width " + bctx, scaledDevSize, ImageUtil.getRealWidth(IconUtil.toImage(scaledIcon, ctx)));
assertEquals("unexpected scaled icon real height " + bctx, scaledDevSize, ImageUtil.getRealHeight(IconUtil.toImage(scaledIcon, ctx)));
// Additionally check that the original image hasn't changed after scaling
Pair<BufferedImage, Graphics2D> pair = createImageAndGraphics(ctx.getScale(SYS_SCALE), icon.getIconWidth(), icon.getIconHeight());
@@ -125,7 +127,7 @@ public class IconScaleTest extends BareTestFixtureTestCase {
icon.paintIcon(null, g2d, 0, 0);
BufferedImage goldImage = loadImage(getIconPath(), ScaleContext.create(ctx));
BufferedImage goldImage = loadImage(getIconPath(), ctx);
ImageComparator.compareAndAssert(
new ImageComparator.AASmootherComparator(0.1, 0.1, new Color(0, 0, 0, 0)), goldImage, iconImage, null);
@@ -5,6 +5,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.reference.SoftReference;
import com.intellij.ui.RetrievableIcon;
import com.intellij.ui.paint.PaintUtil.RoundingMode;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.ImageLoader;
import com.intellij.util.ReflectionUtil;
@@ -291,6 +292,9 @@ public final class IconLoader {
@Nullable
public static Image toImage(@NotNull Icon icon, @Nullable ScaleContext ctx) {
if (icon instanceof RetrievableIcon) {
icon = ((RetrievableIcon)icon).retrieveIcon();
}
if (icon instanceof CachedImageIcon) {
icon = ((CachedImageIcon)icon).getRealIcon(ctx);
}
@@ -298,13 +302,21 @@ public final class IconLoader {
return ((ImageIcon)icon).getImage();
}
else {
final int w = icon.getIconWidth();
final int h = icon.getIconHeight();
final BufferedImage image = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
final Graphics2D g = image.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
BufferedImage image;
if (GraphicsEnvironment.isHeadless()) { // for testing purpose
image = UIUtil.createImage(ctx, icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB, RoundingMode.FLOOR);
} else {
// [tav] todo: match the screen with the provided ctx
image = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration()
.createCompatibleImage(icon.getIconWidth(), icon.getIconHeight(), Transparency.TRANSLUCENT);
}
Graphics2D g = image.createGraphics();
try {
icon.paintIcon(null, g, 0, 0);
} finally {
g.dispose();
}
return image;
}
}
@@ -86,6 +86,13 @@ public class JBHiDPIScaledImage extends BufferedImage {
this(gc, (double)width, (double)height, type);
}
/**
* @see #JBHiDPIScaledImage(GraphicsConfiguration, double, double, int)
*/
public JBHiDPIScaledImage(@Nullable JBUI.ScaleContext ctx, double width, double height, int type, @NotNull RoundingMode rm) {
this(JBUI.sysScale(ctx), width, height, type, rm);
}
/**
* Creates a scaled HiDPI-aware BufferedImage, targeting the graphics config.
*
@@ -95,11 +102,7 @@ public class JBHiDPIScaledImage extends BufferedImage {
* @param type the type
*/
public JBHiDPIScaledImage(@Nullable GraphicsConfiguration gc, double width, double height, int type) {
super((int)(width * JBUI.sysScale(gc)), (int)(height * JBUI.sysScale(gc)), type);
myImage = null;
myUserWidth = width;
myUserHeight = height;
myScale = JBUI.sysScale(gc);
this(gc, width, height, type, RoundingMode.FLOOR);
}
/**
@@ -112,11 +115,15 @@ public class JBHiDPIScaledImage extends BufferedImage {
* @param type the type
*/
public JBHiDPIScaledImage(@Nullable GraphicsConfiguration gc, double width, double height, int type, @NotNull RoundingMode rm) {
super(rm.round(width * JBUI.sysScale(gc)), rm.round(height * JBUI.sysScale(gc)), type);
this(JBUI.sysScale(gc), width, height, type, rm);
}
private JBHiDPIScaledImage(double scale, double width, double height, int type, @NotNull RoundingMode rm) {
super(rm.round(width * scale), rm.round(height * scale), type);
myImage = null;
myUserWidth = width;
myUserHeight = height;
myScale = JBUI.sysScale(gc);
myScale = scale;
}
/**
@@ -2,6 +2,7 @@
package com.intellij.util;
import com.intellij.ui.paint.PaintUtil.RoundingMode;
import com.intellij.util.ui.JBUI.ScaleContext;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -71,6 +72,11 @@ public class RetinaImage { // [tav] todo: create HiDPIImage class
return new JBHiDPIScaledImage(gc, width, height, type, rm);
}
@NotNull
public static BufferedImage create(ScaleContext ctx, double width, double height, int type, RoundingMode rm) {
return new JBHiDPIScaledImage(ctx, width, height, type, rm);
}
/** @deprecated Apple JRE is no longer supported (to be removed in IDEA 2019) */
public static boolean isAppleHiDPIScaledImage(@SuppressWarnings("unused") Image image) {
return false;
@@ -13,7 +13,7 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.ui.*;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.paint.LinePainter2D;
import com.intellij.ui.paint.PaintUtil;
import com.intellij.ui.paint.PaintUtil.RoundingMode;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
@@ -2104,7 +2104,7 @@ public class UIUtil {
* @return a HiDPI-aware BufferedImage in the graphics scale
*/
@NotNull
public static BufferedImage createImage(GraphicsConfiguration gc, double width, double height, int type, PaintUtil.RoundingMode rm) {
public static BufferedImage createImage(GraphicsConfiguration gc, double width, double height, int type, RoundingMode rm) {
if (isJreHiDPI(gc)) {
return RetinaImage.create(gc, width, height, type, rm);
}
@@ -2112,6 +2112,18 @@ public class UIUtil {
return new BufferedImage(rm.round(width), rm.round(height), type);
}
/**
* @see #createImage(GraphicsConfiguration, double, double, int, RoundingMode)
*/
@NotNull
public static BufferedImage createImage(ScaleContext ctx, double width, double height, int type, RoundingMode rm) {
if (isJreHiDPI(ctx)) {
return RetinaImage.create(ctx, width, height, type, rm);
}
//noinspection UndesirableClassUsage
return new BufferedImage(rm.round(width), rm.round(height), type);
}
/**
* Creates a HiDPI-aware BufferedImage in the graphics device scale.
*