Author: tilman Date: Mon Aug 4 18:40:45 2014 New Revision: 1615722 URL: http://svn.apache.org/r1615722 Log: PDFBOX-1915: fix BBox if coordinates are inverted; add BBox to shading 1,3,6,7 as suggested by Shaola Ren; drop empty BBox because of trouble with eci file
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type1ShadingContext.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java?rev=1615722&r1=1615721&r2=1615722&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/AxialShadingContext.java Mon Aug 4 18:40:45 2014 @@ -63,8 +63,8 @@ public class AxialShadingContext impleme private double y1y0; private float d1d0; private double denom; - private final PDRectangle bboxRect; - private float[] bboxTab = new float[4]; + private PDRectangle rectBBox; + float minBBoxX, minBBoxY, maxBBoxX, maxBBoxY; private final double axialLength; private final int[] colorTable; @@ -83,19 +83,29 @@ public class AxialShadingContext impleme this.shading = shading; coords = this.shading.getCoords().toFloatArray(); - bboxRect = shading.getBBox(); - if (bboxRect != null) + rectBBox = shading.getBBox(); + if (rectBBox != null) { - bboxTab[0] = bboxRect.getLowerLeftX(); - bboxTab[1] = bboxRect.getLowerLeftY(); - bboxTab[2] = bboxRect.getUpperRightX(); - bboxTab[3] = bboxRect.getUpperRightY(); + float[] bboxTab = new float[4]; + bboxTab[0] = rectBBox.getLowerLeftX(); + bboxTab[1] = rectBBox.getLowerLeftY(); + bboxTab[2] = rectBBox.getUpperRightX(); + bboxTab[3] = rectBBox.getUpperRightY(); if (ctm != null) { // transform the coords using the given matrix ctm.createAffineTransform().transform(bboxTab, 0, bboxTab, 0, 2); } xform.transform(bboxTab, 0, bboxTab, 0, 2); + minBBoxX = Math.min(bboxTab[0],bboxTab[2]); + minBBoxY = Math.min(bboxTab[1],bboxTab[3]); + maxBBoxX = Math.max(bboxTab[0],bboxTab[2]); + maxBBoxY = Math.max(bboxTab[1],bboxTab[3]); + if (minBBoxX == maxBBoxX || minBBoxY == maxBBoxY) + { + LOG.warn("empty BBox is ignored"); + rectBBox = null; + } } if (ctm != null) @@ -233,9 +243,9 @@ public class AxialShadingContext impleme for (int j = 0; j < h; j++) { double currentY = y + j; - if (bboxRect != null) + if (rectBBox != null) { - if (currentY < bboxTab[3] || currentY > bboxTab[1]) + if (currentY < minBBoxY || currentY > maxBBoxY) { continue; } @@ -244,9 +254,9 @@ public class AxialShadingContext impleme for (int i = 0; i < w; i++) { double currentX = x + i; - if (bboxRect != null) + if (rectBBox != null) { - if (currentX < bboxTab[0] || currentX > bboxTab[2]) + if (currentX < minBBoxX || currentX > maxBBoxX) { continue; } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java?rev=1615722&r1=1615721&r2=1615722&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java Mon Aug 4 18:40:45 2014 @@ -40,6 +40,7 @@ import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSStream; import org.apache.pdfbox.pdmodel.common.PDRange; +import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; import org.apache.pdfbox.util.Matrix; @@ -59,6 +60,8 @@ abstract class PatchMeshesShadingContext protected int rgbBackground; protected final boolean hasFunction; protected final PDShading patchMeshesShadingType; + private PDRectangle rectBBox; + float minBBoxX, minBBoxY, maxBBoxX, maxBBoxY; // the following fields are not intialized in this abstract class protected ArrayList<Patch> patchList; // patch list @@ -84,6 +87,31 @@ abstract class PatchMeshesShadingContext hasFunction = shading.getFunction() != null; shadingColorSpace = shading.getColorSpace(); + rectBBox = shading.getBBox(); + if (rectBBox != null) + { + float[] bboxTab = new float[4]; + bboxTab[0] = rectBBox.getLowerLeftX(); + bboxTab[1] = rectBBox.getLowerLeftY(); + bboxTab[2] = rectBBox.getUpperRightX(); + bboxTab[3] = rectBBox.getUpperRightY(); + if (ctm != null) + { + // transform the coords using the given matrix + ctm.createAffineTransform().transform(bboxTab, 0, bboxTab, 0, 2); + } + xform.transform(bboxTab, 0, bboxTab, 0, 2); + minBBoxX = Math.min(bboxTab[0],bboxTab[2]); + minBBoxY = Math.min(bboxTab[1],bboxTab[3]); + maxBBoxX = Math.max(bboxTab[0],bboxTab[2]); + maxBBoxY = Math.max(bboxTab[1],bboxTab[3]); + if (minBBoxX == maxBBoxX || minBBoxY == maxBBoxY) + { + LOG.warn("empty BBox is ignored"); + rectBBox = null; + } + } + numberOfColorComponents = hasFunction ? 1 : shadingColorSpace.getNumberOfComponents(); // create the output color model using RGB+alpha as color space @@ -383,8 +411,25 @@ abstract class PatchMeshesShadingContext { for (int row = 0; row < h; row++) { + double currentY = y + row; + if (rectBBox != null) + { + if (currentY < minBBoxY || currentY > maxBBoxY) + { + continue; + } + } + for (int col = 0; col < w; col++) { + double currentX = x + col; + if (rectBBox != null) + { + if (currentX < minBBoxX || currentX > maxBBoxX) + { + continue; + } + } Point p = new Point(x + col, y + row); int value; if (pixelTable.containsKey(p)) Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java?rev=1615722&r1=1615721&r2=1615722&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java Mon Aug 4 18:40:45 2014 @@ -31,6 +31,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBoolean; +import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.function.PDFunction; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; import org.apache.pdfbox.util.Matrix; @@ -66,7 +67,9 @@ public class RadialShadingContext implem private float d1d0; private double denom; - + private PDRectangle rectBBox; + float minBBoxX, minBBoxY, maxBBoxX, maxBBoxY; + private final double longestDistance; private int[] colorTable; @@ -84,6 +87,31 @@ public class RadialShadingContext implem this.shading = shading; coords = this.shading.getCoords().toFloatArray(); + rectBBox = shading.getBBox(); + if (rectBBox != null) + { + float[] bboxTab = new float[4]; + bboxTab[0] = rectBBox.getLowerLeftX(); + bboxTab[1] = rectBBox.getLowerLeftY(); + bboxTab[2] = rectBBox.getUpperRightX(); + bboxTab[3] = rectBBox.getUpperRightY(); + if (ctm != null) + { + // transform the coords using the given matrix + ctm.createAffineTransform().transform(bboxTab, 0, bboxTab, 0, 2); + } + xform.transform(bboxTab, 0, bboxTab, 0, 2); + minBBoxX = Math.min(bboxTab[0],bboxTab[2]); + minBBoxY = Math.min(bboxTab[1],bboxTab[3]); + maxBBoxX = Math.max(bboxTab[0],bboxTab[2]); + maxBBoxY = Math.max(bboxTab[1],bboxTab[3]); + if (minBBoxX == maxBBoxX || minBBoxY == maxBBoxY) + { + LOG.warn("empty BBox is ignored"); + rectBBox = null; + } + } + if (ctm != null) { // transform the coords using the given matrix @@ -256,8 +284,24 @@ public class RadialShadingContext implem int[] data = new int[w * h * 4]; for (int j = 0; j < h; j++) { + double currentY = y + j; + if (rectBBox != null) + { + if (currentY < minBBoxY || currentY > maxBBoxY) + { + continue; + } + } for (int i = 0; i < w; i++) { + double currentX = x + i; + if (rectBBox != null) + { + if (currentX < minBBoxX || currentX > maxBBoxX) + { + continue; + } + } useBackground = false; float[] inputValues = calculateInputValues(x + i, y + j); if (Float.isNaN(inputValues[0]) && Float.isNaN(inputValues[1])) Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type1ShadingContext.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type1ShadingContext.java?rev=1615722&r1=1615721&r2=1615722&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type1ShadingContext.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type1ShadingContext.java Mon Aug 4 18:40:45 2014 @@ -29,6 +29,7 @@ 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.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; import org.apache.pdfbox.util.Matrix; @@ -48,6 +49,8 @@ class Type1ShadingContext implements Pai private float[] domain; private Matrix matrix; private float[] background; + private PDRectangle rectBBox; + float minBBoxX, minBBoxY, maxBBoxX, maxBBoxY; /** * Constructor creates an instance to be used for fill operations. @@ -62,6 +65,31 @@ class Type1ShadingContext implements Pai { this.shading = shading; + rectBBox = shading.getBBox(); + if (rectBBox != null) + { + float[] bboxTab = new float[4]; + bboxTab[0] = rectBBox.getLowerLeftX(); + bboxTab[1] = rectBBox.getLowerLeftY(); + bboxTab[2] = rectBBox.getUpperRightX(); + bboxTab[3] = rectBBox.getUpperRightY(); + if (ctm != null) + { + // transform the coords using the given matrix + ctm.createAffineTransform().transform(bboxTab, 0, bboxTab, 0, 2); + } + xform.transform(bboxTab, 0, bboxTab, 0, 2); + minBBoxX = Math.min(bboxTab[0],bboxTab[2]); + minBBoxY = Math.min(bboxTab[1],bboxTab[3]); + maxBBoxX = Math.max(bboxTab[0],bboxTab[2]); + maxBBoxY = Math.max(bboxTab[1],bboxTab[3]); + if (minBBoxX == maxBBoxX || minBBoxY == maxBBoxY) + { + LOG.warn("empty BBox is ignored"); + rectBBox = null; + } + } + // color space shadingColorSpace = this.shading.getColorSpace(); // create the output colormodel using RGB+alpha as colorspace @@ -134,8 +162,24 @@ class Type1ShadingContext implements Pai int[] data = new int[w * h * 4]; for (int j = 0; j < h; j++) { + double currentY = y + j; + if (rectBBox != null) + { + if (currentY < minBBoxY || currentY > maxBBoxY) + { + continue; + } + } for (int i = 0; i < w; i++) { + double currentX = x + i; + if (rectBBox != null) + { + if (currentX < minBBoxX || currentX > maxBBoxX) + { + continue; + } + } int index = (j * w + i) * 4; boolean useBackground = false; float[] values = new float[]