diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index b82094d5b7d..4dba1d221e3 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -36,6 +36,10 @@ import java.security.PrivilegedAction; import javax.print.*; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaSizeName; import javax.print.attribute.standard.PageRanges; import sun.java2d.*; @@ -745,4 +749,34 @@ public final class CPrinterJob extends RasterPrinterJob { protected void startPage(PageFormat arg0, Printable arg1, int arg2, boolean arg3) throws PrinterException { // TODO Auto-generated method stub } -} + + @Override + protected MediaSize getMediaSize(Media media, PrintService service, + PageFormat page) { + if (media == null || !(media instanceof MediaSizeName)) { + return getDefaultMediaSize(page); + } + MediaSize size = MediaSize.getMediaSizeForName((MediaSizeName) media); + return size != null ? size : getDefaultMediaSize(page); + } + + private MediaSize getDefaultMediaSize(PageFormat page){ + final int inch = 72; + Paper paper = page.getPaper(); + float width = (float) (paper.getWidth() / inch); + float height = (float) (paper.getHeight() / inch); + return new MediaSize(width, height, MediaSize.INCH); + } + + @Override + protected MediaPrintableArea getDefaultPrintableArea(PageFormat page, double w, double h) { + final float dpi = 72.0f; + Paper paper = page.getPaper(); + return new MediaPrintableArea( + (float) (paper.getImageableX() / dpi), + (float) (paper.getImageableY() / dpi), + (float) (paper.getImageableWidth() / dpi), + (float) (paper.getImageableHeight() / dpi), + MediaPrintableArea.INCH); + } +} \ No newline at end of file diff --git a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index 03efe2dcead..906058f8a81 100644 --- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -559,18 +559,8 @@ public abstract class RasterPrinterJob extends PrinterJob { } Media media = (Media)attSet.get(Media.class); - if (media == null) { - media = - (Media)service.getDefaultAttributeValue(Media.class); - } - if (!(media instanceof MediaSizeName)) { - media = MediaSizeName.NA_LETTER; - } - MediaSize size = - MediaSize.getMediaSizeForName((MediaSizeName)media); - if (size == null) { - size = MediaSize.NA.LETTER; - } + MediaSize size = getMediaSize(media, service, page); + Paper paper = new Paper(); float dim[] = size.getSize(1); //units == 1 to avoid FP error double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH); @@ -579,40 +569,58 @@ public abstract class RasterPrinterJob extends PrinterJob { MediaPrintableArea area = (MediaPrintableArea) attSet.get(MediaPrintableArea.class); - double ix, iw, iy, ih; + if (area == null) { + area = getDefaultPrintableArea(page, w, h); + } - if (area != null) { - // Should pass in same unit as updatePageAttributes - // to avoid rounding off errors. - ix = Math.rint( - area.getX(MediaPrintableArea.INCH) * DPI); - iy = Math.rint( - area.getY(MediaPrintableArea.INCH) * DPI); - iw = Math.rint( - area.getWidth(MediaPrintableArea.INCH) * DPI); - ih = Math.rint( - area.getHeight(MediaPrintableArea.INCH) * DPI); - } - else { - if (w >= 72.0 * 6.0) { - ix = 72.0; - iw = w - 2 * 72.0; - } else { - ix = w / 6.0; - iw = w * 0.75; - } - if (h >= 72.0 * 6.0) { - iy = 72.0; - ih = h - 2 * 72.0; - } else { - iy = h / 6.0; - ih = h * 0.75; - } - } + double ix, iw, iy, ih; + // Should pass in same unit as updatePageAttributes + // to avoid rounding off errors. + ix = Math.rint( + area.getX(MediaPrintableArea.INCH) * DPI); + iy = Math.rint( + area.getY(MediaPrintableArea.INCH) * DPI); + iw = Math.rint( + area.getWidth(MediaPrintableArea.INCH) * DPI); + ih = Math.rint( + area.getHeight(MediaPrintableArea.INCH) * DPI); paper.setImageableArea(ix, iy, iw, ih); page.setPaper(paper); return page; } + protected MediaSize getMediaSize(Media media, PrintService service, + PageFormat page) { + if (media == null) { + media = (Media)service.getDefaultAttributeValue(Media.class); + } + if (!(media instanceof MediaSizeName)) { + media = MediaSizeName.NA_LETTER; + } + MediaSize size = MediaSize.getMediaSizeForName((MediaSizeName) media); + return size != null ? size : MediaSize.NA.LETTER; + } + + protected MediaPrintableArea getDefaultPrintableArea(PageFormat page, + double w, double h) { + double ix, iw, iy, ih; + if (w >= 72.0 * 6.0) { + ix = 72.0; + iw = w - 2 * 72.0; + } else { + ix = w / 6.0; + iw = w * 0.75; + } + if (h >= 72.0 * 6.0) { + iy = 72.0; + ih = h - 2 * 72.0; + } else { + iy = h / 6.0; + ih = h * 0.75; + } + + return new MediaPrintableArea((float) (ix / DPI), (float) (iy / DPI), + (float) (iw / DPI), (float) (ih / DPI), MediaPrintableArea.INCH); + } protected void updatePageAttributes(PrintService service, PageFormat page) { @@ -809,7 +817,7 @@ public abstract class RasterPrinterJob extends PrinterJob { } protected PageFormat getPageFormatFromAttributes() { - if (attributes == null) { + if (attributes == null || attributes.isEmpty()) { return null; } return attributeToPageFormat(getPrintService(), this.attributes); diff --git a/jdk/test/java/awt/print/PageFormat/ImageableAreaTest.java b/jdk/test/java/awt/print/PageFormat/ImageableAreaTest.java new file mode 100644 index 00000000000..f9e7b4bbea8 --- /dev/null +++ b/jdk/test/java/awt/print/PageFormat/ImageableAreaTest.java @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.text.MessageFormat; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.DialogTypeSelection; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; + +/** + * @test + * @bug 8044444 + * @summary The output's 'Page-n' footer does not show completely + * @author Alexandr Scherbatiy + * @run main/manual ImageableAreaTest + */ +public class ImageableAreaTest { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + + createAndShowTestDialog( + "1. Press the Print Table button\n" + + " Java print dialog should appear.\n" + + "2. Press the Print button on the Java Print dialog.\n" + + "2. Check that the page number is correctly printed.\n" + + "If so, press PASS, else press FAIL.", + "Page number is not correctly printed!", + ImageableAreaTest::printWithJavaPrintDialog); + + createAndShowTestDialog( + "1. Press the Print Table button\n" + + " The table should be printed without the print dialog.\n" + + "2. Check that the page number is correctly printed.\n" + + "If so, press PASS, else press FAIL.", + "Page number is not correctly printed!", + ImageableAreaTest::printWithoutPrintDialog); + + createAndShowTestDialog( + "1. Press the Print Table button\n" + + " Java print dialog should appear.\n" + + "2. Press the Print button on the Java Print dialog.\n" + + "3. Check that the table has about half size of the printed page\n" + + "If so, press PASS, else press FAIL.", + "Custom imageable area is not correctly printed!", + ImageableAreaTest::printWithCustomImageareaSize); + } + }); + } + + private static void printWithJavaPrintDialog() { + final JTable table = createAuthorTable(42); + Printable printable = table.getPrintable( + JTable.PrintMode.NORMAL, + new MessageFormat("Author Table"), + new MessageFormat("Page - {0}")); + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(printable); + + boolean printAccepted = job.printDialog(); + if (printAccepted) { + try { + job.print(); + closeFrame(); + } catch (PrinterException e) { + throw new RuntimeException(e); + } + } + } + + private static void printWithoutPrintDialog() { + + final JTable table = createAuthorTable(42); + PrintRequestAttributeSet pras + = new HashPrintRequestAttributeSet(); + pras.add(new Copies(1)); + + try { + + boolean printAccepted = table.print(JTable.PrintMode.FIT_WIDTH, + new MessageFormat("Author Table"), + new MessageFormat("Page - {0}"), + false, pras, false); + + closeFrame(); + if (!printAccepted) { + throw new RuntimeException("User cancels the printer job!"); + } + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void printWithCustomImageareaSize() { + final JTable table = createAuthorTable(18); + PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet(); + printAttributes.add(DialogTypeSelection.NATIVE); + printAttributes.add(new Copies(1)); + printAttributes.add(new MediaPrintableArea( + 0.25f, 0.25f, 8.0f, 5.0f, MediaPrintableArea.INCH)); + Printable printable = table.getPrintable( + JTable.PrintMode.NORMAL, + new MessageFormat("Author Table"), + new MessageFormat("Page - {0}") + ); + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(printable); + + boolean printAccepted = job.printDialog(printAttributes); + if (printAccepted) { + try { + job.print(printAttributes); + closeFrame(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + throw new RuntimeException("User cancels the printer job!"); + } + } + + private static JFrame frame; + + private static void closeFrame() { + if (frame != null) { + frame.setVisible(false); + frame.dispose(); + } + } + + private static JTable createAuthorTable(int rows) { + final String[] headers = {"Book", "Title"}; + + final Object[][] data = new Object[rows][2]; + for (int i = 0; i < rows; i++) { + int n = i + 1; + data[i] = new Object[]{"Book: " + n, "Title: " + n}; + } + + TableModel dataModel = new AbstractTableModel() { + + public int getColumnCount() { + return headers.length; + } + + public int getRowCount() { + return data.length; + } + + public Object getValueAt(int row, int col) { + return data[row][col]; + } + + public String getColumnName(int column) { + return headers[column]; + } + + public Class getColumnClass(int col) { + return getValueAt(0, col).getClass(); + } + + public void setValueAt(Object aValue, int row, int column) { + data[row][column] = aValue; + } + + public boolean isCellEditable(int row, int col) { + return false; + } + }; + + JTable table = new JTable(dataModel); + table.setGridColor(Color.BLUE); + table.setBackground(Color.WHITE); + table.setForeground(Color.BLACK); + table.setSize(600, 800); + + frame = new JFrame(); + frame.setSize(400, 600); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(table); + frame.setVisible(true); + return table; + } + + private static int testCount; + + private static void createAndShowTestDialog(String description, + String failMessage, Runnable action) { + final JDialog dialog = new JDialog(); + dialog.setTitle("Test: " + (++testCount)); + dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Print Table"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + throw new RuntimeException(failMessage); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + } +}