This document explains how to add Asian and other language fonts to the Java
Runtime by editing the font.properties files.
At this time, this document describes how to install Japanese, Korean,
Chinese, and Traditional Chinese fonts to your system.
The Java 2 SDK for Win32 platforms supports TrueType and Postscript
Type1 fonts. The Java 2 SDK
for Solaris supports scalable outline fonts that can be handled by an X11
server, such as F3, Type1, and TrueType.
Naming of the font.properties Files
There are several font.properties files that come bundled
with the Java 2 SDK. You can find these files in the directory
../lib that is beneath the directory where Java is installed.
These files contain standard font environment information.
The explanations that follow assume that the readers of this document are
working in an English environment. In an English environment, the default
font.properties file has no suffix on its file name, as
follows:
font.properties
However, different operating systems have different fonts installed so there
is a provision to read font properties files with the operating system
version embedded in the name. For instance, Solaris 2.5.1 does not have
support for TrueType fonts so the font properties file,
font.properties.5.5.1, will include only F3 fonts. Thus,
we first look for a file named:
font.properties.<osVersion>
where <osVersion> is the version returned by
System.getProperty("os.version") for most systems. On Windows NT, this
method is overridden to return NT4.0 instead of 4.0 to distinguish between
NT and 95.
However, if your environment is Japanese, Korean, Chinese, or Traditional
Chinese, then you must use the font.properties file that
corresponds to your particular environment. These files can be identified by
the country or locale suffix that is appended to the file name, as follows:
font.properties.<locale>
where locale is one of:
ja
ko
zh
zh_TW
...
Select the file with the suffix for the particular font that you are interested in.
Thus, for Traditional Chinese, you would access the file
font.properties.zh_TW.
NOTE: The <locale> is actually comprised of
<language>_<region>_<encoding> where
<language> is the string returned from
System.getProperty("user.language")
<region> is the string returned from
System.getProperty("user.region")
<encoding> is the string returned from
System.getProperty("file.encoding")
This font.properties.<locale> name can be augmented
by the operating system version also. To sum up, the font properties
files are searched in the following order:
You must work with the font.properties file to add fonts
to the Java Runtime. The font.properties file is platform-
specific. It indicates the fonts that a particular platform uses for its Java virtual
fonts. Fonts are grouped by types or classes. Currently, the Java Runtime
supports the following classes of logical fonts:
Serif
Sans-serif
Monospaced
Dialog
DialogInput
and the following font styles:
plain
bold
italic
bolditalic
The font.properties file defines certain information about
the fonts for your platform. This includes aliases, such as:
alias.timesroman=serif
alias.helvetica=sansserif
NOTE: This is a bad example since timesroman and helvetica are actual font
names and in the Java 2 Platform, we no longer alias these names to a virtual font. Do not use names "Times", "Helvetica", for serif, sans serif, respectively, etc.
It also includes descriptions for the fonts. The descriptions differ between
the Win32 and Solaris platforms. Our examples use serif fonts to illustrate
how
fonts are specified and converted, if necessary. However, the same entries
apply to other types of fonts.
In general, there are entries in the font properties file that specify
the fonts you
want to use. These entries have the following format:
<virtual font name>.<style>.<index number> = <platform font name>, attributes
The virtual font name is the name of the font as recognized by the Java
Runtime. The platform font name is the actual name of the font on your
platform. For example, Dialog and Serif are Java font names, while Times and
Helvetica are the native font names on a Win32 or Solaris platform. The index
number specifies the order of searching for matching font glyphs,
with zero the highest priority.
In the Java 2 Platform, the full matrix of virtual font name and style must be complete.
For example, you must have serif, serif.boldserif.italic, serif.bolditalic. Note that
serif> is equivalent to serif.plain. All names
in this file are case-insensitive.
For example, in the Solaris font.properties file in JDK1.1,
the serif entries are as follows:
As you can see, only the first entry of "serif.plain", "serif.italic",
"serif.bold" and "serif.bolditalic" were specified. The second and third entry
of the font would default to "serif.1" and "serif.2" in each case (since the
same two fonts were used in each of the "serif" fonts styles). However, in the
Java 2 SDK font.properties, the entire matrix must be specified:
As mentioned earlier, the key value for the plain style,
plain does not need to be
specified (serif.0 defaults to the plain style),
however italic, bold or bolditalic
must be specified for those styles.
Adding Locale-Specific Fonts to the Java Runtime
There are two steps you must take to use locale-specific fonts, such as
the Japanese font, on an English environment platform.
Step 1: Install the Font
First, you must install the locale-specific font (for example, Japanese,
Korean, Chinese, or Traditional Chinese font) to your system.
For Windows platform users, Microsoft delivers these Asian fonts free with the
NT4.0 installation CD. Or, you can download these fonts from the Microsoft
World Wide Web home page.
Solaris users must contact SunSoft to request the Asian outline fonts
for Solaris environments.
Step 2: Copy the Font
Once you have installed the fonts on your system, copy the font description
that you are interested in to font.properties. The easiest
way to add one Asian font is to rename the
font.properties.<locale> file to be the new
font.properties file. The locale symbol represents the font
name that you are interested in.
No editing is required when you replace font.properties
with font.properties.<locale> because
font.properties.<locale> is a superset of
font.properties.
These are the locale symbols that specify the different font properties files:
Locale Symbols for Fonts
Font Name
font.properties
Symbol
Japanese
ja
Korean
ko
Chinese
zh
Traditional Chinese
zh_TW
Thus, to use the the Korean font, you copy or rename
font.properties.ko to
font.properties.
Using Multiple Fonts in the Runtime
It is possible to use more than one Asian font in your runtime. To do this,
you must edit the font.properties file. This section describes
the edits you need to make to the file to use multiple Asian fonts.
Specifying Fonts on Win32 Platform
There are three default serif fonts available on an English language Win32
platform. These fonts are:
Arial
WingDings
Symbol
In addition, the descriptions for these serif fonts in the
font.properties file are as follows:
These three lines together indicate the indexes for the three serif fonts that are
available on this platform. Each line indicates one serif font, followed by
the index for that font.
The numbers (0, 1, and 2) that appear after the word
serif, such as serif.0, indicate the order
in which the font glyphs are searched for a corresponding match with the
Unicode, or Java string encoding, codepoint. Thus, if serif.0
and serif.1 both have the glyph that corresponds to the
same Unicode codepoint, then the glyph for serif.0 will be
used.
The first argument is the face name of the Win32 native font. Each line
names a particular font. For example, the line for serif.0
names the font Arial, while the line for serif.2
names the font Symbol.
The second argument takes the form *_CHARSET. In our
example, it is either ANSI_CHARSET or
SYMBOL_CHARSET. This argument indicates the charset entry
of the corresponding font in Win32. (See the Win32 API document for more
details.)
The third argument, if present, is NEED_CONVERTED. This
argument indicates that the corresponding platform font cannot be accessed
with Unicode. When this argument is present, the Java Runtime needs to
convert the Unicode string to this font index before attempting to use the glyph
for the font. Fonts that have this NEED_CONVERTED argument
must have a corresponding fontcharset entry, which indicates the charset
converter to use to convert the Unicode string.
In our example, both serif.1 and serif.2 have the
NEED_CONVERTED argument. Both have fontcharset entries
in the font.properties file, as follows:
The fontcharset entry for serif.1 indicates that, to draw
the WingDings glyph, the Unicode string should be converted using the
sun.awt.windows.CharToByteWingDings converter.
(Recall that the font.properties file has already established the font for
serif.1 as WingDings.)
The specification for the charset converter is described later in the
section The Charset Converter.
NOTE: In the current implementation of the Java 2 Platform,
NEED_CONVERTED is not used.
Font file names
To reduce initialization time, there is now a way to specify the mapping
between logical font name to physical font name. For instance:
The first entry shows the mapping between the font name Arial
and the physical font name, ARIAL.TTF. The next entries
show the mapping for Arial with the different styles applied. This
shortens the initialization time since we don't have to open every font
file to find a font of that particular name.
Win32 Font Files
The current Win32 JDK build provides the following font properties files:
If you need a different font from what is provided, then you must create your
own font properties file.
Specifying Fonts on Solaris Platform
In the Java 2 SDK, the fonts specified in the font.properties file should reference
scalable fonts. This does not mean that the scalable font will always be
used when a specific font point size is requested however. The way in which
X11 works is that given an xlfd string such as
the Xserver will first look for a scalable font that matches the entries found
in the xlfd string (for font foundry, font family, style, slant, encoding, etc).
However, it then will continue to look for a bitmap font which matches this
xlfd string exactly, for this specific pixel/point size (in this case 10 pt).
If one is found, then X11 will return the bitmap directly read from the bitmap
font file which is used rather than a bitmap generated from the data
found in the scalable font file.
For example, the serif font on an English Solaris (2.6+)
platform consists of the following fonts:
serif.0=-monotype-times new roman-regular-r---*-%d-*-*-p-*-iso8859-1
serif.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
serif.2=-*-symbol-medium-r-normal-*-*-%d-*-*-p-*-adobe-symbol
serif.italic.0=-monotype-times new roman-regular-i---*-%d-*-*-p-*-iso8859-1
serif.italic.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
serif.italic.2=-*-symbol-medium-r-normal-*-*-%d-*-*-p-*-adobe-symbol
serif.bold.0=-monotype-times new roman-bold-r---*-%d-*-*-p-*-iso8859-1
serif.bold.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
serif.bold.2=-*-symbol-medium-r-normal-*-*-%d-*-*-p-*-adobe-symbol
serif.bolditalic.0=-monotype-times new roman-bold-i---*-%d-*-*-p-*-iso8859-1
serif.bolditalic.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
serif.bolditalic.2=-*-symbol-medium-r-normal-*-*-%d-*-*-p-*-adobe-symbol
These lines from the Solaris font.properties file indicate
the indexes for serif fonts with different styles. For example, the font whose
face name is serif and whose style is plain consists of
serif.0, serif.1, and
serif.2. In addition, these lines indicate that the serif font
with the style italic consists of serif.italic.0,
serif.italic.1, and serif.italic.2.
Currently, the index of Solaris (X11) font is not a Unicode index.
Because it
is not Unicode, the font always needs to be converted. Each entry must have a
corresponding fontcharset entry to indicate how it should be converted, as
follows:
indicates that all serif.0 fonts, regardless of whether the
type is plain (serif.plain.0), bold
(serif.bold.0), italics
(serif.italic.0), or bold and italics
(serif.bolditalic.0), will be converted using the
sun.io.CharToByte8859_1 converter.
Testing for correct xlfd strings in the font.properties files
The reason scalable fonts should be specified however is because Java2D can
only perform certain operations on scalable fonts, such as generating outlines.
Currently the Java2D code can recognize scalable fonts such as TrueType, Type1
or F3. Therefore, when entering xlfd strings in the font.properties file,
look for these types of fonts installed on the system and specify those.
TrueType fonts will typically have the file extension of "ttf". Type 1 fonts
will have either "pfa" or "pfb" as the extension. F3 fonts will have the
extension "f3b". On Solaris 2.6, in "C" locale, with all packages installed,
you can find fonts of these formats in:
In other locales, the fonts will be installed in a directory such as
/usr/openwin/lib/locale/. For example, in JA locale, under
/usr/openwin/lib/locale/ja, there are fonts installed in:
The location of the font files may be different depending on locale (that
is, may not always be /usr/openwin/lib/locale/<locale>/X11/fonts), but
they are typically under the /usr/openwin/lib/locale/<locale> directory
somewhere.
Once the scalable fonts have been located, look at the "fonts.dir" file that
will be found in the directory with the scalable font files. This file lists
all of the valid xlfd strings for the fonts contained in that directory. For
example, in the "fonts.dir" file located in the
/usr/openwin/lib/locale/ja/X11/fonts/TT
directory, there is an entry like this:
In the xlfd string, you will see 4 consecutive zero (0) values. These indicate
the pixel size, point size, resolution x and resolution y values. When copying
this xlfd string into a font.properties entry, remember to replace the point
size (the second "0") with a "%d" which is later replaced with a specific point
size when the font is used. Also, replace the other "0" values with "*"
(asterisk) to indicate that any value may match this field. So, for example,
if the above font was to be used as entry for the "serif" font specified in
the font.properties file, it would look like:
When the font is actually used, the point size specified when the Java "Font"
object is created is used (the "%d" is replaced with this value), and the
font is initialized for use at that point size.
One way to verify that the xlfd strings that you have entered in the
font.properties file are correct is to try and display that font using "xfd".
"xfd" is an X11 application in /usr/openwin/bin that displays all of the
characters found in a font. To run the application, you specify the font
(as an xlfd string). To verify an xlfd entry in a font.properties file,
replace the "%d" with a valid point size such as 120 (for 12 pt), 140
(for 14 pt), 160 (for 16 pt), etc. (xlfd point size is 10 times the
"pixel size" where "pixel size" is normally thought of as the font point
size). So, in the above example, with the "serif.1" entry for a Japanese
font.properties file, to verify that this xlfd string is correct, run:
If the xlfd string is incorrect, "xfd" will not display a window, and will
exit immediately and print out an error message like this:
Warning: Cannot convert string "<xlfd string>" to type FontStruct
xfd: no font to display
If the xlfd string is correct, a window will appear with all of the characters
specified in that font. If there are more than 256 characters, then only the
first 256 are displayed, but the user may look through all entries by hitting
the "NextPage" button displayed on the application.
Note about scalable fonts
Remember that the fonts specified in the font.properties files must be in
one of the formats mentioned above (TrueType, Type1 or F3). If there no
fonts installed on the system in those formats, then Java2D will not find
any valid fonts so operations like drawString ("some Text") will not work.
There are bugs in the X server for Type1 fonts (more problems
in 2.5.1 than 2.6) so it is preferable to avoid Type1 fonts also.
Solaris Font Files
The font properties files provided by the Java 2 SDK are located in
the jre/lib directory. (In the Java 2 Runtime Environment,
the they are located in the lib directory.) As of version
1.3, the font properties files included with the
SDK and Runtime Environment are the following.
If you need a different font from what is provided, then you must create your
own font properties file.
Exclusion ranges
As mentioned in the previous sections, the numbers after the virtual font name
indicate the order in which the actual fonts are searched to find the
requested glyph. There are sometimes overlapping ranges of glyphs
in each of the physical fonts that comprise the virtual font. An
exclusion range can be added to limit the range in which glyphs are
searched in a physical font.
For example, in the Solaris font.properties.ja file, the following describes
a monospaced font:
monospaced.plain.0=-morisawa-gothic medium bbb-medium-r-normal-sans-*-%d-*-*-m-*-jisx0201.1976-0
monospaced.plain.1=-morisawa-gothic medium bbb-medium-r-normal-sans-*-%d-*-*-m-*-jisx0208.1983-0
monospaced.plain.2=-morisawa-gothic medium bbb-medium-r-normal-sans-*-%d-*-*-m-*-jisx0201.1976-0
monospaced.plain.3=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
monospaced.plain.4=--symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific
The corresponding exclusion range is as follows:
exclusion.monospaced.0=0080-ffff
Thus, glyphs in the range, Unicode 0x0080 to Unicode 0xffff, are excluded
from the first font in the virtual font so the subsequent fonts
(monospaced.plain.1, monospaced.plain.2, monospaced.plain.3,
monospaced.plain.4) will be searched for those glyphs.
The Charset Converter
The charset converter converts Unicode, or Java string
encoding, to the index of the font. For font drawing, the runtime
environment uses
the charset converter that is the subclass of
sun.io.CharToByteConverter.
To add your own font to the runtime environment, you need to create a
charset converter and specify it in the
font.properties file.
The following example illustrates how to add your own platform font to
the Java serif font. In this example, your font contains 256 glyphs, which are
indexed 0 - 0xff. Your font's glyphs correspond to Unicode 0xe000 - 0xe0ff. This
example is divided into two steps. First, you create your
fontcharset converter class. Second, you specify your font
name and converter class name in the font.properties file
file.
Step 1. Create fontcharset Converter
This is the Java code for creating the fontcharset converter.
package mypkg.converter;
import sun.io.CharToByte8859_1;
import sun.io.CharToByteConverter;
import sun.io.ConversionBufferFullException;
public class CharToByteMyFont extends sun.io.CharToByte8859_1 {
/*
* This method indicates the range this font covers.
*/
public boolean canConvert(char ch) {
if (ch >= 0xe000 && ch <= 0xe0ff) {
return true;
}
return false;
}
/*
* This method converts the unicode to this font index.
*/
public int convert(char[] input, int inStart, int inEnd,
byte[] output, int outStart, int outEnd)
throws ConversionBufferFullException {
int outIndex = outStart;
for (int i = inStart; i < inEnd; i++) {
char ch = input[i];
if (ch >= 0xe000 && ch <= 0xe0ff) {
if (outIndex >= outEnd)
throw new ConversionBufferFullException();
output[outIndex++] = (byte)(ch - 0xe000);
}
}
return outIndex - outStart;
}
/*
* This method indicates the charset name for this font.
*/
public String toString() {
return "MyFont";
}
}
Step 2. Add Font and Converter to Properties File
You must first set the font name in the font.properties
file. Do this by adding an index entry for the font. For example, for a serif font,
add a line that designates the serif font followed by the next sequential index
number in the file. The Java Runtime requires that the index numbers for any
one font be continuous.
Thus, to add a serif font to our previous example font.properties file, you
would insert the following line:
serif.3=<your own font name>
The index number must be the next highest index number in the properties
file. In our example file, we have already used serif.0,
serif.1, and serif.2. Therefore, the new
serif font must be serif.3. Had we used a number that was
discontinuous, such as serif.5, the Java Runtime would not
use that entry.
Next, you must define the converter for this font. This requires a
fontcharset entry for the new font, in this case,
serif.3. The following line is the
fontcharset entry that uses the converter created in the Java
code example:
You must also ensure that your new converter is visible to the Java Runtime. To
ensure that the Java Runtime can see your converter, your java application
classpath must include the class path to the converter. In our
example, we must be sure that the class
mypkg.converter.CharToByteMyfont is visible to the Java
Runtime. The simplest way to do this is to put this class under your
$JDK_HOME/classes/myown/package directory.
Debugging font.properties files
The best way to debug a custom font.properties file is by comparing it
with an existing file. First, you need to find the correct font.properties
file (based on osversion, region, encoding, language). Then if you check
the differences between your file and the standard file, the only differences
should be the fonts you wish to substitute (and possibly other fields related
to the new fonts, such as exclusion ranges).
Next, run a test such as SymbolTest in demo/applets/SymbolTest and see if
the standard logical fonts are displayed.