Details
-
Bug
-
Status: Open
-
Minor
-
Resolution: Unresolved
-
1.4, 2.6
-
None
-
None
Description
The PSGraphics2D object incorrectly decides that any non-closed Shape does not need to be clipped when drawn, and so does not write out the clip region from the Graphics2D to the postscript file. This means that any java component that relies on the clipping when drawing lines is not correctly clipped. A good example is a JTable within a JScollPane: the gridlines of the table are drawn for every partly-visible cell, resulting in lines that extend across the scroll bars and beyond.
The following java class produces a test.ps file which exhibits this problem:
//--------------------------------------------------------------------------------------
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.ps.PSDocumentGraphics2D;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class PSClipBug {
public static void main(String[] args) throws FileNotFoundException,IOException{
// Simple 10x10 table example taken from the JTable javadoc
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount()
public int getRowCount()
{ return 10;}public Object getValueAt(int row, int col)
{ return new Integer(row*col); } };
JTable table = new JTable(dataModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scrollpane = new JScrollPane(table);
// Display the JTable so you can see what is being printed
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollpane);
frame.setSize(200, 200);
frame.setVisible(true);
//Open a file stream
FileOutputStream stream = new FileOutputStream("test.ps");
// Create and configure a PSDocumentGraphics2D
PSDocumentGraphics2D doc = new PSDocumentGraphics2D(false);
doc.setupDocument(stream, 576, 792);
GraphicContext gContext = new GraphicContext();
doc.setGraphicContext(gContext);
// Print the scrollpane
scrollpane.print(doc);
// Complete and close the document
doc.finish();
stream.close();
}
}
//--------------------------------------------------------------------------------------
The cause of the bug appears to be the reliance on Area objects in PSGraphics2D.shouldBeClipped(). Non-closed Shapes always produce an empty area, so their intersection with the clip Area is always also always empty.
As a workaround, I have overridden the shouldBeClipped() method and for shapes with an empty area but a non-zero width or height I check for the whether the bounds are completely within the clip and in all other cases return true. This may end up requesting clipping for some cases that do not need it but I think they will be rare in practice and the false positive does not produce incorrect visual artifacts.