FULL PRODUCT VERSION :
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
com.sun.javafx.tk.FontMetrics.computeStringWidth method does not correctly compute the width if there are persian/arabic characters in the string.
The computation is done by PrismFontUtils class which certainly does not take into account the possibility of different glyphs per character. In persian/arabic every character may come into 4 different shapes depending on the characters before and after it and each glyph has a different width.
double width = 0f;
for (int i = 0; i < string.length(); i++) {
width += strike.getCharAdvance(string.charAt(i));
}
The algorithm used by awt has a diffrerent approach and seems to be handling this situation correctly. Source code of FontDesignMetrics:
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);
}
}
REPRODUCIBILITY :
This bug can be reproduced always.
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
com.sun.javafx.tk.FontMetrics.computeStringWidth method does not correctly compute the width if there are persian/arabic characters in the string.
The computation is done by PrismFontUtils class which certainly does not take into account the possibility of different glyphs per character. In persian/arabic every character may come into 4 different shapes depending on the characters before and after it and each glyph has a different width.
double width = 0f;
for (int i = 0; i < string.length(); i++) {
width += strike.getCharAdvance(string.charAt(i));
}
The algorithm used by awt has a diffrerent approach and seems to be handling this situation correctly. Source code of FontDesignMetrics:
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);
}
}
REPRODUCIBILITY :
This bug can be reproduced always.