JDK-4457181 : Unicode Combining Diacritics are not rendered
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.3.0,5.0u15
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2001-05-10
  • Updated: 2010-07-09
  • Resolved: 2011-05-18
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 6 JDK 7
6u11-revFixed 7 b03Fixed
Related Reports
Relates :  
Relates :  
Description
Name: bsC130419			Date: 05/10/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)



package mpi.alt;
/**
   <pre>
   This test report against Java 1.3 covers one major bug:
   (major bug) Java fails to render  combining diacritics.
   (minor bug) java.awt.TextArea.setFont() fails under Windows.
   Combining diacritics are rendered upon the preceding character.
   The combining diacritic choosen is the 'umlaut'.
   The choosen text are the two characters 'a umlaut' and 'u'.
   After an equal sign, the same two characters are shown using precomposed
characters.
   
   The program opens an AWT and a Swing window for each font that claims to
render the
   text.
   The display will fail depending on the operating system, the font and the
GUI.
   The result table is:
   
                | Java     | font       | AWT          | Swing
   -------------+----------+------------+--------------+--------
   Windows 2000 | 1.3.0-C  | AUMS       | font not set | ok
   Windows 2000 | 1.3.0-C  | LSU        | font not set | ok
   Windows NT   | 1.3.0-C  | AUMS       | font not set | ok
   Windows NT   | 1.3.0-C  | LSU        | font not set | ok
   Windows 98   | 1.3.0-C  | AUMS       | font not set | after full
   Windows 98   | 1.3.0-C  | LSU        | font not set | ok
   SunOS 5.7    | 1.3.0_02 | Dialog     | after null   | after null
   SunOS 5.7    | 1.3.0_02 | Serif      | after null   | after null
   MacOS 10.0.2 | 1.3.0    | Geneva     |  ok          | after full
   MacOS 10.0.2 | 1.3.0    | Helvetica  |  ok          | after full
   MacOS 10.0.2 | 1.3.0    | Chicago    |  ok          | after full
   MacOS 10.0.2 | 1.3.0    | Didot      |  ok          | after zero
   
  /Font Legend/
   AUMS = Arial Unicode MS
   LSU  = Lucida Sans Unicode
  /Error Legend/
   font not set = some default font is used, which fails to the render.
   after full   = diacritic is rendered as an wide character on its own.
   after zero   = diacritic has zero width, but still follows preceding
character.
   after null   = diacritic is not shown at all, but a space is used for that.

   
   Java is not able to render the combining diacritic in most of the cases.

   
   Influence on our work:
   It is absolutely essential for us to use combining diacritics
   because there are characters that do not exist as precomposed characters,
   in the IPA range for example.
   Changes must be made to Java.  We cannot accept this situation.
   
   
  Related Bugs:
   (major bug)
     http://developer.java.sun.com/developer/bugParade/bugs/4157067.html
     This bug against Java 1.2 is very similar, but closed because it is said to
     be not reproducable.
   (minor bug)
     http://developer.java.sun.com/developer/bugParade/bugs/4369512.html
     This bug against Java 1.3 is open.

	 </pre>
	 @version $Header:
/data/hsm-archive/eudico/cvs-repository/mpi/alt/CombiningDiacriticsTest.java,v
1.13 2001/05/03 15:44:30 markra Exp $

*/

import java.util.Vector;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Frame;
import java.awt.TextArea;
import javax.swing.JFrame;
import javax.swing.JTextArea;

import java.awt.*;
import javax.swing.*;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/*
  The class has two parts:
  (part 1)
    Look up a font that claims to display the whole text.
  (part 2)
    Display the two characters using swing and awt only.
  Leave the application by killing it with ^C
 */
public class CombiningDiacriticsTest {
	
	char a       = '\u0061';
	char umlaut  = '\u0308';
	char aumlaut = '\u00E4';
	char u       = '\u0075';
	String text1  = "" + a + umlaut + u + "    =     " + aumlaut + u;
	Vector fontVector = new Vector();
	int openFonts = 0;

	ActionListener comboListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JComboBox cb = (JComboBox)e.getSource();
                String fontName = (String)cb.getSelectedItem();
				Font font = new Font(fontName, Font.PLAIN, 18);
				openWindows(font);

            }
		};

	// Init and Setup the Font chooser dialog
	public CombiningDiacriticsTest() throws Exception{
		findFonts();
		JFrame mainFrame = new JFrame("Select Font");
		String[] fontArray = new String[fontVector.size()];
		for (int i=0; i<fontVector.size(); i++) {
			String fontname = (String)fontVector.elementAt(i);
			fontArray[i] = fontname;
		}
        JComboBox fontList = new JComboBox(fontArray);
        fontList.addActionListener(comboListener);
		mainFrame.getContentPane().add(fontList);
		mainFrame.setLocation(5, 50);
		mainFrame.pack();
		mainFrame.setVisible(true);
	}
	
	// Java 1.3 comes with no font to display Unicode with.
	private void findFonts() {
		GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
		String fontList[] = ge.getAvailableFontFamilyNames();
		boolean appropriate = false;
		{
			int i = 0;
			while (i < fontList.length) {
				String fontname = fontList[i];
				Font   font     = new Font(fontname, Font.PLAIN,
18);
				// note: documentation on canDisplayUpTo() is
wrong in 1.2 and 1.3.
				//
http://developer.java.sun.com/developer/bugParade/bugs/4340793.html
				appropriate = font.canDisplayUpTo(this.text1) ==
this.text1.length();
				if (appropriate) {
					this.fontVector.add(fontList[i]);
				}
				i++;
			}
		}
	}

	// Arange the output
	private void openWindows(Font font) {
		int yDiff = 90;
		// awt
		TextArea textArea2 = new TextArea();
		textArea2.setFont(font); // has no effect on Windows NT!
		textArea2.setRows(1);
		textArea2.setColumns(25);
		textArea2.append(text1);
		
		Frame frame = new Frame("AWT: " + font.getName());
		frame.add(textArea2);
		frame.setLocation(10, 200+yDiff*this.openFonts);
		frame.pack();
		frame.setVisible(true);

		// swing
		JTextArea jTextArea2 = new JTextArea();
		jTextArea2.setFont(font);
		jTextArea2.setRows(1);
		jTextArea2.setColumns(25); // has no effect on Windows NT!
		jTextArea2.append(text1);
		
		JFrame jFrame = new JFrame("Swing: " + font.getName());
		jFrame.getContentPane().add(jTextArea2);
		jFrame.setLocation(400, 200+yDiff*this.openFonts);
		jFrame.pack();
		jFrame.setVisible(true);

		this.openFonts++;
	}


	
	static public void main(String[] argv) throws Exception {
		new CombiningDiacriticsTest();
	}




}
(Review ID: 123716) 
======================================================================

Comments
EVALUATION Some of what is reported here is a misunderstanding, and the rest is fixed one way or another 1. The problem that canDisplayUpTo() did not return -1 to indicate all chars could be displayed was also reported as bug 4340793 and fixed in JDK 1.4 beta. 2. The complaint that "java.awt.TextArea.setFont() fails under Windows" is not a bug The fonts that are listed as failing are all "physical" fonts such as Arial MS Unicode. AWT components are only required to support the logical fonts (Dialog etc). so this is not a bug 3. The remaining reported problem is that "Java fails to render combining diacritics." The majority of these complaints seem to be against MacOS I haven't attempted to see if the complaints of some of this failing on Mac OS X are resolved in a later JDK for OS X as I don't have access to a Mac. In any case, as Apple's implementation of this is quite different it needs to be reported to Apple. But basically the problem is that in earlier JDK's layout didn't support this. IN JDk 6 it *does* but you would need to invoke TextLayout explicitly to make this happen. What needs to happen is Swing (and other text rendering API) needs to check for these code points just as we would for Arabic, Thai, Indic etc, and do the right thing. This is the fix I will implement Someone noted that it 'seemed to work' in JDk6 except for having to need to move over apparently two chars. Well the reason for this is that some fonts assign a negative image origin which shifts the diacritical to the left so that even non-layout aware code 'looks' OK. This is the case seen where it looks OK in Swing but you need to move the caret twice to mover past the character. It turns out that writing a dependable test to validate the fix for this is tricky. First, as noted many fonts already 'look' OK. Second, for this to work 'properly' there needs to be the right info in the GSUB table of the font. Some fonts don't do this. These fonts will not be fixed by this case (sorry) but they are few, and old. So its difficult to verify visually. Also programmatically, the composed glyph can legitimately have a different advance than the decomposed base glyph, so that's out too. The likelihood of spurious failures is high.
14-10-2006

EVALUATION Is this still reproducible in Merlin 1.4? ---- Yes, the bug still exists in merlin. bill.strathearn@Eng 2001-05-29 bill.strathearn@Eng 2001-06-11
29-05-2001