Japanese fonts in a Java GUI - java

Is it possible to write a GUI in Java that would display Japanese fonts correctly regardless of the language settings of the OS it's being run on?
I'd like to write a program which is able to do this but I'm not sure how to start going about this. Any advice would be a huge help!

The language settings aren't the problem here. Fonts are.
Java certainly can handle Japanese text, no matter what the system settings are, if the developer doesn't fall into the trap of depending on the platform default encoding by using things like FileReader, or new String(byte[]).
But to actually display the Japanese text, you need a font that has Japanese characters, and fonts are not part of Java. Depending on the OS, Japanese-capable fonts may be part of the default installation, or the user may be prompted to install them as needed, or they may have to be installed manually.

Java can easily display Japanese regardless of if the OS has the fonts installed or not, but this is only for Swing applications. Anything using the console window requires fonts installed in the OS.
Steps:
1) Download one of the truetype fonts from here : http://www.wazu.jp/gallery/Fonts_Japanese2.html
2) Use the following code to allow your swing clients to use your fonts:
InputStream fontStream = getClass().getResourceAsStream("/locationoffontonclasspath/myfontname.ttf");
Font japaneseEnabledFont = null;
boolean japaneseDisplayEnabled = false;
try {
japaneseEnabledFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(japaneseEnabledFont);
japaneseDisplayEnabled = true;
} catch (Exception e) {
// handle exceptions here
} finally {
if (fontStream != null) {
try {fontStream.close();} catch (Exception e1) {}
}
}
if (japaneseDisplayEnabled) {
.....
}
Also, if you wish to use Japanese literals in your sourcecode you have to compile with -Dfile.encoding=utf-8. If using an IDE to compile then you can change the settings on the following screen (right click the project and select properties to get this window): screenshot
More information is available at this page

You can package a TrueType font with your program and load and use it in Swing components like so:
// Create a label in Japanese.
String message = "かつ、尊厳と権利とについて平等である。";
JLabel label = new JLabel(message);
// Load the TrueType font with Japanese characters and apply it.
File file = new File("msmincho.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, file);
font = font.deriveFont(Font.PLAIN, 14f);
label.setFont(font);
Be careful to use the correct charset. If compiling Japanese characters in the code you should compile with javac -encoding utf-8 Foo.java. Also be sure to use the charset explicitly when using Readers.

Add -Dfile.encoding=utf-8 to your command line script that's launching the application.

You can copy your truetype Japanese fonts in $JAVA_HOME\jre\lib\fonts\fallback.
You'll have to create this folder. On linux a symbolic link will do the trick.
Source: http://www.asahi-net.or.jp/~ik2r-myr/kanji/german/linos_g.htm

Related

How to use font from Google Fonts in JTextPane? [duplicate]

I need to use custom fonts (ttf) in my Java Swing application. How do I add them to my package and use them?
Mean while, I just install them in windows and then I use them, but I don't wish that the usage of the application will be so complicated, it`s not very convenient to tell the user to install fonts before using my application.
You could load them via an InputStream:
InputStream is = MyClass.class.getResourceAsStream("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
This loaded font has no predefined font settings so to use, you would have to do:
Font sizedFont = font.deriveFont(12f);
myLabel.setFont(sizedFont);
See:
Physical and Logical Fonts
As Reimeus said, you can use an InputStream. You can also use a File:
File font_file = new File("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, font_file);
In both cases you would put your font files in either the root directory of your project or some sub-directory. The root directory should probably be the directory your program is run from. For example, if you have a directory structure like:
My_Program
|
|-Fonts
| |-TestFont.ttf
|-bin
|-prog.class
you would run your program with from the My_Program directory with java bin/prog. Then in your code the file path and name to pass to either the InputStream or File would be "Fonts/TestFont.ttf".
Try this:
#Override
public Font getFont() {
try {
InputStream is = GUI.class.getResourceAsStream("TestFont.ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
return font;
} catch (FontFormatException | IOException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
return super.getFont();
}
}

Embed non-embedded fonts in PDF with IText

So I have the following problem. I receive a PDF file which contains a set of fonts. These fonts are not embedded into the file. Here is a simple example:
I would like to embed these fonts inside the PDF, so they're self-contained and always available. But things don't seem that simple. I'm using IText to do my PDF processing.
I have read and tried the following questions/answers:
how-to-create-pdf-with-font-information-and-embed-actual-font-when-merging-them
embed-truetype-fonts-in-existing-pdf
embed-font-into-pdf-file-by-using-itext
how-to-check-that-all-used-fonts-are-embedded-in-pdf-with-java-itext
Chapter 16.1.4 Replacing a font of the book iText in Action - 2nd Edition
...
But what had gotten me closest was the following example: EmbedFontPostFacto.java (which comes from the book). I was able to embed the Arial font when providing the Arial.ttf file.
But with this, like with other examples, I need the source file of the font in order to embed it. In my case, I don't have the source file. But I might have them on the system however. So I'd like to query my available fonts on the system and see if it corresponds to the given font.
Something of the likes as
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
java.awt.Font[] fonts = e.getAllFonts();
for(java.awt.Font f : fonts){
System.out.println(f.getFontName());
}
But I cannot transform the given java.awt.Font into a RandomAccessFile or a byte[] to be used in order to embed the font file itself. Is there another way for embedding fonts into a PDF, without having the source file of the font itself?
For Windows C:\Windows\Fonts or such contain all font files, and in the explorer shows also font names. So a manual search is feasible.
In java, you have GraphicsEnvironment.getAvailableFontFamilyNames() and Font.getFamilyName() to check for a name from the PDF like "Arial MT."
However a getter for the file is missing from Font.
So list all files of the font directory, and load each file consecutively as Font.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font font = Font.createFont(Font.TRUETYPE_FONT, ttfFile);
ge.registerFont(font); // If you want to load the font.
if (pdfFontName.startsWith(font.getFamilyName()) {
System.out.printf("%s - %s / %s%n", ttfFile.getName(), font.getFamilyName(),
font.getName());
}

Why do my custom fonts work from Eclipse, but not from an exported JAR?

I am trying to hack together a game in Java, and on the start screen I used a custom font I downloaded. When I run the program from Eclipse, the screen looks like this (just as it should):
However, when I run the program from the compiled jar, the screen looks like this:
Here is my code for loading the font:
title = new JLabel("philip k. dick"); // font requires all lowercase
try {
Font f = Font.createFont(Font.TRUETYPE_FONT, new File(Util.getFile("all used up.ttf")));
title.setFont(new Font(f.getName(), f.getStyle(), 150));
} catch (Exception e) {
e.printStackTrace();
Font oldFont = title.getFont();
title.setFont(new Font(oldFont.getName(), oldFont.getStyle(), 100));
}
The method Util.getFile just adds "resources/" to the beginning of the given String.
There are no errors given when I run the jar from the command line. I know that the program can access the font resource because when I rename the "resources" folder (to prevent access), the screen looks like this:
Additionally, I get this error:
java.io.IOException: Can't read resources/all used up.ttf
Of course, THIS is expected.
I would also like to note that I have other audio and image resources being loaded from the same location, and they work fine. This location is in the folder directly outside of the jar. Also, I am using a Mac, but I get the same problem on Windows.
The contents of your resources directly are typically add to your Jar.
This means that they can no longer be access using a File object, as they are actually now part of a Zip file.
You need to use something like getClass().getResource(...) to it up. This returns an instance of URL which points to the resource (if it can be found)
However, Font.createFont takes either a File or InputStream reference, in this case you should use getClass().getResourceAsInputStream(...), something like...
Font f = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsInputStream("resources/all used up.ttf"));
This makes a "relative" path request from the context of the class trying to load the resource. This is probably not going to work, so instead, you could use
getClass().getResourceAsInputStream("/resources/all used up.ttf")
Which creates an absolute path lookup from the context of the classpath
If you get stuck, try unpacking the Jar and see if the font resides within and where and make adjusts as required.
Updated...
Try using...
Font f = Font.createFont(Font.TRUETYPE_FONT, new File("resources/all used up.ttf"));
title.setFont(f.deriveFont(150f));
As I understand it, new Font(...) is trying to find the font from the available system fonts.
From the Java Docs for Font#createFont...
This base font can then be used with the deriveFont methods in this
class to derive new Font objects with varying sizes, styles,
transforms and font features. ...To make the Font available to Font
constructors the
returned Font must be registered in the GraphicsEnviroment by calling
registerFont(Font).

Do any Java OCR tools convert images of text into editable text files?

I'm working on a project that entails photographing text (from any hard copy of text) and converting that text into a text file. Then I'd like to use that text file to do some different things, such as provide hyperlinks to news articles or allow the user to edit the document.
The tool I've tried so far is Java OCR from sourceforge.net, which works fine on the images provided in the package. But when I photograph my own text, it doesnt work at all. Is there some training process I should be implementing? If so, does anybody know how to implement it? Any help will go a long way. Thank you!
I have a java application where I ended up deciding to use Tesseract OCR, and just call out to it using Runtime.exec(). Perhaps not quite the answer you need, but just in case you'd not considered it.
Edit + code added in response to comment reply
On a Windows installation I think I was able to use an installer, or unzip a ready made binary.
On a Linux server, I needed to compile Tesseract myself, but it's not too hard if you're used to that kind of thing (gcc); the only gotcha is that there's a dependency on Leptonica which also needs to be compiled.
// Tesseract can only handle .tif format, so we have to convert it
ImageIO.write( ImageIO.read( new java.io.File(file.getPath())), "tif", tmpFile[0]);
String[] tesseractCmd = new String[]{"tesseract", tmpFile[0].getAbsolutePath(), StringUtils.removeEnd(tmpFile[1].getAbsolutePath(), ".txt")};
final Process process = Runtime.getRuntime().exec(tesseractCmd);
try {
int exitValue = process.waitFor();
if(exitValue == 0) {
final String extractedText = SearchableTextExtractionUtils.extractPlainText(new FileReader(tmpFile[1]));
return extractedText;
}
throw new SearchableTextExtractionException(exitValue, Arrays.toString(tesseractCmd));
} catch (InterruptedException e) {
throw new SearchableTextExtractionException(e);
} finally {
process.destroy();
}

Get font file as a File object or get its path

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?
// 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);
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.
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.

Categories