Author: ssteiner Date: Mon Sep 9 09:07:10 2019 New Revision: 1866665 URL: http://svn.apache.org/viewvc?rev=1866665&view=rev Log: FOP-2882: Allow PDFFormXObject to improve performance
Modified: xmlgraphics/fop-pdf-images/trunk/lib/fop.jar xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFRotateTestCase.java Modified: xmlgraphics/fop-pdf-images/trunk/lib/fop.jar URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/fop.jar?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java Mon Sep 9 09:07:10 2019 @@ -49,7 +49,7 @@ import org.apache.fop.render.pdf.PDFLogi */ public abstract class AbstractPDFBoxHandler { - protected String createStreamForPDF(ImagePDF image, PDFPage targetPage, FOUserAgent userAgent, + protected Object createStreamForPDF(ImagePDF image, PDFPage targetPage, FOUserAgent userAgent, AffineTransform at, FontInfo fontinfo, Rectangle pos, Map<Integer, PDFArray> pageNumbers, PDFLogicalStructureHandler handler, @@ -108,8 +108,7 @@ public abstract class AbstractPDFBoxHand if (handler != null) { adapter.setCurrentMCID(handler.getPageParentTree().length()); } - String stream = adapter.createStreamFromPDFBoxPage(pddoc, page, originalImageUri, - at, fontinfo, pos); + Object stream = adapter.createStreamFromPDFBoxPage(pddoc, page, originalImageUri, at, fontinfo, pos); if (userAgent.isAccessibilityEnabled() && curentSessionElem != null) { TaggedPDFConductor conductor = new TaggedPDFConductor(curentSessionElem, handler, page, adapter); conductor.handleLogicalStructure(pddoc); Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java Mon Sep 9 09:07:10 2019 @@ -21,6 +21,7 @@ package org.apache.fop.render.pdf.pdfbox import java.awt.Rectangle; import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -69,6 +70,7 @@ import org.apache.fop.fonts.Typeface; import org.apache.fop.pdf.PDFArray; import org.apache.fop.pdf.PDFDictionary; import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFFormXObject; import org.apache.fop.pdf.PDFName; import org.apache.fop.pdf.PDFNumber; import org.apache.fop.pdf.PDFObject; @@ -341,8 +343,8 @@ public class PDFBoxAdapter { * @return the stream * @throws IOException if an I/O error occurs */ - public String createStreamFromPDFBoxPage(PDDocument sourceDoc, PDPage page, String key, - AffineTransform atdoc, FontInfo fontinfo, Rectangle pos) + public Object createStreamFromPDFBoxPage(PDDocument sourceDoc, PDPage page, String key, + AffineTransform atdoc, FontInfo fontinfo, Rectangle pos) throws IOException { handleAnnotations(sourceDoc, page, atdoc); if (pageNumbers.containsKey(targetPage.getPageIndex())) { @@ -359,24 +361,18 @@ public class PDFBoxAdapter { fontsBackup = new COSDictionary(fonts); MergeFontsPDFWriter m = new MergeFontsPDFWriter(fonts, fontinfo, uniqueName, parentFonts, currentMCID); newStream = m.writeText(pdStream); -// if (newStream != null) { -// for (Object f : fonts.keySet().toArray()) { -// COSDictionary fontdata = (COSDictionary)fonts.getDictionaryObject((COSName)f); -// if (getUniqueFontName(fontdata) != null) { -// fonts.removeItem((COSName)f); -// } -// } -// } } - if (newStream == null) { - newStream = (String) clonedVersion.get(key); + if (!pdfDoc.isFormXObjectEnabled()) { if (newStream == null) { - PDFWriter writer = new PDFWriter(uniqueName, currentMCID); - newStream = writer.writeText(pdStream); - clonedVersion.put(key, newStream); + newStream = (String) clonedVersion.get(key); + if (newStream == null) { + PDFWriter writer = new PDFWriter(uniqueName, currentMCID); + newStream = writer.writeText(pdStream); + clonedVersion.put(key, newStream); + } } + pdStream = new PDStream(sourceDoc, new ByteArrayInputStream(newStream.getBytes("ISO-8859-1"))); } - pdStream = new PDStream(sourceDoc, new ByteArrayInputStream(newStream.getBytes("ISO-8859-1"))); mergeXObj(sourcePageResources, fontinfo, uniqueName); PDFDictionary pageResources = (PDFDictionary)cloneForNewDocument(sourcePageResources); @@ -419,6 +415,11 @@ public class PDFBoxAdapter { if (pageStream == null) { pageStream = new PDFStream(); } + + if (pdfDoc.isFormXObjectEnabled()) { + return getFormXObject(pageResources, pageStream, key, page); + } + if (originalPageContents != null) { transferDict(originalPageContents, pageStream, filter); } @@ -464,6 +465,57 @@ public class PDFBoxAdapter { return pdStream; } + private PDFFormXObject getFormXObject(PDFDictionary pageResources, PDFStream pageStream, String key, PDPage page) + throws IOException { + if (pdfDoc.isMergeFontsEnabled()) { + throw new RuntimeException("merge-fonts and form-xobject can't both be enabled"); + } + if (!pageResources.hasObjectNumber()) { + pdfDoc.registerObject(pageResources); + } + PDFFormXObject form = pdfDoc.addFormXObject(null, pageStream, pageResources.makeReference(), key); + final Set<String> page2Form = new HashSet<String>(Arrays.asList("Group", "LastModified", "Metadata")); + transferDict(page.getCOSObject(), pageStream, page2Form, true); + + AffineTransform at = form.getMatrix(); + PDRectangle mediaBox = page.getMediaBox(); + PDRectangle cropBox = page.getCropBox(); + PDRectangle viewBox = cropBox != null ? cropBox : mediaBox; + + //Handle the /Rotation entry on the page dict + int rotation = PDFUtil.getNormalizedRotation(page); + + //Transform to FOP's user space + at.scale(1 / viewBox.getWidth(), 1 / viewBox.getHeight()); + at.translate(mediaBox.getLowerLeftX() - viewBox.getLowerLeftX(), + mediaBox.getLowerLeftY() - viewBox.getLowerLeftY()); + switch (rotation) { + case 90: + at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth()); + at.translate(0, viewBox.getWidth()); + at.rotate(-Math.PI / 2.0); + break; + case 180: + at.translate(viewBox.getWidth(), viewBox.getHeight()); + at.rotate(-Math.PI); + break; + case 270: + at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth()); + at.translate(viewBox.getHeight(), 0); + at.rotate(-Math.PI * 1.5); + break; + default: + //no additional transformations necessary + break; + } + form.setMatrix(at); + + form.setBBox(new Rectangle2D.Float( + viewBox.getLowerLeftX(), viewBox.getLowerLeftY(), + viewBox.getUpperRightX(), viewBox.getUpperRightY())); + return form; + } + private COSDictionary getResources(PDPage page) { PDResources res = page.getResources(); if (res == null) { Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java Mon Sep 9 09:07:10 2019 @@ -30,6 +30,7 @@ import org.apache.xmlgraphics.image.load import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.ImageHandler; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.pdf.PDFContentGenerator; @@ -58,6 +59,7 @@ public class PDFBoxImageHandler extends try { float x = (float)pos.getX() / 1000f; float y = (float)pos.getY() / 1000f; + float w = (float)pos.getWidth() / 1000f; float h = (float)pos.getHeight() / 1000f; AffineTransform pageAdjust = new AffineTransform(); @@ -68,17 +70,21 @@ public class PDFBoxImageHandler extends (float)(generator.getState().getTransform().getTranslateY() - h - y)); } FontInfo fontinfo = (FontInfo)context.getHint("fontinfo"); - String stream = createStreamForPDF(pdfImage, pdfContext.getPage(), pdfContext.getUserAgent(), + Object stream = createStreamForPDF(pdfImage, pdfContext.getPage(), pdfContext.getUserAgent(), pageAdjust, fontinfo, pos, pdfContext.getPageNumbers(), pdfContext.getPdfLogicalStructureHandler(), pdfContext.getCurrentSessionStructElem()); if (stream == null) { return; } - if (pageAdjust.getScaleX() != 0) { - pageAdjust.translate(x * (1 / pageAdjust.getScaleX()), -y * (1 / -pageAdjust.getScaleY())); + if (stream instanceof String) { + if (pageAdjust.getScaleX() != 0) { + pageAdjust.translate(x * (1 / pageAdjust.getScaleX()), -y * (1 / -pageAdjust.getScaleY())); + } + generator.placeImage(pageAdjust, (String) stream); + } else { + generator.placeImage(x, y, w, h, (PDFXObject) stream); } - generator.placeImage(pageAdjust, stream); pdfImage.close(); } catch (Throwable t) { throw new RuntimeException( Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java (original) +++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Mon Sep 9 09:07:10 2019 @@ -74,6 +74,7 @@ import org.apache.fop.pdf.PDFArray; import org.apache.fop.pdf.PDFDictionary; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFFilterList; +import org.apache.fop.pdf.PDFFormXObject; import org.apache.fop.pdf.PDFGState; import org.apache.fop.pdf.PDFPage; import org.apache.fop.pdf.PDFResources; @@ -125,10 +126,11 @@ public class PDFBoxAdapterTestCase { return new PDFPage(new PDFResources(doc), 0, r, r, r, r); } - protected static PDFBoxAdapter getPDFBoxAdapter(boolean mergeFonts) { + protected static PDFBoxAdapter getPDFBoxAdapter(boolean mergeFonts, boolean formXObject) { PDFDocument doc = new PDFDocument(""); PDFPage pdfpage = getPDFPage(doc); doc.setMergeFontsEnabled(mergeFonts); + doc.setFormXObjectEnabled(formXObject); pdfpage.setDocument(doc); pdfpage.setObjectNumber(1); return new PDFBoxAdapter(pdfpage, new HashMap(), new HashMap<Integer, PDFArray>()); @@ -221,24 +223,21 @@ public class PDFBoxAdapterTestCase { PDDocument doc = PDDocument.load(new File(pdf)); PDPage page = doc.getPage(0); AffineTransform at = new AffineTransform(); - String c = getPDFBoxAdapter(true).createStreamFromPDFBoxPage(doc, page, pdf, at, fi, new Rectangle()); -// PDResources sourcePageResources = page.findResources(); -// COSDictionary fonts = (COSDictionary)sourcePageResources.getCOSDictionary().getDictionaryObject(COSName.FONT); -// PDFBoxAdapter.PDFWriter w = adapter. new MergeFontsPDFWriter(fonts, fi, "", new ArrayList<COSName>()); -// String c = w.writeText(page.getContents()); + String c = (String) getPDFBoxAdapter(true, false) + .createStreamFromPDFBoxPage(doc, page, pdf, at, fi, new Rectangle()); doc.close(); return c; } @Test public void testTaggedPDFWriter() throws IOException { - PDFBoxAdapter adapter = getPDFBoxAdapter(false); + PDFBoxAdapter adapter = getPDFBoxAdapter(false, false); adapter.setCurrentMCID(5); PDDocument doc = PDDocument.load(new File(HELLOTagged)); PDPage page = doc.getPage(0); AffineTransform at = new AffineTransform(); Rectangle r = new Rectangle(0, 1650, 842000, 595000); - String stream = adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); + String stream = (String) adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); Assert.assertTrue(stream, stream.contains("/P <</MCID 5 >>BDC")); doc.close(); } @@ -265,7 +264,7 @@ public class PDFBoxAdapterTestCase { @Test public void testAnnot2() throws Exception { - PDFBoxAdapter adapter = getPDFBoxAdapter(false); + PDFBoxAdapter adapter = getPDFBoxAdapter(false, false); PDDocument doc = PDDocument.load(new File(ANNOT)); PDPage page = doc.getPage(0); COSArray annots = (COSArray) page.getCOSObject().getDictionaryObject(COSName.ANNOTS); @@ -290,7 +289,7 @@ public class PDFBoxAdapterTestCase { PDPage page = doc.getPage(0); AffineTransform at = new AffineTransform(); Rectangle r = new Rectangle(0, 1650, 842000, 595000); - String stream = adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); + String stream = (String) adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); Assert.assertTrue(stream.contains("/Link <</MCID 5 >>BDC")); Assert.assertEquals(pageNumbers.size(), 4); PDFAnnotList annots = (PDFAnnotList) pdfpage.get("Annots"); @@ -518,7 +517,7 @@ public class PDFBoxAdapterTestCase { pdfpage, objectCachePerFile, new HashMap<Integer, PDFArray>(), pdfCache); PDDocument doc = PDDocument.load(new File(pdf)); PDPage page = doc.getPage(0); - String stream = adapter.createStreamFromPDFBoxPage( + String stream = (String) adapter.createStreamFromPDFBoxPage( doc, page, pdf, new AffineTransform(), null, new Rectangle()); doc.close(); return stream; @@ -566,7 +565,7 @@ public class PDFBoxAdapterTestCase { PDPage page = doc.getPage(0); page.setResources(null); AffineTransform at = new AffineTransform(); - getPDFBoxAdapter(false).createStreamFromPDFBoxPage(doc, page, CFF1, at, new FontInfo(), new Rectangle()); + getPDFBoxAdapter(false, false).createStreamFromPDFBoxPage(doc, page, CFF1, at, new FontInfo(), new Rectangle()); doc.close(); } @@ -586,4 +585,33 @@ public class PDFBoxAdapterTestCase { c.setPageNumbers(new HashMap<Integer, PDFArray>()); new PDFBoxImageHandler().handleImage(c, img, new Rectangle()); } + + @Test + public void testMergeFontsAndFormXObject() throws IOException { + String msg = ""; + PDDocument doc = PDDocument.load(new File(IMAGE)); + PDPage page = doc.getPage(0); + AffineTransform at = new AffineTransform(); + try { + getPDFBoxAdapter(true, true) + .createStreamFromPDFBoxPage(doc, page, IMAGE, at, new FontInfo(), new Rectangle()); + } catch (RuntimeException e) { + msg = e.getMessage(); + } + doc.close(); + Assert.assertEquals(msg, "merge-fonts and form-xobject can't both be enabled"); + } + + @Test + public void testFormXObject() throws IOException { + PDDocument doc = PDDocument.load(new File(IMAGE)); + PDPage page = doc.getPage(0); + AffineTransform at = new AffineTransform(); + PDFFormXObject formXObject = (PDFFormXObject) getPDFBoxAdapter(false, true) + .createStreamFromPDFBoxPage(doc, page, IMAGE, at, new FontInfo(), new Rectangle()); + doc.close(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + formXObject.output(bos); + Assert.assertTrue(bos.toString("UTF-8").contains("/Type /XObject")); + } } Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFRotateTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFRotateTestCase.java?rev=1866665&r1=1866664&r2=1866665&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFRotateTestCase.java (original) +++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFRotateTestCase.java Mon Sep 9 09:07:10 2019 @@ -75,13 +75,13 @@ public class PDFRotateTestCase { } private AffineTransform getTransform(int angle) throws IOException { - PDFBoxAdapter adapter = PDFBoxAdapterTestCase.getPDFBoxAdapter(false); + PDFBoxAdapter adapter = PDFBoxAdapterTestCase.getPDFBoxAdapter(false, false); PDDocument doc = PDDocument.load(new File(PDFBoxAdapterTestCase.ROTATE)); PDPage page = doc.getPage(0); page.setRotation(angle); AffineTransform at = new AffineTransform(); Rectangle r = new Rectangle(0, 1650, 842000, 595000); - String stream = adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); + String stream = (String) adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r); Assert.assertTrue(stream.contains("/GS0106079 gs")); Assert.assertTrue(stream.contains("/TT0106079 1 Tf")); doc.close(); --------------------------------------------------------------------- To unsubscribe, e-mail: fop-commits-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-h...@xmlgraphics.apache.org