import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class FontDisposeTest
{
  public static void main(String[] args) throws Throwable
  {
    // The bug only happens with Type 1 fonts. The Ghostscript font files
    // should be commonly available. From distro pacakge or
    //  ftp://ftp.gnu.org/gnu/ghostscript/gnu-gs-fonts-other-6.0.tar.gz
    String path = args[0];

    // Load
    System.out.printf("Loading font from '%s'... ",path);
    InputStream stream = new FileInputStream(path);
    Font font = Font.createFont(Font.TYPE1_FONT,stream);
    System.out.printf(" done.\n");

    // Ensure native bits have been generated
    BufferedImage img = new BufferedImage(100,100,BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = img.createGraphics();
    FontRenderContext frc = g2d.getFontRenderContext();

    font.getLineMetrics("derp",frc);
    System.out.printf("Font native scaler initialised.\n");

    // Force disposal - I have not yet figured out a way to get it to happen
    // naturally in a test case context. Just waiting and/or calling
    // System.gc() is not sufficient.
    Field font2DHandleField = Font.class.getDeclaredField("font2DHandle");
    font2DHandleField.setAccessible(true);
    sun.font.Font2DHandle font2DHandle =
      (sun.font.Font2DHandle)font2DHandleField.get(font);

    sun.font.Font2D font2D = font2DHandle.font2D;
    sun.font.Type1Font type1Font = (sun.font.Type1Font)font2D;

    Method getScalerMethod =
      sun.font.Type1Font.class.getDeclaredMethod("getScaler");
    getScalerMethod.setAccessible(true);
    sun.font.FontScaler scaler =
      (sun.font.FontScaler)getScalerMethod.invoke(type1Font);

    System.out.println("Forcing font native scaler disposal.\n");
    scaler.dispose();
    System.out.println("\nIf nothing happened, try again with environment variable 'MALLOC_CHECK_=3'.\n");
  }
}
