Отображение китайского текста в апплете - PullRequest
3 голосов
/ 18 ноября 2009

У нас есть апплет, который может отображать китайский текст. Для него мы указываем шрифт (Arial), он отлично работает как под Windows, так и под Mac OSX.

Но в Firefox в Linux иероглифы отображаются в виде квадратов. Есть ли способ обойти это? Обратите внимание, что мы не можем предполагать наличие определенного файла шрифта на клиенте.

Ответы [ 4 ]

3 голосов
/ 18 ноября 2009

Это указывало на то, что шрифт не поддерживает китайские иероглифы (что вы, вероятно, догадались).

Вам может показаться интересным метод java.awt.Font.canDisplayUpto ().

http://www.j2ee.me/javase/6/docs/api/java/awt/Font.html#canDisplayUpTo(java.lang.String)

"Указывает, может ли этот шрифт отображать указанную строку. Для строк с кодировкой Unicode важно знать, может ли конкретный шрифт отображать строку. Этот метод возвращает смещение в строку String, которая является первым символом. этот шрифт не может отображаться без использования отсутствующего кода глифа. Если шрифт может отображать все символы, возвращается -1. "

2 голосов
/ 18 ноября 2009

Это потому, что все Arial на Windows и Mac имеют шрифт Unicode, но в Linux он имеет только кодировку Latin-1. Во многих дистрибутивах Linux китайские шрифты не являются обязательными, и китайские шрифты могут быть недоступны.

Обычная техника - поиск по всему шрифту, чтобы увидеть, что любой из них может отображать китайские иероглифы. Например,

static final Font defaultFont =new Font( "Arial Unicode MS", Font.BOLD, 48 );

static private Font[] allFonts;

static final char sampleChineseCharacter = '\u4F60';  // ni3 as in ni3 hao3

public static void loadFonts() {

    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

    allFonts = env.getAllFonts();
    int nFonts = allFonts != null ? allFonts.length : 0;
    fontNames = new String[nFonts];
    fontMap = new Hashtable();
    String currentFamily = "";
    int j = 0;

    for ( int i = 0; i < nFonts; i++ ) {

        Font font = allFonts[ i ];

        System.out.println( allFonts[ i ] );

        if ( font.canDisplay( sampleChineseCharacter )) {

                currentFamily = font.getFamily();

                Object key = fontMap.put( currentFamily, font );

                if ( key == null ) {

                    // The currentFamily hasn't been seen yet.

                    fontNames[ j ] = currentFamily;
                    j++;

                }

        }

    }

    String tmp[] = fontNames;
    fontNames = new String[j];
    System.arraycopy( tmp, 0, fontNames, 0, j );

}
0 голосов
/ 29 июня 2010

Я обнаружил, что код здесь не подходит для моих нужд.

Мне нужно было проверить неизвестную входную строку, чтобы определить, какой шрифт использовать, следовательно, мне нужно было проверить каждый отдельный символ. (см. ниже)

Кстати, метод font.canDisplayUpTo не будет работать. Он может одобрить шрифт, который может отображать только некоторые символы.

Итак, просто используйте этот код ниже.

Font[] allFonts;
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

allFonts = env.getAllFonts();

Font targetFont = null;
for ( int i = 0; i < allFonts.length; i++ ) 
{
    Font font = allFonts[ i ];
    boolean canDisplayAll = true;
    for (char c : text.toCharArray())
    {
        if (!font.canDisplay(c))
        {
            canDisplayAll = false;
            break;
        }
    }
    if (canDisplayAll)
    {
        logger.debug("font can display the text " + font.getName());
        targetFont = font;
        break;
    }
    else
    {
        logger.debug("cant display " + font.getName());
    }
}
0 голосов
/ 18 ноября 2009

Возможно, вам придется передать следующий параметр в теге объекта: <param name="java_arguments" value="-Dfile.encoding=utf-8" />

...