You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2014/01/31 19:25:04 UTC

svn commit: r1563199 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics: pattern/ shading/

Author: lehmi
Date: Fri Jan 31 18:25:03 2014
New Revision: 1563199

URL: http://svn.apache.org/r1563199
Log:
PDFBOX-615: added support for type 4 and type 5 shading patterns as proposed by Tilman Hausherr

Added:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java   (with props)
Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDShadingPatternResources.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDShadingPatternResources.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDShadingPatternResources.java?rev=1563199&r1=1563198&r2=1563199&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDShadingPatternResources.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/pattern/PDShadingPatternResources.java Fri Jan 31 18:25:03 2014
@@ -34,13 +34,16 @@ import org.apache.pdfbox.pdmodel.graphic
 import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingResources;
 import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType2;
 import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType3;
+import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType4;
+import org.apache.pdfbox.pdmodel.graphics.shading.PDShadingType5;
 import org.apache.pdfbox.pdmodel.graphics.shading.RadialShadingPaint;
+import org.apache.pdfbox.pdmodel.graphics.shading.Type4ShadingPaint;
+import org.apache.pdfbox.pdmodel.graphics.shading.Type5ShadingPaint;
 import org.apache.pdfbox.util.Matrix;
 
 /**
  * This represents the resources for a shading pattern.
  *
- * @version $Revision: 1.0 $
  */
 public class PDShadingPatternResources extends PDPatternResources
 {
@@ -211,9 +214,13 @@ public class PDShadingPatternResources e
             case PDShadingResources.SHADING_TYPE3:
                 paint = new RadialShadingPaint((PDShadingType3)getShading(), getMatrix(), pageHeight);
                 break;
-            case PDShadingResources.SHADING_TYPE1: 
             case PDShadingResources.SHADING_TYPE4:
+                paint = new Type4ShadingPaint((PDShadingType4)getShading(), getMatrix(), pageHeight);
+                break;
             case PDShadingResources.SHADING_TYPE5:
+                paint = new Type5ShadingPaint((PDShadingType5)getShading(), getMatrix(), pageHeight);
+                break;
+            case PDShadingResources.SHADING_TYPE1: 
             case PDShadingResources.SHADING_TYPE6:
             case PDShadingResources.SHADING_TYPE7:
                 LOG.debug( "Error: Unsupported shading type " + shadingType );

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,330 @@
+/*
+ * 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.PaintContext;
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.util.ArrayList;
+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.pdmodel.common.function.PDFunction;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceN;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
+import org.apache.pdfbox.pdmodel.graphics.color.PDSeparation;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ *
+ * Helper class that Type4ShadingContext and Type5ShadingContext must extend;
+ * does the shading of Gouraud triangles.
+ *
+ * @author lehmi
+ * @author Tilman Hausherr
+ *
+ */
+public abstract class GouraudShadingContext implements PaintContext
+{
+    private static final Log LOG = LogFactory.getLog(GouraudShadingContext.class);
+
+    private ColorModel outputColorModel;
+    private PDColorSpace colorSpace;
+    /**
+     * number of color components.
+     */
+    protected int numberOfColorComponents;
+    /**
+     * triangle list.
+     */
+    protected ArrayList<GouraudTriangle> triangleList;
+    /**
+     * bits per coordinate.
+     */
+    protected int bitsPerCoordinate;
+    /**
+     * bits per color component.
+     */
+    protected int bitsPerColorComponent;
+    /**
+     * background values.
+     */
+    protected float[] background;
+    private ColorSpace shadingColorSpace;
+    private PDFunction shadingTinttransform;
+    /**
+     * color conversion function.
+     */
+    protected PDFunction function = null; //TODO implement common PDShadingtype for 4 and 5
+    private Area area = new Area(); //TODO for later optimization
+
+    /**
+     * Constructor creates an instance to be used for fill operations.
+     *
+     * @param shadingType the shading type to be used
+     * @param colorModelValue the color model to be used
+     * @param xform transformation for user to device space
+     * @param ctm current transformation matrix
+     * @param pageHeight height of the current page
+     * @throws IOException if something went wrong
+     *
+     */
+    protected GouraudShadingContext(PDShadingResources shadingType, ColorModel colorModelValue,
+            AffineTransform xform, Matrix ctm, int pageHeight) throws IOException
+    {
+        triangleList = new ArrayList<GouraudTriangle>();
+        colorSpace = shadingType.getColorSpace();
+        LOG.debug("colorSpace: " + colorSpace);
+        numberOfColorComponents = colorSpace.getNumberOfComponents();
+        LOG.debug("numberOfColorComponents: " + numberOfColorComponents);
+        LOG.debug("BBox: " + shadingType.getBBox());
+        LOG.debug("Background: " + shadingType.getBackground());
+
+        // create the output colormodel using RGB+alpha as colorspace
+        ColorSpace outputCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        outputColorModel = new ComponentColorModel(outputCS, true, false, Transparency.TRANSLUCENT,
+                DataBuffer.TYPE_BYTE);
+
+        // get the shading colorSpace
+        try
+        {
+            if (!(colorSpace instanceof PDDeviceRGB))
+            {
+                // we have to create an instance of the shading colorspace if it isn't RGB
+                shadingColorSpace = colorSpace.getJavaColorSpace();
+                if (colorSpace instanceof PDDeviceN)
+                {
+                    shadingTinttransform = ((PDDeviceN) colorSpace).getTintTransform();
+                }
+                else if (colorSpace instanceof PDSeparation)
+                {
+                    shadingTinttransform = ((PDSeparation) colorSpace).getTintTransform();
+                }
+            }
+        }
+        catch (IOException exception)
+        {
+            LOG.error("error while creating colorSpace", exception);
+        }
+
+    }
+
+    /**
+     * Read a vertex from the bit input stream and do the interpolations
+     * described in the PDF specification.
+     *
+     * @param input bit input stream
+     * @param flag the flag or any value if not relevant
+     * @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
+     *
+     * @return a new vertex with the flag and the interpolated values
+     *
+     * @throws IOException if something went wrong
+     */
+    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor, 
+            PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
+    {
+        float[] colorComponentTab = new float[numberOfColorComponents];
+        long x = input.readBits(bitsPerCoordinate);
+        long y = input.readBits(bitsPerCoordinate);
+        double dstX = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
+        double dstY = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
+        LOG.debug("coord: " + String.format("[%06X,%06X] -> [%f,%f]", x, y, dstX, dstY));
+        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]);
+        }
+        return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
+    }
+
+    /**
+     * transform a list of vertices from shading to user space (if applicable)
+     * and from user to device space.
+     *
+     * @param vertexList list of vertices
+     * @param xform transformation for user to device space
+     * @param ctm current transformation matrix
+     * @param pageHeight height of the current page
+     */
+    protected void transformVertices(ArrayList<Vertex> vertexList, Matrix ctm, AffineTransform xform, int pageHeight)
+    {
+        for (Vertex v : vertexList)
+        {
+            LOG.debug(v);
+
+            // this segment "inspired" by RadialShadingContext
+            if (ctm != null)
+            {
+                // transform from shading to user space
+                ctm.createAffineTransform().transform(v.point, v.point);
+                // transform from user to device space
+                xform.transform(v.point, v.point);
+            }
+            else
+            {
+                // the shading is used as pattern colorspace in combination
+                // with a fill-, stroke- or showText-operator
+                // move the 0,0-reference including the y-translation from user to device space
+                v.point = new Point.Double(v.point.getX(), pageHeight + xform.getTranslateY() - v.point.getY());
+            }
+
+            LOG.debug(v);
+        }
+    }
+
+    /**
+     * create a java area that includes all the triangles.
+     */
+    protected void createArea()
+    {
+        for (GouraudTriangle triangle : triangleList)
+        {
+            area.add(new Area(triangle.polygon));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dispose()
+    {
+        triangleList = null;
+        outputColorModel = null;
+        colorSpace = null;
+        shadingColorSpace = null;
+        shadingTinttransform = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final ColorModel getColorModel()
+    {
+        return outputColorModel;
+    }
+
+    /**
+     * 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, float srcMax, float dstMin, float dstMax)
+    {
+        return dstMin + (src * (dstMax - dstMin) / srcMax);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final Raster getRaster(int x, int y, int w, int h)
+    {
+        float[] values = new float[numberOfColorComponents];
+        WritableRaster raster = getColorModel().createCompatibleWritableRaster(w, h);
+        if (!triangleList.isEmpty())
+        {
+            int[] data = new int[w * h * 4];
+            for (int row = 0; row < h; row++)
+            {
+                for (int col = 0; col < w; col++)
+                {
+                    Point2D p = new Point(x + col, y + row);
+
+                    //TODO test optmization after ch14.pdf works:
+                    // check whether point is in combined java area
+                    for (GouraudTriangle triangle : triangleList)
+                    {
+                        if (triangle.contains(p))
+                        {
+                            double[] weights = triangle.getWeights(p);
+                            for (int i = 0; i < numberOfColorComponents; ++i)
+                            {
+                                values[i] = (float) (triangle.colorA[i] * weights[0] + triangle.colorB[i] * weights[1] 
+                                        + triangle.colorC[i] * weights[2]);
+                            }
+                            //TODO optimize: quit loop when triangle is found
+                        }
+                        else
+                        {
+                            if (background != null)
+                            {
+                                values = background;
+                            }
+                            else
+                            {
+                                continue;
+                            }
+                        }
+
+                        //TODO handle function
+                        // convert color values from shading colorspace to RGB
+                        if (shadingColorSpace != null)
+                        {
+                            if (shadingTinttransform != null)
+                            {
+                                try
+                                {
+                                    values = shadingTinttransform.eval(values);
+                                }
+                                catch (IOException exception)
+                                {
+                                    LOG.error("error while processing a function", exception);
+                                }
+                            }
+                            values = shadingColorSpace.toRGB(values);
+                        }
+
+                        int index = (row * w + col) * 4;
+                        data[index] = (int) (values[0] * 255);
+                        data[index + 1] = (int) (values[1] * 255);
+                        data[index + 2] = (int) (values[2] * 255);
+                        data[index + 3] = 255;
+                    }
+
+                }
+            }
+            raster.setPixels(0, 0, w, h, data);
+        }
+        return raster;
+    }
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,124 @@
+/*
+ * 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.Polygon;
+import java.awt.geom.Point2D;
+
+/**
+ * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
+ * 
+ * @author Tilman Hausherr
+ */
+public class GouraudTriangle
+{
+    /**
+     * the polygon representing the triangle.
+     */
+    protected final Polygon polygon = new Polygon();
+    /** 
+     * point A of the triangle.
+     */
+    protected final Point2D pointA;
+    /** 
+     * point B of the triangle.
+     */
+    protected final Point2D pointB;
+    /** 
+     * point C of the triangle.
+     */
+    protected final Point2D pointC;
+    /** 
+     * the color of point A.
+     */
+    protected final float[] colorA;
+    /** 
+     * the color of point B.
+     */
+    protected final float[] colorB;
+    /** 
+     * the color of point C.
+     */
+    protected final float[] colorC;
+    
+    
+    /**
+     * Constructor for using 3 points and their colors.
+     * @param a point A of the triangle
+     * @param aColor color of point A
+     * @param b point B of the triangle
+     * @param bColor color of point B
+     * @param c point C of the triangle
+     * @param cColor color of point C
+     */
+    public GouraudTriangle(Point2D a, float[] aColor, Point2D b, float[] bColor, Point2D c, float[] cColor)
+    {
+        pointA = a;
+        pointB = b;
+        pointC = c;
+        colorA = aColor;
+        colorB = bColor;
+        colorC = cColor;
+        polygon.addPoint((int) Math.round(a.getX()), (int) Math.round(a.getY()));
+        polygon.addPoint((int) Math.round(b.getX()), (int) Math.round(b.getY()));
+        polygon.addPoint((int) Math.round(c.getX()), (int) Math.round(c.getY()));
+    }
+
+    /**
+     * Check whether the point is within the triangle.
+     * 
+     * @param p Point
+     * 
+     * @return true if yes, false if no
+     */
+    public boolean contains(Point2D p)
+    {
+        // if there is ever a need to optimize, go here
+        // http://stackoverflow.com/a/9755252/535646
+        // http://math.stackexchange.com/q/51326
+        return polygon.contains(p);
+    }
+
+    /**
+     * Get the area of a triangle.
+     *
+     */
+    private double getArea(Point2D a, Point2D b, Point2D c)
+    {
+        // inspiration: http://stackoverflow.com/a/2145584/535646
+        // test: http://www.mathopenref.com/coordtrianglearea.html
+        return Math.abs((a.getX() - c.getX()) * (b.getY() - a.getY()) - (a.getX() - b.getX()) 
+                * (c.getY() - a.getY())) / 2;
+    }
+
+    /**
+     * calculate color weights with barycentric interpolation.
+     * 
+     * @param p Point within triangle
+     *
+     * @return array of weights (between 0 and 1) for a b c
+     */
+    public double[] getWeights(Point2D p)
+    {
+        // http://classes.soe.ucsc.edu/cmps160/Fall10/resources/barycentricInterpolation.pdf
+        double area = getArea(pointA, pointB, pointC);
+        return new double[]{getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p) 
+                / area, getArea(pointA, pointB, p) / area};
+    }
+
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java?rev=1563199&r1=1563198&r2=1563199&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType4.java Fri Jan 31 18:25:03 2014
@@ -16,11 +16,10 @@
  */
 package org.apache.pdfbox.pdmodel.graphics.shading;
 
-
-
 import java.io.IOException;
 
 import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.pdmodel.common.PDRange;
@@ -29,15 +28,14 @@ import org.apache.pdfbox.pdmodel.common.
 /**
  * This represents resources for a shading type 4 (Free-Form Gouraud-Shaded Triangle Meshes).
  *
- * @version $Revision: 1.0 $
  */
 public class PDShadingType4 extends PDShadingResources
 {
     
     private PDFunction function = null;
     /**
-     * An array of 2 × n numbers specifying the linear mapping of sample values 
-     * into the range appropriate for the function’s output values. 
+     * An array of 2^n numbers specifying the linear mapping of sample values 
+     * into the range appropriate for the function's output values. 
      * Default value: same as the value of Range
      */
     private COSArray decode = null;
@@ -81,7 +79,9 @@ public class PDShadingType4 extends PDSh
     {
         if (function == null)
         {
-            function = PDFunction.create(getCOSDictionary().getDictionaryObject(COSName.FUNCTION));
+            COSBase dictionaryFunctionObject = getCOSDictionary().getDictionaryObject(COSName.FUNCTION);
+            if (dictionaryFunctionObject != null)
+                function = PDFunction.create(dictionaryFunctionObject);
         }
         return function;
     }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java?rev=1563199&r1=1563198&r2=1563199&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType5.java Fri Jan 31 18:25:03 2014
@@ -21,6 +21,7 @@ package org.apache.pdfbox.pdmodel.graphi
 import java.io.IOException;
 
 import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.pdmodel.common.PDRange;
@@ -29,15 +30,14 @@ import org.apache.pdfbox.pdmodel.common.
 /**
  * This represents resources for a shading type 5 (Lattice-Form Gouraud-Shaded Triangle Meshes).
  *
- * @version $Revision: 1.0 $
  */
 public class PDShadingType5 extends PDShadingResources
 {
     
     private PDFunction function = null;
     /**
-     * An array of 2 × n numbers specifying the linear mapping of sample values 
-     * into the range appropriate for the function’s output values. 
+     * An array of 2^n numbers specifying the linear mapping of sample values 
+     * into the range appropriate for the function's output values. 
      * Default value: same as the value of Range
      */
     private COSArray decode = null;
@@ -81,7 +81,9 @@ public class PDShadingType5 extends PDSh
     {
         if (function == null)
         {
-            function = PDFunction.create(getCOSDictionary().getDictionaryObject(COSName.FUNCTION));
+            COSBase dictionaryFunctionObject = getCOSDictionary().getDictionaryObject(COSName.FUNCTION);
+            if (dictionaryFunctionObject != null)
+                function = PDFunction.create(dictionaryFunctionObject);
         }
         return function;
     }

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,264 @@
+/*
+ * 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.image.ColorModel;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+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.COSArray;
+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;
+
+/**
+ * This represents the Paint of a type 4 (Gouraud triangle mesh) shading context.
+ * 
+ * @author Tilman Hausherr
+ */
+class Type4ShadingContext extends GouraudShadingContext
+{
+    private static final Log LOG = LogFactory.getLog(Type4ShadingContext.class);
+
+    private PDShadingType4 shadingType;
+    private int bitsPerFlag;
+    
+
+    /**
+     * Constructor creates an instance to be used for fill operations.
+     * 
+     * @param shadingType4 the shading type to be used
+     * @param colorModelValue the color model to be used
+     * @param xform transformation for user to device space
+     * @param ctm current transformation matrix
+     * @param pageHeight height of the current page
+     * 
+     */
+    public Type4ShadingContext(PDShadingType4 shadingType4, ColorModel colorModelValue,
+            AffineTransform xform, Matrix ctm, int pageHeight) throws IOException
+    {
+        super(shadingType4, colorModelValue, xform, ctm, pageHeight);
+        
+        ArrayList<Vertex> vertexList = new ArrayList<Vertex>();
+        shadingType = shadingType4;
+
+        LOG.debug("Type4ShadingContext");
+
+        bitsPerColorComponent = shadingType.getBitsPerComponent();
+        LOG.debug("bitsPerColorComponent: " + bitsPerColorComponent);
+        bitsPerCoordinate = shadingType.getBitsPerCoordinate();
+        LOG.debug(Math.pow(2, bitsPerCoordinate) - 1);
+        long maxSrcCoord = (int) Math.pow(2, bitsPerCoordinate) - 1;
+        long maxSrcColor = (int) Math.pow(2, bitsPerColorComponent) - 1;
+        LOG.debug("maxSrcCoord: " + maxSrcCoord);
+        LOG.debug("maxSrcColor: " + maxSrcColor);
+
+        COSDictionary cosDictionary = shadingType.getCOSDictionary();
+        COSStream cosStream = (COSStream) cosDictionary;
+
+        //The Decode key specifies how
+        //to decode coordinate and color component data into the ranges of values
+        //appropriate for each. The ranges are specified as [xmin xmax ymin ymax c1,min,
+        //c1,max,..., cn, min, cn,max].
+        //
+        // see p344
+        COSArray decode = (COSArray) cosDictionary.getDictionaryObject(COSName.DECODE);
+        LOG.debug("decode: " + decode);
+        PDRange rangeX = shadingType4.getDecodeForParameter(0);
+        PDRange rangeY = shadingType4.getDecodeForParameter(1);
+        LOG.debug("rangeX: " + rangeX.getMin() + ", " + rangeX.getMax());
+        LOG.debug("rangeY: " + rangeY.getMin() + ", " + rangeY.getMax());
+
+        PDRange[] colRangeTab = new PDRange[numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; ++i)
+        {
+            colRangeTab[i] = shadingType.getDecodeForParameter(2 + i);
+        }
+
+        LOG.debug("bitsPerCoordinate: " + bitsPerCoordinate);
+        bitsPerFlag = shadingType.getBitsPerFlag();
+        if (shadingType.getFunction() != null)
+        {
+            LOG.error("function based type 4 shading not implemented, please file issue with sample file");
+        }
+        LOG.debug("function: " + shadingType.getFunction()); //TODO implement function based shading
+        LOG.debug("bitsPerFlag: " + bitsPerFlag); //TODO handle cases where bitperflag isn't 8
+        LOG.debug("Stream size: " + cosStream.getInt(COSName.LENGTH));
+        
+        // get background values if available
+        COSArray bg = shadingType.getBackground();
+        if (bg != null)
+        {
+            background = bg.toFloatArray();
+        }
+        
+        //TODO missing: BBox, AntiAlias (p. 305 in 1.7 spec)
+        
+        // p318:
+        //  reading in sequence from higher-order to lower-order bit positions
+        ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.getFilteredStream());
+        while (true)
+        {
+            try
+            {
+                byte flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+                LOG.debug("flag: " + flag);
+                switch (flag)
+                {
+                    case 0:
+                        Vertex v1 = readVertex(mciis, flag, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRangeTab);
+                        Vertex v2 = readVertex(mciis, (byte) mciis.readBits(bitsPerFlag), maxSrcCoord, maxSrcColor, 
+                                rangeX, rangeY, colRangeTab);
+                        Vertex v3 = readVertex(mciis, (byte) mciis.readBits(bitsPerFlag), maxSrcCoord, maxSrcColor, 
+                                rangeX, rangeY, colRangeTab);
+
+                        // add them after they're read, so that they are never added if there is a premature EOF
+                        vertexList.add(v1);
+                        vertexList.add(v2);
+                        vertexList.add(v3);
+                        break;
+                    case 1:
+                    case 2:
+                        vertexList.add(readVertex(mciis, flag, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRangeTab));
+                        break;
+                    default:
+                        LOG.warn("bad flag: " + flag);
+                        break;
+                }
+            }
+            catch (EOFException ex)
+            {
+                LOG.debug("EOF");
+                if (vertexList.size() < 3)
+                {
+                    LOG.warn("Incomplete mesh is ignored");
+                    vertexList.clear();
+                }
+                else if (vertexList.size() > 1 && vertexList.get(0).flag != 0)
+                {
+                    LOG.warn("Mesh with incorrect start flag " + vertexList.get(0).flag + " is ignored");
+                    vertexList.clear();
+                }
+                // check that there are 3 entries if there is a 0 flag
+                int vi = 0;
+                while (vi < vertexList.size())
+                {
+                    if (vertexList.get(vi).flag == 0)
+                    {
+                        if (vi + 2 >= vertexList.size())
+                        {
+                            LOG.warn("Mesh with incomplete triangle");
+                            // remove rest
+                            while (vertexList.size() >= vi + 1)
+                            {
+                                vertexList.remove(vi);
+                            }
+                            break;
+                        }
+                        vi += 3;
+                    }
+                    else
+                    {
+                        ++vi;
+                    }
+                }
+                break;
+            }
+        }
+        mciis.close();
+        transformVertices(vertexList, ctm, xform, pageHeight);
+        createTriangleList(vertexList);
+        createArea();
+    }
+
+    /**
+     * Create GouraudTriangle list from vertices, see p.316 of pdf spec 1.7.
+     * 
+     * @param vertexList list of vertices
+     */
+    private void createTriangleList(ArrayList<Vertex> vertexList)
+    {
+        Point2D a = null, b = null, c = null;
+        float[] aColor = null, bColor = null, cColor = null;
+        int vi = 0;
+        while (vi < vertexList.size())
+        {
+            Vertex v = vertexList.get(vi);
+            switch (v.flag)
+            {
+                case 0:
+                    a = v.point;
+                    aColor = v.color;
+                    ++vi;
+
+                    v = vertexList.get(vi);
+                    b = v.point;
+                    bColor = v.color;
+                    ++vi;
+
+                    v = vertexList.get(vi);
+                    c = v.point;
+                    cColor = v.color;
+                    break;
+
+                case 1:
+                    a = b;
+                    aColor = bColor;
+
+                    b = c;
+                    bColor = cColor;
+
+                    v = vertexList.get(vi);
+                    c = v.point;
+                    cColor = v.color;
+                    break;
+
+                case 2:
+                    b = c;
+                    bColor = cColor;
+
+                    v = vertexList.get(vi);
+                    c = v.point;
+                    cColor = v.color;
+                    break;
+
+                default:
+                    break;
+            }
+            ++vi;
+            triangleList.add(new GouraudTriangle(a, aColor, b, bColor, c, cColor));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+        shadingType = null;
+    }
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,82 @@
+/*
+ * 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.Paint;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * This represents the Paint of an type4 shading.
+ *
+ */
+public class Type4ShadingPaint implements Paint
+{
+    private PDShadingType4 shading;
+    private Matrix currentTransformationMatrix;
+    private int pageHeight;
+
+    /**
+     * Constructor.
+     *
+     * @param shadingType4 the shading resources
+     * @param ctm current transformation matrix
+     * @param pageHeightValue the height of the page
+     */
+    public Type4ShadingPaint(PDShadingType4 shadingType4, Matrix ctm, int pageHeightValue)
+    {
+        shading = shadingType4;
+        currentTransformationMatrix = ctm;
+        pageHeight = pageHeightValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getTransparency()
+    {
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform xform, RenderingHints hints)
+    {
+        try
+        {
+            return new Type4ShadingContext(shading, cm, xform, currentTransformationMatrix, pageHeight);
+        }
+        catch (IOException ex)
+        {
+            Logger.getLogger(Type4ShadingPaint.class.getName()).log(Level.SEVERE, null, ex);
+            return null;
+        }
+    }
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type4ShadingPaint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,174 @@
+/*
+ * 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.image.ColorModel;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+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.COSArray;
+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;
+
+/**
+ *
+ * This represents the Paint of a type 5 (Gouraud triangle lattice) shading
+ * context.
+ *
+ * @author Tilman Hausherr
+ */
+public class Type5ShadingContext extends GouraudShadingContext
+{
+    private static final Log LOG = LogFactory.getLog(Type5ShadingContext.class);
+
+    private PDShadingType5 shadingType;
+
+    /**
+     * Constructor creates an instance to be used for fill operations.
+     *
+     * @param shadingType5 the shading type to be used
+     * @param colorModelValue the color model to be used
+     * @param xform transformation for user to device space
+     * @param ctm current transformation matrix
+     * @param pageHeight height of the current page
+     * 
+     * @throws IOException if something went wrong
+     */
+    public Type5ShadingContext(PDShadingType5 shadingType5, ColorModel colorModelValue,
+            AffineTransform xform, Matrix ctm, int pageHeight) throws IOException
+    {
+        super(shadingType5, colorModelValue, xform, ctm, pageHeight);
+
+        shadingType = shadingType5;
+
+        LOG.debug("Type5ShadingContext");
+
+        bitsPerColorComponent = shadingType.getBitsPerComponent();
+        LOG.debug("bitsPerColorComponent: " + bitsPerColorComponent);
+        bitsPerCoordinate = shadingType.getBitsPerCoordinate();
+        LOG.debug(Math.pow(2, bitsPerCoordinate) - 1);
+        long maxSrcCoord = (int) Math.pow(2, bitsPerCoordinate) - 1;
+        long maxSrcColor = (int) Math.pow(2, bitsPerColorComponent) - 1;
+        LOG.debug("maxSrcCoord: " + maxSrcCoord);
+        LOG.debug("maxSrcColor: " + maxSrcColor);
+
+        COSDictionary cosDictionary = shadingType.getCOSDictionary();
+        COSStream cosStream = (COSStream) cosDictionary;
+
+        //The Decode key specifies how
+        //to decode coordinate and color component data into the ranges of values
+        //appropriate for each. The ranges are specified as [xmin xmax ymin ymax c1,min,
+        //c1,max,..., cn, min, cn,max].
+        //
+        // see p344
+        COSArray decode = (COSArray) cosDictionary.getDictionaryObject(COSName.DECODE);
+        LOG.debug("decode: " + decode);
+        PDRange rangeX = shadingType5.getDecodeForParameter(0);
+        PDRange rangeY = shadingType5.getDecodeForParameter(1);
+        LOG.debug("rangeX: " + rangeX.getMin() + ", " + rangeX.getMax());
+        LOG.debug("rangeY: " + rangeY.getMin() + ", " + rangeY.getMax());
+
+        PDRange[] colRangeTab = new PDRange[numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; ++i)
+        {
+            colRangeTab[i] = shadingType.getDecodeForParameter(2 + i);
+        }
+
+        LOG.debug("bitsPerCoordinate: " + bitsPerCoordinate);
+        if (shadingType.getFunction() != null)
+        {
+            LOG.error("function based type 4 shading not implemented, please file issue with sample file");
+        }
+        LOG.debug("function: " + shadingType.getFunction()); //TODO implement function based shading
+
+        // get background values if available
+        COSArray bg = shadingType.getBackground();
+        if (bg != null)
+        {
+            background = bg.toFloatArray();
+        }
+
+        //TODO missing: BBox, AntiAlias (p. 305 in 1.7 spec)
+
+        // p318:
+        //  reading in sequence from higher-order to lower-order bit positions
+        ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.getFilteredStream());
+
+        int verticesPerRow = shadingType.getVerticesPerRow(); //TODO check >=2
+        LOG.debug("verticesPerRow" + verticesPerRow);
+
+        try
+        {
+            ArrayList<Vertex> prevVertexRow = new ArrayList<Vertex>();
+            while (true)
+            {
+                // read a vertex row
+                ArrayList<Vertex> vertexList = new ArrayList<Vertex>();
+                for (int row = 0; row < verticesPerRow; ++row)
+                {
+                    vertexList.add(readVertex(mciis, (byte) 0, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRangeTab));
+                }
+                transformVertices(vertexList, ctm, xform, pageHeight);
+
+                // create the triangles from two rows
+                if (!prevVertexRow.isEmpty())
+                {
+                    for (int vj = 0; vj < vertexList.size() - 1; ++vj)
+                    {
+                        // p.192,194 pdf spec 1.7
+                        Vertex vij = prevVertexRow.get(vj); // v i,j
+                        Vertex vijplus1 = prevVertexRow.get(vj + 1); // v i,j+1
+                        Vertex viplus1j = vertexList.get(vj); // v i+1,j
+                        Vertex viplus1jplus1 = vertexList.get(vj + 1); // v i+1,j+1
+                        triangleList.add(new GouraudTriangle(vij.point, vij.color, vijplus1.point, vijplus1.color, 
+                                viplus1j.point, viplus1j.color));
+                        triangleList.add(new GouraudTriangle(vijplus1.point, vijplus1.color, viplus1j.point, 
+                                viplus1j.color, viplus1jplus1.point, viplus1jplus1.color));
+                    }
+                }
+                prevVertexRow = vertexList;
+            }
+        }
+        catch (EOFException ex)
+        {
+            LOG.debug("EOF");
+        }
+
+        mciis.close();
+
+        createArea();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+        shadingType = null;
+    }
+
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,83 @@
+/*
+ * 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.Paint;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * This represents the Paint of an type5 shading.
+ *
+ *
+ */
+public class Type5ShadingPaint implements Paint
+{
+    private PDShadingType5 shading;
+    private Matrix currentTransformationMatrix;
+    private int pageHeight;
+
+    /**
+     * Constructor.
+     *
+     * @param shadingType5 the shading resources
+     * @param ctm current transformation matrix
+     * @param pageHeightValue
+     */
+    public Type5ShadingPaint(PDShadingType5 shadingType5, Matrix ctm, int pageHeightValue)
+    {
+        shading = shadingType5;
+        currentTransformationMatrix = ctm;
+        pageHeight = pageHeightValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getTransparency()
+    {
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform xform, RenderingHints hints)
+    {
+        try
+        {
+            return new Type5ShadingContext(shading, cm, xform, currentTransformationMatrix, pageHeight);
+        }
+        catch (IOException ex)
+        {
+            Logger.getLogger(Type5ShadingPaint.class.getName()).log(Level.SEVERE, null, ex);
+            return null;
+        }
+    }
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type5ShadingPaint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java?rev=1563199&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java Fri Jan 31 18:25:03 2014
@@ -0,0 +1,56 @@
+/*
+ * 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.Point2D;
+
+/**
+ * 
+ * Helper class to deal with Vertices for type 4 and 5 shading.
+ *
+ * @author Tilman Hausherr
+ */
+class Vertex
+{
+    public byte flag; // used only with type 4 shading
+    public Point2D point;
+    public float[] color;
+
+    public Vertex(byte flag, Point2D point, float[] color)
+    {
+        this.flag = flag;
+        this.point = point;
+        this.color = color.clone();
+    }
+
+    @Override
+    public String toString()
+    {
+        String colorStr = "";
+        for (float f : color)
+        {
+            if (!colorStr.isEmpty())
+            {
+                colorStr += " ";
+            }
+            colorStr += String.format("%3.2f", f);
+        }
+        return "Vertex{" + flag + ": " + point + ", colors=[" + colorStr + "] }";
+    }
+
+}

Propchange: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Vertex.java
------------------------------------------------------------------------------
    svn:eol-style = native