You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/03/06 10:05:09 UTC
svn commit: r1574811 [1/2] - in /pdfbox/trunk:
pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/
pdfbox/src/main/java/org/apache/pdfbox/pdmod...
Author: jahewson
Date: Thu Mar 6 09:05:08 2014
New Revision: 1574811
URL: http://svn.apache.org/r1574811
Log:
PDFBOX-1963, PDFBOX-1962: Refactor RenderUtil, PageDrawer and PDFImageWriter into 'rendering' module
Added:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFPrinter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
Removed:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPageable.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFImageWriter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/RenderUtil.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDPattern.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/ImageIOUtil.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/AppendRectangleToPath.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipEvenOddRule.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipNonZeroRule.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClosePath.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveTo.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateFinalPoint.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateInitialPoint.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/EndPath.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddAndStrokePath.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddRule.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroAndStrokePath.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroRule.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/LineTo.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/MoveTo.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/SHFill.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/StrokePath.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/PDSimpleFontTest.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/util/TestImageIOUtils.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/util/TestPDFToImage.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/util/TestRendering.java
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFReader.java
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFToImage.java
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PrintPDF.java
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/PDFPagePanel.java
pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/PageWrapper.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java Thu Mar 6 09:05:08 2014
@@ -1288,6 +1288,16 @@ public class PDDocument implements Close
}
/**
+ * Returns the page at the given index.
+ * @param pageIndex the page index
+ * @return the page at the given index.
+ */
+ public PDPage getPage(int pageIndex)
+ {
+ return (PDPage) getDocumentCatalog().getAllPages().get(pageIndex);
+ }
+
+ /**
* This will return the total page count of the PDF document.
*
* @return The total number of pages in the PDF document.
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java Thu Mar 6 09:05:08 2014
@@ -53,10 +53,7 @@ public class PDPage implements COSObject
*/
private static final Log LOG = LogFactory.getLog(PDPage.class);
- /**
- * Default DPI in user space.
- */
- public static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
+ private static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
private static final float MM_TO_UNITS = 1 / (10 * 2.54f) * DEFAULT_USER_SPACE_UNIT_DPI;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java Thu Mar 6 09:05:08 2014
@@ -22,6 +22,7 @@ import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDAbstractPattern;
+import org.apache.pdfbox.rendering.PDFRenderer;
import java.awt.Color;
import java.awt.Paint;
@@ -231,9 +232,9 @@ public abstract class PDColorSpace imple
* @return an AWT paint
* @throws IOException if the color conversion fails
*/
- public Paint toPaint(PDColor color) throws IOException
+ public Paint toPaint(PDFRenderer renderer, PDColor color) throws IOException
{
- return toPaint(color, 0);
+ return toPaint(renderer, color, 0);
}
/**
@@ -245,7 +246,7 @@ public abstract class PDColorSpace imple
* @return an AWT paint
* @throws IOException if the color conversion fails
*/
- public Paint toPaint(PDColor color, int pageHeight) throws IOException
+ public Paint toPaint(PDFRenderer renderer, PDColor color, int pageHeight) throws IOException
{
float[] rgb = toRGB(color.getComponents());
return new Color(rgb[0], rgb[1], rgb[2]);
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDPattern.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDPattern.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDPattern.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDPattern.java Thu Mar 6 09:05:08 2014
@@ -34,6 +34,7 @@ import org.apache.pdfbox.pdmodel.graphic
import org.apache.pdfbox.pdmodel.graphics.shading.Type1ShadingPaint;
import org.apache.pdfbox.pdmodel.graphics.shading.Type4ShadingPaint;
import org.apache.pdfbox.pdmodel.graphics.shading.Type5ShadingPaint;
+import org.apache.pdfbox.rendering.PDFRenderer;
import java.awt.Color;
import java.awt.Paint;
@@ -110,13 +111,13 @@ public final class PDPattern extends PDS
}
@Override
- public Paint toPaint(PDColor color) throws IOException
+ public Paint toPaint(PDFRenderer renderer, PDColor color) throws IOException
{
throw new UnsupportedOperationException();
}
@Override
- public Paint toPaint(PDColor color, int pageHeight) throws IOException
+ public Paint toPaint(PDFRenderer renderer, PDColor color, int pageHeight) throws IOException
{
if (!patterns.containsKey(color.getPatternName()))
{
@@ -126,7 +127,7 @@ public final class PDPattern extends PDS
PDAbstractPattern pattern = patterns.get(color.getPatternName());
if (pattern instanceof PDTilingPattern)
{
- return toTilingPaint((PDTilingPattern)pattern, color);
+ return toTilingPaint(renderer, (PDTilingPattern)pattern, color);
}
else
{
@@ -134,22 +135,22 @@ public final class PDPattern extends PDS
}
}
- public Paint toTilingPaint(PDTilingPattern tilingPattern, PDColor color)
+ public Paint toTilingPaint(PDFRenderer renderer, PDTilingPattern tilingPattern, PDColor color)
throws IOException
{
if (tilingPattern.getPaintType() == PDTilingPattern.PAINT_COLORED)
{
// colored tiling pattern
- return new TilingPaint(tilingPattern);
+ return new TilingPaint(renderer, tilingPattern);
}
else
{
// uncolored tiling pattern
- return new TilingPaint(tilingPattern, underlyingColorSpace, color);
+ return new TilingPaint(renderer, tilingPattern, underlyingColorSpace, color);
}
}
- public Paint toShadingPaint(PDShadingPattern shadingPattern, int pageHeight)
- throws IOException
+
+ public Paint toShadingPaint(PDShadingPattern shadingPattern, int pageHeight) throws IOException
{
PDShading shadingResources = shadingPattern.getShading();
int shadingType = shadingResources != null ? shadingResources.getShadingType() : 0;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java Thu Mar 6 09:05:08 2014
@@ -16,17 +16,12 @@
*/
package org.apache.pdfbox.pdmodel.graphics.pattern;
-import java.awt.Color;
import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.PaintContext;
import java.awt.Rectangle;
-import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
@@ -34,11 +29,11 @@ import java.awt.image.DataBuffer;
import java.awt.image.WritableRaster;
import java.io.IOException;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
-import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPattern;
import org.apache.pdfbox.util.Matrix;
/**
@@ -46,23 +41,15 @@ import org.apache.pdfbox.util.Matrix;
* @author Andreas Lehmkühler
* @author John Hewson
*/
-public class TilingPaint implements Paint
+public class TilingPaint extends TexturePaint
{
- private static Color TRANSPARENT = new Color(0, 0, 0, 0);
-
- private final PDTilingPattern pattern;
- private final PDColorSpace colorSpace;
- private final PDColor color;
-
/**
* Creates a new colored tiling Paint.
* @param pattern tiling pattern dictionary
*/
- public TilingPaint(PDTilingPattern pattern) throws IOException
+ public TilingPaint(PDFRenderer renderer, PDTilingPattern pattern) throws IOException
{
- this.pattern = pattern;
- this.colorSpace = null;
- this.color = null;
+ super(getImage(renderer, pattern, null ,null), getTransformedRect(pattern));
}
/**
@@ -71,146 +58,67 @@ public class TilingPaint implements Pain
* @param colorSpace color space for this tiling
* @param color color for this tiling
*/
- public TilingPaint(PDTilingPattern pattern, PDColorSpace colorSpace, PDColor color)
- throws IOException
+ public TilingPaint(PDFRenderer renderer, PDTilingPattern pattern, PDColorSpace colorSpace,
+ PDColor color) throws IOException
{
- this.pattern = pattern;
- this.colorSpace = colorSpace;
- this.color = color;
- }
-
- @Override
- public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
- Rectangle2D userBounds, AffineTransform xform,
- RenderingHints hints)
- {
- System.out.println("TilingPaint#createContext" +
- " rectangle: " + deviceBounds +
- " affineTransform: " + xform);
- try
- {
- ColorSpace outputCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- ColorModel cm2 = new ComponentColorModel(outputCS, true, false,
- Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
-
- // DISABLED
- //return new TilingPaintContext(cm2 /*HACK*/, deviceBounds, xform, getTilingImage(cm, xform));
-
- hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-
- // EXPERIMENT
- // ... CRAZY HACK:
- TexturePaint paint = new TexturePaint(getTilingImage(cm, xform), getTransformedRect(xform, false));
- return paint.createContext(cm, deviceBounds, userBounds, xform, hints); // ^^^^^ USE SPACE RECT, NO XFORM.
- }
- catch (IOException e)
- {
- e.printStackTrace(); // TODO !!!!!!
- // TODO: log
- return TRANSPARENT.createContext(cm, deviceBounds, userBounds,
- xform, hints);
- }
+ super(getImage(renderer, pattern, colorSpace, color), getTransformedRect(pattern));
}
// gets rect in parent content stream coordinates
- private Rectangle getTransformedRect(AffineTransform transform, boolean applyCTM)
+ private static Rectangle getTransformedRect(PDTilingPattern pattern)
{
- // pattern matrix
- Rectangle rect;
if (pattern.getMatrix() == null)
{
- rect = new Rectangle(pattern.getBBox().createDimension());
+ return new Rectangle(pattern.getBBox().createDimension());
}
else
{
AffineTransform at = pattern.getMatrix().createAffineTransform();
- rect = new Rectangle(pattern.getBBox().createDimension());
- rect = at.createTransformedShape(rect).getBounds();
- }
-
- // x/y step
- if (pattern.getMatrix() != null)
- {
- // TODO can be -ve
- rect.width = Math.round(pattern.getXStep() * Math.abs(pattern.getMatrix().getXScale()));
- rect.height = Math.round(pattern.getYStep() * Math.abs(pattern.getMatrix().getYScale()));
- }
- else
- {
- rect.width = pattern.getXStep();
- rect.height = pattern.getYStep();
- }
-
- // ctm
- if (applyCTM)
- {
- rect = transform.createTransformedShape(rect).getBounds();
+ Rectangle rect = new Rectangle(pattern.getBBox().createDimension());
+ return at.createTransformedShape(rect).getBounds();
}
-
- return rect;
}
// gets image in parent stream coordinates
- private BufferedImage getTilingImage(ColorModel colorModel, AffineTransform transform)
- throws IOException
+ private static BufferedImage getImage(PDFRenderer renderer, PDTilingPattern pattern,
+ PDColorSpace colorSpace, PDColor color) throws IOException
{
- // TODO use colorModel parameter
ColorSpace outputCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel cm = new ComponentColorModel(outputCS, true, false,
Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
- Rectangle rect = getTransformedRect(transform, true);
- int width = 1000;
- int height = 1000;
+ Rectangle rect = getTransformedRect(pattern);
+ int width = Math.round((float)rect.getWidth());
+ int height = Math.round((float)rect.getHeight());
// create raster
WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
BufferedImage image = new BufferedImage(cm, raster, false, null);
+ // TODO xStep and yStep
+
// matrix
- AffineTransform patternMatrix;
+ Matrix matrix;
if (pattern.getMatrix() == null)
{
// identity
- patternMatrix = new AffineTransform();
+ matrix = new Matrix();
}
else
{
- // pattern matrix
- patternMatrix = pattern.getMatrix().createAffineTransform();
-
- // flip -ve x-scale
- if (patternMatrix.getScaleX() < -0)
- {
- patternMatrix.scale(-1, 1);
- }
+ // undo translation
+ matrix = (Matrix)pattern.getMatrix().clone();
+ matrix.setValue(2, 0, matrix.getValue(2, 0) - (float)rect.getX()); // tx
+ matrix.setValue(2, 1, matrix.getValue(2, 1) - (float)rect.getY()); // ty
}
- // ************************************************************************************************************
- // I've figured this out: the pattern is drawn only once over the page background and then sampled. PDFBOX-1094
- // ************************************************************************************************************
-
- // ****TODO**** This code works for tiling_pattern1 but not for PDFBOX-1094 (instrument the fill commands to find out why)
+ // TODO shouldn't create PageDrawer here, the class needs to be overridable
+ // can we re-use the existing PageDrawer somehow and just push/pop its graphics state?
- // NEW HACK: ASSUME STREAM TRANSFORM IS IDENTITY
- transform = AffineTransform.getScaleInstance(transform.getScaleX(), -transform.getScaleY()); // <--- HACK SCALING TAKEN FROM CTM (but should be from stream start)
-
-
- // TODO supposed to be relative to the parent stream's initial CTM, not its current CTM
- //patternMatrix.scale(transform.getScaleX(), -transform.getScaleY());
- transform.preConcatenate(patternMatrix);
-
- Matrix matrix = new Matrix();
- matrix.setFromAffineTransform(transform); // !!
-
- Graphics2D graphics = image.createGraphics();
- PageDrawer drawer = new PageDrawer();
+ PageDrawer drawer = new PageDrawer(renderer);
PDRectangle pdRect = new PDRectangle(0, 0, width, height);
- // NEW HACK: this is usually done in drawPage
- graphics.scale(1, -1);
- graphics.translate(0, -height);
-
+ Graphics2D graphics = image.createGraphics();
drawer.drawTilingPattern(graphics, pattern, pdRect, matrix, colorSpace, color);
drawer.dispose();
graphics.dispose();
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFPrinter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFPrinter.java?rev=1574811&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFPrinter.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFPrinter.java Thu Mar 6 09:05:08 2014
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.rendering;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Paper;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterIOException;
+import java.awt.print.PrinterJob;
+import java.io.IOException;
+
+/**
+ * Prints a PDF document using AWT.
+ * This class may be overridden in order to perform custom printing.
+ *
+ * @author Andreas Lehmkühler
+ * @author John Hewson
+ */
+public class PDFPrinter
+{
+ protected final PDDocument document;
+ protected final PDFRenderer renderer;
+ protected final PrinterJob printerJob;
+
+ /**
+ * Creates a new PDFPrinter.
+ * @param document the document to print
+ */
+ public PDFPrinter(PDDocument document) throws PrinterException
+ {
+ this(document, PrinterJob.getPrinterJob());
+ }
+
+ /**
+ * Creates a new PDFPrinter for a given printer job.
+ * @param document the document to print
+ * @param printerJob the printer job to use
+ */
+ public PDFPrinter(PDDocument document, PrinterJob printerJob) throws PrinterException
+ {
+ if (document == null)
+ {
+ throw new IllegalArgumentException("document");
+ }
+ else if (printerJob == null)
+ {
+ throw new IllegalArgumentException("printerJob");
+ }
+ else if (!document.getCurrentAccessPermission().canPrint())
+ {
+ throw new PrinterException("You do not have permission to print this document");
+ }
+ this.document = document;
+ this.renderer = new PDFRenderer(document);
+ this.printerJob = printerJob;
+ }
+
+ /**
+ * Prints the given document using the default printer without prompting the user.
+ * @throws java.awt.print.PrinterException if the document cannot be printed
+ */
+ public void silentPrint() throws PrinterException
+ {
+ silentPrint(PrinterJob.getPrinterJob());
+ }
+
+ /**
+ * Prints the given document using the default printer without prompting the user.
+ * @param printerJob a printer job definition
+ * @throws PrinterException if the document cannot be printed
+ */
+ public void silentPrint(PrinterJob printerJob) throws PrinterException
+ {
+ print(printerJob, true);
+ }
+
+ /**
+ * Prints the given document using the default printer without prompting the user.
+ * The image is generated using {@link PageDrawer}.
+ * This is a convenience method to create the java.awt.print.PrinterJob.
+ * Advanced printing tasks can be performed using {@link #getPageable()} instead.
+ * @throws PrinterException if the document cannot be printed
+ */
+ public void print() throws PrinterException
+ {
+ print(PrinterJob.getPrinterJob());
+ }
+
+ /**
+ * Prints the given document using the default printer without prompting the user.
+ * @param printerJob the printer job.
+ * @throws PrinterException if the document cannot be printed
+ */
+ public void print(PrinterJob printerJob) throws PrinterException
+ {
+ print(printerJob, false);
+ }
+
+ // todo: new
+ public PDFPageable getPageable()
+ {
+ return new PDFPageable();
+ }
+
+ // prints a document
+ private void print(PrinterJob job, boolean isSilent) throws PrinterException
+ {
+ if (job == null)
+ {
+ throw new IllegalArgumentException("job cannot be null");
+ }
+ else
+ {
+ job.setPageable(new PDFPageable());
+ if (isSilent || job.printDialog())
+ {
+ job.print();
+ }
+ }
+ }
+
+ protected class PDFPageable implements Pageable
+ {
+ @Override
+ public int getNumberOfPages()
+ {
+ return document.getNumberOfPages();
+ }
+
+ @Override
+ public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException
+ {
+ PageFormat format = printerJob.defaultPage();
+
+ PDPage page = document.getPage(pageIndex);
+ Dimension media = page.findMediaBox().createDimension();
+ Dimension crop = page.findCropBox().createDimension();
+
+ // Center the ImageableArea if the crop is smaller than the media
+ double diffWidth = 0.0;
+ double diffHeight = 0.0;
+ if (!media.equals(crop))
+ {
+ diffWidth = (media.getWidth() - crop.getWidth()) / 2.0;
+ diffHeight = (media.getHeight() - crop.getHeight()) / 2.0;
+ }
+
+ Paper paper = format.getPaper();
+ if (media.getWidth() < media.getHeight())
+ {
+ format.setOrientation(PageFormat.PORTRAIT);
+ paper.setImageableArea(diffWidth, diffHeight, crop.getWidth(), crop.getHeight());
+ }
+ else
+ {
+ format.setOrientation(PageFormat.LANDSCAPE);
+ paper.setImageableArea(diffHeight, diffWidth, crop.getHeight(), crop.getWidth());
+ }
+ format.setPaper(paper);
+
+ return format;
+ }
+
+ @Override
+ public Printable getPrintable(int i) throws IndexOutOfBoundsException
+ {
+ if (i >= getNumberOfPages())
+ {
+ throw new IndexOutOfBoundsException(i + " >= " + getNumberOfPages());
+ }
+ return new PDFPrintable();
+ }
+ }
+
+ protected class PDFPrintable implements Printable
+ {
+ @Override
+ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
+ throws PrinterException
+ {
+ if (pageIndex < 0 || pageIndex >= document.getNumberOfPages())
+ {
+ return NO_SUCH_PAGE;
+ }
+
+ // draws to graphics using PDFRender
+ try
+ {
+ // TODO need to specify print DPI
+ renderer.renderPageToGraphics(pageIndex, (Graphics2D) graphics);
+ return PAGE_EXISTS;
+ }
+ catch (IOException io)
+ {
+ throw new PrinterIOException(io);
+ }
+ }
+ }
+}
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java?rev=1574811&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PDFRenderer.java Thu Mar 6 09:05:08 2014
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.rendering;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+
+/**
+ * Renders a PDF document to an AWT BufferedImage.
+ * This class may be overridden in order to perform custom rendering.
+ *
+ * @author John Hewson
+ * @author Andreas Lehmkühler
+ */
+public class PDFRenderer
+{
+ protected final PDDocument document;
+ // TODO keep rendering state such as caches here
+
+ /**
+ * Creates a new PDFRenderer.
+ * @param document the document to render
+ */
+ public PDFRenderer(PDDocument document)
+ {
+ this.document = document;
+ }
+
+ /**
+ * Returns the given page as an RGB image at 72 DPI
+ * @param pageIndex the zero-based index of the page to be converted.
+ * @return the rendered page image
+ * @throws IOException if the PDF cannot be read
+ */
+ public BufferedImage renderImage(int pageIndex) throws IOException
+ {
+ return renderImage(pageIndex, 1);
+ }
+
+ /**
+ * Returns the given page as an RGB image at the given scale.
+ * A scale of 1 will render at 72 DPI.
+ * @param pageIndex the zero-based index of the page to be converted
+ * @param scale the scaling factor, where 1 = 72 DPI
+ * @return the rendered page image
+ * @throws IOException if the PDF cannot be read
+ */
+ public BufferedImage renderImage(int pageIndex, float scale) throws IOException
+ {
+ return renderImage(pageIndex, scale, false);
+ }
+
+ /**
+ * Returns the given page as an RGB or ARGB image at the given scale.
+ * @param pageIndex the zero-based index of the page to be converted
+ * @param scale the scaling factor, where 1 = 72 DPI
+ * @param useAlpha true if an ARGB image is to be returned
+ * @return the rendered page image
+ * @throws IOException if the PDF cannot be read
+ */
+ public BufferedImage renderImage(int pageIndex, float scale, boolean useAlpha)
+ throws IOException
+ {
+ PDPage page = document.getPage(pageIndex);
+
+ PDRectangle cropBox = page.findCropBox();
+ float widthPt = cropBox.getWidth();
+ float heightPt = cropBox.getHeight();
+ int widthPx = Math.round(widthPt * scale);
+ int heightPx = Math.round(heightPt * scale);
+ int rotationAngle = page.findRotation();
+
+ // normalize the rotation angle
+ if (rotationAngle < 0)
+ {
+ rotationAngle += 360;
+ }
+ else if (rotationAngle >= 360)
+ {
+ rotationAngle -= 360;
+ }
+
+ int imageType = useAlpha ?
+ BufferedImage.TYPE_INT_ARGB :
+ BufferedImage.TYPE_INT_RGB;
+
+ // swap width and height
+ BufferedImage image;
+ if (rotationAngle == 90 || rotationAngle == 270)
+ {
+ image = new BufferedImage(heightPx, widthPx, imageType);
+ }
+ else
+ {
+ image = new BufferedImage(widthPx, heightPx, imageType);
+ }
+
+ // use a transparent background if the imageType supports alpha
+ Graphics2D g = image.createGraphics();
+ if (!useAlpha)
+ {
+ g.setBackground(Color.WHITE);
+ }
+
+ renderPage(page, g, image.getWidth(), image.getHeight(), scale, scale);
+ g.dispose();
+
+ return image;
+ }
+
+ /**
+ * Renders a given page to an AWT Graphics2D instance.
+ * @param pageIndex the zero-based index of the page to be converted
+ * @param graphics the Graphics2D on which to draw the page
+ * @throws IOException if the PDF cannot be read
+ */
+ public void renderPageToGraphics(int pageIndex, Graphics2D graphics) throws IOException
+ {
+ PDPage page = document.getPage(pageIndex);
+ // TODO need width/wight calculations? should these be in PageDrawer?
+ PDRectangle cropBox = page.findCropBox();
+ renderPage(page, graphics, (int)cropBox.getWidth(), (int)cropBox.getHeight(), 1f, 1f);
+ }
+
+ // renders a page to the given graphics
+ // TODO need to be able to override this
+ private void renderPage(PDPage page, Graphics2D graphics, int width, int height, float scaleX,
+ float scaleY) throws IOException
+ {
+ graphics.clearRect(0, 0, width, height);
+ int rotationAngle = page.findRotation();
+ if (rotationAngle != 0)
+ {
+ int translateX = 0;
+ int translateY = 0;
+ switch (rotationAngle)
+ {
+ case 90:
+ translateX = width;
+ break;
+ case 270:
+ translateY = height;
+ break;
+ case 180:
+ translateX = width;
+ translateY = height;
+ break;
+ default:
+ break;
+ }
+ graphics.translate(translateX, translateY);
+ graphics.rotate((float) Math.toRadians(rotationAngle));
+ }
+ // TODO should we be passing the scale to PageDrawer rather than messing with Graphics?
+ graphics.scale(scaleX, scaleY);
+ PageDrawer drawer = new PageDrawer(this); // TODO: need to make it easy to use a custom PageDrawer
+ drawer.drawPage(graphics, page, page.findCropBox());
+ drawer.dispose();
+ }
+}
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java?rev=1574811&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Thu Mar 6 09:05:08 2014
@@ -0,0 +1,876 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pdfbox.rendering;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.RenderingHints;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.cff.CFFFont;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.type1.Type1Font;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdfviewer.font.Glyph2D;
+import org.apache.pdfbox.pdfviewer.font.TTFGlyph2D;
+import org.apache.pdfbox.pdfviewer.font.Type1Glyph2D;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDMatrix;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.font.FontManager;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType0Font;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType2Font;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
+import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary;
+import org.apache.pdfbox.pdmodel.font.PDSimpleFont;
+import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+import org.apache.pdfbox.pdmodel.font.PDType1CFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.font.PDType3Font;
+import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState;
+import org.apache.pdfbox.pdmodel.graphics.PDLineDashPattern;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
+import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPattern;
+import org.apache.pdfbox.pdmodel.graphics.shading.AxialShadingPaint;
+import org.apache.pdfbox.pdmodel.graphics.shading.PDShading;
+import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType2;
+import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType3;
+import org.apache.pdfbox.pdmodel.graphics.shading.RadialShadingPaint;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
+import org.apache.pdfbox.pdmodel.graphics.state.PDTextState;
+import org.apache.pdfbox.util.Matrix;
+import org.apache.pdfbox.util.PDFStreamEngine;
+import org.apache.pdfbox.util.ResourceLoader;
+import org.apache.pdfbox.util.TextPosition;
+
+/**
+ * This will paint a page in a PDF document to a graphics context.
+ *
+ * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
+ *
+ */
+public class PageDrawer extends PDFStreamEngine
+{
+ private static final Log LOG = LogFactory.getLog(PageDrawer.class);
+ private static final Color COLOR_TRANSPARENT = new Color(0, 0, 0, 0);
+
+ // parent document renderer
+ private final PDFRenderer renderer;
+
+ private Graphics2D graphics;
+
+ // clipping winding rule used for the clipping path.
+ private int clippingWindingRule = -1;
+
+ private GeneralPath linePath = new GeneralPath();
+
+ private Map<PDFont, Glyph2D> fontGlyph2D = new HashMap<PDFont, Glyph2D>();
+ private Map<PDFont, Font> awtFonts = new HashMap<PDFont, Font>();
+
+ private int pageHeight;
+
+ /**
+ * Default constructor, loads properties from file.
+ *
+ * @throws IOException If there is an error loading properties from the file.
+ */
+ public PageDrawer(PDFRenderer renderer) throws IOException
+ {
+ super(ResourceLoader.loadProperties("org/apache/pdfbox/resources/PageDrawer.properties", true));
+ this.renderer = renderer;
+ }
+
+ /**
+ * Returns the parent renderer.
+ * @return the parent renderer.
+ */
+ public PDFRenderer getRenderer()
+ {
+ return renderer;
+ }
+
+ /**
+ * This will draw the page to the requested context.
+ *
+ * @param g The graphics context to draw onto.
+ * @param page The page to draw.
+ * @param pageSize The size of the page to draw.
+ *
+ * @throws IOException If there is an IO error while drawing the page.
+ */
+ public void drawPage(Graphics g, PDPage page, PDRectangle pageSize) throws IOException
+ {
+ graphics = (Graphics2D) g;
+ pageHeight = (int)pageSize.getHeight();
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ graphics.translate(0, pageHeight);
+ graphics.scale(1, -1);
+ // TODO use getStroke() to set the initial stroke
+ graphics.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
+
+ // Only if there is some content, we have to process it.
+ // Otherwise we are done here and we will produce an empty page
+ if (page.getContents() != null)
+ {
+ PDResources resources = page.findResources();
+ processStream(resources, page.getContents().getStream(), page.findCropBox(), page.findRotation());
+ }
+
+ List<PDAnnotation> annotations = page.getAnnotations();
+ for (int i = 0; i < annotations.size(); i++)
+ {
+ PDAnnotation annot = (PDAnnotation) annotations.get(i);
+ PDRectangle rect = annot.getRectangle();
+ String appearanceName = annot.getAppearanceStream();
+ PDAppearanceDictionary appearDictionary = annot.getAppearance();
+ if (appearDictionary != null)
+ {
+ if (appearanceName == null)
+ {
+ appearanceName = "default";
+ }
+ Map<String, PDAppearanceStream> appearanceMap = appearDictionary.getNormalAppearance();
+ if (appearanceMap != null)
+ {
+ PDAppearanceStream appearance = (PDAppearanceStream) appearanceMap.get(appearanceName);
+ if (appearance != null)
+ {
+ Point2D point = new Point2D.Float(rect.getLowerLeftX(), rect.getLowerLeftY());
+ Matrix matrix = appearance.getMatrix();
+ if (matrix != null)
+ {
+ // transform the rectangle using the given matrix
+ AffineTransform at = matrix.createAffineTransform();
+ at.scale(1, -1);
+ at.transform(point, point);
+ }
+ graphics.translate((int) point.getX(), -(int) point.getY());
+ processSubStream(appearance.getResources(), appearance.getStream());
+ graphics.translate(-(int) point.getX(), (int) point.getY());
+ }
+ }
+ }
+ }
+ graphics = null;
+ }
+
+ /**
+ * This will draw the pattern stream to the requested context.
+ *
+ * @param g The graphics context to draw onto.
+ * @param pattern The tiling pattern to be used.
+ * @param pageDimension The size of the page to draw.
+ * @throws IOException If there is an IO error while drawing the page.
+ */
+ public void drawTilingPattern(Graphics2D g, PDTilingPattern pattern, PDRectangle pageDimension,
+ Matrix matrix, PDColorSpace colorSpace, PDColor color)
+ throws IOException
+ {
+ graphics = g;
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ initStream(pageDimension, 0);
+
+ // transform ctm
+ Matrix concat = getGraphicsState().getCurrentTransformationMatrix().multiply(matrix);
+ getGraphicsState().setCurrentTransformationMatrix(concat);
+
+ // color
+ if (colorSpace != null)
+ {
+ getGraphicsState().setNonStrokingColorSpace(colorSpace);
+ getGraphicsState().setNonStrokingColor(color);
+ getGraphicsState().setStrokingColorSpace(colorSpace);
+ getGraphicsState().setStrokingColor(color);
+ }
+
+ processSubStream(pattern.getResources(), (COSStream)pattern.getCOSObject());
+ }
+
+ /**
+ * Remove all cached resources.
+ */
+ public void dispose()
+ {
+ super.dispose();
+ if (fontGlyph2D != null)
+ {
+ Iterator<Glyph2D> iter = fontGlyph2D.values().iterator();
+ while (iter.hasNext())
+ {
+ iter.next().dispose();
+ }
+ fontGlyph2D.clear();
+ fontGlyph2D = null;
+ }
+ if (awtFonts != null)
+ {
+ awtFonts.clear();
+ }
+ graphics = null;
+ linePath = null;
+ }
+
+ /**
+ * You should override this method if you want to perform an action when a text is being processed.
+ *
+ * @param text The text to process
+ */
+ protected void processTextPosition(TextPosition text)
+ {
+ try
+ {
+ PDGraphicsState graphicsState = getGraphicsState();
+ Composite composite;
+ Paint paint;
+ switch (graphicsState.getTextState().getRenderingMode())
+ {
+ case PDTextState.RENDERING_MODE_FILL_TEXT:
+ composite = graphicsState.getNonStrokeJavaComposite();
+ paint = getNonStrokingPaint();
+ break;
+ case PDTextState.RENDERING_MODE_STROKE_TEXT:
+ composite = graphicsState.getStrokeJavaComposite();
+ paint = getStrokingPaint();
+ break;
+ case PDTextState.RENDERING_MODE_NEITHER_FILL_NOR_STROKE_TEXT:
+ // basic support for text rendering mode "invisible"
+ // TODO why are we drawing anything at all?
+ paint = COLOR_TRANSPARENT;
+ composite = graphicsState.getStrokeJavaComposite();
+ break;
+ default:
+ // TODO : need to implement....
+ LOG.debug("Unsupported RenderingMode " + this.getGraphicsState().getTextState().getRenderingMode()
+ + " in PageDrawer.processTextPosition()." + " Using RenderingMode "
+ + PDTextState.RENDERING_MODE_FILL_TEXT + " instead");
+ composite = graphicsState.getNonStrokeJavaComposite();
+ paint = getNonStrokingPaint();
+ }
+ graphics.setComposite(composite);
+ graphics.setPaint(paint);
+
+ PDFont font = text.getFont();
+ AffineTransform at = text.getTextPos().createAffineTransform();
+ PDMatrix fontMatrix = font.getFontMatrix();
+ // TODO setClip() is a massive performance hot spot. Investigate optimization possibilities
+ graphics.setClip(graphicsState.getCurrentClippingPath());
+
+ // use different methods to draw the string
+ if (font.isType3Font())
+ {
+ // Type3 fonts don't use the same units within the font matrix as all the other fonts
+ at.scale(fontMatrix.getValue(0, 0), fontMatrix.getValue(1, 1));
+ // Type3 fonts are using streams for each character
+ drawType3String((PDType3Font) font, text, at);
+ }
+ else
+ {
+ Glyph2D glyph2D = createGlyph2D(font);
+ if (glyph2D != null)
+ {
+ AffineTransform fontMatrixAT = new AffineTransform(fontMatrix.getValue(0, 0), fontMatrix.getValue(
+ 0, 1), fontMatrix.getValue(1, 0), fontMatrix.getValue(1, 1), fontMatrix.getValue(2, 0),
+ fontMatrix.getValue(2, 1));
+ at.concatenate(fontMatrixAT);
+ // Let PDFBox render the font if supported
+ drawGlyph2D(glyph2D, text.getCodePoints(), at);
+ }
+ else
+ {
+ // Use AWT to render the font (standard14 fonts, substituted embedded fonts)
+ // TODO to be removed in the long run
+ drawString((PDSimpleFont) font, text.getCharacter(), at);
+ }
+ }
+ }
+ catch (IOException io)
+ {
+ io.printStackTrace();
+ }
+ }
+
+ /**
+ * Render the font using the Glyph2d interface.
+ *
+ * @param glyph2D the Glyph2D implementation provided a GeneralPath for each glyph
+ * @param codePoints the string to be rendered
+ * @param at the transformation
+ * @throws IOException if something went wrong
+ */
+ private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, AffineTransform at) throws IOException
+ {
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ for (int i = 0; i < codePoints.length; i++)
+ {
+ GeneralPath path = glyph2D.getPathForCharacterCode(codePoints[i]);
+ if (path != null)
+ {
+ AffineTransform atInverse = null;
+ if (!at.isIdentity())
+ {
+ try
+ {
+ atInverse = at.createInverse();
+ }
+ catch (NoninvertibleTransformException exception)
+ {
+ LOG.error("Can't invert the given affine transformation", exception);
+ }
+ }
+ if (atInverse != null)
+ {
+ graphics.transform(at);
+ }
+ graphics.fill(path);
+ if (atInverse != null)
+ {
+ graphics.transform(atInverse);
+ }
+ }
+ }
+ }
+
+ /**
+ * Render the text using a type 3 font.
+ *
+ * @param font the type3 font
+ * @param text the text to be rendered
+ * @param at the transformation
+ *
+ * @throws IOException if something went wrong
+ */
+ private void drawType3String(PDType3Font font, TextPosition text, AffineTransform at) throws IOException
+ {
+ int[] codePoints = text.getCodePoints();
+ int textLength = codePoints.length;
+ for (int i = 0; i < textLength; i++)
+ {
+ COSStream stream = font.getCharStream((char)codePoints[i]);
+ if (stream != null)
+ {
+ // save the current graphics state
+ getGraphicsStack().push((PDGraphicsState) getGraphicsState().clone());
+
+ Matrix ctm = new Matrix();
+ ctm.setFromAffineTransform(at);
+ getGraphicsState().setCurrentTransformationMatrix(ctm);
+ processSubStream(font.getType3Resources(), stream);
+
+ // restore the saved graphics state
+ setGraphicsState(getGraphicsStack().pop());
+ }
+ else
+ {
+ LOG.debug("drawType3String: stream for character " + (char)codePoints[i] + " not found");
+ }
+ }
+ }
+
+ /**
+ * This will draw a string on a canvas using the font.
+ *
+ * @param font the font to be used to draw the string
+ * @param string The string to draw.
+ * @param at The transformation matrix with all information for scaling and shearing of the font.
+ *
+ * @throws IOException If there is an error drawing the specific string.
+ */
+ private void drawString(PDSimpleFont font, String string, AffineTransform at) throws IOException
+ {
+ Font awtFont = createAWTFont(font);
+ FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
+ GlyphVector glyphs = awtFont.createGlyphVector(frc, string);
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ writeFont(at, glyphs);
+ }
+
+ private void writeFont(final AffineTransform at, final GlyphVector glyphs)
+ {
+ try
+ {
+ // Convert from PDF, where glyphs are upright when direction is from
+ // bottom to top, to AWT, where this is the other way around
+ at.scale(1, -1);
+ AffineTransform atInverse = at.createInverse();
+ graphics.transform(at);
+ graphics.drawGlyphVector(glyphs, 0, 0);
+ graphics.transform(atInverse);
+ }
+ catch (NoninvertibleTransformException exception)
+ {
+ LOG.error("Can't invert the given affine transformation", exception);
+ }
+ }
+
+ /**
+ * Provides an AWT font for the given PDFont.
+ *
+ * @param font the font which needs an AWT font
+ * @return the corresponding AWT font
+ * @throws IOException if something went wrong
+ */
+ private Font createAWTFont(PDSimpleFont font) throws IOException
+ {
+ Font awtFont = null;
+ // Is there already a AWTFont for the given font?
+ if (awtFonts.containsKey(font))
+ {
+ awtFont = awtFonts.get(font);
+ }
+ else
+ {
+ if (font instanceof PDType1Font)
+ {
+ PDType1Font type1Font = (PDType1Font) font;
+ PDFontDescriptor fd = type1Font.getFontDescriptor();
+ if (fd instanceof PDFontDescriptorDictionary)
+ {
+ PDFontDescriptorDictionary fdDictionary = (PDFontDescriptorDictionary) fd;
+ if (fdDictionary.getFontFile() == null)
+ {
+ // check if the font is part of our environment
+ if (fd.getFontName() != null)
+ {
+ awtFont = FontManager.getAwtFont(fd.getFontName());
+ }
+ if (awtFont != null)
+ {
+ type1Font.setIsFontSubstituted(true);
+ }
+ else
+ {
+ LOG.info("Can't find the specified font " + fd.getFontName());
+ }
+ }
+ }
+ else
+ {
+ // check if the font is part of our environment
+ String baseFont = type1Font.getBaseFont();
+ awtFont = FontManager.getAwtFont(baseFont);
+ if (awtFont == null)
+ {
+ LOG.info("Can't find the specified basefont " + baseFont);
+ }
+ }
+ }
+ else
+ {
+ LOG.info("Unsupported type of font " + font.getClass().getName());
+ }
+ if (awtFont == null)
+ {
+ // Fallback: we can't find anything, so we have to use the standard font
+ awtFont = FontManager.getStandardFont();
+ LOG.info("Using font " + awtFont.getName() + " instead of " + font.getBaseFont());
+ font.setIsFontSubstituted(true);
+ }
+ awtFonts.put(font, awtFont);
+ }
+ return awtFont;
+ }
+
+ /**
+ * Provide a Glyph2D for the given font.
+ *
+ * @param font the font
+ * @return the implementation of the Glyph2D interface for the given font
+ * @throws IOException if something went wrong
+ */
+ private Glyph2D createGlyph2D(PDFont font) throws IOException
+ {
+ Glyph2D glyph2D = null;
+ // Is there already a Glyph2D for the given font?
+ if (fontGlyph2D.containsKey(font))
+ {
+ glyph2D = fontGlyph2D.get(font);
+ }
+ else
+ {
+ // check if the given font is supported
+ if (font instanceof PDTrueTypeFont)
+ {
+ PDTrueTypeFont ttfFont = (PDTrueTypeFont) font;
+ // get the true type font raw data
+ TrueTypeFont ttf = ttfFont.getTTFFont();
+ if (ttf != null)
+ {
+ glyph2D = new TTFGlyph2D(ttf, font);
+ }
+ }
+ else if (font instanceof PDType1Font)
+ {
+ PDType1Font pdType1Font = (PDType1Font) font;
+ PDType1CFont type1CFont = pdType1Font.getType1CFont();
+ if (type1CFont != null)
+ {
+ // get the cffFont raw data
+ CFFFont cffFont = type1CFont.getCFFFont();
+ if (cffFont != null)
+ {
+ glyph2D = new Type1Glyph2D(cffFont, type1CFont.getFontEncoding());
+ }
+ }
+ else
+ {
+ // get the pfb raw data
+ Type1Font type1Font = pdType1Font.getType1Font();
+ if (type1Font != null)
+ {
+ glyph2D = new Type1Glyph2D(type1Font, pdType1Font.getFontEncoding());
+ }
+ }
+ }
+ else if (font instanceof PDType0Font)
+ {
+ PDType0Font type0Font = (PDType0Font) font;
+ if (type0Font.getDescendantFont() instanceof PDCIDFontType2Font)
+ {
+ // a CIDFontType2Font contains TTF font
+ PDCIDFontType2Font cidType2Font = (PDCIDFontType2Font) type0Font.getDescendantFont();
+ // get the true type font raw data
+ TrueTypeFont ttf = cidType2Font.getTTFFont();
+ if (ttf != null)
+ {
+ glyph2D = new TTFGlyph2D(ttf, font, cidType2Font);
+ }
+ }
+ else if (type0Font.getDescendantFont() instanceof PDCIDFontType0Font)
+ {
+ // a CIDFontType2Font contains TTF font
+ PDCIDFontType0Font cidType2Font = (PDCIDFontType0Font) type0Font.getDescendantFont();
+ PDType1CFont type1CFont = cidType2Font.getType1CFont();
+ if (type1CFont != null)
+ {
+ // get the cffFont raw data
+ CFFFont cffFont = type1CFont.getCFFFont();
+ if (cffFont != null)
+ {
+ glyph2D = new Type1Glyph2D(cffFont, type1CFont.getFontEncoding());
+ }
+ }
+ }
+ }
+ // cache the Glyph2D instance
+ if (glyph2D != null)
+ {
+ fontGlyph2D.put(font, glyph2D);
+ }
+ }
+ return glyph2D;
+ }
+
+ /**
+ * Get the current line path to be drawn.
+ *
+ * @return The current line path to be drawn.
+ */
+ public GeneralPath getLinePath()
+ {
+ return linePath;
+ }
+
+ // returns the stroking AWT Paint
+ private Paint getStrokingPaint() throws IOException
+ {
+ return getGraphicsState().getStrokingColorSpace()
+ .toPaint(renderer, getGraphicsState().getStrokingColor(), pageHeight);
+ }
+
+ // returns the non-stroking AWT Paint
+ private Paint getNonStrokingPaint() throws IOException
+ {
+ return getGraphicsState().getNonStrokingColorSpace()
+ .toPaint(renderer, getGraphicsState().getNonStrokingColor(), pageHeight);
+ }
+
+ // create a new stroke based on the current CTM and the current stroke
+ private BasicStroke getStroke()
+ {
+ PDGraphicsState state = getGraphicsState();
+
+ // apply the CTM
+ float lineWidth = transformWidth(state.getLineWidth());
+
+ // minimum line width as used by Adobe Reader
+ if (lineWidth < 0.25)
+ {
+ lineWidth = 0.25f;
+ }
+
+ PDLineDashPattern dashPattern = state.getLineDashPattern();
+ int phaseStart = dashPattern.getPhase();
+ float[] dashArray = dashPattern.getDashArray();
+ if (dashArray != null)
+ {
+ // apply the CTM
+ for (int i = 0; i < dashArray.length; ++i)
+ {
+ dashArray[i] = transformWidth(dashArray[i]);
+ }
+ phaseStart = (int)transformWidth(phaseStart);
+
+ // empty dash array is illegal
+ if (dashArray.length == 0)
+ {
+ dashArray = null;
+ }
+ }
+ return new BasicStroke(lineWidth, state.getLineCap(), state.getLineJoin(),
+ state.getMiterLimit(), dashArray, phaseStart);
+ }
+
+ /**
+ * Stroke the path.
+ *
+ * @throws IOException If there is an IO error while stroking the path.
+ */
+ public void strokePath() throws IOException
+ {
+ graphics.setComposite(getGraphicsState().getStrokeJavaComposite());
+ Paint strokingPaint = getStrokingPaint();
+ if (strokingPaint == null)
+ {
+ LOG.info("ColorSpace " + getGraphicsState().getStrokingColorSpace().getName() +
+ " doesn't provide a stroking color, using white instead!");
+ strokingPaint = Color.WHITE;// ((PageDrawer)context).strokePath();
+ }
+ graphics.setPaint(strokingPaint);
+ graphics.setStroke(getStroke());
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ graphics.setClip(getGraphicsState().getCurrentClippingPath());
+ graphics.draw(linePath);
+ linePath.reset();
+ }
+
+ /**
+ * Fill the path.
+ *
+ * @param windingRule The winding rule this path will use.
+ *
+ * @throws IOException If there is an IO error while filling the path.
+ */
+ public void fillPath(int windingRule) throws IOException
+ {
+ graphics.setComposite(getGraphicsState().getNonStrokeJavaComposite());
+ Paint nonStrokingPaint = getNonStrokingPaint();
+ if (nonStrokingPaint == null)
+ {
+ LOG.info("ColorSpace " + getGraphicsState().getNonStrokingColorSpace().getName() +
+ " doesn't provide a non-stroking color, using white instead!");
+ nonStrokingPaint = Color.WHITE;
+ }
+ graphics.setPaint(nonStrokingPaint);
+ linePath.setWindingRule(windingRule);
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ graphics.setClip(getGraphicsState().getCurrentClippingPath());
+ graphics.fill(linePath);
+ linePath.reset();
+ }
+
+ /**
+ * Strokes and fills the path.
+ *
+ * @param windingRule The winding rule this path will use.
+ *
+ * @throws IOException If there is an IO error while filling the path.
+ */
+ public void strokeAndFillPath(int windingRule) throws IOException
+ {
+ // TODO can we avoid cloning the path?
+ GeneralPath path = (GeneralPath)linePath.clone();
+ strokePath();
+ linePath = path;
+ fillPath(windingRule);
+ }
+
+ // This code generalizes the code Jim Lynch wrote for AppendRectangleToPath
+ /**
+ * use the current transformation matrix to transform a single point.
+ *
+ * @param x x-coordinate of the point to be transform
+ * @param y y-coordinate of the point to be transform
+ * @return the transformed coordinates as Point2D.Double
+ */
+ public Point2D.Double transformedPoint(double x, double y)
+ {
+ double[] position = { x, y };
+ getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
+ .transform(position, 0, position, 0, 1);
+ return new Point2D.Double(position[0], position[1]);
+ }
+
+ // transforms a width using the CTM
+ private float transformWidth(float width)
+ {
+ Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
+
+ if (ctm == null)
+ {
+ // TODO does the CTM really need to use null?
+ return width;
+ }
+
+ float x = ctm.getValue(0, 0) + ctm.getValue(1, 0);
+ float y = ctm.getValue(0, 1) + ctm.getValue(1, 1);
+ return width * (float)Math.sqrt((x * x + y * y) * 0.5);
+ }
+
+ /**
+ * Set the clipping Path.
+ *
+ * @param windingRule The winding rule this path will use.
+ *
+ * @deprecated use {@link #setClippingWindingRule(int)} instead
+ *
+ */
+ public void setClippingPath(int windingRule)
+ {
+ setClippingWindingRule(windingRule);
+ }
+
+ /**
+ * Set the clipping winding rule.
+ *
+ * @param windingRule The winding rule which will be used for clipping.
+ *
+ */
+ public void setClippingWindingRule(int windingRule)
+ {
+ clippingWindingRule = windingRule;
+ }
+
+ /**
+ * Set the clipping Path.
+ *
+ */
+ public void endPath()
+ {
+ if (clippingWindingRule > -1)
+ {
+ PDGraphicsState graphicsState = getGraphicsState();
+ GeneralPath clippingPath = (GeneralPath) linePath.clone(); // TODO do we really need to clone this? isn't the line path reset anyway?
+ clippingPath.setWindingRule(clippingWindingRule);
+ // If there is already set a clipping path, we have to intersect the new with the existing one
+ if (graphicsState.getCurrentClippingPath() != null)
+ {
+ Area currentArea = new Area(getGraphicsState().getCurrentClippingPath());
+ Area newArea = new Area(clippingPath);
+ currentArea.intersect(newArea);
+ graphicsState.setCurrentClippingPath(currentArea);
+ }
+ else
+ {
+ graphicsState.setCurrentClippingPath(clippingPath);
+ }
+ clippingWindingRule = -1;
+ }
+ linePath.reset();
+ }
+
+ /**
+ * Draw the AWT image. Called by Invoke. Moved into PageDrawer so that Invoke doesn't have to reach in here for
+ * Graphics as that breaks extensibility.
+ *
+ * @param awtImage The image to draw.
+ * @param at The transformation to use when drawing.
+ *
+ */
+ public void drawImage(Image awtImage, AffineTransform at)
+ {
+ graphics.setComposite(getGraphicsState().getNonStrokeJavaComposite());
+ graphics.setClip(getGraphicsState().getCurrentClippingPath());
+ int width = awtImage.getWidth(null);
+ int height = awtImage.getHeight(null);
+ AffineTransform imageTransform = new AffineTransform(at);
+ imageTransform.scale(1.0 / width, -1.0 / height);
+ imageTransform.translate(0, -height);
+ graphics.drawImage(awtImage, imageTransform, null);
+ }
+
+ /**
+ * Fill with Shading. Called by SHFill operator.
+ *
+ * @param shadingName The name of the Shading Dictionary to use for this fill instruction.
+ *
+ * @throws IOException If there is an IO error while shade-filling the clipping area.
+ */
+ // TODO would this now be better off using PDPattern?
+ public void shFill(COSName shadingName) throws IOException
+ {
+ PDShading shading = getResources().getShadings().get(shadingName.getName());
+ LOG.debug("Shading = " + shading.toString());
+ int shadingType = shading.getShadingType();
+ Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
+ Paint paint = null;
+ switch (shadingType)
+ {
+ case 1:
+ // TODO
+ LOG.debug("Function based shading not yet supported");
+ break;
+ case 2:
+ paint = new AxialShadingPaint((PDShadingType2) shading, ctm, pageHeight);
+ break;
+ case 3:
+ paint = new RadialShadingPaint((PDShadingType3) shading, ctm, pageHeight);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // TODO
+ LOG.debug("Shading type " + shadingType + " not yet supported");
+ break;
+ default:
+ throw new IOException("Invalid ShadingType " + shadingType + " for Shading " + shadingName);
+ }
+ graphics.setComposite(getGraphicsState().getNonStrokeJavaComposite());
+ graphics.setPaint(paint);
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ graphics.fill(getGraphicsState().getCurrentClippingPath());
+ }
+}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/ImageIOUtil.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/ImageIOUtil.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/ImageIOUtil.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/ImageIOUtil.java Thu Mar 6 09:05:08 2014
@@ -80,15 +80,13 @@ public class ImageIOUtil
* @param image the image to be written
* @param imageFormat the target format (ex. "png")
* @param filename used to construct the filename for the individual images
- * @param imageType the image type (see {@link BufferedImage}.TYPE_*)
* @param resolution the resolution in dpi (dots per inch)
*
* @return true if the images were produced, false if there was an error
* @throws IOException if an I/O error occurs
*/
- public static boolean writeImage(BufferedImage image, String imageFormat, String filename,
- int imageType, int resolution)
- throws IOException
+ public static boolean writeImage(BufferedImage image, String imageFormat, String filename,
+ int resolution) throws IOException
{
String fileName = filename + "." + imageFormat;
File file = new File(fileName);
@@ -105,8 +103,8 @@ public class ImageIOUtil
* @return true if the images were produced, false if there was an error
* @throws IOException if an I/O error occurs
*/
- public static boolean writeImage(BufferedImage image, String imageFormat, OutputStream outputStream)
- throws IOException
+ public static boolean writeImage(BufferedImage image, String imageFormat,
+ OutputStream outputStream) throws IOException
{
return writeImage(image, imageFormat, outputStream, DEFAULT_SCREEN_RESOLUTION);
}
@@ -122,8 +120,8 @@ public class ImageIOUtil
* @return true if the images were produced, false if there was an error
* @throws IOException if an I/O error occurs
*/
- public static boolean writeImage(BufferedImage image, String imageFormat, Object outputStream, int resolution)
- throws IOException
+ public static boolean writeImage(BufferedImage image, String imageFormat, Object outputStream,
+ int resolution) throws IOException
{
return writeImage(image, imageFormat, outputStream, resolution, DEFAULT_COMPRESSION_QUALITY);
}
@@ -141,9 +139,8 @@ public class ImageIOUtil
* @return true if the images were produced, false if there was an error
* @throws IOException if an I/O error occurs
*/
- public static boolean writeImage(BufferedImage image, String imageFormat, Object outputStream, int resolution,
- float quality)
- throws IOException
+ public static boolean writeImage(BufferedImage image, String imageFormat, Object outputStream,
+ int resolution, float quality) throws IOException
{
boolean bSuccess = true;
ImageOutputStream output = null;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/AppendRectangleToPath.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/AppendRectangleToPath.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/AppendRectangleToPath.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/AppendRectangleToPath.java Thu Mar 6 09:05:08 2014
@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
import org.apache.pdfbox.pdmodel.graphics.image.PDInlineImage;
@@ -50,7 +50,7 @@ public final class BeginInlineImage exte
{
PDColorSpace colorSpace = drawer.getGraphicsState().getNonStrokingColorSpace();
PDColor color = drawer.getGraphicsState().getNonStrokingColor();
- awtImage = image.getStencilImage(colorSpace.toPaint(color)); // <--- TODO: pass page height?
+ awtImage = image.getStencilImage(colorSpace.toPaint(drawer.getRenderer(), color)); // <--- TODO: pass page height?
}
else
{
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipEvenOddRule.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipEvenOddRule.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipEvenOddRule.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipEvenOddRule.java Thu Mar 6 09:05:08 2014
@@ -20,7 +20,7 @@ import java.awt.geom.GeneralPath;
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipNonZeroRule.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipNonZeroRule.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipNonZeroRule.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClipNonZeroRule.java Thu Mar 6 09:05:08 2014
@@ -20,7 +20,7 @@ import java.awt.geom.GeneralPath;
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClosePath.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClosePath.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClosePath.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/ClosePath.java Thu Mar 6 09:05:08 2014
@@ -19,7 +19,7 @@ package org.apache.pdfbox.util.operator.
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveTo.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveTo.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveTo.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveTo.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.awt.geom.Point2D;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateFinalPoint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateFinalPoint.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateFinalPoint.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateFinalPoint.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.awt.geom.Point2D;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateInitialPoint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateInitialPoint.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateInitialPoint.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/CurveToReplicateInitialPoint.java Thu Mar 6 09:05:08 2014
@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/EndPath.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/EndPath.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/EndPath.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/EndPath.java Thu Mar 6 09:05:08 2014
@@ -19,7 +19,7 @@ package org.apache.pdfbox.util.operator.
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddAndStrokePath.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddAndStrokePath.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddAndStrokePath.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddAndStrokePath.java Thu Mar 6 09:05:08 2014
@@ -19,7 +19,7 @@ package org.apache.pdfbox.util.operator.
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddRule.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddRule.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddRule.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillEvenOddRule.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroAndStrokePath.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroAndStrokePath.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroAndStrokePath.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroAndStrokePath.java Thu Mar 6 09:05:08 2014
@@ -19,7 +19,7 @@ package org.apache.pdfbox.util.operator.
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroRule.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroRule.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroRule.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/FillNonZeroRule.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java Thu Mar 6 09:05:08 2014
@@ -28,7 +28,7 @@ import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.filter.MissingImageReaderException;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
@@ -71,7 +71,7 @@ public final class Invoke extends Operat
{
PDColorSpace colorSpace = drawer.getGraphicsState().getNonStrokingColorSpace();
PDColor color = drawer.getGraphicsState().getNonStrokingColor();
- awtImage = image.getStencilImage(colorSpace.toPaint(color)); // <--- TODO: pass page height?
+ awtImage = image.getStencilImage(colorSpace.toPaint(drawer.getRenderer(), color)); // <--- TODO: pass page height?
}
else
{
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/LineTo.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/LineTo.java?rev=1574811&r1=1574810&r2=1574811&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/LineTo.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/LineTo.java Thu Mar 6 09:05:08 2014
@@ -21,7 +21,7 @@ import java.awt.geom.Point2D;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.pdfviewer.PageDrawer;
+import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.util.PDFOperator;
import org.apache.pdfbox.util.operator.OperatorProcessor;