4

I have a Font object in Java for a font file. I need to convert that object to a File object or get the font file path.

Is there a way to do this?


What I'm doing here is calling a method from an external library that loads a font file to use it in writing:

loadTTF(PDDocument pdfFile, File fontfile);

So I wanted to let the user choose a font from the ones defined in his operating system using :

GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font[] fonts = e.getAllFonts();

Then when the user chooses a font, I pass it to the loadTTF(...) method to load it.

Is there a bad practice here?

Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
Brad
  • 4,457
  • 10
  • 56
  • 93

3 Answers3

5
// use reflection on Font2D (<B>PhysicalFont.platName</B>) e.g.
Font f = new Font("Courier New", 0, 10);

Font2D f2d = FontManager.findFont2D(f.getFontName(), f.getStyle(),      
               FontManager.LOGICAL_FALLBACK).handle.font2D;

Field platName = PhysicalFont.class.getDeclaredField("platName");
platName.setAccessible(true);
String fontPath = (String)platName.get(f2d);
platName.setAccessible(false);

// that's it..
System.out.println(fontPath);
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Gill
  • 59
  • 1
  • 1
  • 1
    I found a simpler call for obtaining the Font2D. I'm using the Oracle JRE on Windows, "1.8.0_51". -------- "Font2D f2d = sun.font.FontUtilities.getFont2D(myJavaAWTFont);" -------- Also, in my personal implementation, I first check if the field needs to be made accessible at all. (Formality.) "final boolean wasAccessible = platName.isAccessible();" And then I set/restore the accessibility considering the boolean. – Dreamspace President Nov 03 '15 at 07:32
3

Ok ... This will return the font file path :

String fontFilePath = FontManager.getFontPath( true ) + "/" + FontManager.getFileNameForFontName( fontName );

I have tried this in Windows and Linux and in both it worked fine.

Brad
  • 4,457
  • 10
  • 56
  • 93
  • 1
    This won't compile in Maven since FontManager is internal Sun API – magarciaschopohl Dec 03 '12 at 13:06
  • 1
    The internal API changed in Java 7. See http://stackoverflow.com/questions/13684342/jdk7-sun-font-fontmanager-replacement-how-to-get-filename-information-from-font . – Andy Thomas Nov 19 '13 at 20:27
  • This would not work with the fonts that come with the Java installation itself. I listed all available fonts with their file path with Gill's/Peter O.'s solution, and some were not in "C:\Windows\Fonts" but instead in "C:\Program Files\Java\jdk1.8.0_51\jre\lib\fonts\", which wouldn't work with this solution. – Dreamspace President Nov 03 '15 at 07:27
1

No.

A Font in Java is just a representation and definition of how characters can be displayed graphically. It has nothing to do with the filesystem, and technically need not even be ultimately defined in a file (see for example the createFont() method that takes an arbitrary input stream, which could come from anywhere e.g. a network socket). In any case, it would certainly be a ridiculous break in abstraction for you to be able to get the path of the underlying system file that defines the font.

I would suggest that you might be doing the wrong thing in your other method if you're relying on accepting a file. Or if this really is needed, then you're doing the wrong thing in this method by thinking that a Font object has a simple correlation to an underlying file. If you really need to get the file path of a particular font you'll need to approach it from a different angle that doesn't involve java.awt.Font.

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228