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

Thai text rendered incorrectly using some AffineTransform-derived fonts

XMLWordPrintable

    • 2d
    • x86_64
    • windows_7

      ADDITIONAL SYSTEM INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      openjdk version "17-ea" 2021-09-14
      OpenJDK Runtime Environment (build 17-ea+28-2534)
      OpenJDK 64-Bit Server VM (build 17-ea+28-2534, mixed mode, sharing)


      A DESCRIPTION OF THE PROBLEM :
      When rendering Thai text, scaling fonts via deriveFont(float) seems to always work correctly. However, when the font is scaled via deriveFont(AffineTransform), the vowels above the main line of text appear to be misplaced, mangling the meaning of the text.

      We tested using 3 fonts: Tahoma, Arial and Noto. Of these 3 fonts, 1 of them (Arial) behaved correctly regardless of the scaling method used. The other 2 (Tahoma and Noto) mangled the text when using deriveFont(AffineTransform).

      Results are consistent in both OpenJDK 16.0.1 and OpenJDK 17 EA-28.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the code below.

      It assumes the presence of 2 Windows fonts and a Google Noto font (which is a free download at https://www.google.com/get/noto/#sans-thai).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Both lines should match for all 3 pairs of lines (Tahoma 1 and 2, Arial 1 and 2, Noto 1 and 2).
      ACTUAL -
      The Tahoma and Noto lines do not match, because the vowels are misplaced on the second line.

      ---------- BEGIN SOURCE ----------
      public class ThaiTest {

          public static void main(String... args) throws Exception {

              String text = "\u0e27\u0e31\u0e0a\u0e23\u0e34\u0e19\u0020\u0e40\u0e2b\u0e25\u0e37\u0e2d\u0e25\u0e49\u0e19";
              Font tahoma = Font.createFont(Font.TRUETYPE_FONT, new File("C:/Windows/Fonts/tahoma.ttf"));
              Font arial = Font.createFont(Font.TRUETYPE_FONT, new File("C:/Windows/Fonts/ARIALUNI.TTF"));
              Font noto = Font.createFont(Font.TRUETYPE_FONT, new File("NotoSansThai-Regular.ttf"));

              BufferedImage img = new BufferedImage(700, 700, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g2d = img.createGraphics();
              g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
              g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              g2d.setColor(Color.WHITE);
              g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
              g2d.setColor(Color.BLACK);

              g2d.setFont(tahoma.deriveFont(50f));
              g2d.drawString("Tahoma 1: " + text, 30, 100);

              g2d.setFont(tahoma.deriveFont(AffineTransform.getScaleInstance(50, 50)));
              g2d.drawString("Tahoma 2: " + text, 30, 200);

              g2d.setFont(arial.deriveFont(50f));
              g2d.drawString("Arial 1: " + text, 30, 300);

              g2d.setFont(arial.deriveFont(AffineTransform.getScaleInstance(50, 50)));
              g2d.drawString("Arial 2: " + text, 30, 400);

              g2d.setFont(noto.deriveFont(50f));
              g2d.drawString("Noto 1: " + text, 30, 500);

              g2d.setFont(noto.deriveFont(AffineTransform.getScaleInstance(50, 50)));
              g2d.drawString("Noto 2: " + text, 30, 600);

              g2d.dispose();

              ImageIO.write(img, "png", new File("thai.png"));
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Consider using a different font which doesn't exhibit the issue, or avoid deriveFont(AffineTransform) (not always possible if needing to scale height and width separately).

      FREQUENCY : always


        1. thai.png
          thai.png
          32 kB
        2. thai17.png
          thai17.png
          37 kB
        3. ThaiTest.java
          2 kB

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

              Created:
              Updated: