IDEA-195614 IAE in EffectPainter2D

This commit is contained in:
Anton Tarasov
2018-07-16 15:59:35 +03:00
parent 4a5c845418
commit 11dd1e065d
2 changed files with 21 additions and 2 deletions
@@ -9,6 +9,7 @@ import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.WavePainter2D;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.awt.*;
@@ -319,14 +320,24 @@ public enum EffectPainter2D implements RegionPainter2D<Font> {
}
}
@Nullable
BufferedImage getImage(Graphics2D g, Color color, double height) {
ConcurrentHashMap<Integer, BufferedImage> cache = UIUtil.isJreHiDPI(g) ? myHiDPICache : myNormalCache;
return cache.computeIfAbsent(Objects.hash(color.getRGB(), JBUI.sysScale(g), height), k -> createImage(g, color, height));
int key = Objects.hash(color.getRGB(), JBUI.sysScale(g), height);
BufferedImage image = cache.get(key);
if (image == null) {
image = createImage(g, color, height);
if (image != null) cache.putIfAbsent(key, image);
}
return image;
}
@Nullable
BufferedImage createImage(Graphics2D g, Paint paint, double height) {
double period = getPeriod(height);
int width = (int)period << (paint instanceof Color ? 8 : 1);
if (width <= 0 || height <= 0) return null;
BufferedImage image = UIUtil.createImage(g, width, height, BufferedImage.TYPE_INT_ARGB, RoundingMode.FLOOR);
paintImage(image.createGraphics(), paint, width, height, period);
return image;
@@ -341,6 +352,8 @@ public enum EffectPainter2D implements RegionPainter2D<Font> {
g.setComposite(AlphaComposite.SrcOver);
BufferedImage image = paint instanceof Color ? getImage(g, (Color)paint, height) : createImage(g, paint, height);
if (image == null) return;
int period = image.getWidth(null);
if (image instanceof JBHiDPIScaledImage) period /= 2;
double offset = (x % period + period) % period; // normalize
@@ -149,6 +149,8 @@ public class PaintUtil {
public static double alignToInt(double usrValue, @NotNull ScaleContext ctx, @Nullable RoundingMode rm, @Nullable ParityMode pm) {
if (rm == null) rm = ROUND;
double scale = getScale(ctx);
if (scale == 0) return 0;
int devValue = devValue(usrValue, scale, pm != null && rm == ROUND ? FLOOR : rm);
if (pm != null && ParityMode.of(devValue) != pm) {
devValue += (rm == FLOOR) ? -1 : 1;
@@ -198,7 +200,11 @@ public class PaintUtil {
private static double getScale(ScaleContext ctx) {
// exclude the user scale, unless it's zero
return ctx.getScale(USR_SCALE) == 0 ? 0 : ctx.getScale(PIX_SCALE) / ctx.getScale(USR_SCALE);
double scale = ctx.getScale(USR_SCALE) == 0 ? 0 : ctx.getScale(PIX_SCALE) / ctx.getScale(USR_SCALE);
if (scale <= 0) {
Logger.getInstance(PaintUtil.class).warn("bad scale in the context: " + ctx.toString(), new Throwable());
}
return scale;
}
/**