diff --git a/pdfbox/pom.xml b/pdfbox/pom.xml index 5d90c2306c2..79d37a1e3d3 100644 --- a/pdfbox/pom.xml +++ b/pdfbox/pom.xml @@ -41,6 +41,13 @@ + + + org.apache.commons + commons-collections4 + 4.4 + + org.apache.pdfbox fontbox diff --git a/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java b/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java index 3911ea402db..0237680f3d0 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java @@ -24,8 +24,12 @@ import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; + +import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength; +import org.apache.commons.collections4.map.ReferenceMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.cos.COSName; @@ -71,6 +75,11 @@ public class PDFRenderer private float imageDownscalingOptimizationThreshold = 0.5f; private final PDPageTree pageTree; + + private final Map pageDrawerCache = new ReferenceMap<>(ReferenceStrength.HARD, ReferenceStrength.WEAK); + + + /** * Creates a new PDFRenderer. @@ -436,6 +445,7 @@ public void renderPageToGraphics(int pageIndex, Graphics2D graphics, float scale * @param destination controlling visibility of optional content groups * @throws IOException if the PDF cannot be read */ + public void renderPageToGraphics(int pageIndex, Graphics2D graphics, float scaleX, float scaleY, RenderDestination destination) throws IOException { @@ -453,7 +463,12 @@ public void renderPageToGraphics(int pageIndex, Graphics2D graphics, float scale PageDrawerParameters parameters = new PageDrawerParameters(this, page, subsamplingAllowed, destination, actualRenderingHints, imageDownscalingOptimizationThreshold); - PageDrawer drawer = createPageDrawer(parameters); + PageDrawer drawer = pageDrawerCache.get(pageIndex); + if (drawer == null) { + drawer = new PageDrawer(parameters); + pageDrawerCache.put(pageIndex, drawer); + } + drawer.drawPage(graphics, cropBox); } diff --git a/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java b/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java index 1003a793f99..add703ac2ba 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.pdmodel.common.PDRectangle; @@ -49,20 +50,26 @@ class TilingPaint implements Paint private final Paint paint; private final Matrix patternMatrix; private static final int MAXEDGE; - private static final String DEFAULTMAXEDGE = "3000"; + private static final String DEFAULTMAXEDGE_64 = "3000"; + private static final String DEFAULTMAXEDGE_32 = "500"; static { - String s = System.getProperty("pdfbox.rendering.tilingpaint.maxedge", DEFAULTMAXEDGE); + String defaultMaxEdge = DEFAULTMAXEDGE_64; + if ("32".equals(System.getProperty("sun.arch.data.model"))) { + defaultMaxEdge = DEFAULTMAXEDGE_32; + } + + String s = System.getProperty("pdfbox.rendering.tilingpaint.maxedge", defaultMaxEdge); int val; try { - val = Integer.parseInt(s); + val = Integer.parseInt(s); } catch (NumberFormatException ex) { LOG.error("Default will be used", ex); - val = Integer.parseInt(DEFAULTMAXEDGE); + val = Integer.parseInt(defaultMaxEdge); } MAXEDGE = val; } @@ -233,8 +240,11 @@ private Rectangle2D getAnchorRect(PDTilingPattern pattern) throws IOException LOG.info("bbox: " + bbox); LOG.info("pattern matrix: " + pattern.getMatrix()); LOG.info("concatenated matrix: " + patternMatrix); - width = Math.min(MAXEDGE, Math.abs(width)) * Math.signum(width); - height = Math.min(MAXEDGE, Math.abs(height)) * Math.signum(height); + + float scale = (float)Math.sqrt( (MAXEDGE * MAXEDGE) / (width * height) ); + width = width * scale; + height = height * scale; + //TODO better solution needed } diff --git a/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaintFactory.java b/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaintFactory.java index 93fa71641a7..0f16644d531 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaintFactory.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaintFactory.java @@ -20,11 +20,11 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Map; -import java.util.WeakHashMap; +import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength; +import org.apache.commons.collections4.map.ReferenceMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.pdmodel.graphics.color.PDColor; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; @@ -41,8 +41,8 @@ class TilingPaintFactory private static final Log LOG = LogFactory.getLog(TilingPaintFactory.class); private final PageDrawer drawer; - private final Map> weakCache - = new WeakHashMap<>(); + private final Map weakCache + = new ReferenceMap<>(ReferenceStrength.HARD, ReferenceStrength.WEAK); TilingPaintFactory(PageDrawer drawer) { @@ -55,16 +55,13 @@ Paint create(PDTilingPattern pattern, PDColorSpace colorSpace, Paint paint = null; TilingPaintParameter tilingPaintParameter = new TilingPaintParameter(drawer.getInitialMatrix(), pattern.getCOSObject(), colorSpace, color, xform); - WeakReference weakRef = weakCache.get(tilingPaintParameter); - if (weakRef != null) - { - // PDFBOX-4058: additional WeakReference makes gc work better - paint = weakRef.get(); - } + + paint = weakCache.get(tilingPaintParameter); + if (paint == null) { paint = new TilingPaint(drawer, pattern, colorSpace, color, xform); - weakCache.put(tilingPaintParameter, new WeakReference<>(paint)); + weakCache.put(tilingPaintParameter, paint); } return paint; } @@ -140,7 +137,8 @@ public boolean equals(Object obj) LOG.debug("Couldn't convert color to RGB - treating as not equal", ex); return false; } - return !(this.xform != other.xform && (this.xform == null || !this.xform.equals(other.xform))); + + return !(this.xform != other.xform && (this.xform == null || !( this.xform.getScaleX() == other.xform.getScaleX() && this.xform.getScaleY() == other.xform.getScaleY() ))); } @Override @@ -151,7 +149,8 @@ public int hashCode() hash = 23 * hash + (this.patternDict != null ? this.patternDict.hashCode() : 0); hash = 23 * hash + (this.colorSpace != null ? this.colorSpace.hashCode() : 0); hash = 23 * hash + (this.color != null ? this.color.hashCode() : 0); - hash = 23 * hash + (this.xform != null ? this.xform.hashCode() : 0); + hash = 23 * hash + (this.xform != null ? Double.hashCode(this.xform.getScaleX()) : 0); + hash = 23 * hash + (this.xform != null ? Double.hashCode(this.xform.getScaleY()) : 0); return hash; } diff --git a/pdfbox/src/test/java/org/apache/pdfbox/printing/SimplifiedPdfBoxPdfPrinter.java b/pdfbox/src/test/java/org/apache/pdfbox/printing/SimplifiedPdfBoxPdfPrinter.java new file mode 100644 index 00000000000..420c86c0d40 --- /dev/null +++ b/pdfbox/src/test/java/org/apache/pdfbox/printing/SimplifiedPdfBoxPdfPrinter.java @@ -0,0 +1,89 @@ +/** + * + */ +package org.apache.pdfbox.printing; + +import java.awt.print.PrinterJob; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.attribute.HashPrintRequestAttributeSet; + +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.io.MemoryUsageSetting; +import org.apache.pdfbox.pdmodel.PDDocument; + +/** + * @author Kevin + * + */ +public class SimplifiedPdfBoxPdfPrinter { + + private final String printerName; + + /** + * + */ + public SimplifiedPdfBoxPdfPrinter(String printerName) { + this.printerName = printerName; + } + + private static void forceFileExist(File f) throws IOException{ + new FileOutputStream(f).close(); + } + + private static PrintService getPrintService(String name){ + PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null); + for (PrintService service : services) { + if (service.getName().equalsIgnoreCase(name)){ + return service; + } + } + return null; + } + + + public void print(File pdf) throws Exception { + if (!pdf.exists()) + throw new IOException(pdf + " does not exist before printing - conversion to prn not possible"); + + PrintService printService = getPrintService(printerName); + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintService(printService); + + try(PDDocument doc = Loader.loadPDF(pdf, MemoryUsageSetting.setupMixed(5000000L))){ + PDFPageable pageable = new PDFPageable(doc); + + job.setPageable(pageable); + + // create a new HashPrintRequestAttributeSet and initialize it with the printer's default attributes + HashPrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); + + File tempPrn = File.createTempFile("tempPrn", ""); + + // set the output file as a destination + attributes.add(new javax.print.attribute.standard.Destination(tempPrn.toURI())); + + + // print with the attributes + job.print(attributes); + } + + } + + + public static void main(String[] args) throws Exception { + long start = System.currentTimeMillis(); + + SimplifiedPdfBoxPdfPrinter svc = new SimplifiedPdfBoxPdfPrinter("\\\\Moby\\Cust Suc Dell C2660dn"); + svc.print(new File("S:\\ClientData\\ClientData\\XPRIA-TPT100892\\JrachvUniverse_H21.pdf")); + + //svc.print(new File("C:\\Users\\kevin\\Downloads\\gs-bugzilla692158-schleuse-veryslow.pdf")); + + System.out.println("Elapsed: " + (System.currentTimeMillis() - start)/1000L + " secs"); + } +}