Author: lehmi Date: Mon Feb 10 21:47:56 2014 New Revision: 1566760 URL: http://svn.apache.org/r1566760 Log: PDFBOX-1094: added colored tiling support
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java (with props) pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java (with props) pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html (with props) Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDRectangle.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPatternResources.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java?rev=1566760&r1=1566759&r2=1566760&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java Mon Feb 10 21:47:56 2014 @@ -82,9 +82,9 @@ import org.apache.pdfbox.util.TextPositi /** * This will paint a page in a PDF document to a graphics context. - * + * * @author <a href="mailto:b...@benlitchfield.com">Ben Litchfield</a> - * + * */ public class PageDrawer extends PDFStreamEngine { @@ -182,10 +182,30 @@ public class PageDrawer extends PDFStrea } /** + * This will draw the page to the requested context. + * + * @param g The graphics context to draw onto. + * @param stream The stream to be used. + * @param resources resources to be used when drawing the stream + * @param pageDimension The size of the page to draw. + * + * @throws IOException If there is an IO error while drawing the page. + */ + public void drawStream(Graphics g, COSStream stream, PDResources resources, PDRectangle pageDimension) + throws IOException + { + graphics = (Graphics2D) g; + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); + processStream(resources, stream, pageDimension, 0); + } + + /** * Remove all cached resources. */ public void dispose() { + super.dispose(); if (fontGlyph2D != null) { Iterator<Glyph2D> iter = fontGlyph2D.values().iterator(); @@ -358,7 +378,6 @@ public class PageDrawer extends PDFStrea ctm.setFromAffineTransform(at); getGraphicsState().setCurrentTransformationMatrix(ctm); processSubStream(font.getType3Resources(), stream); - // restore the saved graphics state setGraphicsState((PDGraphicsState) getGraphicsStack().pop()); } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDRectangle.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDRectangle.java?rev=1566760&r1=1566759&r2=1566760&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDRectangle.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDRectangle.java Mon Feb 10 21:47:56 2014 @@ -29,7 +29,7 @@ import java.awt.Dimension; * This represents a rectangle in a PDF document. * * @author <a href="mailto:b...@benlitchfield.com">Ben Litchfield</a> - * @version $Revision: 1.12 $ + * */ public class PDRectangle implements COSObjectable { @@ -42,11 +42,7 @@ public class PDRectangle implements COSO */ public PDRectangle() { - rectArray = new COSArray(); - rectArray.add( new COSFloat( 0.0f ) ); - rectArray.add( new COSFloat( 0.0f ) ); - rectArray.add( new COSFloat( 0.0f ) ); - rectArray.add( new COSFloat( 0.0f ) ); + this(0.0f, 0.0f, 0.0f, 0.0f); } /** @@ -57,9 +53,22 @@ public class PDRectangle implements COSO */ public PDRectangle( float width, float height ) { + this(0.0f, 0.0f, width, height); + } + + /** + * Constructor. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param width The width of the rectangle. + * @param height The height of the rectangle. + */ + public PDRectangle( float x, float y, float width, float height ) + { rectArray = new COSArray(); - rectArray.add( new COSFloat( 0.0f ) ); - rectArray.add( new COSFloat( 0.0f ) ); + rectArray.add( new COSFloat( x ) ); + rectArray.add( new COSFloat( y ) ); rectArray.add( new COSFloat( width ) ); rectArray.add( new COSFloat( height ) ); } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPatternResources.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPatternResources.java?rev=1566760&r1=1566759&r2=1566760&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPatternResources.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPatternResources.java Mon Feb 10 21:47:56 2014 @@ -21,24 +21,51 @@ import java.awt.Paint; import java.awt.geom.AffineTransform; import java.io.IOException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSFloat; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSNumber; -import org.apache.pdfbox.pdmodel.graphics.pattern.PDPatternResources; import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.graphics.pattern.tiling.ColoredTilingPaint; import org.apache.pdfbox.util.Matrix; /** * This represents the resources for a tiling pattern. * - * @version $Revision: 1.0 $ */ public class PDTilingPatternResources extends PDPatternResources { - + /** + * Log instance. + */ + private static final Log LOG = LogFactory.getLog(PDTilingPatternResources.class); + + /** + * paint type 1 = colored tiling pattern. + */ + public static final int COLORED_TILING_PATTERN = 1; + /** + * paint type 2 = uncolored tiling pattern. + */ + public static final int UNCOLORED_TILING_PATTERN = 2; + + /** + * tiling type 1 = constant spacing. + */ + public static final int TILING_CONSTANT_SPACING = 1; + /** + * tiling type 2 = no distortion. + */ + public static final int TILING_NO_DISTORTION = 2; + /** + * tiling type 3 = constant spacing and faster tiling. + */ + public static final int TILING_CONSTANT_SPACING_FASTER_TILING = 3; + /** * Default constructor. */ @@ -279,8 +306,20 @@ public class PDTilingPatternResources ex @Override public Paint getPaint(int pageHeight) throws IOException { - // TODO Auto-generated method stub - return null; + Paint paint = null; + int paintType = getPaintType(); + switch (paintType) + { + case COLORED_TILING_PATTERN: + paint = new ColoredTilingPaint(this); + break; + case UNCOLORED_TILING_PATTERN: + LOG.debug("Error: Unsupported pattern type " + paintType); + break; + default: + throw new IOException("Error: Unknown paint type " + getPaintType()); + } + return paint; } } Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java?rev=1566760&view=auto ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java (added) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java Mon Feb 10 21:47:56 2014 @@ -0,0 +1,136 @@ +/* + * 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.pdmodel.graphics.pattern.tiling; + +import java.awt.PaintContext; +import java.awt.color.ColorSpace; +import java.awt.image.ColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.util.Arrays; + +import org.apache.pdfbox.pdmodel.common.PDRectangle; + +/** + * This class represents the PaintContext of an axial shading. + * + */ +public class ColoredTilingContext implements PaintContext +{ + + private ColorModel outputColorModel; + private Raster tilingImage; + + private int xstep; + private int ystep; + private int lowerLeftX; + private int lowerLeftY; + + /** + * Constructor creates an instance to be used for fill operations. + * + * @param cm the colormodel to be used + * @param image the tiling image + * @param xStep horizontal spacing between pattern cells + * @param yStep vertical spacing between pattern cells + * @param bBox bounding box of the tiling image + * + */ + public ColoredTilingContext(ColorModel cm, Raster image, int xStep, int yStep, PDRectangle bBox) + { + outputColorModel = cm; + tilingImage = image; + xstep = Math.abs(xStep); + ystep = Math.abs(yStep); + lowerLeftX = (int) bBox.getLowerLeftX(); + lowerLeftY = (int) bBox.getLowerLeftY(); + } + + /** + * {@inheritDoc} + */ + public void dispose() + { + outputColorModel = null; + tilingImage = null; + } + + /** + * {@inheritDoc} + */ + public ColorModel getColorModel() + { + return outputColorModel; + } + + /** + * {@inheritDoc} + */ + public Raster getRaster(int x, int y, int w, int h) + { + // get underlying colorspace + ColorSpace cs = getColorModel().getColorSpace(); + // number of color components including alpha channel + int numComponents = cs.getNumComponents() + 1; + // all the data, plus alpha channel + int[] imgData = new int[w * h * (numComponents)]; + + // array holding the processed pixels + int[] pixel = new int[numComponents]; + + // for each device coordinate + for (int j = 0; j < h; j++) + { + for (int i = 0; i < w; i++) + { + // figure out what pixel we are at relative to the image + int xloc = (x + i) - lowerLeftX; + int yloc = (y + j) - lowerLeftY; + + xloc %= xstep; + yloc %= ystep; + + if (xloc < 0) + { + xloc = xstep + xloc; + } + if (yloc < 0) + { + yloc = ystep + yloc; + } + + // check if we are inside the image + if (xloc < tilingImage.getWidth() && yloc < tilingImage.getHeight()) + { + tilingImage.getPixel(xloc, yloc, pixel); + } + else + { + Arrays.fill(pixel, 0); + } + int base = (j * w + i) * numComponents; + for (int c = 0; c < numComponents; c++) + { + imgData[base + c] = pixel[c]; + } + } + } + WritableRaster raster = getColorModel().createCompatibleWritableRaster(w, h); + raster.setPixels(0, 0, w, h, imgData); + return raster; + } +} Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingContext.java ------------------------------------------------------------------------------ svn:eol-style = native Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java?rev=1566760&view=auto ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java (added) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java Mon Feb 10 21:47:56 2014 @@ -0,0 +1,142 @@ +/* + * 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.pdmodel.graphics.pattern.tiling; + +import java.awt.Paint; +import java.awt.PaintContext; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.WritableRaster; +import java.io.IOException; + +import org.apache.pdfbox.cos.COSStream; +import org.apache.pdfbox.pdfviewer.PageDrawer; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPatternResources; +import org.apache.pdfbox.util.Matrix; + +/** + * This represents the Paint of an axial shading. + * + */ +public class ColoredTilingPaint implements Paint +{ + private PDTilingPatternResources patternResources; + private ColorModel outputColorModel; + + /** + * Constructor. + * + * @param resources tiling pattern resources + * + */ + public ColoredTilingPaint(PDTilingPatternResources resources) + { + patternResources = resources; + } + + /** + * {@inheritDoc} + */ + public int getTransparency() + { + return Transparency.TRANSLUCENT; + } + + /** + * {@inheritDoc} + */ + public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, + AffineTransform xform, RenderingHints hints) + { + // get the pattern matrix + Matrix patternMatrix = patternResources.getMatrix(); + AffineTransform patternAT = patternMatrix != null ? patternMatrix.createAffineTransform() : null; + + // get the bounding box + PDRectangle box = patternResources.getBBox(); + Rectangle2D rect = new Rectangle((int) box.getLowerLeftX(), (int) box.getLowerLeftY(), + (int) box.getWidth(), (int) box.getHeight()); + + rect = xform.createTransformedShape(rect).getBounds2D(); + int width = (int) rect.getWidth(); + int height = (int) rect.getHeight(); + + if (patternAT != null) + { + rect = patternAT.createTransformedShape(rect).getBounds2D(); + } + PDRectangle bBox = new PDRectangle((float) rect.getMinX(), (float) rect.getMinY(), (float) rect.getMaxX(), + (float) rect.getMaxY()); + + // xStep + yStep + double[] steps = new double[] { patternResources.getXStep(), patternResources.getYStep() }; + xform.deltaTransform(steps, 0, steps, 0, 1); + if (patternAT != null) + { + patternAT.deltaTransform(steps, 0, steps, 0, 1); + } + int xStep = (int) (steps[0]); + int yStep = (int) (steps[1]); + + ColorSpace outputCS = ColorSpace.getInstance(ColorSpace.CS_sRGB); + outputColorModel = new ComponentColorModel(outputCS, true, false, Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = outputColorModel.createCompatibleWritableRaster(width, height); + + BufferedImage image = new BufferedImage(outputColorModel, raster, false, null); + BufferedImage tilingImage = null; + try + { + PageDrawer drawer = new PageDrawer(); + drawer.drawStream(image.getGraphics(), (COSStream) patternResources.getCOSObject(), + patternResources.getResources(), box); + drawer.dispose(); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + AffineTransform imageTransform = null; + if (patternAT != null && !patternAT.isIdentity()) + { + // get the scaling factor for each dimension + imageTransform = AffineTransform.getScaleInstance(patternMatrix.getXScale(), patternMatrix.getYScale()); + } + else + { + imageTransform = new AffineTransform(); + } + imageTransform.scale(1.0, -1.0); + imageTransform.translate(0, -height); + AffineTransformOp scaleOP = new AffineTransformOp(imageTransform, AffineTransformOp.TYPE_BILINEAR); + tilingImage = scaleOP.filter(image, null); + + return new ColoredTilingContext(outputColorModel, tilingImage.getData(), xStep, yStep, bBox); + } +} Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/ColoredTilingPaint.java ------------------------------------------------------------------------------ svn:eol-style = native Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html?rev=1566760&view=auto ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html (added) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html Mon Feb 10 21:47:56 2014 @@ -0,0 +1,25 @@ +<!-- + ! 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. + !--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> + +</head> +<body> +This package deals with tiling patterns which are used instead of colors. +</body> +</html> Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/tiling/package.html ------------------------------------------------------------------------------ svn:eol-style = native Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java?rev=1566760&r1=1566759&r2=1566760&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java Mon Feb 10 21:47:56 2014 @@ -184,7 +184,6 @@ public class PDFStreamEngine { validCharCnt = 0; totalCharCnt = 0; - drawingRectangle = null; } /** @@ -290,7 +289,7 @@ public class PDFStreamEngine * * @param str The string to be processed. * - * @return the processed string. + * @return the altered string */ protected String inspectFontEncoding(String str) { @@ -700,4 +699,35 @@ public class PDFStreamEngine return totalCharCnt; } + /** + * Remove all cached resources. + */ + public void dispose() + { + resetEngine(); + drawingRectangle = null; + graphicsState = null; + textLineMatrix = null; + textMatrix = null; + if (graphicsStack != null) + { + graphicsStack.clear(); + graphicsStack = null; + } + if (streamResourcesStack != null) + { + streamResourcesStack.clear(); + streamResourcesStack = null; + } + if (operators != null) + { + operators.clear(); + operators = null; + } + if (unsupportedOperators != null) + { + unsupportedOperators.clear(); + } + } + }