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/12/15 18:12:07 UTC
svn commit: r1643042 - in /pdfbox/trunk:
examples/src/main/java/org/apache/pdfbox/examples/util/
pdfbox/src/main/java/org/apache/pdfbox/contentstream/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel...
Author: jahewson
Date: Wed Dec 3 02:02:13 2014
New Revision: 1643042
URL: http://svn.apache.org/r1643042
Log:
PDFBOX-2423: Improve pattern rendering
Added:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java
- copied, changed from r1642606, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java
Removed:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPatternDrawer.java
Modified:
pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFStreamEngine.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFTextStreamEngine.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/PDTilingPattern.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/text/TextPosition.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java
Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PrintImageLocations.java Wed Dec 3 02:02:13 2014
@@ -132,7 +132,7 @@ public class PrintImageLocations extends
double imageXScale = imageTransform.getScaleX();
double imageYScale = imageTransform.getScaleY();
- System.out.println("position = " + ctmNew.getXPosition() + ", " + ctmNew.getYPosition());
+ System.out.println("position = " + ctmNew.getTranslateX() + ", " + ctmNew.getTranslateY());
// size in pixel
System.out.println("size = " + imageWidth + "px, " + imageHeight + "px");
// size in page units
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFStreamEngine.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFStreamEngine.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFStreamEngine.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFStreamEngine.java Wed Dec 3 02:02:13 2014
@@ -16,8 +16,9 @@
*/
package org.apache.pdfbox.contentstream;
-import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -43,7 +44,8 @@ import org.apache.pdfbox.pdmodel.font.PD
import org.apache.pdfbox.pdmodel.font.PDFontFactory;
import org.apache.pdfbox.pdmodel.font.PDType3CharProc;
import org.apache.pdfbox.pdmodel.font.PDType3Font;
-import org.apache.pdfbox.pdmodel.graphics.blend.BlendMode;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPattern;
import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState;
@@ -69,13 +71,13 @@ public class PDFStreamEngine
private Matrix textMatrix;
private Matrix textLineMatrix;
- protected Matrix subStreamMatrix = new Matrix();
private final Stack<PDGraphicsState> graphicsStack = new Stack<PDGraphicsState>();
private PDResources resources;
private PDPage currentPage;
private boolean isProcessingPage;
+ private Matrix initialMatrix;
// skip malformed or otherwise unparseable input where possible
private boolean forceParsing;
@@ -147,6 +149,7 @@ public class PDFStreamEngine
textMatrix = null;
textLineMatrix = null;
resources = null;
+ initialMatrix = page.getMatrix();
}
/**
@@ -292,19 +295,19 @@ public class PDFStreamEngine
// zero-sized rectangles are not valid
if (rect.getWidth() > 0 && rect.getHeight() > 0)
{
- // transformed appearance box
- PDRectangle transformedBox = bbox.transform(matrix);
+ // transformed appearance box fixme: may be an arbitrary shape
+ Rectangle2D transformedBox = bbox.transform(matrix).getBounds2D();
// compute a matrix which scales and translates the transformed appearance box to align
// with the edges of the annotation's rectangle
Matrix a = Matrix.getTranslatingInstance(rect.getLowerLeftX(), rect.getLowerLeftY());
- a.concatenate(Matrix.getScaleInstance(rect.getWidth() / transformedBox.getWidth(),
- rect.getHeight() / transformedBox.getHeight()));
- a.concatenate(Matrix.getTranslatingInstance(-transformedBox.getLowerLeftX(),
- -transformedBox.getLowerLeftY()));
+ a.concatenate(Matrix.getScaleInstance((float)(rect.getWidth() / transformedBox.getWidth()),
+ (float)(rect.getHeight() / transformedBox.getHeight())));
+ a.concatenate(Matrix.getTranslatingInstance((float) -transformedBox.getX(),
+ (float) -transformedBox.getY()));
// Matrix shall be concatenated with A to form a matrix AA that maps from the appearances
- // coordinate system to the annotationâs rectangle in default user space
+ // coordinate system to the annotation's rectangle in default user space
Matrix aa = Matrix.concatenate(matrix, a);
// make matrix AA the CTM
@@ -321,23 +324,61 @@ public class PDFStreamEngine
}
/**
- * Processes the given tiling pattern.
+ * Process the given tiling pattern.
*
- * @param tilingPattern tiling patten
+ * @param tilingPattern the tiling pattern
+ * @param color color to use, if this is an uncoloured pattern, otherwise null.
+ * @param colorSpace color space to use, if this is an uncoloured pattern, otherwise null.
*/
- protected final void processTilingPattern(PDTilingPattern tilingPattern) throws IOException
+ protected final void processTilingPattern(PDTilingPattern tilingPattern, PDColor color,
+ PDColorSpace colorSpace) throws IOException
+ {
+ processTilingPattern(tilingPattern, color, colorSpace, tilingPattern.getMatrix());
+ }
+
+ /**
+ * Process the given tiling pattern. Allows the pattern matrix to be overridden for custom
+ * rendering.
+ *
+ * @param tilingPattern the tiling pattern
+ * @param color color to use, if this is an uncoloured pattern, otherwise null.
+ * @param colorSpace color space to use, if this is an uncoloured pattern, otherwise null.
+ * @param patternMatrix the pattern matrix, may be overridden for custom rendering.
+ */
+ protected final void processTilingPattern(PDTilingPattern tilingPattern, PDColor color,
+ PDColorSpace colorSpace, Matrix patternMatrix)
+ throws IOException
{
PDResources parent = pushResources(tilingPattern);
- saveGraphicsState();
- // note: we don't transform the CTM using the stream's matrix, as TilingPaint handles this
+ Matrix parentMatrix = initialMatrix;
+ initialMatrix = Matrix.concatenate(initialMatrix, patternMatrix);
+
+ // set up a clean state (new clipping path, line path, etc.)
+ Rectangle2D bbox = tilingPattern.getBBox().transform(patternMatrix).getBounds2D();
+ PDRectangle rect = new PDRectangle((float)bbox.getX(), (float)bbox.getY(),
+ (float)bbox.getWidth(), (float)bbox.getHeight());
+ graphicsStack.push(new PDGraphicsState(rect));
+
+ // non-colored patterns have to be given a color
+ if (colorSpace != null)
+ {
+ color = new PDColor(color.getComponents(), colorSpace);
+ getGraphicsState().setNonStrokingColorSpace(colorSpace);
+ getGraphicsState().setNonStrokingColor(color);
+ getGraphicsState().setStrokingColorSpace(colorSpace);
+ getGraphicsState().setStrokingColor(color);
+ }
+
+ // transform the CTM using the stream's matrix
+ getGraphicsState().getCurrentTransformationMatrix().concatenate(patternMatrix);
// clip to bounding box
- PDRectangle bbox = tilingPattern.getBBox();
- clipToRect(bbox);
+ clipToRect(tilingPattern.getBBox());
processStreamOperators(tilingPattern);
+ initialMatrix = parentMatrix;
restoreGraphicsState();
popResources(parent);
}
@@ -395,35 +436,22 @@ public class PDFStreamEngine
*/
private void processStream(PDContentStream contentStream) throws IOException
{
- processStream(contentStream, null);
- }
-
- /**
- * Process a content stream.
- *
- * @param contentStream the content stream
- * @param patternBBox fixme: temporary workaround for tiling patterns
- * @throws IOException if there is an exception while processing the stream
- */
- private void processStream(PDContentStream contentStream, PDRectangle patternBBox)
- throws IOException
- {
PDResources parent = pushResources(contentStream);
saveGraphicsState();
+ Matrix parentMatrix = initialMatrix;
+ initialMatrix = Matrix.concatenate(initialMatrix, contentStream.getMatrix());
+
// transform the CTM using the stream's matrix
getGraphicsState().getCurrentTransformationMatrix().concatenate(contentStream.getMatrix());
// clip to bounding box
PDRectangle bbox = contentStream.getBBox();
- if (patternBBox != null)
- {
- bbox = patternBBox;
- }
clipToRect(bbox);
processStreamOperators(contentStream);
+ initialMatrix = parentMatrix;
restoreGraphicsState();
popResources(parent);
}
@@ -433,10 +461,6 @@ public class PDFStreamEngine
*/
private void processStreamOperators(PDContentStream contentStream) throws IOException
{
- // fixme: stream matrix
- Matrix oldSubStreamMatrix = subStreamMatrix;
- subStreamMatrix = getGraphicsState().getCurrentTransformationMatrix();
-
List<COSBase> arguments = new ArrayList<COSBase>();
PDFStreamParser parser = new PDFStreamParser(contentStream.getContentStream(), forceParsing);
try
@@ -464,9 +488,6 @@ public class PDFStreamEngine
{
parser.close();
}
-
- // fixme: stream matrix
- subStreamMatrix = oldSubStreamMatrix;
}
/**
@@ -510,8 +531,8 @@ public class PDFStreamEngine
{
if (rectangle != null)
{
- PDRectangle clip = rectangle.transform(getGraphicsState().getCurrentTransformationMatrix());
- getGraphicsState().intersectClippingPath(new Area(clip.toGeneralPath()));
+ GeneralPath clip = rectangle.transform(getGraphicsState().getCurrentTransformationMatrix());
+ getGraphicsState().intersectClippingPath(clip);
}
}
@@ -867,14 +888,6 @@ public class PDFStreamEngine
{
textMatrix = value;
}
-
- /**
- * Returns the subStreamMatrix.
- */
- protected Matrix getSubStreamMatrix()
- {
- return subStreamMatrix;
- }
/**
* Returns the stream' resources.
@@ -892,6 +905,11 @@ public class PDFStreamEngine
return currentPage;
}
+ public Matrix getInitialMatrix()
+ {
+ return initialMatrix;
+ }
+
/**
* use the current transformation matrix to transformPoint a single point.
*
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFTextStreamEngine.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFTextStreamEngine.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFTextStreamEngine.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/contentstream/PDFTextStreamEngine.java Wed Dec 3 02:02:13 2014
@@ -150,12 +150,12 @@ public class PDFTextStreamEngine extends
// (modified) text rendering matrix
Matrix nextTextRenderingMatrix = td.multiply(textMatrix).multiply(ctm); // text space -> device space
- float nextX = nextTextRenderingMatrix.getXPosition();
- float nextY = nextTextRenderingMatrix.getYPosition();
+ float nextX = nextTextRenderingMatrix.getTranslateX();
+ float nextY = nextTextRenderingMatrix.getTranslateY();
// (modified) width and height calculations
- float dxDisplay = nextX - textRenderingMatrix.getXPosition();
- float dyDisplay = height * textRenderingMatrix.getYScale();
+ float dxDisplay = nextX - textRenderingMatrix.getTranslateX();
+ float dyDisplay = height * textRenderingMatrix.getScaleY();
//
// start of the original method
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=1643042&r1=1643041&r2=1643042&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 Wed Dec 3 02:02:13 2014
@@ -280,19 +280,28 @@ public class PDRectangle implements COSO
}
/**
- * Returns a copy of this rectangle which has been transformed using the given matrix.
+ * Returns a path which represents this rectangle having been transformed by the given matrix.
+ * Note that the resulting path need not be rectangular.
*/
- public PDRectangle transform(Matrix matrix)
+ public GeneralPath transform(Matrix matrix)
{
- Point2D.Float lowerLeft = matrix.transformPoint(getLowerLeftX(), getLowerLeftY());
- Point2D.Float upperRight = matrix.transformPoint(getUpperRightX(), getUpperRightY());
+ float x1 = getLowerLeftX();
+ float y1 = getLowerLeftY();
+ float x2 = getUpperRightX();
+ float y2 = getUpperRightY();
- PDRectangle rect = new PDRectangle();
- rect.setLowerLeftX(lowerLeft.x);
- rect.setLowerLeftY(lowerLeft.y);
- rect.setUpperRightX(upperRight.x);
- rect.setUpperRightY(upperRight.y);
- return rect;
+ Point2D p0 = matrix.transformPoint(x1, y1);
+ Point2D p1 = matrix.transformPoint(x2, y1);
+ Point2D p2 = matrix.transformPoint(x2, y2);
+ Point2D p3 = matrix.transformPoint(x1, y2);
+
+ GeneralPath path = new GeneralPath();
+ path.moveTo((float) p0.getX(), (float) p0.getY());
+ path.lineTo((float) p1.getX(), (float) p1.getY());
+ path.lineTo((float) p2.getX(), (float) p2.getY());
+ path.lineTo((float) p3.getX(), (float) p3.getY());
+ path.closePath();
+ return path;
}
/**
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPattern.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPattern.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPattern.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDTilingPattern.java Wed Dec 3 02:02:13 2014
@@ -31,6 +31,7 @@ import org.apache.pdfbox.util.Matrix;
/**
* A tiling pattern dictionary.
+ *
* @author Andreas Lehmkühler
*/
public class PDTilingPattern extends PDAbstractPattern implements PDContentStream
@@ -259,6 +260,28 @@ public class PDTilingPattern extends PDA
matrix.setValue(1, 1, ((COSNumber) array.get(3)).floatValue());
matrix.setValue(2, 0, ((COSNumber) array.get(4)).floatValue());
matrix.setValue(2, 1, ((COSNumber) array.get(5)).floatValue());
+
+ // repair mechanism for invalid matrices, this is based on pure guesswork based on the
+ // PoolCompPDFA.pdf from PDFBOX-1265 which renders fine in Acrobat despite having a
+ // scaling factor of zero.
+ if (matrix.getScaleX() == 0)
+ {
+ matrix.setValue(0, 0, ((COSNumber) array.get(1)).floatValue()); // scale x -> skew x
+ matrix.setValue(1, 0, 0); // skew x -> 0
+ }
+ if (matrix.getScaleY() == 0)
+ {
+ matrix.setValue(1, 1, ((COSNumber) array.get(2)).floatValue()); // scale y -> skew y
+ matrix.setValue(0, 1, 0); // skew y -> 0
+ }
+ if (matrix.getScaleX() == 0)
+ {
+ matrix.setValue(0, 0, 1);
+ }
+ if (matrix.getScaleY() == 0)
+ {
+ matrix.setValue(1, 1, 1);
+ }
}
else
{
Modified: 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=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Wed Dec 3 02:02:13 2014
@@ -45,7 +45,6 @@ import org.apache.pdfbox.pdmodel.graphic
import org.apache.pdfbox.pdmodel.graphics.image.PDImage;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDAbstractPattern;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDShadingPattern;
-import org.apache.pdfbox.pdmodel.graphics.pattern.TilingPaint;
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
import org.apache.pdfbox.rendering.font.CIDType0Glyph2D;
import org.apache.pdfbox.rendering.font.Glyph2D;
@@ -77,7 +76,7 @@ import org.apache.pdfbox.util.Vector;
*
* @author Ben Litchfield
*/
-public class PageDrawer extends PDFGraphicsStreamEngine
+public final class PageDrawer extends PDFGraphicsStreamEngine
{
private static final Log LOG = LogFactory.getLog(PageDrawer.class);
@@ -181,7 +180,7 @@ public class PageDrawer extends PDFGraph
* @throws IOException If there is an IO error while drawing the page.
*/
public void drawTilingPattern(Graphics2D g, PDTilingPattern pattern, PDColorSpace colorSpace,
- PDColor color) throws IOException
+ PDColor color, Matrix patternMatrix) throws IOException
{
Graphics2D oldGraphics = graphics;
graphics = g;
@@ -193,21 +192,8 @@ public class PageDrawer extends PDFGraph
lastClip = null;
setRenderingHints();
- saveGraphicsState();
+ processTilingPattern(pattern, color, colorSpace, patternMatrix);
- // non-colored patterns have to be given a color
- if (colorSpace != null)
- {
- color = new PDColor(color.getComponents(), colorSpace);
- getGraphicsState().setNonStrokingColorSpace(colorSpace);
- getGraphicsState().setNonStrokingColor(color);
- getGraphicsState().setStrokingColorSpace(colorSpace);
- getGraphicsState().setStrokingColor(color);
- }
-
- processTilingPattern(pattern);
-
- restoreGraphicsState();
graphics = oldGraphics;
linePath = oldLinePath;
lastClip = oldLastClip;
@@ -253,14 +239,8 @@ public class PageDrawer extends PDFGraph
LOG.error("shadingPattern is null, will be filled with transparency");
return new Color(0,0,0,0);
}
+ return shading.toPaint(getInitialMatrix());
- // fixme: shading needs to use the correct matrix
- Matrix patternMatrix = shadingPattern.getMatrix();
- if (patternMatrix == null)
- {
- patternMatrix = new Matrix();
- }
- return shading.toPaint(patternMatrix);
}
}
}
@@ -860,11 +840,11 @@ public class PageDrawer extends PDFGraph
Matrix transform = Matrix.concatenate(ctm, form.getMatrix());
// transform the bbox
- PDRectangle bbox = form.getBBox().transform(transform);
+ GeneralPath transformedBox = form.getBBox().transform(transform);
// clip the bbox to prevent giant bboxes from consuming all memory
Area clip = (Area)getGraphicsState().getCurrentClippingPath().clone();
- clip.intersect(new Area(bbox.toGeneralPath()));
+ clip.intersect(new Area(transformedBox));
Rectangle2D clipRect = clip.getBounds2D();
this.bbox = new PDRectangle((float)clipRect.getX(), (float)clipRect.getY(),
(float)clipRect.getWidth(), (float)clipRect.getHeight());
Copied: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java (from r1642606, 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/rendering/TilingPaint.java?p2=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/TilingPaint.java&p1=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/TilingPaint.java&r1=1642606&r2=1643042&rev=1643042&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/rendering/TilingPaint.java Wed Dec 3 02:02:13 2014
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.pdfbox.pdmodel.graphics.pattern;
+package org.apache.pdfbox.rendering;
import java.awt.Graphics2D;
import java.awt.Paint;
@@ -38,7 +38,8 @@ import java.math.RoundingMode;
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.rendering.PageDrawer;
+import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPattern;
+import org.apache.pdfbox.util.Matrix;
/**
* AWT Paint for a tiling pattern, which consists of a small repeating graphical figure.
@@ -46,7 +47,7 @@ import org.apache.pdfbox.rendering.PageD
* @author Andreas Lehmkühler
* @author John Hewson
*/
-public class TilingPaint implements Paint
+class TilingPaint implements Paint
{
private final PDTilingPattern pattern;
private final TexturePaint paint;
@@ -64,7 +65,7 @@ public class TilingPaint implements Pain
throws IOException
{
this.paint = new TexturePaint(getImage(drawer, pattern, null, null, xform),
- getAnchorRect(pattern));
+ getAnchorRect(pattern));
this.pattern = pattern;
}
@@ -82,22 +83,30 @@ public class TilingPaint implements Pain
PDColor color, AffineTransform xform) throws IOException
{
this.paint = new TexturePaint(getImage(drawer, pattern, colorSpace, color, xform),
- getAnchorRect(pattern));
+ getAnchorRect(pattern));
this.pattern = pattern;
}
- // note: this is not called in TexturePaint subclasses, which is why we wrap TexturePaint
+ /**
+ * Not called in TexturePaint subclasses, which is why we wrap TexturePaint.
+ */
@Override
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints)
{
- // todo: use userBounds or deviceBounds to avoid scaling issue with Tracemonkey?
AffineTransform xformPattern = (AffineTransform)xform.clone();
- xformPattern.concatenate(pattern.getMatrix().createAffineTransform());
+
+ // applies the pattern matrix with scaling removed
+ AffineTransform patternNoScale = pattern.getMatrix().createAffineTransform();
+ patternNoScale.scale(1 / patternNoScale.getScaleX(), 1 / patternNoScale.getScaleY());
+ xformPattern.concatenate(patternNoScale);
+
return paint.createContext(cm, deviceBounds, userBounds, xformPattern, hints);
}
- // gets image in parent stream coordinates
+ /**
+ * Returns the pattern image in parent stream coordinates.
+ */
private static BufferedImage getImage(PageDrawer drawer, PDTilingPattern pattern,
PDColorSpace colorSpace, PDColor color,
AffineTransform xform) throws IOException
@@ -122,15 +131,44 @@ public class TilingPaint implements Pain
BufferedImage image = new BufferedImage(cm, raster, false, null);
Graphics2D graphics = image.createGraphics();
- graphics.transform(xform); // device transform (i.e. DPI)
- drawer.drawTilingPattern(graphics, pattern, colorSpace, color);
+
+ // flip a -ve YStep around its own axis (see gs-bugzilla694385.pdf)
+ if (pattern.getYStep() < 0)
+ {
+ graphics.translate(0, rasterHeight);
+ graphics.scale(1, -1);
+ }
+
+ // flip a -ve XStep around its own axis
+ if (pattern.getXStep() < 0)
+ {
+ graphics.translate(rasterWidth, 0);
+ graphics.scale(-1, 1);
+ }
+
+ // device transform (i.e. DPI)
+ graphics.transform(xform);
+
+ // apply only the scaling from the pattern transform, doing scaling here improves the
+ // image quality and prevents large scale-down factors from creating huge tiling cells.
+ Matrix patternMatrix = Matrix.getScaleInstance(
+ Math.abs(pattern.getMatrix().getScaleX()),
+ Math.abs(pattern.getMatrix().getScaleY()));
+
+ // move origin to (0,0)
+ patternMatrix.concatenate(
+ Matrix.getTranslatingInstance(-pattern.getBBox().getLowerLeftX(),
+ -pattern.getBBox().getLowerLeftY()));
+
+ // render using PageDrawer
+ drawer.drawTilingPattern(graphics, pattern, colorSpace, color, patternMatrix);
graphics.dispose();
return image;
}
/**
- * Returns the closest integer which is larger than the given number.
+ * Returns the closest integer which is //larger than the given number.
* Uses BigDecimal to avoid floating point error which would cause gaps in the tiling.
*/
private static int ceiling(double num)
@@ -146,8 +184,10 @@ public class TilingPaint implements Pain
return Transparency.TRANSLUCENT;
}
- // includes XStep/YStep
- public static Rectangle2D getAnchorRect(PDTilingPattern pattern)
+ /**
+ * Returns the anchor rectangle, which includes the XStep/YStep and scaling.
+ */
+ private static Rectangle2D getAnchorRect(PDTilingPattern pattern)
{
float xStep = pattern.getXStep();
if (xStep == 0)
@@ -161,7 +201,13 @@ public class TilingPaint implements Pain
yStep = pattern.getBBox().getHeight();
}
+ float xScale = pattern.getMatrix().getScaleX();
+ float yScale = pattern.getMatrix().getScaleY();
+
+ // returns the anchor rect with scaling applied
PDRectangle anchor = pattern.getBBox();
- return new Rectangle2D.Float(anchor.getLowerLeftX(), anchor.getLowerLeftY(), xStep, yStep);
+ return new Rectangle2D.Float(anchor.getLowerLeftX() * xScale,
+ anchor.getLowerLeftY() * yScale,
+ xStep * xScale, yStep * yScale);
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/text/TextPosition.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/text/TextPosition.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/text/TextPosition.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/text/TextPosition.java Wed Dec 3 02:02:13 2014
@@ -349,11 +349,11 @@ public final class TextPosition
{
if (rotation == 90 || rotation == 270)
{
- return Math.abs(endY - textMatrix.getYPosition());
+ return Math.abs(endY - textMatrix.getTranslateY());
}
else
{
- return Math.abs(endX - textMatrix.getXPosition());
+ return Math.abs(endX - textMatrix.getTranslateX());
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java?rev=1643042&r1=1643041&r2=1643042&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java Wed Dec 3 02:02:13 2014
@@ -26,10 +26,9 @@ import java.awt.geom.Point2D;
/**
* This class will be used for matrix manipulation.
*
- * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
- * @version $Revision: 1.14 $
+ * @author Ben Litchfield
*/
-public class Matrix implements Cloneable
+public final class Matrix implements Cloneable
{
static final float[] DEFAULT_SINGLE =
{
@@ -106,7 +105,9 @@ public class Matrix implements Cloneable
* Set the values of the matrix from the AffineTransform.
*
* @param af The transform to get the values from.
+ * @deprecated This method is due to be removed, please contact us if you make use of it.
*/
+ @Deprecated
public void setFromAffineTransform( AffineTransform af )
{
single[0] = (float)af.getScaleX();
@@ -166,7 +167,9 @@ public class Matrix implements Cloneable
* Return a single dimension array of all values in the matrix.
*
* @return The values ot this matrix.
+ * @deprecated Use {@link float[][] #getValues} instead.
*/
+ @Deprecated
public double[][] getValuesAsDouble()
{
double[][] retval = new double[3][3];
@@ -204,7 +207,19 @@ public class Matrix implements Cloneable
}
/**
- * This will take the current matrix and multipy it with a matrix that is passed in.
+ * Scales this matrix by the given factors.
+ *
+ * @param sx x-scale
+ * @param sy y-scale
+ */
+ public void scale(float sx, float sy)
+ {
+ Matrix m = Matrix.getScaleInstance(sx, sy);
+ concatenate(m);
+ }
+
+ /**
+ * This will take the current matrix and multiply it with a matrix that is passed in.
*
* @param b The matrix to multiply by.
*
@@ -350,7 +365,9 @@ public class Matrix implements Cloneable
* Create a new matrix with just the scaling operators.
*
* @return A new matrix with just the scaling operators.
+ * @deprecated This method is due to be removed, please contact us if you make use of it.
*/
+ @Deprecated
public Matrix extractScaling()
{
Matrix retval = new Matrix();
@@ -382,7 +399,9 @@ public class Matrix implements Cloneable
* Create a new matrix with just the translating operators.
*
* @return A new matrix with just the translating operators.
+ * @deprecated This method is due to be removed, please contact us if you make use of it.
*/
+ @Deprecated
public Matrix extractTranslating()
{
Matrix retval = new Matrix();
@@ -436,9 +455,13 @@ public class Matrix implements Cloneable
}
/**
- * Get the xscaling factor of this matrix.
+ * Get the x-scaling factor of this matrix. This is a deprecated method which actually
+ * returns the x-scaling factor multiplied by the x-shear.
+ *
* @return The x-scale.
+ * @deprecated Use {@link #getScaleX} instead
*/
+ @Deprecated
public float getXScale()
{
float xScale = single[0];
@@ -469,9 +492,13 @@ public class Matrix implements Cloneable
}
/**
- * Get the y scaling factor of this matrix.
+ * Get the y-scaling factor of this matrix. This is a deprecated method which actually
+ * returns the y-scaling factor multiplied by the y-shear.
+ *
* @return The y-scale factor.
+ * @deprecated Use {@link #getScaleY} instead
*/
+ @Deprecated
public float getYScale()
{
float yScale = single[4];
@@ -484,25 +511,79 @@ public class Matrix implements Cloneable
}
/**
- * Get the x position in the matrix.
+ * Returns the x-scaling factor of this matrix.
+ */
+ public float getScaleX()
+ {
+ return single[0];
+ }
+
+ /**
+ * Returns the y-shear factor of this matrix.
+ */
+ public float getShearY()
+ {
+ return single[1];
+ }
+
+ /**
+ * Returns the x-shear factor of this matrix.
+ */
+ public float getShearX()
+ {
+ return single[3];
+ }
+
+ /**
+ * Returns the y-scaling factor of this matrix.
+ */
+ public float getScaleY()
+ {
+ return single[4];
+ }
+
+ /**
+ * Returns the x-translation of this matrix.
+ */
+ public float getTranslateX()
+ {
+ return single[6];
+ }
+
+ /**
+ * Returns the y-translation of this matrix.
+ */
+ public float getTranslateY()
+ {
+ return single[7];
+ }
+
+ /**
+ * Get the x position in the matrix. This method is deprecated as it is incorrectly named.
+ *
* @return The x-position.
+ * @deprecated Use {@link #getTranslateX} instead
*/
+ @Deprecated
public float getXPosition()
{
return single[6];
}
/**
- * Get the y position.
+ * Get the y position. This method is deprecated as it is incorrectly named.
+ *
* @return The y position.
+ * @deprecated Use {@link #getTranslateY} instead
*/
+ @Deprecated
public float getYPosition()
{
return single[7];
}
/**
- * Returns a COS array which represnets this matrix.
+ * Returns a COS array which represents this matrix.
*/
public COSArray toCOSArray()
{