JDK-6452415 : Swing text components using a physical font print text as filled shapes (bigger spool files).
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0u7,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000,windows_xp
  • CPU: x86
  • Submitted: 2006-07-25
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
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
6u4Fixed 7 b03Fixed
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.5.0_07

EXTRA RELEVANT SYSTEM CONFIGURATION :
HP Laser Jet 4000 PCL6

A DESCRIPTION OF THE PROBLEM :
Printer spool file created is much larger when running under 1.5.0_07 jre then what is created when running under 1.4.3_02 jre

Example: Original text file of 11,430 bytes (sample.txt) when printed:
1.4.2_03 file created is 74,367 bytes
1.5.0_07 file created is 1,578,860 bytes
21 Times larger.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have create a test program that reads in an ASCII text file
(sample.txt) and launches our applications print screen.
When the print button is clicked, I choose a typical printer (in my case
- HP Laser Jet 4000 PCL6) that I have configured to print to a file.

I created 2 bat files:

run-spooltest14.bat - runs the test program under 1.4.2_03 and creates
the 74,367 byte file.
run-spooltest15.bat - runs the test program under 1.5.0_07 and creates
the 1,578,860 byte file.


I have also created bat files to compile TextReportScreen.java which has
all the printer specific code.

compile-spooltest14.bat - compiles TextReportScreen.java under 1.4
compile-spooltest15.bat - compiles TextReportScreen.java under 1.5 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Generated same file size in 5.0_07
ACTUAL -
1.5.0_07 file created is 1,578,860 bytes
21 Times larger.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
1.5.0_07 file created is 1,578,860 bytes
21 Times larger.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Attached Seperatly
---------- END SOURCE ----------
That test case is too complex.
Here's a simpler one that's more to the point.
All that's needed is to print a Swing text component after setting a physical font
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.print.*;

public class PrintTextPane implements Printable, ActionListener {

    JTextPane pane;

    public int print(Graphics g, PageFormat pf, int page) throws
                                                        PrinterException {
        if (page > 0) {
            return NO_SUCH_PAGE;
        }
        Graphics2D g2d = (Graphics2D)g;
        System.out.println("BEFORE = " + g2d.getTransform());
        g2d.translate(pf.getImageableX(), pf.getImageableY());
        System.out.println("AFTER = " + g2d.getTransform());
        pane.printAll(g);
        return PAGE_EXISTS;
    }

    public void actionPerformed(ActionEvent e) {
/*
        try {
             pane.print();
         } catch (PrinterException ex) {
               throw new RuntimeException(ex);
         }
*/
         PrinterJob job = PrinterJob.getPrinterJob();
         job.setPrintable(this);
         boolean ok = job.printDialog();
         if (ok) {
             try {
                  job.print();
             } catch (PrinterException ex) {
                   throw new RuntimeException(ex);
             }
         }

    }

    public PrintTextPane(JTextPane f) {
        pane = f;
    }
   static String text = "Twinkle twinkle little star, \n" +
                        "How I wonder what you are.";

    public static void main(String args[]) {
        JFrame f = new JFrame("Print Text Pane");
        f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        JTextPane pane = new JTextPane();
        SimpleAttributeSet aset = new SimpleAttributeSet();
        StyleConstants.setFontFamily(aset, "Courier New");
        //StyleConstants.setFontFamily(aset, "Monospaced");
        pane.setCharacterAttributes(aset, false);
        pane.setText(text);
        f.add("Center", pane);
        JButton printButton = new JButton("Print TextPane");
        printButton.addActionListener(new PrintTextPane(pane));
        f.add("South", printButton);
        f.pack();
        f.setVisible(true);
    }
}

Comments
WORK AROUND Use a logical font instead of a physical font (Serif, Sans Serif, Monospaced, Dialog, DialogInput) *** (#1 of 1): [ UNSAVED ] ###@###.###
25-07-2006

EVALUATION This problem is specific to printing Swing text components on windows where the user specifies a physical font (eg Arial, Lucida Sans Regular) instead of letting Swing use one of the standard logical fonts (Serif, Sans Serif, Monospaced, Dialog, DialogInput) This behaviour was introduced in 5.0 by the swing fix for 5023890 : zh: Tooltip strings on Java ControlPanel are displayed as cubics The problem there was that tooltips were using swing text components but in a chinese (zh) locale they were not displaying chinese characters because Swing saw only the default "Microsoft Sans Serif" font. A fix was made in swing text code to use some internal API that added fallback fonts. The printing implementation has code to handle such fonts and passes on to GDI just the cases it can handle. This works fine for 'drawString()' and 'drawChars()' However in this case that code is bypassed as Swing is printing using a TextLayout constructed with the screen FontRenderContext in order to ensure that text is not clipped. That was a long standing problem and the fix is 4352983 : Clipping of text when printing. So what we have here is the combination of using TextLayout with a non-standard font. That TexLayout printing code path is not optimised to understand these special fonts. The fix is to add a simple piece of logic to this printing path to see if GDI can handle it. Its a few lines of extra code in WPathGraphics.java But in testing this it was noted that the new JDK 6 Swing text printing API also was printing as shapes in this case. This printing API is supposed to lay out for the printer, not the screen so should not need to use TextLayout and so should have avoided this path and taken the already optimised drawString path. However it was noted that in comparing FontRenderContext's they were spuriously considered to be different because of a different translation component in the transforms of the component and the printer graphics. Whilst the WPathGraphics.java fix will mostly resolve that, really this text code should directly use drawString instead as unnecessary work is being done because of this failed comparison. The fix is to update Swing's comparison of FontRenderContexts to ignore translations. This raises an interesting question as to whether FontRenderContext.equals() should do this too, and also whether Graphics2D.getFontRenderContext() should return a FontRenderContext which has a translation at all. The latter probably wouldn't help if a FRC was constructed by calling Graphics2D.getTransform() as that must always include the translate. But this issue is beyond the scope of this bug report which should address just the specific case at hand.
25-07-2006