void ( @NotNull Graphics2D g, int componentWidth, int componentHeight, @NotNull Image image, @NotNull IdeBackgroundUtil.Fill fillType, @NotNull IdeBackgroundUtil.Anchor anchor, float alpha, @NotNull Insets insets ) { Insets i = JBUI.insets( insets.top * componentHeight / 100, insets.left * componentWidth / 100, insets.bottom * componentHeight / 100, insets.right * componentWidth / 100 ); int cw = componentWidth - i.left - i.right; int ch = componentHeight - i.top - i.bottom; int w = image.getWidth(null); int h = image.getHeight(null); if (w <= 0 || h <= 0) { return; } // performance: pre-compute scaled image or tiles @Nullable GraphicsConfiguration cfg = g.getDeviceConfiguration(); Cached cached = cachedMap.get(cfg); VolatileImage scaled = cached == null ? null : cached.image; Rectangle src0 = new Rectangle(); Rectangle dst0 = new Rectangle(); calcSrcDst(src0, dst0, w, h, cw, ch, fillType); alignRect(src0, w, h, anchor); if (fillType == IdeBackgroundUtil.Fill.TILE) { alignRect(dst0, cw, ch, anchor); } int sw0 = scaled == null ? -1 : scaled.getWidth(null); int sh0 = scaled == null ? -1 : scaled.getHeight(null); boolean repaint = cached == null || !cached.src.equals(src0) || !cached.dst.equals(dst0); while ((scaled = validateImage(cfg, scaled)) == null || repaint) { int sw = Math.min(cw, dst0.width); int sh = Math.min(ch, dst0.height); if (scaled == null || sw0 < sw || sh0 < sh) { scaled = createImage(cfg, sw, sh); cachedMap.put(cfg, cached = new Cached(scaled, src0, dst0)); } else { cached.src.setBounds(src0); cached.dst.setBounds(dst0); } Graphics2D gg = scaled.createGraphics(); gg.setComposite(AlphaComposite.Src); if (fillType == IdeBackgroundUtil.Fill.SCALE) { gg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); StartupUiUtil.drawImage(gg, image, dst0, src0, null); } else if (fillType == IdeBackgroundUtil.Fill.TILE) { Rectangle r = new Rectangle(0, 0, 0, 0); for (int x = 0; x < dst0.width; x += w) { for (int y = 0; y < dst0.height; y += h) { r.setBounds(dst0.x + x, dst0.y + y, src0.width, src0.height); StartupUiUtil.drawImage(gg, image, r, src0, null); } } } else { StartupUiUtil.drawImage(gg, image, dst0, src0, null); } gg.dispose(); repaint = false; } long currentTime = System.currentTimeMillis(); cached.touched = currentTime; if (cachedMap.size() > 2) { clearImages(currentTime); } Rectangle src = new Rectangle(0, 0, cw, ch); Rectangle dst = new Rectangle(i.left, i.top, cw, ch); if (fillType != IdeBackgroundUtil.Fill.TILE) { alignRect(src, dst0.width, dst0.height, anchor); } float adjustedAlpha = Boolean.TRUE.equals(g.getRenderingHint(IdeBackgroundUtil.ADJUST_ALPHA)) ? 0.65f * alpha : alpha; GraphicsConfig gc = new GraphicsConfig(g).setAlpha(adjustedAlpha); StartupUiUtilKt.drawImage(g, scaled, dst, src, null, null); gc.restore(); }