-
Bug
-
Resolution: Unresolved
-
P4
-
11
-
generic
-
windows
ADDITIONAL SYSTEM INFORMATION :
Windows 11, Windows 10, Java 11
A DESCRIPTION OF THE PROBLEM :
While trying to use javax printing with a print attribute set to a print tray when two print trays contain the same media size(legal) the print is respecting the media tray and ignoring the media size and mediaprintablearea. Attempting to print a legal-size image comes out resized or cutoff to a letter size image. This only seems to happen when two trays are set to legal on the printer and legal printing seems to work correctly when one tray is legal.
While the IPP spec states that either mediasizename or mediatray are to be specified - it also feels as if the mediasize is supposed to be inferred and the resizing to a different mediasize is incorrect.
This feels like a regression from previous versions of the javax printing api where one could specify both tray and media size through the use of the SunAlternateMedia while not requiring an additional popup.
It also seems as if the ServiceUI.printDialog prompt is still using the SunAlternateMedia mapping in order for this to work correctly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In order to reproduce the following pseudocode will print with a border at the wrong size when a printer has two trays mapped to a legal-size paper.
Printers used:
HP LaserJet Pro M402
Canon imageRunner Advance DX C3930i
I have tried multiple drivers - Microsoft IPP, Microsoft PCL6, HP PCL 6, Canon UFR II, that are all up to date.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the above to print a black border on a legal sized piece of paper from the selected tray and printer name.
ACTUAL -
it prints in a letter sized border.
---------- BEGIN SOURCE ----------
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class Main {
public static PrintService getPrintServiceByName(String name) {
if (name == null) {
return PrintServiceLookup.lookupDefaultPrintService();
}
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService service : services) {
if (service.getName().equals(name)) {
return service;
}
}
for (PrintService service : services) {
if (service.getName().equalsIgnoreCase(name)) {
return service;
}
}
return null;
}
private static MediaTray getMediaTrayByName(PrintService service, String name) {
try {
Object vals = service.getSupportedAttributeValues(Media.class, null, null);
if (vals instanceof Object[]) {
Object[] trays = (Object[]) vals;
for (Object tray : trays) {
if (tray instanceof MediaTray && name.equals(tray.toString())) {
return (MediaTray) tray;
}
}
}
} catch (ArrayIndexOutOfBoundsException e) {
}
return null;
}
public static void main(String[] args) {
String printerName = "Canon Generic Plus UFR II";
String paperTray = "Drawer 4";
PrintService printService = getPrintServiceByName(printerName);
DocPrintJob job = printService.createPrintJob();
PrintRequestAttributeSet attrSet = new HashPrintRequestAttributeSet();
DocFlavor flavor = DocFlavor.BYTE_ARRAY.PNG;
attrSet.add(MediaSizeName.NA_LEGAL);
MediaPrintableArea[] printableAreas =
(MediaPrintableArea[]) printService.getSupportedAttributeValues(MediaPrintableArea.class, flavor, attrSet);
attrSet.add(getMediaTrayByName(printService, paperTray));
int width = (int) (72 * printableAreas[0].getWidth(MediaPrintableArea.INCH));
int height = (int) (72 * printableAreas[0].getHeight(MediaPrintableArea.INCH));
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // Assuming 72 DPI
Graphics2D g2 = image.createGraphics();
g2.setColor(Color.WHITE);
g2.fill(new Rectangle2D.Float(0, 0, image.getWidth(), image.getHeight()));
g2.setColor(Color.BLACK);
g2.drawRect(0, 0, image.getWidth() - 1, image.getHeight() - 1); // Draw border
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(image, "PNG", baos);
byte[] imageData = baos.toByteArray();
Doc doc = new SimpleDoc(imageData, flavor, null);
job.print(doc, attrSet);
} catch (PrintException | IOException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
ServiceUI.printDialog, though the popup renders this ineffective for my use case.
There also are multiple threads on stackoverflow mentioning intercepting the print job and modifying it with a script, though I have not used this method.
FREQUENCY : always
Windows 11, Windows 10, Java 11
A DESCRIPTION OF THE PROBLEM :
While trying to use javax printing with a print attribute set to a print tray when two print trays contain the same media size(legal) the print is respecting the media tray and ignoring the media size and mediaprintablearea. Attempting to print a legal-size image comes out resized or cutoff to a letter size image. This only seems to happen when two trays are set to legal on the printer and legal printing seems to work correctly when one tray is legal.
While the IPP spec states that either mediasizename or mediatray are to be specified - it also feels as if the mediasize is supposed to be inferred and the resizing to a different mediasize is incorrect.
This feels like a regression from previous versions of the javax printing api where one could specify both tray and media size through the use of the SunAlternateMedia while not requiring an additional popup.
It also seems as if the ServiceUI.printDialog prompt is still using the SunAlternateMedia mapping in order for this to work correctly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In order to reproduce the following pseudocode will print with a border at the wrong size when a printer has two trays mapped to a legal-size paper.
Printers used:
HP LaserJet Pro M402
Canon imageRunner Advance DX C3930i
I have tried multiple drivers - Microsoft IPP, Microsoft PCL6, HP PCL 6, Canon UFR II, that are all up to date.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the above to print a black border on a legal sized piece of paper from the selected tray and printer name.
ACTUAL -
it prints in a letter sized border.
---------- BEGIN SOURCE ----------
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class Main {
public static PrintService getPrintServiceByName(String name) {
if (name == null) {
return PrintServiceLookup.lookupDefaultPrintService();
}
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService service : services) {
if (service.getName().equals(name)) {
return service;
}
}
for (PrintService service : services) {
if (service.getName().equalsIgnoreCase(name)) {
return service;
}
}
return null;
}
private static MediaTray getMediaTrayByName(PrintService service, String name) {
try {
Object vals = service.getSupportedAttributeValues(Media.class, null, null);
if (vals instanceof Object[]) {
Object[] trays = (Object[]) vals;
for (Object tray : trays) {
if (tray instanceof MediaTray && name.equals(tray.toString())) {
return (MediaTray) tray;
}
}
}
} catch (ArrayIndexOutOfBoundsException e) {
}
return null;
}
public static void main(String[] args) {
String printerName = "Canon Generic Plus UFR II";
String paperTray = "Drawer 4";
PrintService printService = getPrintServiceByName(printerName);
DocPrintJob job = printService.createPrintJob();
PrintRequestAttributeSet attrSet = new HashPrintRequestAttributeSet();
DocFlavor flavor = DocFlavor.BYTE_ARRAY.PNG;
attrSet.add(MediaSizeName.NA_LEGAL);
MediaPrintableArea[] printableAreas =
(MediaPrintableArea[]) printService.getSupportedAttributeValues(MediaPrintableArea.class, flavor, attrSet);
attrSet.add(getMediaTrayByName(printService, paperTray));
int width = (int) (72 * printableAreas[0].getWidth(MediaPrintableArea.INCH));
int height = (int) (72 * printableAreas[0].getHeight(MediaPrintableArea.INCH));
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // Assuming 72 DPI
Graphics2D g2 = image.createGraphics();
g2.setColor(Color.WHITE);
g2.fill(new Rectangle2D.Float(0, 0, image.getWidth(), image.getHeight()));
g2.setColor(Color.BLACK);
g2.drawRect(0, 0, image.getWidth() - 1, image.getHeight() - 1); // Draw border
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(image, "PNG", baos);
byte[] imageData = baos.toByteArray();
Doc doc = new SimpleDoc(imageData, flavor, null);
job.print(doc, attrSet);
} catch (PrintException | IOException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
ServiceUI.printDialog, though the popup renders this ineffective for my use case.
There also are multiple threads on stackoverflow mentioning intercepting the print job and modifying it with a script, though I have not used this method.
FREQUENCY : always