JDK-8137106 : EUDC (End User Defined Characters) are not displayed on Windows with Java 8u60+
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 8u60,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-09-17
  • Updated: 2016-04-27
  • Resolved: 2015-12-09
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 8 JDK 9
8u101Fixed 9 b100Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows 7 32/64, Windows 8 32/64 Window 8.1 32/64 windows 10 32/64

EXTRA RELEVANT SYSTEM CONFIGURATION :
DBCS(Japanese, Chinese, Korea and others) Windows 

A DESCRIPTION OF THE PROBLEM :
Oracle Java 8.0 does not display EUDC (End User Defined Characters a.k.a UDC or Gaiji.)
In case of  Oracle 7.0, IBM 7.0 and IBM 8.0, we can see system UDCs registered with Windows.

This page states as "On Windows, if there is a system EUDC (End User Defined Characters) font registered with Windows, the runtime automatically adds this font as well as a fallback font for 2D rendering."
So , Oracle Java 8.0 also should display EUDC on Windows like Oracle 7.0 and others.

http://docs.oracle.com/javase/8/docs/technotes/guides/intl/fontconfig.html 



REGRESSION.  Last worked in version 8u60

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This is a test class , Java2D_UDC. 

In this, EUDC u+E000, u+E001and  u+E002 are used for test and should be displayed if you resister them as your Windows  EUDC.
Oracle 7.0 displays them. But Oracle 8.0 does not . Instead, it displays squares for each. 

-------------------------------------------
import java.awt.*;
import javax.swing.*;

public class Java2D_UDC extends JPanel{

  public static void main(String[] args){

    JFrame frame = new JFrame();

    Java2D_UDC comp = new Java2D_UDC();
    frame.getContentPane().add(comp);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(0, 0, 400, 60);
    frame.setTitle("Font Test");
    frame.setVisible(true);
  }

  public void paintComponent(Graphics g){
    Graphics2D g2d = (Graphics2D)g;
  	
  	Font font = new Font(Font.MONOSPACED, Font.PLAIN, 16);
        g2d.setFont(font);
  
	String testStr="UDC:\uE000\uE001\uE002";
	g2d.drawString(testStr , 5, 20);  	
  }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Oracle 8.0 should display EUDCs on Windows like as Oracle 7.0, IBM Java 7.0 and IBM Java 8.0 .
ACTUAL -
Oracle 8.0 does not display EUDCs on Windows.
Instead, it displays squares for each. 

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
1) Resister EUDCs to u+E000, u+E001and  u+E002 on WIndows.
2) Run this as 'java Java2D_UDC' 

------------------------------------------
import java.awt.*;
import javax.swing.*;

public class Java2D_UDC extends JPanel{

  public static void main(String[] args){

    JFrame frame = new JFrame();

    Java2D_UDC comp = new Java2D_UDC();
    frame.getContentPane().add(comp);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(0, 0, 400, 60);
    frame.setTitle("Font Test");
    frame.setVisible(true);
  }

  public void paintComponent(Graphics g){
    Graphics2D g2d = (Graphics2D)g;
  	
  	Font font = new Font(Font.MONOSPACED, Font.PLAIN, 16);
        g2d.setFont(font);
  
	String testStr="UDC:\uE000\uE001\uE002";
	g2d.drawString(testStr , 5, 20);  	
  }
}

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

CUSTOMER SUBMITTED WORKAROUND :
Use Oracle 7.0 or IBM Java 7.0 / 8.0


Comments
No failures related to this fix in nightly. SQE OK to take customer escalated bug fix.
14-12-2015

The problem stems from JDK 7 when a refactoring to allow for pluggable font managers introduced a potential recursion into the initialisation. It appears that since then in (at least) this code path we have initialised Composite Fonts twice. This recursion really should not be happening. The recursion occurs when during the iintialisation of the composites as part of the initialisation of the factory, a call is made into Win32FontManager to get the EUDC font. This in turn creates a TrueTypeFont which needs to add the open file on that font to the "pool" which is managed by the singleton font manager which it tries to access using FontManagerFactory.getInstance(). The only reason this does not StackOverFlow is that the Win32FontManager is now sufficiently initialised it just returns "null" for the eudc font. The relevant 8u60 changes that exposed this were ensuring we didn't needlessly replace fonts that we already had initialised. In the case recursion occurred the recursive call was first to install the fonts but at that time the EUDC font had not been initialised. After the nested call returned the outer call went on to initialise the composite fonts with the EUDC font but they were no longer selected to replace the previous fonts. So we end up with the used composites not having EUDC support. The FontManagerFactory.getInstance() calls are scattered in many places. Proving none introduce similar recursion is not easy. And refactoring to do things in a way that this could not occur is tricky. Given that this needs a safe backport, the expedient thing is to tackle the specific case where we are recursing. We don't need to add the EUDC font to the pool during opening it for validation. So add a boolean which instead makes sure the file is opened and closed privately during this sequence. This changed behaviour is invoked in *just* the case where a EUDC font is found and created. So the risk of any regression here is limited to the case where we are broken anyway. A test for this is not practical as it requires a user to install an EUDC font which requires special steps different than installing a normal font. Manual verification will be required.
04-12-2015

1. Checked this for JDK 7u85, 8u51, 8u60, 8u66 ea b15, and 9 ea b82. 2. Result: 7u85: OK 8u51: OK 8u60: FAIL 8u66 ea b15: FAIL 9 ea b82: FAIL 3. Steps to reproduce: - Run "eudcedit", create font glyph EUDC u+E000, u+E001and u+E002 and save it. - Compile and run attached testcase: > javac Java2D_UDC.java > java Java2D_UDC 4. Output: See attached screenshot with 8u51 (disp_8u51.png) and 8u60 (disp_8u60.png). Moving this up for dev. team to look into. ILW:MMH = P2
24-09-2015