You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2021/04/02 07:08:09 UTC
svn commit: r1888288 - in
/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox:
pdmodel/graphics/shading/ rendering/
Author: tilman
Date: Fri Apr 2 07:08:09 2021
New Revision: 1888288
URL: http://svn.apache.org/viewvc?rev=1888288&view=rev
Log:
PDFBOX-5134: calculating the bounding boxes of the triangles reduces shading rendering times if no bounding box is preset, as suggested by Oliver Schmidtmer; Closes #109
Added:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java (with props)
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShading.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDTriangleBasedShadingType.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TriangleBasedShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Fri Apr 2 07:08:09 2021
@@ -19,17 +19,13 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.imageio.stream.ImageInputStream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.pdfbox.pdmodel.common.PDRange;
+
import org.apache.pdfbox.util.Matrix;
/**
@@ -40,8 +36,6 @@ import org.apache.pdfbox.util.Matrix;
*/
abstract class GouraudShadingContext extends TriangleBasedShadingContext
{
- private static final Log LOG = LogFactory.getLog(GouraudShadingContext.class);
-
/**
* triangle list.
*/
@@ -62,53 +56,6 @@ abstract class GouraudShadingContext ext
super(shading, colorModel, xform, matrix);
}
- /**
- * Read a vertex from the bit input stream performs interpolations.
- *
- * @param input bit input stream
- * @param maxSrcCoord max value for source coordinate (2^bits-1)
- * @param maxSrcColor max value for source color (2^bits-1)
- * @param rangeX dest range for X
- * @param rangeY dest range for Y
- * @param colRangeTab dest range array for colors
- * @param matrix the pattern matrix concatenated with that of the parent content stream
- * @return a new vertex with the flag and the interpolated values
- * @throws IOException if something went wrong
- */
- protected Vertex readVertex(ImageInputStream input, long maxSrcCoord, long maxSrcColor,
- PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab,
- Matrix matrix, AffineTransform xform) throws IOException
- {
- float[] colorComponentTab = new float[numberOfColorComponents];
- long x = input.readBits(bitsPerCoordinate);
- long y = input.readBits(bitsPerCoordinate);
- float dstX = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
- float dstY = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
- LOG.debug("coord: " + String.format("[%06X,%06X] -> [%f,%f]", x, y, dstX, dstY));
- Point2D p = matrix.transformPoint(dstX, dstY);
- xform.transform(p, p);
-
- for (int n = 0; n < numberOfColorComponents; ++n)
- {
- int color = (int) input.readBits(bitsPerColorComponent);
- colorComponentTab[n] = interpolate(color, maxSrcColor, colRangeTab[n].getMin(),
- colRangeTab[n].getMax());
- LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
- + "-> color[" + n + "]: " + colorComponentTab[n]);
- }
-
- // "Each set of vertex data shall occupy a whole number of bytes.
- // If the total number of bits required is not divisible by 8, the last data byte
- // for each vertex is padded at the end with extra bits, which shall be ignored."
- int bitOffset = input.getBitOffset();
- if (bitOffset != 0)
- {
- input.readBits(8 - bitOffset);
- }
-
- return new Vertex(p, colorComponentTab);
- }
-
final void setTriangleList(List<ShadedTriangle> triangleList)
{
this.triangleList = triangleList;
@@ -129,20 +76,6 @@ abstract class GouraudShadingContext ext
super.dispose();
}
- /**
- * Calculate the interpolation, see p.345 pdf spec 1.7.
- *
- * @param src src value
- * @param srcMax max src value (2^bits-1)
- * @param dstMin min dst value
- * @param dstMax max dst value
- * @return interpolated value
- */
- private float interpolate(float src, long srcMax, float dstMin, float dstMax)
- {
- return dstMin + (src * (dstMax - dstMin) / srcMax);
- }
-
@Override
protected boolean isDataEmpty()
{
Added: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java?rev=1888288&view=auto
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java (added)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java Fri Apr 2 07:08:09 2021
@@ -0,0 +1,265 @@
+/*
+ * 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.shading;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * Common resources for shading types 6 and 7
+ */
+abstract class PDMeshBasedShadingType extends PDShadingType4
+{
+
+ private static final Log LOG = LogFactory.getLog(PDMeshBasedShadingType.class);
+
+ PDMeshBasedShadingType(COSDictionary shadingDictionary)
+ {
+ super(shadingDictionary);
+ }
+
+ /**
+ * Create a patch list from a data stream, the returned list contains all the patches contained in the data stream.
+ *
+ * @param shadingType the shading type
+ * @param xform transformation for user to device space
+ * @param matrix the pattern matrix concatenated with that of the parent content stream
+ * @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
+ * @return the obtained patch list
+ * @throws IOException when something went wrong
+ */
+ @SuppressWarnings({ "squid:S2583", "squid:S1166" })
+ final List<Patch> collectPatches(AffineTransform xform, Matrix matrix, int controlPoints)
+ throws IOException
+ {
+ COSDictionary dict = getCOSObject();
+ if (!(dict instanceof COSStream))
+ {
+ return Collections.emptyList();
+ }
+ PDRange rangeX = getDecodeForParameter(0);
+ PDRange rangeY = getDecodeForParameter(1);
+ if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0
+ || Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
+ {
+ return Collections.emptyList();
+ }
+ int bitsPerFlag = getBitsPerFlag();
+ PDRange[] colRange = new PDRange[getNumberOfColorComponents()];
+ for (int i = 0; i < getNumberOfColorComponents(); ++i)
+ {
+ colRange[i] = getDecodeForParameter(2 + i);
+ if (colRange[i] == null)
+ {
+ throw new IOException("Range missing in shading /Decode entry");
+ }
+ }
+ List<Patch> list = new ArrayList<Patch>();
+ long maxSrcCoord = (long) Math.pow(2, getBitsPerCoordinate()) - 1;
+ long maxSrcColor = (long) Math.pow(2, getBitsPerComponent()) - 1;
+ COSStream cosStream = (COSStream) dict;
+
+ ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream());
+ try
+ {
+ Point2D[] implicitEdge = new Point2D[4];
+ float[][] implicitCornerColor = new float[2][getNumberOfColorComponents()];
+ byte flag = 0;
+
+ try
+ {
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ }
+ catch (EOFException ex)
+ {
+ LOG.error(ex);
+ }
+
+ boolean eof = false;
+ while (!eof)
+ {
+ try
+ {
+ boolean isFree = (flag == 0);
+ Patch current = readPatch(mciis, isFree, implicitEdge, implicitCornerColor,
+ maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform,
+ controlPoints);
+ if (current == null)
+ {
+ break;
+ }
+ list.add(current);
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ switch (flag)
+ {
+ case 0:
+ break;
+ case 1:
+ implicitEdge = current.getFlag1Edge();
+ implicitCornerColor = current.getFlag1Color();
+ break;
+ case 2:
+ implicitEdge = current.getFlag2Edge();
+ implicitCornerColor = current.getFlag2Color();
+ break;
+ case 3:
+ implicitEdge = current.getFlag3Edge();
+ implicitCornerColor = current.getFlag3Color();
+ break;
+ default:
+ LOG.warn("bad flag: " + flag);
+ break;
+ }
+ }
+ catch (EOFException ex)
+ {
+ eof = true;
+ }
+ }
+ }
+ finally
+ {
+ mciis.close();
+ }
+ return list;
+ }
+
+ /**
+ * Read a single patch from a data stream, a patch contains information of its coordinates and color parameters.
+ *
+ * @param input the image source data stream
+ * @param isFree whether this is a free patch
+ * @param implicitEdge implicit edge when a patch is not free, otherwise it's not used
+ * @param implicitCornerColor implicit colors when a patch is not free, otherwise it's not used
+ * @param maxSrcCoord the maximum coordinate value calculated from source data
+ * @param maxSrcColor the maximum color value calculated from source data
+ * @param rangeX range for coordinate x
+ * @param rangeY range for coordinate y
+ * @param colRange range for color
+ * @param matrix the pattern matrix concatenated with that of the parent content stream
+ * @param xform transformation for user to device space
+ * @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
+ * @return a single patch
+ * @throws IOException when something went wrong
+ */
+ protected Patch readPatch(ImageInputStream input, boolean isFree, Point2D[] implicitEdge,
+ float[][] implicitCornerColor, long maxSrcCoord, long maxSrcColor, PDRange rangeX,
+ PDRange rangeY, PDRange[] colRange, Matrix matrix, AffineTransform xform,
+ int controlPoints) throws IOException
+ {
+ float[][] color = new float[4][getNumberOfColorComponents()];
+ Point2D[] points = new Point2D[controlPoints];
+ int pStart = 4, cStart = 2;
+ if (isFree)
+ {
+ pStart = 0;
+ cStart = 0;
+ }
+ else
+ {
+ points[0] = implicitEdge[0];
+ points[1] = implicitEdge[1];
+ points[2] = implicitEdge[2];
+ points[3] = implicitEdge[3];
+
+ for (int i = 0; i < getNumberOfColorComponents(); i++)
+ {
+ color[0][i] = implicitCornerColor[0][i];
+ color[1][i] = implicitCornerColor[1][i];
+ }
+ }
+
+ try
+ {
+ for (int i = pStart; i < controlPoints; i++)
+ {
+ long x = input.readBits(getBitsPerCoordinate());
+ long y = input.readBits(getBitsPerCoordinate());
+ float px = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
+ float py = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
+ Point2D p = matrix.transformPoint(px, py);
+ xform.transform(p, p);
+ points[i] = p;
+ }
+ for (int i = cStart; i < 4; i++)
+ {
+ for (int j = 0; j < getNumberOfColorComponents(); j++)
+ {
+ long c = input.readBits(getBitsPerComponent());
+ color[i][j] = interpolate(c, maxSrcColor, colRange[j].getMin(),
+ colRange[j].getMax());
+ }
+ }
+ }
+ catch (EOFException ex)
+ {
+ LOG.debug("EOF", ex);
+ return null;
+ }
+ return generatePatch(points, color);
+ }
+
+ /**
+ * Create a patch using control points and 4 corner color values, in Type6ShadingContext, a CoonsPatch is returned;
+ * in Type6ShadingContext, a TensorPatch is returned.
+ *
+ * @param points 12 or 16 control points
+ * @param color 4 corner colors
+ * @return a patch instance
+ */
+ abstract Patch generatePatch(Point2D[] points, float[][] color);
+
+ @Override
+ abstract public Rectangle2D getBounds(AffineTransform xform, Matrix matrix) throws IOException;
+
+ Rectangle2D getBounds(AffineTransform xform, Matrix matrix, int controlPoints)
+ throws IOException
+ {
+ Rectangle2D bounds = null;
+ for (Patch patch : collectPatches(xform, matrix, controlPoints))
+ {
+ for (ShadedTriangle shadedTriangle : patch.listOfTriangles)
+ {
+ if (bounds == null)
+ {
+ bounds = new Rectangle2D.Double(shadedTriangle.corner[0].getX(),
+ shadedTriangle.corner[0].getY(), 0, 0);
+ }
+ bounds.add(shadedTriangle.corner[0]);
+ bounds.add(shadedTriangle.corner[1]);
+ bounds.add(shadedTriangle.corner[2]);
+ }
+ }
+ return bounds;
+ }
+}
Propchange: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDMeshBasedShadingType.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShading.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShading.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShading.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShading.java Fri Apr 2 07:08:09 2021
@@ -17,6 +17,8 @@
package org.apache.pdfbox.pdmodel.graphics.shading;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
@@ -196,6 +198,19 @@ public abstract class PDShading implemen
}
/**
+ * Calculate a bounding rectangle around the areas of this shading context.
+ *
+ * @param xform
+ * @param matrix
+ * @return Bounding rectangle or null, if not supported by this shading type.
+ * @throws java.io.IOException
+ */
+ public Rectangle2D getBounds(AffineTransform xform, Matrix matrix) throws IOException
+ {
+ return null;
+ }
+
+ /**
* This will set the AntiAlias value.
*
* @param antiAlias the new AntiAlias value
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java Fri Apr 2 07:08:09 2021
@@ -17,9 +17,23 @@
package org.apache.pdfbox.pdmodel.graphics.shading;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.common.PDRange;
import org.apache.pdfbox.util.Matrix;
/**
@@ -27,6 +41,8 @@ import org.apache.pdfbox.util.Matrix;
*/
public class PDShadingType4 extends PDTriangleBasedShadingType
{
+ private static final Log LOG = LogFactory.getLog(PDShadingType4.class);
+
/**
* Constructor using the given shading dictionary.
*
@@ -69,4 +85,118 @@ public class PDShadingType4 extends PDTr
{
return new Type4ShadingPaint(this, matrix);
}
+
+ @SuppressWarnings("squid:S1166")
+ @Override
+ List<ShadedTriangle> collectTriangles(AffineTransform xform, Matrix matrix)
+ throws IOException
+ {
+ int bitsPerFlag = getBitsPerFlag();
+ COSDictionary dict = getCOSObject();
+ if (!(dict instanceof COSStream))
+ {
+ return Collections.emptyList();
+ }
+ PDRange rangeX = getDecodeForParameter(0);
+ PDRange rangeY = getDecodeForParameter(1);
+ if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 ||
+ Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
+ {
+ return Collections.emptyList();
+ }
+ PDRange[] colRange = new PDRange[getNumberOfColorComponents()];
+ for (int i = 0; i < getNumberOfColorComponents(); ++i)
+ {
+ colRange[i] = getDecodeForParameter(2 + i);
+ }
+ List<ShadedTriangle> list = new ArrayList<ShadedTriangle>();
+ long maxSrcCoord = (long) Math.pow(2, getBitsPerCoordinate()) - 1;
+ long maxSrcColor = (long) Math.pow(2, getBitsPerComponent()) - 1;
+ COSStream stream = (COSStream) dict;
+
+ ImageInputStream mciis = new MemoryCacheImageInputStream(stream.createInputStream());
+ try
+ {
+ byte flag = (byte) 0;
+ try
+ {
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ }
+ catch (EOFException ex)
+ {
+ LOG.error(ex);
+ }
+
+ boolean eof = false;
+ while (!eof)
+ {
+ Vertex p0, p1, p2;
+ Point2D[] ps;
+ float[][] cs;
+ int lastIndex;
+ try
+ {
+ switch (flag)
+ {
+ case 0:
+ p0 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
+ matrix, xform);
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ if (flag != 0)
+ {
+ LOG.error("bad triangle: " + flag);
+ }
+ p1 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
+ matrix, xform);
+ mciis.readBits(bitsPerFlag);
+ if (flag != 0)
+ {
+ LOG.error("bad triangle: " + flag);
+ }
+ p2 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
+ matrix, xform);
+ ps = new Point2D[] { p0.point, p1.point, p2.point };
+ cs = new float[][] { p0.color, p1.color, p2.color };
+ list.add(new ShadedTriangle(ps, cs));
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ break;
+ case 1:
+ case 2:
+ lastIndex = list.size() - 1;
+ if (lastIndex < 0)
+ {
+ LOG.error("broken data stream: " + list.size());
+ }
+ else
+ {
+ ShadedTriangle preTri = list.get(lastIndex);
+ p2 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY,
+ colRange, matrix, xform);
+ ps = new Point2D[] { flag == 1 ? preTri.corner[1] : preTri.corner[0],
+ preTri.corner[2],
+ p2.point };
+ cs = new float[][] { flag == 1 ? preTri.color[1] : preTri.color[0],
+ preTri.color[2],
+ p2.color };
+ list.add(new ShadedTriangle(ps, cs));
+ flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+ }
+ break;
+ default:
+ LOG.warn("bad flag: " + flag);
+ break;
+ }
+ }
+ catch (EOFException ex)
+ {
+ eof = true;
+ }
+ }
+ }
+ finally
+ {
+ mciis.close();
+ }
+ return list;
+ }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java Fri Apr 2 07:08:09 2021
@@ -17,9 +17,21 @@
package org.apache.pdfbox.pdmodel.graphics.shading;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.common.PDRange;
import org.apache.pdfbox.util.Matrix;
/**
@@ -69,4 +81,101 @@ public class PDShadingType5 extends PDTr
{
return new Type5ShadingPaint(this, matrix);
}
+
+ @SuppressWarnings("squid:S1166")
+ @Override
+ List<ShadedTriangle> collectTriangles(AffineTransform xform, Matrix matrix) throws IOException
+ {
+ COSDictionary dict = getCOSObject();
+ if (!(dict instanceof COSStream))
+ {
+ return Collections.emptyList();
+ }
+ PDRange rangeX = getDecodeForParameter(0);
+ PDRange rangeY = getDecodeForParameter(1);
+ if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 ||
+ Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
+ {
+ return Collections.emptyList();
+ }
+ int numPerRow = getVerticesPerRow();
+ PDRange[] colRange = new PDRange[getNumberOfColorComponents()];
+ for (int i = 0; i < getNumberOfColorComponents(); ++i)
+ {
+ colRange[i] = getDecodeForParameter(2 + i);
+ }
+ List<Vertex> vlist = new ArrayList<Vertex>();
+ long maxSrcCoord = (long) Math.pow(2, getBitsPerCoordinate()) - 1;
+ long maxSrcColor = (long) Math.pow(2, getBitsPerComponent()) - 1;
+ COSStream cosStream = (COSStream) dict;
+
+ ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream());
+ try
+ {
+ boolean eof = false;
+ while (!eof)
+ {
+ Vertex p;
+ try
+ {
+ p = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform);
+ vlist.add(p);
+ }
+ catch (EOFException ex)
+ {
+ eof = true;
+ }
+ }
+ }
+ finally
+ {
+ mciis.close();
+ }
+ int rowNum = vlist.size() / numPerRow;
+ Vertex[][] latticeArray = new Vertex[rowNum][numPerRow];
+ List<ShadedTriangle> list = new ArrayList<ShadedTriangle>();
+ if (rowNum < 2)
+ {
+ // must have at least two rows; if not, return empty list
+ return list;
+ }
+ for (int i = 0; i < rowNum; i++)
+ {
+ for (int j = 0; j < numPerRow; j++)
+ {
+ latticeArray[i][j] = vlist.get(i * numPerRow + j);
+ }
+ }
+
+ for (int i = 0; i < rowNum - 1; i++)
+ {
+ for (int j = 0; j < numPerRow - 1; j++)
+ {
+ Point2D[] ps = new Point2D[] {
+ latticeArray[i][j].point,
+ latticeArray[i][j + 1].point,
+ latticeArray[i + 1][j].point };
+
+ float[][] cs = new float[][] {
+ latticeArray[i][j].color,
+ latticeArray[i][j + 1].color,
+ latticeArray[i + 1][j].color };
+
+ list.add(new ShadedTriangle(ps, cs));
+
+ ps = new Point2D[] {
+ latticeArray[i][j + 1].point,
+ latticeArray[i + 1][j].point,
+ latticeArray[i + 1][j + 1].point };
+
+ cs = new float[][]{
+ latticeArray[i][j + 1].color,
+ latticeArray[i + 1][j].color,
+ latticeArray[i + 1][j + 1].color };
+
+ list.add(new ShadedTriangle(ps, cs));
+ }
+ }
+ return list;
+ }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java Fri Apr 2 07:08:09 2021
@@ -17,6 +17,10 @@
package org.apache.pdfbox.pdmodel.graphics.shading;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.util.Matrix;
@@ -24,7 +28,7 @@ import org.apache.pdfbox.util.Matrix;
/**
* Resources for a shading type 6 (Coons Patch Mesh).
*/
-public class PDShadingType6 extends PDShadingType4
+public class PDShadingType6 extends PDMeshBasedShadingType
{
/**
* Constructor using the given shading dictionary.
@@ -47,4 +51,16 @@ public class PDShadingType6 extends PDSh
{
return new Type6ShadingPaint(this, matrix);
}
+
+ @Override
+ protected Patch generatePatch(Point2D[] points, float[][] color)
+ {
+ return new CoonsPatch(points, color);
+ }
+
+ @Override
+ public Rectangle2D getBounds(AffineTransform xform, Matrix matrix) throws IOException
+ {
+ return getBounds(xform, matrix, 12);
+ }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java Fri Apr 2 07:08:09 2021
@@ -17,6 +17,10 @@
package org.apache.pdfbox.pdmodel.graphics.shading;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.util.Matrix;
@@ -24,7 +28,7 @@ import org.apache.pdfbox.util.Matrix;
/**
* Resources for a shading type 7 (Tensor-Product Patch Mesh).
*/
-public class PDShadingType7 extends PDShadingType6
+public class PDShadingType7 extends PDMeshBasedShadingType
{
/**
* Constructor using the given shading dictionary.
@@ -47,4 +51,16 @@ public class PDShadingType7 extends PDSh
{
return new Type7ShadingPaint(this, matrix);
}
+
+ @Override
+ protected Patch generatePatch(Point2D[] points, float[][] color)
+ {
+ return new TensorPatch(points, color);
+ }
+
+ @Override
+ public Rectangle2D getBounds(AffineTransform xform, Matrix matrix) throws IOException
+ {
+ return getBounds(xform, matrix, 16);
+ }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDTriangleBasedShadingType.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDTriangleBasedShadingType.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDTriangleBasedShadingType.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDTriangleBasedShadingType.java Fri Apr 2 07:08:09 2021
@@ -15,10 +15,21 @@
*/
package org.apache.pdfbox.pdmodel.graphics.shading;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.List;
+
+import javax.imageio.stream.ImageInputStream;
+
+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.COSName;
import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.util.Matrix;
/**
* Common resources for shading types 4,5,6 and 7
@@ -30,20 +41,30 @@ abstract class PDTriangleBasedShadingTyp
// value: same as the value of Range
private COSArray decode = null;
+ private static final Log LOG = LogFactory.getLog(TriangleBasedShadingContext.class);
+
+ private int bitsPerCoordinate = -1;
+ private int bitsPerColorComponent = -1;
+ private int numberOfColorComponents = -1;
+
PDTriangleBasedShadingType(COSDictionary shadingDictionary)
{
super(shadingDictionary);
}
/**
- * The bits per component of this shading. This will return -1 if one has
- * not been set.
+ * The bits per component of this shading. This will return -1 if one has not been set.
*
* @return the number of bits per component
*/
public int getBitsPerComponent()
{
- return getCOSObject().getInt(COSName.BITS_PER_COMPONENT, -1);
+ if (bitsPerColorComponent == -1)
+ {
+ bitsPerColorComponent = getCOSObject().getInt(COSName.BITS_PER_COMPONENT, -1);
+ LOG.debug("bitsPerColorComponent: " + bitsPerColorComponent);
+ }
+ return bitsPerColorComponent;
}
/**
@@ -54,6 +75,7 @@ abstract class PDTriangleBasedShadingTyp
public void setBitsPerComponent(int bitsPerComponent)
{
getCOSObject().setInt(COSName.BITS_PER_COMPONENT, bitsPerComponent);
+ bitsPerColorComponent = bitsPerComponent;
}
/**
@@ -64,17 +86,39 @@ abstract class PDTriangleBasedShadingTyp
*/
public int getBitsPerCoordinate()
{
- return getCOSObject().getInt(COSName.BITS_PER_COORDINATE, -1);
+ if (bitsPerCoordinate == -1)
+ {
+ bitsPerCoordinate = getCOSObject().getInt(COSName.BITS_PER_COORDINATE, -1);
+ LOG.debug("bitsPerCoordinate: " + (Math.pow(2, bitsPerCoordinate) - 1));
+ }
+ return bitsPerCoordinate;
}
/**
* Set the number of bits per coordinate.
*
- * @param bitsPerComponent the number of bits per coordinate
+ * @param bitsPerCoordinate the number of bits per coordinate
*/
- public void setBitsPerCoordinate(int bitsPerComponent)
+ public void setBitsPerCoordinate(int bitsPerCoordinate)
{
- getCOSObject().setInt(COSName.BITS_PER_COORDINATE, bitsPerComponent);
+ getCOSObject().setInt(COSName.BITS_PER_COORDINATE, bitsPerCoordinate);
+ this.bitsPerCoordinate = bitsPerCoordinate;
+ }
+
+ /**
+ * The number of color components of this shading.
+ *
+ * @return number of color components of this shading
+ */
+ public int getNumberOfColorComponents() throws IOException
+ {
+ if (numberOfColorComponents == -1)
+ {
+ numberOfColorComponents = getFunction() != null ? 1
+ : getColorSpace().getNumberOfComponents();
+ LOG.debug("numberOfColorComponents: " + numberOfColorComponents);
+ }
+ return numberOfColorComponents;
}
/**
@@ -118,5 +162,85 @@ abstract class PDTriangleBasedShadingTyp
}
return retval;
}
+
+ /**
+ * Calculate the interpolation, see p.345 pdf spec 1.7.
+ *
+ * @param src src value
+ * @param srcMax max src value (2^bits-1)
+ * @param dstMin min dst value
+ * @param dstMax max dst value
+ * @return interpolated value
+ */
+ protected float interpolate(float src, long srcMax, float dstMin, float dstMax)
+ {
+ return dstMin + (src * (dstMax - dstMin) / srcMax);
+ }
+
+ /**
+ * Read a vertex from the bit input stream performs interpolations.
+ *
+ * @param input bit input stream
+ * @param maxSrcCoord max value for source coordinate (2^bits-1)
+ * @param maxSrcColor max value for source color (2^bits-1)
+ * @param rangeX dest range for X
+ * @param rangeY dest range for Y
+ * @param colRangeTab dest range array for colors
+ * @param matrix the pattern matrix concatenated with that of the parent content stream
+ * @return a new vertex with the flag and the interpolated values
+ * @throws IOException if something went wrong
+ */
+ protected Vertex readVertex(ImageInputStream input, long maxSrcCoord, long maxSrcColor,
+ PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab,
+ Matrix matrix, AffineTransform xform) throws IOException
+ {
+ float[] colorComponentTab = new float[numberOfColorComponents];
+ long x = input.readBits(bitsPerCoordinate);
+ long y = input.readBits(bitsPerCoordinate);
+ float dstX = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
+ float dstY = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
+ LOG.debug("coord: " + String.format("[%06X,%06X] -> [%f,%f]", x, y, dstX, dstY));
+ Point2D p = matrix.transformPoint(dstX, dstY);
+ xform.transform(p, p);
+
+ for (int n = 0; n < numberOfColorComponents; ++n)
+ {
+ int color = (int) input.readBits(bitsPerColorComponent);
+ colorComponentTab[n] = interpolate(color, maxSrcColor, colRangeTab[n].getMin(),
+ colRangeTab[n].getMax());
+ LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
+ + "-> color[" + n + "]: " + colorComponentTab[n]);
+ }
+ // "Each set of vertex data shall occupy a whole number of bytes.
+ // If the total number of bits required is not divisible by 8, the last data byte
+ // for each vertex is padded at the end with extra bits, which shall be ignored."
+ int bitOffset = input.getBitOffset();
+ if (bitOffset != 0)
+ {
+ input.readBits(8 - bitOffset);
+ }
+
+ return new Vertex(p, colorComponentTab);
+ }
+
+ abstract List<ShadedTriangle> collectTriangles(AffineTransform xform, Matrix matrix) throws IOException;
+
+ @Override
+ public Rectangle2D getBounds(AffineTransform xform, Matrix matrix) throws IOException
+ {
+ Rectangle2D bounds = null;
+ for (ShadedTriangle shadedTriangle : collectTriangles(xform, matrix))
+ {
+ if (bounds == null)
+ {
+ bounds = new Rectangle2D.Double(shadedTriangle.corner[0].getX(),
+ shadedTriangle.corner[0].getY(), 0, 0);
+ }
+ bounds.add(shadedTriangle.corner[0]);
+ bounds.add(shadedTriangle.corner[1]);
+ bounds.add(shadedTriangle.corner[2]);
+ }
+ return bounds;
+ }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java Fri Apr 2 07:08:09 2021
@@ -18,22 +18,13 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
-import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.MemoryCacheImageInputStream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.pdmodel.common.PDRange;
+
import org.apache.pdfbox.util.Matrix;
/**
@@ -44,7 +35,6 @@ import org.apache.pdfbox.util.Matrix;
*/
abstract class PatchMeshesShadingContext extends TriangleBasedShadingContext
{
- private static final Log LOG = LogFactory.getLog(PatchMeshesShadingContext.class);
/**
* patch list
@@ -62,215 +52,15 @@ abstract class PatchMeshesShadingContext
* @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
* @throws IOException if something went wrong
*/
- protected PatchMeshesShadingContext(PDShadingType6 shading, ColorModel colorModel,
+ protected PatchMeshesShadingContext(PDMeshBasedShadingType shading, ColorModel colorModel,
AffineTransform xform, Matrix matrix, Rectangle deviceBounds,
int controlPoints) throws IOException
{
super(shading, colorModel, xform, matrix);
- patchList = collectPatches(shading, xform, matrix, controlPoints);
+ patchList = shading.collectPatches(xform, matrix, controlPoints);
createPixelTable(deviceBounds);
}
- /**
- * Create a patch list from a data stream, the returned list contains all the patches contained
- * in the data stream.
- *
- * @param shadingType the shading type
- * @param xform transformation for user to device space
- * @param matrix the pattern matrix concatenated with that of the parent content stream
- * @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
- * @return the obtained patch list
- * @throws IOException when something went wrong
- */
- final List<Patch> collectPatches(PDShadingType6 shadingType, AffineTransform xform,
- Matrix matrix, int controlPoints) throws IOException
- {
- COSDictionary dict = shadingType.getCOSObject();
- if (!(dict instanceof COSStream))
- {
- return Collections.emptyList();
- }
- PDRange rangeX = shadingType.getDecodeForParameter(0);
- PDRange rangeY = shadingType.getDecodeForParameter(1);
- if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 ||
- Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
- {
- return Collections.emptyList();
- }
- int bitsPerFlag = shadingType.getBitsPerFlag();
- PDRange[] colRange = new PDRange[numberOfColorComponents];
- for (int i = 0; i < numberOfColorComponents; ++i)
- {
- colRange[i] = shadingType.getDecodeForParameter(2 + i);
- if (colRange[i] == null)
- {
- throw new IOException("Range missing in shading /Decode entry");
- }
- }
- List<Patch> list = new ArrayList<Patch>();
- long maxSrcCoord = (long) Math.pow(2, bitsPerCoordinate) - 1;
- long maxSrcColor = (long) Math.pow(2, bitsPerColorComponent) - 1;
- COSStream cosStream = (COSStream) dict;
-
- ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream());
- try
- {
- Point2D[] implicitEdge = new Point2D[4];
- float[][] implicitCornerColor = new float[2][numberOfColorComponents];
- byte flag = 0;
-
- try
- {
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- }
- catch (EOFException ex)
- {
- LOG.error(ex);
- }
-
- boolean eof = false;
- while (!eof)
- {
- try
- {
- boolean isFree = (flag == 0);
- Patch current = readPatch(mciis, isFree, implicitEdge, implicitCornerColor,
- maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform, controlPoints);
- if (current == null)
- {
- break;
- }
- list.add(current);
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- switch (flag)
- {
- case 0:
- break;
- case 1:
- implicitEdge = current.getFlag1Edge();
- implicitCornerColor = current.getFlag1Color();
- break;
- case 2:
- implicitEdge = current.getFlag2Edge();
- implicitCornerColor = current.getFlag2Color();
- break;
- case 3:
- implicitEdge = current.getFlag3Edge();
- implicitCornerColor = current.getFlag3Color();
- break;
- default:
- LOG.warn("bad flag: " + flag);
- break;
- }
- }
- catch (EOFException ex)
- {
- eof = true;
- }
- }
- }
- finally
- {
- mciis.close();
- }
- return list;
- }
-
- /**
- * Read a single patch from a data stream, a patch contains information of its coordinates and
- * color parameters.
- *
- * @param input the image source data stream
- * @param isFree whether this is a free patch
- * @param implicitEdge implicit edge when a patch is not free, otherwise it's not used
- * @param implicitCornerColor implicit colors when a patch is not free, otherwise it's not used
- * @param maxSrcCoord the maximum coordinate value calculated from source data
- * @param maxSrcColor the maximum color value calculated from source data
- * @param rangeX range for coordinate x
- * @param rangeY range for coordinate y
- * @param colRange range for color
- * @param matrix the pattern matrix concatenated with that of the parent content stream
- * @param xform transformation for user to device space
- * @param controlPoints number of control points, 12 for type 6 shading and 16 for type 7 shading
- * @return a single patch
- * @throws IOException when something went wrong
- */
- protected Patch readPatch(ImageInputStream input, boolean isFree, Point2D[] implicitEdge,
- float[][] implicitCornerColor, long maxSrcCoord, long maxSrcColor,
- PDRange rangeX, PDRange rangeY, PDRange[] colRange, Matrix matrix,
- AffineTransform xform, int controlPoints) throws IOException
- {
- float[][] color = new float[4][numberOfColorComponents];
- Point2D[] points = new Point2D[controlPoints];
- int pStart = 4, cStart = 2;
- if (isFree)
- {
- pStart = 0;
- cStart = 0;
- }
- else
- {
- points[0] = implicitEdge[0];
- points[1] = implicitEdge[1];
- points[2] = implicitEdge[2];
- points[3] = implicitEdge[3];
-
- for (int i = 0; i < numberOfColorComponents; i++)
- {
- color[0][i] = implicitCornerColor[0][i];
- color[1][i] = implicitCornerColor[1][i];
- }
- }
-
- try
- {
- for (int i = pStart; i < controlPoints; i++)
- {
- long x = input.readBits(bitsPerCoordinate);
- long y = input.readBits(bitsPerCoordinate);
- float px = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
- float py = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
- Point2D p = matrix.transformPoint(px, py);
- xform.transform(p, p);
- points[i] = p;
- }
- for (int i = cStart; i < 4; i++)
- {
- for (int j = 0; j < numberOfColorComponents; j++)
- {
- long c = input.readBits(bitsPerColorComponent);
- color[i][j] = interpolate(c, maxSrcColor, colRange[j].getMin(),
- colRange[j].getMax());
- }
- }
- }
- catch (EOFException ex)
- {
- LOG.debug("EOF");
- return null;
- }
- return generatePatch(points, color);
- }
-
- /**
- * Create a patch using control points and 4 corner color values, in
- * Type6ShadingContext, a CoonsPatch is returned; in Type6ShadingContext, a
- * TensorPatch is returned.
- *
- * @param points 12 or 16 control points
- * @param color 4 corner colors
- * @return a patch instance
- */
- abstract Patch generatePatch(Point2D[] points, float[][] color);
-
- /**
- * Get a point coordinate on a line by linear interpolation.
- */
- private float interpolate(float x, long maxValue, float rangeMin, float rangeMax)
- {
- return rangeMin + (x / maxValue) * (rangeMax - rangeMin);
- }
-
@Override
protected Map<Point, Integer> calcPixelTable(Rectangle deviceBounds) throws IOException
{
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TriangleBasedShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TriangleBasedShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TriangleBasedShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TriangleBasedShadingContext.java Fri Apr 2 07:08:09 2021
@@ -38,14 +38,6 @@ import org.apache.pdfbox.util.Matrix;
*/
abstract class TriangleBasedShadingContext extends ShadingContext implements PaintContext
{
- private static final Log LOG = LogFactory.getLog(TriangleBasedShadingContext.class);
-
- protected int bitsPerCoordinate;
- protected int bitsPerColorComponent;
- protected int numberOfColorComponents;
-
- private final boolean hasFunction;
-
// map of pixels within triangles to their RGB color
private Map<Point, Integer> pixelTable;
@@ -62,14 +54,6 @@ abstract class TriangleBasedShadingConte
Matrix matrix) throws IOException
{
super(shading, cm, xform, matrix);
- PDTriangleBasedShadingType triangleBasedShadingType = (PDTriangleBasedShadingType) shading;
- hasFunction = shading.getFunction() != null;
- bitsPerCoordinate = triangleBasedShadingType.getBitsPerCoordinate();
- LOG.debug("bitsPerCoordinate: " + (Math.pow(2, bitsPerCoordinate) - 1));
- bitsPerColorComponent = triangleBasedShadingType.getBitsPerComponent();
- LOG.debug("bitsPerColorComponent: " + bitsPerColorComponent);
- numberOfColorComponents = hasFunction ? 1 : getShadingColorSpace().getNumberOfComponents();
- LOG.debug("numberOfColorComponents: " + numberOfColorComponents);
}
/**
@@ -156,7 +140,7 @@ abstract class TriangleBasedShadingConte
*/
private int evalFunctionAndConvertToRGB(float[] values) throws IOException
{
- if (hasFunction)
+ if (getShading().getFunction() != null)
{
values = getShading().evalFunction(values);
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java Fri Apr 2 07:08:09 2021
@@ -18,20 +18,11 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
-import java.io.EOFException;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.MemoryCacheImageInputStream;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.pdmodel.common.PDRange;
import org.apache.pdfbox.util.Matrix;
/**
@@ -62,118 +53,7 @@ class Type4ShadingContext extends Gourau
bitsPerFlag = shading.getBitsPerFlag();
//TODO handle cases where bitperflag isn't 8
LOG.debug("bitsPerFlag: " + bitsPerFlag);
- setTriangleList(collectTriangles(shading, xform, matrix));
+ setTriangleList(shading.collectTriangles(xform, matrix));
createPixelTable(deviceBounds);
}
-
- private List<ShadedTriangle> collectTriangles(PDShadingType4 freeTriangleShadingType, AffineTransform xform, Matrix matrix)
- throws IOException
- {
- COSDictionary dict = freeTriangleShadingType.getCOSObject();
- if (!(dict instanceof COSStream))
- {
- return Collections.emptyList();
- }
- PDRange rangeX = freeTriangleShadingType.getDecodeForParameter(0);
- PDRange rangeY = freeTriangleShadingType.getDecodeForParameter(1);
- if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 ||
- Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
- {
- return Collections.emptyList();
- }
- PDRange[] colRange = new PDRange[numberOfColorComponents];
- for (int i = 0; i < numberOfColorComponents; ++i)
- {
- colRange[i] = freeTriangleShadingType.getDecodeForParameter(2 + i);
- }
- List<ShadedTriangle> list = new ArrayList<ShadedTriangle>();
- long maxSrcCoord = (long) Math.pow(2, bitsPerCoordinate) - 1;
- long maxSrcColor = (long) Math.pow(2, bitsPerColorComponent) - 1;
- COSStream stream = (COSStream) dict;
-
- ImageInputStream mciis = new MemoryCacheImageInputStream(stream.createInputStream());
- try
- {
- byte flag = (byte) 0;
- try
- {
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- }
- catch (EOFException ex)
- {
- LOG.error(ex);
- }
-
- boolean eof = false;
- while (!eof)
- {
- Vertex p0, p1, p2;
- Point2D[] ps;
- float[][] cs;
- int lastIndex;
- try
- {
- switch (flag)
- {
- case 0:
- p0 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
- matrix, xform);
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- if (flag != 0)
- {
- LOG.error("bad triangle: " + flag);
- }
- p1 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
- matrix, xform);
- mciis.readBits(bitsPerFlag);
- if (flag != 0)
- {
- LOG.error("bad triangle: " + flag);
- }
- p2 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange,
- matrix, xform);
- ps = new Point2D[] { p0.point, p1.point, p2.point };
- cs = new float[][] { p0.color, p1.color, p2.color };
- list.add(new ShadedTriangle(ps, cs));
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- break;
- case 1:
- case 2:
- lastIndex = list.size() - 1;
- if (lastIndex < 0)
- {
- LOG.error("broken data stream: " + list.size());
- }
- else
- {
- ShadedTriangle preTri = list.get(lastIndex);
- p2 = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY,
- colRange, matrix, xform);
- ps = new Point2D[] { flag == 1 ? preTri.corner[1] : preTri.corner[0],
- preTri.corner[2],
- p2.point };
- cs = new float[][] { flag == 1 ? preTri.color[1] : preTri.color[0],
- preTri.color[2],
- p2.color };
- list.add(new ShadedTriangle(ps, cs));
- flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
- }
- break;
- default:
- LOG.warn("bad flag: " + flag);
- break;
- }
- }
- catch (EOFException ex)
- {
- eof = true;
- }
- }
- }
- finally
- {
- mciis.close();
- }
- return list;
- }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java Fri Apr 2 07:08:09 2021
@@ -18,20 +18,11 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
-import java.io.EOFException;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.MemoryCacheImageInputStream;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.pdmodel.common.PDRange;
import org.apache.pdfbox.util.Matrix;
/**
@@ -60,104 +51,7 @@ class Type5ShadingContext extends Gourau
LOG.debug("Type5ShadingContext");
- setTriangleList(collectTriangles(shading, xform, matrix));
+ setTriangleList(shading.collectTriangles(xform, matrix));
createPixelTable(deviceBounds);
}
-
- private List<ShadedTriangle> collectTriangles(PDShadingType5 latticeTriangleShadingType,
- AffineTransform xform, Matrix matrix) throws IOException
- {
- COSDictionary dict = latticeTriangleShadingType.getCOSObject();
- if (!(dict instanceof COSStream))
- {
- return Collections.emptyList();
- }
- PDRange rangeX = latticeTriangleShadingType.getDecodeForParameter(0);
- PDRange rangeY = latticeTriangleShadingType.getDecodeForParameter(1);
- if (Float.compare(rangeX.getMin(), rangeX.getMax()) == 0 ||
- Float.compare(rangeY.getMin(), rangeY.getMax()) == 0)
- {
- return Collections.emptyList();
- }
- int numPerRow = latticeTriangleShadingType.getVerticesPerRow();
- PDRange[] colRange = new PDRange[numberOfColorComponents];
- for (int i = 0; i < numberOfColorComponents; ++i)
- {
- colRange[i] = latticeTriangleShadingType.getDecodeForParameter(2 + i);
- }
- List<Vertex> vlist = new ArrayList<Vertex>();
- long maxSrcCoord = (long) Math.pow(2, bitsPerCoordinate) - 1;
- long maxSrcColor = (long) Math.pow(2, bitsPerColorComponent) - 1;
- COSStream cosStream = (COSStream) dict;
-
- ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.createInputStream());
- try
- {
- boolean eof = false;
- while (!eof)
- {
- Vertex p;
- try
- {
- p = readVertex(mciis, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, matrix, xform);
- vlist.add(p);
- }
- catch (EOFException ex)
- {
- eof = true;
- }
- }
- }
- finally
- {
- mciis.close();
- }
- int rowNum = vlist.size() / numPerRow;
- Vertex[][] latticeArray = new Vertex[rowNum][numPerRow];
- List<ShadedTriangle> list = new ArrayList<ShadedTriangle>();
- if (rowNum < 2)
- {
- // must have at least two rows; if not, return empty list
- return list;
- }
- for (int i = 0; i < rowNum; i++)
- {
- for (int j = 0; j < numPerRow; j++)
- {
- latticeArray[i][j] = vlist.get(i * numPerRow + j);
- }
- }
-
- for (int i = 0; i < rowNum - 1; i++)
- {
- for (int j = 0; j < numPerRow - 1; j++)
- {
- Point2D[] ps = new Point2D[] {
- latticeArray[i][j].point,
- latticeArray[i][j + 1].point,
- latticeArray[i + 1][j].point };
-
- float[][] cs = new float[][] {
- latticeArray[i][j].color,
- latticeArray[i][j + 1].color,
- latticeArray[i + 1][j].color };
-
- list.add(new ShadedTriangle(ps, cs));
-
- ps = new Point2D[] {
- latticeArray[i][j + 1].point,
- latticeArray[i + 1][j].point,
- latticeArray[i + 1][j + 1].point };
-
- cs = new float[][]{
- latticeArray[i][j + 1].color,
- latticeArray[i + 1][j].color,
- latticeArray[i + 1][j + 1].color };
-
- list.add(new ShadedTriangle(ps, cs));
- }
- }
- return list;
- }
-
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java Fri Apr 2 07:08:09 2021
@@ -17,7 +17,6 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
import java.io.IOException;
import org.apache.pdfbox.util.Matrix;
@@ -45,10 +44,4 @@ class Type6ShadingContext extends PatchM
{
super(shading, colorModel, xform, matrix, deviceBounds, 12);
}
-
- @Override
- protected Patch generatePatch(Point2D[] points, float[][] color)
- {
- return new CoonsPatch(points, color);
- }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java Fri Apr 2 07:08:09 2021
@@ -17,7 +17,6 @@ package org.apache.pdfbox.pdmodel.graphi
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.image.ColorModel;
import java.io.IOException;
import org.apache.pdfbox.util.Matrix;
@@ -45,10 +44,4 @@ class Type7ShadingContext extends PatchM
{
super(shading, colorModel, xform, matrix, deviceBounds, 16);
}
-
- @Override
- protected Patch generatePatch(Point2D[] points, float[][] color)
- {
- return new TensorPatch(points, color);
- }
}
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java?rev=1888288&r1=1888287&r2=1888288&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Fri Apr 2 07:08:09 2021
@@ -1413,7 +1413,20 @@ public class PageDrawer extends PDFGraph
}
else
{
- area = getGraphicsState().getCurrentClippingPath();
+ Rectangle2D bounds = shading.getBounds(new AffineTransform(), ctm);
+ if (bounds != null)
+ {
+ bounds.add(new Point2D.Double(Math.floor(bounds.getMinX() - 1),
+ Math.floor(bounds.getMinY() - 1)));
+ bounds.add(new Point2D.Double(Math.ceil(bounds.getMaxX() + 1),
+ Math.ceil(bounds.getMaxY() + 1)));
+ area = new Area(bounds);
+ area.intersect(getGraphicsState().getCurrentClippingPath());
+ }
+ else
+ {
+ area = getGraphicsState().getCurrentClippingPath();
+ }
}
if (isContentRendered())
{