Java Chinese garbled & special character solution

Source: Internet
Author: User

Java Chinese garbled & special character solution

I believe many friends have encountered the Java garbled problem, recently I also solve a "use text to generate pictures in the process of Chinese and special characters garbled" problem; it took me a lot of time to debug the Sun.font, SUN.AWT below the various source code, finally understand its mechanism, solve the current problem; now write down the problem solving process and make a record so that you don't meet again later.

Problems encountered

Here is the code I want to execute (which is extremely simplified, but the meaning remains the same):

1  Public Static voidMain (string[] args)throwsIOException {2File File =NewFile ("Test.png");3Font font =NewFont ("Arial", Font.plain, 10);4BufferedImage bi =NewBufferedImage (400, 200, Bufferedimage.type_int_argb);5graphics2d g2 =(graphics2d) bi.getgraphics ();6 G2.setbackground (color.white);7G2.clearrect (0, 0, 400, 200);8 G2.setfont (font);9 G2.setcolor (color.black);Ten G2.setrenderinghint (renderinghints.key_text_antialiasing, renderinghints.value_text_antialias_on); OneG2.drawstring ("Why not (????) (????) Is that a special name? @¥¥¥ why not (????) (????) This name is special ", 0, 10); A g2.dispose (); - imageio.write (BI, PNG, file); -}

The goal, of course, is to look at the following scenarios when opening test.png:

After the local debugging is not a problem, put it on the test machine (Linux) to execute, the results of the execution is simply flapping the street:

jdk1.8 's Sun Source download

Adhere to the usual style of programmers: since there is a problem, then debug!
The pit Daddy is now the source package already does not contain the Sun package code!
Fortunately, Java official confirmed that the OPENJDK code is basically consistent with the JVM source, can be downloaded directly from the openjdk8u: jdk8u

As for how to use the source debug, this does not write ... It's not going to be basic, so don't look at this article.

Positioning problems

Direct download good source, remote breakpoint, server execution, in debug first found the first to produce local and test server inconsistent code:

The original JVM created the font will use Fontmanagerfactory to get fontmanager, and different systems use Fontmanager is different! Mac uses Cfontmanager, and Linux uses x11fontmanager!.

So what is the difference between these two fontmanager?

    • Cfontmanager will create CFont as FONT2D, the CFont is a class created specifically for Mac by the JVM, and the comments on classes and methods can be known that in MAC environments sometimes physical fonts are cfont wrapped, which is done in native code:

    • X11fontmanager creates a font2d that contains a collection of logical and physical fonts. X11fontmanager inherited the Fcfontmanager,fcfontmanager inherited the Sunfontmanager; let's take a look at the Loadfonts () method of X11fontmanager, Using Sunfontmanager's loadfonts () directly, Sunfontmanager's loadfonts () method loads the physical font, Sunfontmanager implements the Fontmanager preferlocalefonts () method, which loads the logical font:

logical fonts and physical fonts

Code debug to this side of the basic has been identified is a different environment font loading problem, then in the debug Linux environment when the logical fonts and physical fonts found what is it?

Physical font

Physical fonts are actual font libraries that contain glyph data and tables that map character sequences to glyph sequences using font techniques such as TrueType or PostScript Type 1. All implementations of Java Platform support TrueType fonts, and support for other font technologies is implementation-related. Physical fonts can use font names, such as Helvetica, Palatino, Honmincho, or any number of other font names. Typically, only a limited set of writing systems is supported for each physical font, for example, only Latin characters are supported, or only Japanese and basic Latin are supported. The available sets of physical fonts vary depending on the configuration. Applications that require a specific font can use the CreateFont method to bundle the fonts and instantiate them.

Logical font

Logical fonts are the five font families defined by the Java platform that must be supported by all Java runtime environments: Serif, Sansserif, monospaced, Dialog, and Dialoginput. These logical fonts are not actual font libraries. In addition, the logical font names are mapped to physical fonts by the Java runtime environment. Mapping relationships are related to implementations and the usual locale, so they provide different skins and specifications. In general, to cover a large range of characters, each logical font name is mapped to several physical fonts.

Problem solving

Debug a lot of source code, but the key point of this problem is here, other debug content is not posted.
Now that we have confirmed that the local (Mac environment) is native code to help us do the physical font of the package, converted to CFont for rendering, and the Linux environment X11fontmanager just to help us load the physical font and logical font, but we need to make our own choice, So the first step to solving the problem is obvious: change the creation of the font from the physical font to the logical font

1 //   Serif, Sansserif, monospaced, Dialog and dialoginput randomly choose 2new Font ("Serif", Font.plain, 10);

After the change to execute code, is still garbled! Continuing debug, found that the physical font of the logical font serif mapping on Linux does not have the Chinese font and the corresponding special symbol font, it is very simple, install the Chinese font (SIMSUN.TTF) directly on Linux, and then install the special symbol "????" The fonts can be displayed (MYSI.TTF), and the two fonts are also placed under the JDK Fonts directory (java_home/jre/lib/fonts). There are Linux font installation methods behind the article.

After completing the above changes, restart the service and perform the successful display again! Warmly celebrate ~ ~ ~

JVM Logical Font mapping configuration

The above changes can solve the Chinese and special characters garbled problem, but I found in the debug process during the logical font loading process, the JVM will refer to a configuration file, In Sun.awt.FontConfiguration, this configuration class completes the mapping of logical and physical fonts, and also instructs Sunfontmanager to create logical fonts, and this fontconfiguration read configuration file is Fontconfig.prope Rties, this configuration file directory is Java_home/jre/lib

Looking at the information, the JVM font configuration file is loaded in the following order:
Java_home/jre/lib/fontconfig. OS. Version.properties
Java_home/jre/lib/fontconfig. OS. Version.bfc
Java_home/jre/lib/fontconfig. Os.properties
Java_home/jre/lib/fontconfig. Os.bfc
Java_home/jre/lib/fontconfig. Version.properties
Java_home/jre/lib/fontconfig. Version.bfc
Java_home/jre/lib/fontconfig.properties
Java_home/jre/lib/fontconfig.bfc

OS is a system, for example: Linux, CentOs, Redhat, etc; version is the revision number.

In this configuration file, you can modify the logical font correspondence with the physical font, that is, you can manually modify the serif, Sansserif, monospaced, Dialog, and dialoginput five logical fonts used in different scenarios of the actual physical font.

For a chestnut, the following configuration will serif.plain the logical font in Chinese using SIMSUN.TTF, Latin using Java's own font:

1# @ (#) linux.fontconfig.SuSE.properties 1.2 03/10/172 #3# Copyright 2003Sun Microsystems, Inc. All rights reserved.4 #5 6 # Version7Version=18 9 # Component Font MappingsTenSerif.plain.chinese=-misc-simsun-medium-r-normal--*-%d-*-*-c-*-iso10646-1 OneSerif.plain.latin-1=-b&h-lucidabright-medium-r-normal--*-%d-*-*-p-*-iso8859-1 A  - # Search Sequences -Sequence.allfonts=latin-1, Chinese the  - # exclusion Ranges -  - # Font File Names +Filename.-misc-simsun-medium-r-normal--*-%d-*-*-c-*-iso10646-1=/usr/share/fonts/myfonts/simsun.ttf
Linux installation Fonts
    • Linux Fonts directory:/usr/share/fonts
    • Create a new directory under fonts, for example: mkdir myfonts
    • Place the fonts you want to install under the new directory, for example: CP ~/test/simsun.ttf/usr/share/fonts/myfonts
    • Go to myfonts directory: cd/usr/share/fonts/myfonts
    • Execute the following command:
      • Mkfontscale
      • Mkfontdir
      • Fc-cache-fv
    • To see if the corresponding font has been installed: fc-list
    • The FC-CACHE-FV command is used to refresh the Linux font cache to make it effective immediately

PS: All operations above require root privileges





Java Chinese garbled & special character solution

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.