8048328: CUPS Printing does not report supported printer resolutions
Reviewed-by: bae, jgodinez
This commit is contained in:
parent
93f94161b3
commit
d7f59acb44
jdk
make/mapfiles
src
share/classes/sun/print
solaris
test/javax/print/attribute
@ -204,6 +204,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_print_CUPSPrinter_canConnect;
|
||||
Java_sun_print_CUPSPrinter_getMedia;
|
||||
Java_sun_print_CUPSPrinter_getPageSizes;
|
||||
Java_sun_print_CUPSPrinter_getResolutions;
|
||||
|
||||
Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow;
|
||||
Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box;
|
||||
|
@ -76,6 +76,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_print_CUPSPrinter_canConnect;
|
||||
Java_sun_print_CUPSPrinter_getMedia;
|
||||
Java_sun_print_CUPSPrinter_getPageSizes;
|
||||
Java_sun_print_CUPSPrinter_getResolutions;
|
||||
|
||||
# libfontmanager entry points
|
||||
AWTIsHeadless;
|
||||
|
@ -442,6 +442,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_print_CUPSPrinter_canConnect;
|
||||
Java_sun_print_CUPSPrinter_getMedia;
|
||||
Java_sun_print_CUPSPrinter_getPageSizes;
|
||||
Java_sun_print_CUPSPrinter_getResolutions;
|
||||
|
||||
awt_GetDrawingSurface;
|
||||
awt_FreeDrawingSurface;
|
||||
|
@ -168,13 +168,6 @@ public class PSPrinterJob extends RasterPrinterJob {
|
||||
private static final String IMAGE_STR = " string /imStr exch def";
|
||||
private static final String IMAGE_RESTORE = "imSave restore";
|
||||
|
||||
private static final String COORD_PREP = " 0 exch translate "
|
||||
+ "1 -1 scale"
|
||||
+ "[72 " + PS_XRES + " div "
|
||||
+ "0 0 "
|
||||
+ "72 " + PS_YRES + " div "
|
||||
+ "0 0]concat";
|
||||
|
||||
private static final String SetFontName = "F";
|
||||
|
||||
private static final String DrawStringName = "S";
|
||||
@ -275,6 +268,9 @@ public class PSPrinterJob extends RasterPrinterJob {
|
||||
|
||||
private AffineTransform mLastTransform;
|
||||
|
||||
private double xres = PS_XRES;
|
||||
private double yres = PS_XRES;
|
||||
|
||||
/* non-null if printing EPS for Java Plugin */
|
||||
private EPSPrinter epsPrinter = null;
|
||||
|
||||
@ -796,6 +792,15 @@ public class PSPrinterJob extends RasterPrinterJob {
|
||||
}
|
||||
}
|
||||
|
||||
private String getCoordPrep() {
|
||||
return " 0 exch translate "
|
||||
+ "1 -1 scale"
|
||||
+ "[72 " + getXRes() + " div "
|
||||
+ "0 0 "
|
||||
+ "72 " + getYRes() + " div "
|
||||
+ "0 0]concat";
|
||||
}
|
||||
|
||||
/**
|
||||
* The RasterPrintJob super class calls this method
|
||||
* at the start of each page.
|
||||
@ -852,7 +857,7 @@ public class PSPrinterJob extends RasterPrinterJob {
|
||||
mPSStream.println(" >> setpagedevice");
|
||||
}
|
||||
mPSStream.println(PAGE_SAVE);
|
||||
mPSStream.println(paperHeight + COORD_PREP);
|
||||
mPSStream.println(paperHeight + getCoordPrep());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1493,14 +1498,22 @@ public class PSPrinterJob extends RasterPrinterJob {
|
||||
* to be rendered.
|
||||
*/
|
||||
protected double getXRes() {
|
||||
return PS_XRES;
|
||||
return xres;
|
||||
}
|
||||
/**
|
||||
* Return the y resolution of the coordinates
|
||||
* to be rendered.
|
||||
*/
|
||||
protected double getYRes() {
|
||||
return PS_YRES;
|
||||
return yres;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resolution at which to print.
|
||||
*/
|
||||
protected void setXYRes(double x, double y) {
|
||||
xres = x;
|
||||
yres = y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,6 +72,7 @@ import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.AttributeSet;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.ResolutionSyntax;
|
||||
import javax.print.attribute.Size2DSyntax;
|
||||
import javax.print.attribute.standard.Chromaticity;
|
||||
import javax.print.attribute.standard.Copies;
|
||||
@ -86,6 +87,7 @@ import javax.print.attribute.standard.MediaSize;
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
import javax.print.attribute.standard.OrientationRequested;
|
||||
import javax.print.attribute.standard.PageRanges;
|
||||
import javax.print.attribute.standard.PrinterResolution;
|
||||
import javax.print.attribute.standard.PrinterState;
|
||||
import javax.print.attribute.standard.PrinterStateReason;
|
||||
import javax.print.attribute.standard.PrinterStateReasons;
|
||||
@ -283,6 +285,7 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
private String jobNameAttr;
|
||||
private String userNameAttr;
|
||||
private PageRanges pageRangesAttr;
|
||||
protected PrinterResolution printerResAttr;
|
||||
protected Sides sidesAttr;
|
||||
protected String destinationAttr;
|
||||
protected boolean noJobSheet = false;
|
||||
@ -1064,6 +1067,14 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
attrset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the device resolution.
|
||||
* Overridden and used only by the postscript code.
|
||||
* Windows code pulls the information from the attribute set itself.
|
||||
*/
|
||||
protected void setXYRes(double x, double y) {
|
||||
}
|
||||
|
||||
/* subclasses may need to pull extra information out of the attribute set
|
||||
* They can override this method & call super.setAttributes()
|
||||
*/
|
||||
@ -1072,6 +1083,7 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
/* reset all values to defaults */
|
||||
setCollated(false);
|
||||
sidesAttr = null;
|
||||
printerResAttr = null;
|
||||
pageRangesAttr = null;
|
||||
copiesAttr = 0;
|
||||
jobNameAttr = null;
|
||||
@ -1117,6 +1129,18 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
sidesAttr = Sides.ONE_SIDED;
|
||||
}
|
||||
|
||||
printerResAttr = (PrinterResolution)attributes.get(PrinterResolution.class);
|
||||
if (service.isAttributeCategorySupported(PrinterResolution.class)) {
|
||||
if (!isSupportedValue(printerResAttr, attributes)) {
|
||||
printerResAttr = (PrinterResolution)
|
||||
service.getDefaultAttributeValue(PrinterResolution.class);
|
||||
}
|
||||
double xr =
|
||||
printerResAttr.getCrossFeedResolution(ResolutionSyntax.DPI);
|
||||
double yr = printerResAttr.getFeedResolution(ResolutionSyntax.DPI);
|
||||
setXYRes(xr, yr);
|
||||
}
|
||||
|
||||
pageRangesAttr = (PageRanges)attributes.get(PageRanges.class);
|
||||
if (!isSupportedValue(pageRangesAttr, attributes)) {
|
||||
pageRangesAttr = null;
|
||||
|
@ -39,6 +39,7 @@ import javax.print.attribute.standard.MediaSizeName;
|
||||
import javax.print.attribute.standard.MediaSize;
|
||||
import javax.print.attribute.standard.MediaTray;
|
||||
import javax.print.attribute.standard.MediaPrintableArea;
|
||||
import javax.print.attribute.standard.PrinterResolution;
|
||||
import javax.print.attribute.Size2DSyntax;
|
||||
import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.EnumSyntax;
|
||||
@ -57,6 +58,8 @@ public class CUPSPrinter {
|
||||
// CUPS does not support multi-threading.
|
||||
private static synchronized native String[] getMedia(String printer);
|
||||
private static synchronized native float[] getPageSizes(String printer);
|
||||
private static synchronized native void
|
||||
getResolutions(String printer, ArrayList<Integer> resolutionList);
|
||||
//public static boolean useIPPMedia = false; will be used later
|
||||
|
||||
private MediaPrintableArea[] cupsMediaPrintables;
|
||||
@ -68,6 +71,7 @@ public class CUPSPrinter {
|
||||
public int nTrays = 0;
|
||||
private String[] media;
|
||||
private float[] pageSizes;
|
||||
int[] resolutionsArray;
|
||||
private String printer;
|
||||
|
||||
private static boolean libFound;
|
||||
@ -119,6 +123,12 @@ public class CUPSPrinter {
|
||||
nTrays = media.length/2-nPageSizes;
|
||||
assert (nTrays >= 0);
|
||||
}
|
||||
ArrayList<Integer> resolutionList = new ArrayList<>();
|
||||
getResolutions(printer, resolutionList);
|
||||
resolutionsArray = new int[resolutionList.size()];
|
||||
for (int i=0; i < resolutionList.size(); i++) {
|
||||
resolutionsArray[i] = resolutionList.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +170,12 @@ public class CUPSPrinter {
|
||||
return cupsMediaTrays;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the raw packed array of supported printer resolutions.
|
||||
*/
|
||||
int[] getRawResolutions() {
|
||||
return resolutionsArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize media by translating PPD info to PrintService attributes.
|
||||
|
@ -96,6 +96,8 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
private MediaSizeName[] mediaSizeNames;
|
||||
private CustomMediaSizeName[] customMediaSizeNames;
|
||||
private int defaultMediaIndex;
|
||||
private int[] rawResolutions = null;
|
||||
private PrinterResolution[] printerResolutions = null;
|
||||
private boolean isCupsPrinter;
|
||||
private boolean init;
|
||||
private Boolean isPS;
|
||||
@ -414,6 +416,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
mediaTrays = cps.getMediaTrays();
|
||||
customMediaSizeNames = cps.getCustomMediaSizeNames();
|
||||
defaultMediaIndex = cps.getDefaultMediaIndex();
|
||||
rawResolutions = cps.getRawResolutions();
|
||||
urlConnection.disconnect();
|
||||
init = true;
|
||||
return;
|
||||
@ -765,6 +768,15 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
return sidesSup;
|
||||
}
|
||||
}
|
||||
} else if (category == PrinterResolution.class) {
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if (supportedRes == null) {
|
||||
return null;
|
||||
}
|
||||
PrinterResolution []arr =
|
||||
new PrinterResolution[supportedRes.length];
|
||||
System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);
|
||||
return arr;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -1043,6 +1055,14 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
if (getAttMap != null && getAttMap.containsKey("color-supported")) {
|
||||
catList.add(Chromaticity.class);
|
||||
}
|
||||
|
||||
// CUPS does not report printer resolution via IPP but it
|
||||
// may be gleaned from the PPD.
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if (supportedRes != null && (supportedRes.length > 0)) {
|
||||
catList.add(PrinterResolution.class);
|
||||
}
|
||||
|
||||
supportedCats = new Class<?>[catList.size()];
|
||||
catList.toArray(supportedCats);
|
||||
return supportedCats;
|
||||
@ -1362,6 +1382,10 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} if (attr.getCategory() == PrinterResolution.class) {
|
||||
if (attr instanceof PrinterResolution) {
|
||||
return isSupportedResolution((PrinterResolution)attr);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1523,11 +1547,48 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
|
||||
}
|
||||
}
|
||||
return Sides.ONE_SIDED;
|
||||
} else if (category == PrinterResolution.class) {
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if ((supportedRes != null) && (supportedRes.length > 0)) {
|
||||
return supportedRes[0];
|
||||
} else {
|
||||
return new PrinterResolution(300, 300, PrinterResolution.DPI);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private PrinterResolution[] getPrintResolutions() {
|
||||
if (printerResolutions == null) {
|
||||
if (rawResolutions == null) {
|
||||
printerResolutions = new PrinterResolution[0];
|
||||
} else {
|
||||
int numRes = rawResolutions.length / 2;
|
||||
PrinterResolution[] pres = new PrinterResolution[numRes];
|
||||
for (int i=0; i < numRes; i++) {
|
||||
pres[i] = new PrinterResolution(rawResolutions[i*2],
|
||||
rawResolutions[i*2+1],
|
||||
PrinterResolution.DPI);
|
||||
}
|
||||
printerResolutions = pres;
|
||||
}
|
||||
}
|
||||
return printerResolutions;
|
||||
}
|
||||
|
||||
private boolean isSupportedResolution(PrinterResolution res) {
|
||||
PrinterResolution[] supportedRes = getPrintResolutions();
|
||||
if (supportedRes != null) {
|
||||
for (int i=0; i<supportedRes.length; i++) {
|
||||
if (res.equals(supportedRes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ServiceUIFactory getServiceUIFactory() {
|
||||
return null;
|
||||
}
|
||||
|
@ -394,3 +394,112 @@ Java_sun_print_CUPSPrinter_getPageSizes(JNIEnv *env,
|
||||
unlink(filename);
|
||||
return sizeArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates the supplied ArrayList<Integer> with resolutions.
|
||||
* The first pair of elements will be the default resolution.
|
||||
* If resolution isn't supported the list will be empty.
|
||||
* If needed we can add a 2nd ArrayList<String> which would
|
||||
* be populated with the corresponding UI name.
|
||||
* PPD specifies the syntax for resolution as either "Ndpi" or "MxNdpi",
|
||||
* eg 300dpi or 600x600dpi. The former is a shorthand where xres==yres.
|
||||
* We will always expand to the latter as we use a single array list.
|
||||
* Note: getMedia() and getPageSizes() both open the ppd file
|
||||
* This is not going to scale forever so if we add anymore we
|
||||
* should look to consolidate this.
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_print_CUPSPrinter_getResolutions(JNIEnv *env,
|
||||
jobject printObj,
|
||||
jstring printer,
|
||||
jobject arrayList)
|
||||
{
|
||||
ppd_file_t *ppd = NULL;
|
||||
ppd_option_t *resolution;
|
||||
int defx = 0, defy = 0;
|
||||
int resx = 0, resy = 0;
|
||||
jclass intCls, cls;
|
||||
jmethodID intCtr, arrListAddMID;
|
||||
int i;
|
||||
|
||||
intCls = (*env)->FindClass(env, "java/lang/Integer");
|
||||
CHECK_NULL(intCls);
|
||||
intCtr = (*env)->GetMethodID(env, intCls, "<init>", "(I)V");
|
||||
CHECK_NULL(intCtr);
|
||||
cls = (*env)->FindClass(env, "java/util/ArrayList");
|
||||
CHECK_NULL(cls);
|
||||
arrListAddMID =
|
||||
(*env)->GetMethodID(env, cls, "add", "(Ljava/lang/Object;)Z");
|
||||
CHECK_NULL(arrListAddMID);
|
||||
|
||||
const char *name = (*env)->GetStringUTFChars(env, printer, NULL);
|
||||
if (name == NULL) {
|
||||
(*env)->ExceptionClear(env);
|
||||
JNU_ThrowOutOfMemoryError(env, "Could not create printer name");
|
||||
}
|
||||
const char *filename;
|
||||
|
||||
// NOTE: cupsGetPPD returns a pointer to a filename of a temporary file.
|
||||
// unlink() must be called to remove the file after using it.
|
||||
filename = j2d_cupsGetPPD(name);
|
||||
(*env)->ReleaseStringUTFChars(env, printer, name);
|
||||
CHECK_NULL(filename);
|
||||
if ((ppd = j2d_ppdOpenFile(filename)) == NULL) {
|
||||
unlink(filename);
|
||||
DPRINTF("unable to open PPD %s\n", filename)
|
||||
}
|
||||
resolution = j2d_ppdFindOption(ppd, "Resolution");
|
||||
if (resolution != NULL) {
|
||||
int matches = sscanf(resolution->defchoice, "%dx%ddpi", &defx, &defy);
|
||||
if (matches == 2) {
|
||||
if (defx <= 0 || defy <= 0) {
|
||||
defx = 0;
|
||||
defy = 0;
|
||||
}
|
||||
} else {
|
||||
matches = sscanf(resolution->defchoice, "%ddpi", &defx);
|
||||
if (matches == 1) {
|
||||
if (defx <= 0) {
|
||||
defx = 0;
|
||||
} else {
|
||||
defy = defx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defx > 0) {
|
||||
jobject rxObj = (*env)->NewObject(env, intCls, intCtr, defx);
|
||||
jobject ryObj = (*env)->NewObject(env, intCls, intCtr, defy);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
|
||||
}
|
||||
|
||||
for (i = 0; i < resolution->num_choices; i++) {
|
||||
char *resStr = resolution->choices[i].choice;
|
||||
int matches = sscanf(resStr, "%dx%ddpi", &resx, &resy);
|
||||
if (matches == 2) {
|
||||
if (resx <= 0 || resy <= 0) {
|
||||
resx = 0;
|
||||
resy = 0;
|
||||
}
|
||||
} else {
|
||||
matches = sscanf(resStr, "%ddpi", &resx);
|
||||
if (matches == 1) {
|
||||
if (resx <= 0) {
|
||||
resx = 0;
|
||||
} else {
|
||||
resy = resx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resx > 0 && (resx != defx || resy != defy )) {
|
||||
jobject rxObj = (*env)->NewObject(env, intCls, intCtr, resx);
|
||||
jobject ryObj = (*env)->NewObject(env, intCls, intCtr, resy);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
|
||||
(*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j2d_ppdClose(ppd);
|
||||
unlink(filename);
|
||||
}
|
||||
|
58
jdk/test/javax/print/attribute/PrintResAttr.java
Normal file
58
jdk/test/javax/print/attribute/PrintResAttr.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8048328
|
||||
* @summary CUPS Printing does not report supported printer resolutions.
|
||||
* @run main PrintResAttr
|
||||
*/
|
||||
|
||||
/*
|
||||
* Since there is no guarantee you have any printers that support
|
||||
* resolution this test can't verify that resolution is being
|
||||
* reported when supported. But when they are it should test that
|
||||
* the code behaves reasonably.
|
||||
*/
|
||||
import javax.print.*;
|
||||
import javax.print.attribute.*;
|
||||
import javax.print.attribute.standard.*;
|
||||
|
||||
public class PrintResAttr {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
PrintService[] services =
|
||||
PrintServiceLookup.lookupPrintServices(null,null);
|
||||
for (int i=0; i<services.length; i++) {
|
||||
if (services[i].isAttributeCategorySupported(PrinterResolution.class)) {
|
||||
System.out.println("Testing " + services[i]);
|
||||
PrinterResolution[] res = (PrinterResolution[])
|
||||
services[i].getSupportedAttributeValues(PrinterResolution.class,
|
||||
null,null);
|
||||
System.out.println("# supp res= " + res.length);
|
||||
for (int r=0;r<res.length;r++) System.out.println(res[r]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user