Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8087298

FontMetrics.computeStringWidth method is not correct for persian/arabic

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 9
    • 8u45
    • javafx
    • x86_64
    • windows_7

      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.

            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: