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


i have problem. application interface works slower if use eastern languages there. felt in components such jlist, jcombobox, jtable.

how found performance of fontmetrics.stringwidth method slow (500+ times) if in text @ least 1 letter arabic or persian. how know commonly used method in various swing components.

is there way boost method performance?

here example class demonstrates problem:

import java.awt.font; import java.awt.fontmetrics; import java.awt.graphics; import java.awt.image.bufferedimage;  public class fontmetricsspeedtest {   public static void main( string args[] ) {   string persian="صصصصصصصصصصصصصصصصصصصصص";   string english="abcde()agjklj;lkjelwk";   fontmetrics fm=createfontmetrics(new font("dialog",font.plain,12));   int size=50000;   long start=system.currenttimemillis();   for(int i=0;i<size;i++)   {    fm.stringwidth(persian);   }   system.out.println("calculation time persian: "+(system.currenttimemillis()-start)+" ms");   start=system.currenttimemillis();   for(int i=0;i<size;i++)   {    fm.stringwidth(english);   }   system.out.println("calculation time english: "+(system.currenttimemillis()-start)+" ms");  }  private static fontmetrics createfontmetrics(font font)  {   bufferedimage bi = new bufferedimage(1, 1, bufferedimage.type_int_argb_pre);   graphics g = bi.getgraphics();   fontmetrics fm = g.getfontmetrics(font);   g.dispose();   bi = null;   return fm;  } } 

for me gives next output:

calculation time persian: 5482 ms

calculation time english: 11 ms

i've dug little , found next:

from source of fontdesignmetrics can see main actions sequence

public int stringwidth(string str) { float width = 0; if (font.haslayoutattributes()) {     /* textlayout throws iae null, throw npe explicitly */     if (str == null) {         throw new nullpointerexception("str null");     }     if (str.length() == 0) {         return 0;     }     width = new textlayout(str, font, frc).getadvance(); } else {     int length = str.length();     (int = 0; < 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) used. caches characters widths. persian , arabic characters textlayout used instead of. main purpose because eastern characters may have varios shape , width depend on context. possible add method cache characters width not give exact values such ignore nuances of different characters widths. ignore various ligatures.

i've tested textlayout separately , slow both languages english , persian. real cause of slow performance slow work of sun.font.textlayout class. used determine string width in case characters in string not simple. unfortunately don't know how boost textlayout performance now.

if interested here article various font , text layout nuances http://download.oracle.com/javase/1.4.2/docs/guide/2d/spec/j2d-fonts.html


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -