JDK-7017058 : Malayalam glyph substitution is failing for Malayalam with Windows Kartika font.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6,9,11
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2011-02-03
  • Updated: 2019-06-26
  • Resolved: 2018-09-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12
11.0.2Fixed 12 b14Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

We are trying to render characters from the Indic Malayalam language

I have coded the example as both an .html and .java file.  The example attempts to render two lines of Malayalam characters.  The two lines differ only in the last character,

\u0D2C\u0D3E\u0D32\u0D28\u0D4D
and
\u0D2C\u0D3E\u0D32\u0D28\u0D4D\u200D

The last character, \u200D, (a "zero width joiner") should
trigger a ligature to be formed.

The .html example is rendered correctly using Internet Explorer.
The .java example does not render the second line correctly.
Both the java.awt.font.TextLayout and Font.layoutGlyphVector
fail to render correctly.

The bug has attachments two PNG files
jdk_kartika.png : JDK rendering via the Java program below
ie_kartika.ong : IE rendering of the HTML

Java :-
-------
import java.awt.*;
import java.awt.font.*;
import java.util.*;
import javax.swing.*;


public class MalayalamTest extends JFrame
{
    private static String[] TEXT =
    {
        "Testing glyph substitution for Malayalam language.",
        "\u0D2C\u0D3E\u0D32\u0D28\u0D4D",
        "0D2C 0D3E 0D32 0D28 0D4D",
        "\u0D2C\u0D3E\u0D32\u0D28\u0D4D\u200D",
        "0D2C 0D3E 0D32 0D28 0D4D 200D"
    };
   
   
    private static Font font;
   

    public static void main(String[] args)
      throws Exception
    {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
       
        // set the language to Malayalam
        Locale.setDefault(new Locale("ml"));

        // create the rendering font
        HashMap attrs = new HashMap();
        attrs.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
        attrs.put(TextAttribute.KERNING,   TextAttribute.KERNING_ON);
        font = new Font("Kartika", Font.PLAIN, 24).deriveFont(attrs);
        System.out.println("using " + font);

        // display the test JFrame
        MalayalamTest f = new MalayalamTest();
        f.setTitle("Malayalam Test");
        f.setSize(600, 300);
        f.setForeground(Color.black);
        f.show();
    }
   
   
    public void paint(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                           RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        FontRenderContext frc = g2.getFontRenderContext();

        for (int i = 0; i < TEXT.length; i++)
        {
            String text = TEXT[i];
            int x = 10;
            int y = 60 + 40*i + 20*((i+1)/2);
           
            // render using TextLayout
            TextLayout layout = new TextLayout(text, font, frc);
            layout.draw(g2, x, y);


        }
    }
}

---

HTML :-

<html>
    <head>
        <title>Malayalam Test</title>
    </head>
   
    <body>
        <h3>Testing glyph substitution for Malayalam language</h3>
        <br>
       
        <font size="32" face="Kartika">&#x0D2C;&#x0D3E;&#x0D32;&#x0D28;&#x0D4D;</font>
        <code>0D2C 0D3E 0D32 0D28 0D4D</code>
        <br><br><br>

        <font size="32" face="Kartika">&#x0D2C;&#x0D3E;&#x0D32;&#x0D28;&#x0D4D;&#x200D;</font>
        <code>0D2C 0D3E 0D32 0D28 0D4D 200D</code>
        <br>
        The last three unicode characters form a ligature (glyph substitution)
    </body>
</html>

Comments
Ok The link to the process: http://openjdk.java.net/projects/jdk-updates/approval.html
19-09-2018

Fix Request Requested by users at Google. Trivial jdk11 backport http://cr.openjdk.java.net/~martin/webrevs/jdk11u/zwj/
19-09-2018

This is also the cause of these two bugs https://bugs.openjdk.java.net/browse/JDK-8195836 : Benhali layout https://bugs.openjdk.java.net/browse/JDK-8191130 : Sinhala layout
05-09-2018

JDK is special casing ZWJ and some other control characters to map to the invisible glyph via a method called getControlCodeGlyph. The basic logic for that was introduced in fixing https://bugs.openjdk.java.net/browse/JDK-4517298 However the current version of the code is from a JDK 1.5 rewrite of the font code, which preserved the idea/logic but in Java code. The consequence is that if the GSUB table in a font maps a glyph sequence which includes glyphs for these special characters, we are disabling that sequence because we've reported 0XFFFE instead of the glyph the font maps. To fix this we need to defer to the font file for mapping at least some of these special characters, falling back to the current logic only if it does not map it.
28-08-2018

JDK9 replaced OpenType engine to HarfBuzz per JDK-8064530 (oracle bug24559738 Integrate harfbuzz opentype layout engine per JEP 258.) Yet this is still reproducible with JDK9(JDK9.0.1+11) e.g. this is the problem with Malayalam Chillus Unicode http://www.unicode.org/versions/Unicode10.0.0/ch12.pdf page 508, Table 12-37 The sequence of "legacy representaiotn5.0" does not appear as the glyph in the "Visual" column but with the first consonant with virama dot above. This original case, \u0D28\u0D4D\u200D should be rendered like \u0D7B malayalam letter chillu N Same problem seen with other characters listed. e.g. \u0D23\u0D4D\u200D \u0D30\u0D4D\u200D \u0D32\u0D4D\u200D \u0D33\u0D4D\u200D
07-11-2017

PUBLIC COMMENTS Confirmed able to reproduce as described. Could not find a non-windows environment which reproduced the HTML behavior.
05-03-2011

EVALUATION I see the same with JDK 1.7 b128, so its not fixed in the latest ICU
04-02-2011