< prev index next >

src/java.desktop/share/classes/sun/print/PSPrinterJob.java

Print this page

        

@@ -104,10 +104,11 @@
 import java.nio.file.Files;
 
 //REMIND: Remove use of this class when IPPPrintService is moved to share directory.
 import java.lang.reflect.Method;
 import javax.print.attribute.standard.JobSheets;
+import javax.print.attribute.standard.MediaPrintableArea;
 
 /**
  * A class which initiates and executes a PostScript printer job.
  *
  * @author Richard Blanchard

@@ -487,10 +488,124 @@
         }
 
         return doPrint;
     }
 
+    private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {
+        int units = MediaPrintableArea.INCH;
+        MediaPrintableArea[] mediaPrintables = 
+                new CUPSPrinter(getPrintService().getName()).getMediaPrintableArea();
+        if (mediaPrintables != null) {
+            for (int i=0; i<mediaPrintables.length; i++) {
+                if ((mpa.getX(units) >= mediaPrintables[i].getX(units)) &&
+                    (mpa.getY(units) >= mediaPrintables[i].getY(units)) &&
+                    (mpa.getX(units) + mpa.getWidth(units) <=
+                                mediaPrintables[i].getX(units) +
+                                mediaPrintables[i].getWidth(units)) &&
+                    (mpa.getY(units) + mpa.getHeight(units) <=
+                                mediaPrintables[i].getY(units) +
+                                mediaPrintables[i].getHeight(units))) {
+                    return true;
+                }
+            }
+        }
+        return false;        
+    }
+    
+    @Override
+    protected void validatePaper(Paper origPaper, Paper newPaper) {
+        if (origPaper == null || newPaper == null) {
+            return;
+        } else {
+            double wid = origPaper.getWidth();
+            double hgt = origPaper.getHeight();
+            double ix = origPaper.getImageableX();
+            double iy = origPaper.getImageableY();
+            double iw = origPaper.getImageableWidth();
+            double ih = origPaper.getImageableHeight();
+            double imgX, imgY, imgWid, imgHgt;            
+                        
+            MediaPrintableArea mpa = null;            
+            MediaPrintableArea origmpa = new MediaPrintableArea((float)ix/72.0f, 
+                     (float)iy/72.0f, (float)iw/72.0f, (float)ih/72.0f, MediaPrintableArea.INCH);
+            
+            if (isSupportedMediaPrintableArea(origmpa)) {
+                mpa = origmpa;
+            } else {            
+                /* 
+                 * this returns the imageable area of default media of chosen printer
+                 * from CUPS via CUPSPrinter#getPageSizes().
+                 */
+                mpa = (MediaPrintableArea)
+                     getPrintService().getDefaultAttributeValue(MediaPrintableArea.class);
+            }
+            if (mpa != null) {
+                imgX = mpa.getX(MediaPrintableArea.INCH) * 72;
+                imgY = mpa.getY(MediaPrintableArea.INCH) * 72;
+                imgWid = mpa.getWidth(MediaPrintableArea.INCH) * 72;
+                imgHgt = mpa.getHeight(MediaPrintableArea.INCH) * 72;
+            } else {
+                imgX = newPaper.getImageableX();
+                imgY = newPaper.getImageableY();
+                imgWid = newPaper.getImageableWidth();
+                imgHgt = newPaper.getImageableHeight();
+            }
+            
+            wid = ((wid > 0.0) ? wid : newPaper.getWidth());
+            hgt = ((hgt > 0.0) ? hgt : newPaper.getHeight());
+            if ((imgX*2) + imgWid > wid) {
+                imgWid = wid - imgX*2;
+            }
+            if ((imgY*2) + imgHgt > hgt) {
+                imgHgt = hgt - imgY*2;
+            }
+             
+            /* We try to mitigate the effects of floating point rounding errors
+             * by only setting a value if it would differ from the value in the
+             * target by at least 0.10 points = 1/720 inches.
+             * eg if the values present in the target are close to the calculated
+             * values then we accept the target.
+             */
+            final double epsilon = 0.10;
+            
+            if (ix < 0.0) {
+                ix = 0.0;
+            }
+            if (iy < 0.0) {
+                iy = 0.0;
+            }
+            if (iw < 0.0) {
+                iw = 0.0;
+            }
+            if (ih < 0.0) {
+                ih = 0.0;
+            }
+            if ((ix + epsilon) < imgX) {
+                ix = imgX;
+            }
+            if ((iy + epsilon) < imgY) {
+                iy = imgY;
+            }
+            if (iw + epsilon > imgWid) {
+                iw = imgWid;
+            }
+            if (ih + epsilon > imgHgt) {
+                ih = imgHgt;
+            }
+            if ((ix + iw + epsilon) > (imgX + imgWid)) {
+                ix = (imgX + imgWid) - iw;
+            }
+            if ((iy + ih + epsilon) > (imgY + imgHgt)) {
+                iy = (imgY + imgHgt) - ih;
+            }
+            
+            newPaper.setSize(wid, hgt);
+            newPaper.setImageableArea(ix, iy, iw, ih);
+        }
+    }
+
+
     /**
      * Invoked by the RasterPrinterJob super class
      * this method is called to mark the start of a
      * document.
      */
< prev index next >