Julien Hoarau Julien Hoarau - 6 months ago 12
Java Question

How to retrieve the native font name in Java?

Is there a way in Java to get the native font name from a

Font
object?

I get my Font using this code
Font.decode("Serif")
and for debugging purpose I would like to know the native font used.

Answer

It might not be that simple. Some fonts are composed of many physical fonts, using different physical fonts for different glyphs.

For example, on my Windows system the Serif font uses 12 physical fonts:

  • ** TrueType Font: Family=Times New Roman Name=Times New Roman style=0 fileName=C:\Windows\Fonts\TIMES.TTF
  • ** TrueType Font: Family=Wingdings Name=Wingdings style=0 fileName=C:\Windows\Fonts\WINGDING.TTF
  • ** TrueType Font: Family=Symbol Name=Symbol style=0 fileName=C:\Windows\Fonts\SYMBOL.TTF
  • ** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
  • ** TrueType Font: Family=MingLiU Name=MingLiU style=0 fileName=C:\Windows\Fonts\MINGLIU.TTC
  • ** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
  • ** TrueType Font: Family=SimSun Name=SimSun style=0 fileName=C:\Windows\Fonts\SIMSUN.TTC
  • ** TrueType Font: Family=Lucida Sans Name=Lucida Sans Regular style=0 fileName=C:\Java\jdk\jdk1.6.0_37\jre\lib\fonts\LucidaSansRegular.ttf
  • ** TrueType Font: Family=MS Mincho Name=MS Mincho style=0 fileName=C:\Windows\Fonts\MSMINCHO.TTC
  • ** TrueType Font: Family=Batang Name=Batang style=0 fileName=C:\Windows\Fonts\batang.TTC
  • ** TrueType Font: Family=MingLiU-ExtB Name=MingLiU-ExtB style=0 fileName=C:\Windows\Fonts\MINGLIUB.TTC
  • ** TrueType Font: Family=SimSun-ExtB Name=SimSun-ExtB style=0 fileName=C:\Windows\Fonts\SIMSUNB.TTF

The following code can break down a font into its physical components. It uses a reflection hack to access a sun.awt.Font2D object, so use at your own risk (works with Oracle Java 6u37):

import java.awt.Font;
import java.lang.reflect.Method;
import java.util.Locale;

import sun.font.CompositeFont;
import sun.font.Font2D;
import sun.font.PhysicalFont;

public class FontTester
{
    public static void main(String... args)
    throws Exception
    {
        Font font = new Font("Serif", Font.PLAIN, 12);
        describeFont(font);
    }

    private static void describeFont(Font font)
    throws Exception
    {
        Method method = font.getClass().getDeclaredMethod("getFont2D");
        method.setAccessible(true);
        Font2D f = (Font2D)method.invoke(font);

        describeFont2D(f);
    }

    private static void describeFont2D(Font2D font)
    {
        if (font instanceof CompositeFont)
        {
            System.out.println("Font '" + font.getFontName(Locale.getDefault()) + "' is composed of:");

            CompositeFont cf = (CompositeFont)font;
            for (int i = 0; i < cf.getNumSlots(); i++)
            {
                PhysicalFont pf = cf.getSlotFont(i);
                describeFont2D(pf);
            }
        }
        else
            System.out.println("-> " + font);
    }
}
Comments