String width via fontmetrics calculation is very slow if there are arabic or persian letters in text

后端 未结 4 1409
一向
一向 2021-01-04 03:50

I have a problem. My application interface works much slower if i use eastern languages there. Especially i felt it in components such as JList, JCombobox, JTable.

4条回答
  •  半阙折子戏
    2021-01-04 04:23

    I've dug for a little and found next:

    From the source of the FontDesignMetrics we can see the main actions sequence

    public int stringWidth(String str) {
    float width = 0;
    if (font.hasLayoutAttributes()) {
        /* TextLayout throws IAE for null, so throw NPE explicitly */
        if (str == null) {
            throw new NullPointerException("str is null");
        }
        if (str.length() == 0) {
            return 0;
        }
        width = new TextLayout(str, font, frc).getAdvance();
    } else {
        int length = str.length();
        for (int i = 0; i < length; i++) {
            char ch = str.charAt(i);
            if (ch < 0x100) {
                width += getLatinCharWidth(ch);
            } else if (FontManager.isNonSimpleChar(ch)) {
                width = new TextLayout(str, font, frc).getAdvance();
                break;
            } else {
                width += handleCharWidth(ch);
            }
        }
    }
    return (int) (0.5 + width);
    

    }

    For latin characters method getLatinCharWidth(ch) is used. It caches all the characters widths. But for persian and arabic characters TextLayout is used instead of. The main purpose is because eastern characters may have varios shape and width depend on context. It is possible to add method which will cache characters width but it will not give exact values such as it will ignore nuances of different characters widths. Also it will ignore various ligatures.

    I've tested TextLayout separately and it is slow for both languages english and persian. So the real cause of the slow performance is the slow work of the sun.font.TextLayout class. It is used to determine string width in case characters in the string are not simple. Unfortunately i don't know how to boost TextLayout performance for a now.

    If somebody is interested here the article about various font and text layout nuances is http://download.oracle.com/javase/1.4.2/docs/guide/2d/spec/j2d-fonts.html

提交回复
热议问题