JDK-8055867 : Some characters not printed correctly in HTML text
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7,8,9
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-06-28
  • Updated: 2016-09-05
  • Resolved: 2016-09-05
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.
Other
tbd_majorResolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
When printing HTML text via an editor pane, a "left double quotation mark" character is sometimes printed as a "o grave accent".

Spacing around the character is sometimes also incorrect.

REGRESSION.  Last worked in version 6u31

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start the test program. Click on Print.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The double left quotation mark is printed as a quotation mark and spacing around the character is respected.
ACTUAL -
The quotation marks are sometimes printed as accentuated o characters.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Case65093 {
	
	static String htmlText = "<html>"
			+ "<h3><span style=\" text-decoration: underline;\">&#8220;</span></h3>"
			+ "<h3><u>&#8220;</u></h3>"
			+ "<h3><u>&#8220;ITEM</u></h3>"
			+ "<h3><u>&#8220;ITEM&#8221;</u></h3>"
			+ "<h3><u>COL &#8220;ITEM&#8221;</u></h3>"
			+ "<h3><u>COLU &#8220;ITEM&#8221;</u></h3>"
			+ "<h3><u>COLUM &#8220;ITEM&#8221;</u></h3>"
			+ "<p><span style=\" text-decoration: underline;\">&#8220;</span></p>"
			+ "<p><u>&#8220;</u></p>"
			+ "<p><u>&#8220;ITEM</u></p>"
			+ "<p><u>&#8220;ITEM&#8221;</u></p>"
			+ "<p><u>COL &#8220;ITEM&#8221;</u></p>"
			+ "<p><u>COLU &#8220;ITEM&#8221;</u></p>"
			+ "<p><u>COLUM &#8220;ITEM&#8221;</u></p>"
			;
	
	private static void createAndShowGUI() {
        JFrame f = new JFrame("Swing Paint Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(250,250);
        
        JButton printButton = new JButton("Print");
        printButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				print();
			}
		});
        f.setContentPane(printButton);
        
        f.setVisible(true);
    }
	
	private static void print() {
		PrinterJob printerJob = PrinterJob.getPrinterJob();
		printerJob.setPrintable(new Printable() {

			@Override
			public int print(Graphics graphics, PageFormat pageFormat,
					int pageIndex) throws PrinterException {

				graphics.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());
				graphics.drawLine(0, 0, (int)pageFormat.getWidth(), (int)pageFormat.getHeight());

				JEditorPane editorPane = new JEditorPane("text/html", htmlText);
				editorPane.setSize((int)pageFormat.getImageableWidth(), (int)pageFormat.getImageableHeight());
				
				editorPane.print(graphics);
				
				return pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE;
			}
			
		});
		try {
			printerJob.print();
		} catch (PrinterException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
            @Override
			public void run() {
                createAndShowGUI();
            }
        });
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use Java 6 instead of Java 7.

Comments
I tried to find in which release the problem of incorrect glyph was fixed but while trying to test promoted bundle 9b40,9b30,9b20,9b10 and even 9b01 I found in none of those bundle, I can see the incorrect glyph and the spacing also seem to be correct (though not exactly same as screen). Same observation with b80 till b95. Another interesting thing is the spacing problem is seen to be more acute from 9b96 till b134. If I run b96 with -Dsun.font.layoutengine=icu, then the spacing becomes same as pre-96 builds, ie space between L and " is more for COL "ITEM" I think I reproduce the problem in my jdk9build last year which I was building with VS2013 servicepack4 and now I have VS2013 (no servicepack) same as official compiler as my laptop got formatted and then I could not find VS2013SP4. I tried 8b132 where also I could not see the incorrect glyph and the spacing is same as seen in 9bundle. I could only reproduce with 1.7.0_05b01 where incorrect glyph is seen and spacing in some lines are all over the place.
01-09-2016

I don't know how/why the incorrect glyph was fixed (and I always prefer we can point to the reason rather than just accepting it). The remaining issue seems to me to be a duplicate of https://bugs.openjdk.java.net/browse/JDK-6784965 This is basically a not-perfect implementation of TextLayout.getJustifiedLayout() which is called by Swing.
31-08-2016

Phil is supposed to look at this windows font issue.
31-08-2016

ExtendedTextSourceLabel.java#applyJustificationDeltas() updates the positions with incorrect info. SwingUtilities2.drawChars() calls getJustifiedLayout() which calls getJustifiedLine() and TextLine.getJustifiedLine() calls float justifyAdvance = getAdvanceBetween(newComponents, justStart, justLimit); // get the actual justification delta justifyDelta = (justificationWidth - justifyAdvance) * justifyRatio; where justificationWidth is 82 and justifyAdvance is 85.56 and justifyRatio is 1. so justifyDelta is -3.56 Now, ExtendedTextSourceLabel.applyJustificationDeltas() does check for whitespace and compute position delta differently than non-whitespace if (Character.isWhitespace(chars[offset + v2l(i)])) { newPositions[i*2] += deltaPos; float deltaAdv = deltas[deltaStart + i*2] + deltas[deltaStart + i*2 + 1]; newCharinfo[i * numvals + posx] += deltaPos; newCharinfo[i * numvals + visx] += deltaPos; newCharinfo[i * numvals + advx] += deltaAdv; deltaPos += deltaAdv; } else { deltaPos += deltas[deltaStart + i*2]; newPositions[i*2] += deltaPos; newCharinfo[i * numvals + posx] += deltaPos; newCharinfo[i * numvals + visx] += deltaPos; deltaPos += deltas[deltaStart + i*2 + 1]; }
31-08-2016

In latest jdk9, we are getting COL"ITEM" printed out instead of COL "ITEM" as seen on console ie, space is ignored while printing [ no morphing to accented 'o' characters is seen] What I found is in call to PathGraphics.printedSimpleGlyphVector() we call float[] positions = g.getGlyphPositions(0, numGlyphs, null); and this returns incorrect positions for '"' glyph. Basically, when we go to for (int i=0; i<numGlyphs; i++) { String s = new String(chars, i, 1); drawString(s, x+positions[i*2], y+positions[i*2+1], font, gvFrc, 0f); } we have for COL "ITEM" string "C", x = 3, pos=0, y = 28.0, pos=0 "O", x= 3, pos=10.19, y = 28.0, pos=0 "L", x= 3, pos=21.11, y = 28.0, pos=0 <sp>, x= 3, pos=29.7, y = 28.0, pos=0 """, x=3, pos=29.62, y = 28.0 pos=0 "I", x=3, pos=36.7, y = 28.0, pos=0 "T", x=3, pos=42.22, y=28.0, pos=0 so we can see for quotation char after <sp> character, the position is 29.62 less than position for <sp> which is 29.7 so during printing, <sp> is ignored.
31-08-2016

It seems the following code snippet in PathGraphics.java#printedSimpleGlyphVector if (numGlyphs > 10 && printGlyphVector(g, x, y)) { return true; } which has been added for performance in jdk7 causes this character/glyphs to be printed through printGlyphVector() since COLU "ITEM" numGlyphs is > 10 which is causing the issue. For this unicode character " ", windows printer should use Lucida font when we register via Win32FontManager.registerJREFontsForPrinting() which uses AddFontResourceEx to request windows to use our font but it seems windows is not using our font despite being requested to (although it does not return failure) and use its own font resulting in this problem.
18-08-2015

this is not a regression from 9 pov
27-08-2014

Compile and run JDK8055867.java to reproduce. Click Print button to print HTML on the default printer.
25-08-2014

The issue is not reproduced on 6u81: the quotes are displayed as expected, at the same time, the space disappears from the sixth line.
25-08-2014

The sixth line of text is displayed correctly on the screen: COLU ���ITEM��� But when printed, it looks this way: COLU��ITEM�� That is the space disappeared, and the double quotes morphed into accented 'o' characters. &#8220; is U+201C "Left Double Quotation Mark" character, and &#8221; is, correspondingly, U+201D "Right Double Quotation Mark".
25-08-2014