font.properties
files
This document explains how to add Asian and other language fonts to the Java Runtime JDK 1.2. More specifically, this document covers the JDK 1.2 special feature for adding these fonts to the Java Runtime. It is very likely that this feature will change in future JDK releases.
At this time, this document describes how to install Japanese, Korean, Chinese, and Traditional Chinese fonts to your system.
The JDK 1.2 release for Win32 platforms supports TrueType and Postscript Type1 fonts. JDK 1.2 for Solaris supports scalable outline fonts that can be handled by an X11 server, such as F3, Type1, and TrueType.
There are severalfont.properties
files that come bundled with the JDK 1.2. 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 defaultfont.properties
file has no suffix on its file name, as follows: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.propertiesfont.properties.5.5.1
, will include only F3 fonts. Thus, we first look for a file named:where font.properties.<osVersion><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:wherefont.properties.<locale>locale
is one of:Select the file with the suffix for the particular font that you are interested in. Thus, for Traditional Chinese, you would access the fileja ko zh zh_TW ...font.properties.zh_TW
.NOTE: The
<locale>
is actually comprised of<language>_<region>_<encoding>
where
<language>
is the string returned fromSystem.getProperty("user.language")
<region>
is the string returned fromSystem.getProperty("user.region")
<encoding>
is the string returned fromSystem.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:font.properties.<language>_<region>_<encoding>.<osVersion> font.properties.<language>_<region>_<encoding> font.properties.<language>_<region>.<osVersion> font.properties.<language>_<region> font.properties.<language>_<encoding>.<osVersion> font.properties.<language>_<encoding> font.properties.<language>_<osVersion> font.properties.<language> font.properties.<encoding>.<osVersion> font.properties.<encoding> font.properties.<osVersion> font.properties
You must work with thefont.properties
file to add fonts to the Java Runtime. Thefont.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 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:NOTE: This is a bad example since timesroman and helvetica are actual font names and in JDK1.2, we no longer alias these names to a virtual font.alias.timesroman=serif alias.helvetica=sansserifIt 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>, attributesThe 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 JDK1.2, the full matrix of virtual font name and style must be complete. For example, you must have
serif
,serif.bold
serif.italic
,serif.bolditalic
. Note thatserif>
is equivalent toserif.plain
. All names in this file are case-insensitive.For example, in the Solaris
font.properties
file in JDK1.1, theserif
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 JDK 1.2 font.properties, the entire matrix must be specified:serif.plain.0=-linotype-times-medium-r-normal--*-%d-*-*-p-*-iso8859-1 serif.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific serif.2=--symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific serif.italic.0=-linotype-times-medium-i-normal--*-%d-*-*-p-*-iso8859-1 serif.bold.0=-linotype-times-bold-r-normal--*-%d-*-*-p-*-iso8859-1 serif.bolditalic.0=-linotype-times-bold-i-normal--*-%d-*-*-p-*-iso8859-1As mentioned earlier, the key value for theserif.0=-linotype-times-medium-r-normal--*-%d-*-*-p-*-iso8859-1 serif.1=-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific serif.2=--symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific serif.italic.0=-linotype-times-medium-i-normal--*-%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-*-sun-fontspecific serif.bold.0=-linotype-times-bold-r-normal--*-%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-*-sun-fontspecific serif.bolditalic.0=-linotype-times-bold-i-normal--*-%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-*-sun-fontspecificplain
style,plain
does not need to be specified (serif.0
defaults to theplain
style), howeveritalic
,bold
orbolditalic
must be specified for those styles.
There are two steps you must take to use Asian fonts, such as the Japanese font, on an English environment platform.Step 1: Install the Font
First, you must install the 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 newfont.properties
file. The locale symbol represents the font name that you are interested in. No editing is required when you replacefont.properties
with font.properties.<locale> because font.properties.<locale> is a superset offont.properties
. These are the locale symbols that specify the different font properties files:Locale Symbols for Fonts
Font Name font.properties
SymbolJapanese ja
Korean ko
Chinese zh
Traditional Chinese zh_TW
Thus, to use the the Korean font, you copy or rename
font.properties.ko
tofont.properties
.
It is possible to use more than one Asian font in your runtime. To do this, you must edit thefont.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.serif.0=Arial,ANSI_CHARSET serif.1=WingDings,SYMBOL_CHARSET,NEED_CONVERTED serif.2=Symbol,SYMBOL_CHARSET,NEED_CONVERTEDThe numbers (0, 1, and 2) that appear after the word
serif
, such asserif.0
, indicate the order in which the font glyphs are searched for a corresponding match with the Unicode, or Java string encoding, codepoint. Thus, ifserif.0
andserif.1
both have the glyph that corresponds to the same Unicode codepoint, then the glyph forserif.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 forserif.2
names the font Symbol.The second argument takes the form
*_CHARSET
. In our example, it is eitherANSI_CHARSET
orSYMBOL_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 thisNEED_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 forfontcharset.serif.1=sun.awt.windows.CharToByteWingDings fontcharset.serif.2=sun.awt.CharToByteSymbolserif.1
indicates that, to draw the WingDings glyph, the Unicode string should be converted using thesun.awt.windows.CharToByteWingDings
converter. (Recall that the font.properties file has already established the font forserif.1
as WingDings.)The specification for the charset converter is described later in the section The Charset Converter.
NOTE: In the current implementation of JDK1.2,
NEED_CONVERTED
is not used.Font file names in JDK1.2
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 namefilename.Arial=ARIAL.TTF filename.Arial_Bold=ARIALBD.TTF filename.Arial_Italic=ARIALI.TTF filename.Arial_Bold_Italic=ARIALBI.TTFArial
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../lib/font.properties ./lib/font.properties.ar ./lib/font.properties.iw ./lib/font.properties.ja ./lib/font.properties.ko ./lib/font.properties.ru ./lib/font.properties.th ./lib/font.properties.zh ./lib/font.properties.zh.NT4.0 ./lib/font.properties.zh_TWSpecifying Fonts on Solaris Platform
In JDK 1.2, 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
-adobe-courier-bold-o-normal--10-100-75-75-m-60-iso8859-1the 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-symbolThese 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 ofserif.0
,serif.1
, andserif.2
. In addition, these lines indicate that the serif font with the style italic consists ofserif.italic.0
,serif.italic.1
, andserif.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:
For example, the line:fontcharset.serif.0=sun.io.CharToByte8859_1 fontcharset.serif.1=sun.awt.motif.CharToByteX11Dingbats fontcharset.serif.2=sun.awt.CharToByteSymbolindicates that allfontcharset.serif.0=sun.io.CharToByte8859_1serif.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 thesun.io.CharToByte8859_1
converter.
font.properties
filesThe 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:
Type1: /usr/openwin/lib/X11/fonts/Type1 TrueType: /usr/openwin/lib/X11/fonts/TrueType F3: /usr/openwin/lib/X11/fonts/F3In 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:
TrueType: /usr/openwin/lib/locale/ja/X11/fonts/TT F3: /usr/openwin/lib/locale/ja/X11/fonts/F3The 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:
HG-MinchoL.ttf -ricoh-hg mincho l-medium-r-normal--0-0-0-0-m-0-jisx0208.1983-0In 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:
serif.1=-ricoh-hg mincho l-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0When 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:
% xfd -fn "-ricoh-hg mincho l-medium-r-normal--*-140-*-*-m-*-jisx0208.1983-0"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 displayIf 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.
Currently there is a bug in JDK1.2 where we do not rotate (or scale or shear) F3 fonts. Thus it is desirable to choose a TrueType font if one exists, rather than an F3 font. 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 current Solaris JDK build provides the following font properties files:
./lib/font.properties ./lib/font.properties.5.6 ./lib/font.properties.5.7 ./lib/font.properties.cs ./lib/font.properties.el ./lib/font.properties.hu ./lib/font.properties.ja ./lib/font.properties.ja.5.6 ./lib/font.properties.ko ./lib/font.properties.ko.5.6 ./lib/font.properties.ko.5.7 ./lib/font.properties.lt ./lib/font.properties.lv ./lib/font.properties.pl ./lib/font.properties.ru ./lib/font.properties.tr ./lib/font.properties.zh_EUC_CN ./lib/font.properties.zh_EUC_CN.5.6 ./lib/font.properties.zh_EUC_CN.5.7 ./lib/font.properties.zh_TW_Big5 ./lib/font.properties.zh_EUC_TW ./lib/psfont.properties.jaIf 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:
The corresponding exclusion range is as follows: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-fontspecificexclusion.monospaced.0=0080-ffffThus, 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.
Thecharset
converter converts Unicode, or Java string encoding, to the index of the font. For font drawing, the JDK 1.1 Runtime uses thecharset
converter that is the subclass ofsun.io.CharToByteConverter
.To add your own font to your JDK 1.1 Runtime, you need to create a
charset
converter and specify it in thefont.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 thefont.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:
The index number must be the next highest index number in the properties file. In our example file, we have already usedserif.3=<your own font name>serif.0
,serif.1
, andserif.2
. Therefore, the new serif font must beserif.3
. Had we used a number that was discontinuous, such asserif.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 thefontcharset
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 applicationfontcharset.serif.3=mypkg.converter.CharToByteMyfontclasspath
must include the class path to the converter. In our example, we must be sure that the classmypkg.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.
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.