pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From til...@apache.org
Subject svn commit: r1607727 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/
Date Thu, 03 Jul 2014 19:35:55 GMT
Author: tilman
Date: Thu Jul  3 19:35:54 2014
New Revision: 1607727

URL: http://svn.apache.org/r1607727
Log:
PDFBOX-1915: Shading types 6 and 7 (Coons and tensor-product patch meshes), implemented by Shaola Ren as part of GSoC2014

Added:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsPatch.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsTriangle.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoordinateColorPair.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CubicBezierCurve.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Line.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Patch.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TensorPatch.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingPaint.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java   (with props)
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingPaint.java   (with props)
Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsPatch.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsPatch.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsPatch.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsPatch.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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;
+import java.util.ArrayList;
+
+/**
+ * This class is used to describe a patch for type 6 shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class CoonsPatch extends Patch
+{   
+    /**
+     * Constructor of a patch for type 6 shading.
+     * @param points 12 control points
+     * @param color  4 corner colors
+     */
+    protected CoonsPatch(Point2D[] points, float[][] color)
+    {
+        super(points, color);
+        controlPoints = reshapeControlPoints(points);
+        level = calLevel();
+        listOfCoonsTriangle = getCoonsTriangle();
+    }
+    
+    // adjust the 12 control points to 4 groups, each group defines one edge of a patch
+    private Point2D[][] reshapeControlPoints(Point2D[] points)
+    {
+        Point2D[][] fourRows = new Point2D[4][4];
+        fourRows[2] = new Point2D[]
+                                {
+                                    points[0], points[1], points[2], points[3]
+                                }; // d1
+        fourRows[1] = new Point2D[]
+                                {
+                                    points[3], points[4], points[5], points[6]
+                                }; // c2
+        fourRows[3] = new Point2D[]
+                                {
+                                    points[9], points[8], points[7], points[6]
+                                }; // d2
+        fourRows[0] = new Point2D[]
+                                {
+                                    points[0], points[11], points[10], points[9]
+                                }; // c1
+        return fourRows;
+    }
+    
+    // calculate the dividing level from control points
+    private int[] calLevel()
+    {
+        int[] l = {4, 4};
+        // if two opposite edges are both lines, there is a possibility to reduce the dividing level
+        if (isEdgeALine(controlPoints[0]) & isEdgeALine(controlPoints[1]))
+        {
+            double lc1 = getLen(controlPoints[0][0], controlPoints[0][3]), 
+                                lc2 = getLen(controlPoints[1][0], controlPoints[1][3]);
+            // determine the dividing level by the lengths of edges
+            if (lc1 > 800 || lc2 > 800)
+            {
+            }
+            else if (lc1 > 400 || lc2 > 400)
+            {
+                l[0] = 3;
+            }
+            else if (lc1 > 200 || lc2 > 200)
+            {
+                l[0] = 2;
+            }
+            else
+            {
+                l[0] = 1;
+            }
+        }
+        
+        // the other two opposite edges
+        if (isEdgeALine(controlPoints[2]) & isEdgeALine(controlPoints[3]))
+        {
+            double ld1 = getLen(controlPoints[2][0], controlPoints[2][3]), 
+                                ld2 = getLen(controlPoints[3][0], controlPoints[3][3]);
+            if (ld1 > 800 || ld2 > 800)
+            {
+            }
+            else if (ld1 > 400 || ld2 > 400)
+            {
+                l[1] = 3;
+            }
+            else if (ld1 > 200 || ld2 > 200)
+            {
+                l[1] = 2;
+            }
+            else
+            {
+                l[1] = 1;
+            }
+        }
+        return l;
+    }
+
+    // get a list of CoonsTriangles which compose this coons patch
+    private ArrayList<CoonsTriangle> getCoonsTriangle()
+    {
+        // 4 edges are 4 cubic Bezier curves
+        CubicBezierCurve eC1 = new CubicBezierCurve(controlPoints[0], level[0]);
+        CubicBezierCurve eC2 = new CubicBezierCurve(controlPoints[1], level[0]);
+        CubicBezierCurve eD1 = new CubicBezierCurve(controlPoints[2], level[1]);
+        CubicBezierCurve eD2 = new CubicBezierCurve(controlPoints[3], level[1]);
+        CoordinateColorPair[][] patchCC = getPatchCoordinatesColor(eC1, eC2, eD1, eD2);
+        return getCoonsTriangle(patchCC);
+    }
+    
+    @Override
+    protected Point2D[] getFlag1Edge()
+    {
+        return controlPoints[1].clone();
+    }
+    
+    @Override
+    protected Point2D[] getFlag2Edge()
+    {
+        Point2D[] implicitEdge = new Point2D[4];
+        implicitEdge[0] = controlPoints[3][3];
+        implicitEdge[1] = controlPoints[3][2];
+        implicitEdge[2] = controlPoints[3][1];
+        implicitEdge[3] = controlPoints[3][0];
+        return implicitEdge;
+    }
+    
+    @Override
+    protected Point2D[] getFlag3Edge()
+    {
+        Point2D[] implicitEdge = new Point2D[4];
+        implicitEdge[0] = controlPoints[0][3];
+        implicitEdge[1] = controlPoints[0][2];
+        implicitEdge[2] = controlPoints[0][1];
+        implicitEdge[3] = controlPoints[0][0];
+        return implicitEdge;
+    }
+    
+    /*
+    dividing a patch into a grid, return a matrix of the coordinate and color at the crossing points of the grid, 
+    the rule to calculate the coordinate is defined in page 195 of PDF32000_2008.pdf, the rule to calculate the 
+    cooresponding color is bilinear interpolation
+    */
+    private CoordinateColorPair[][] getPatchCoordinatesColor(CubicBezierCurve C1, CubicBezierCurve C2, CubicBezierCurve D1, CubicBezierCurve D2)
+    {
+        Point2D[] curveC1 = C1.getCubicBezierCurve();
+        Point2D[] curveC2 = C2.getCubicBezierCurve();
+        Point2D[] curveD1 = D1.getCubicBezierCurve();
+        Point2D[] curveD2 = D2.getCubicBezierCurve();
+        
+        int numberOfColorComponents = cornerColor[0].length;
+        int szV = curveD1.length;
+        int szU = curveC1.length;
+        
+        CoordinateColorPair[][] patchCC = new CoordinateColorPair[szV][szU];
+        
+        double stepV = (double) 1 / (szV - 1);
+        double stepU = (double) 1 / (szU - 1);
+        double v = - stepV;
+        for(int i = 0; i < szV; i++)
+        {
+            // v and u are the assistant parameters
+            v += stepV;
+            double u = - stepU;
+            for(int j = 0; j < szU; j++)
+            {
+                u += stepU;
+                double scx = (1 - v) * curveC1[j].getX() + v * curveC2[j].getX();
+                double scy = (1 - v) * curveC1[j].getY() + v * curveC2[j].getY();
+                double sdx = (1 - u) * curveD1[i].getX() + u * curveD2[i].getX();
+                double sdy = (1 - u) * curveD1[i].getY() + u * curveD2[i].getY();
+                double sbx = (1 - v) * ((1 - u) * controlPoints[0][0].getX() + u * controlPoints[0][3].getX()) 
+                        + v * ((1 - u) * controlPoints[1][0].getX() + u * controlPoints[1][3].getX());
+                double sby = (1 - v) * ((1 - u) * controlPoints[0][0].getY() + u * controlPoints[0][3].getY()) 
+                        + v * ((1 - u) * controlPoints[1][0].getY() + u * controlPoints[1][3].getY());
+                
+                double sx = scx + sdx - sbx;
+                double sy = scy + sdy - sby;
+                // the above code in this for loop defines the patch surface (coordinates)
+                
+                Point2D tmpC = new Point2D.Double(sx, sy);
+                
+                float[] paramSC = new float[numberOfColorComponents];
+                for(int ci = 0; ci < numberOfColorComponents; ci++)
+                {
+                    paramSC[ci] = (float) ((1 - v) * ((1 - u) * cornerColor[0][ci] + u * cornerColor[3][ci]) 
+                            + v * ((1 - u) * cornerColor[1][ci] + u * cornerColor[2][ci])); // bilinear interpolation
+                }
+                patchCC[i][j] = new CoordinateColorPair(tmpC, paramSC);
+            }
+        }
+        return patchCC;
+    }  
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsTriangle.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsTriangle.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsTriangle.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoonsTriangle.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.Point;
+import java.awt.geom.Point2D;
+import java.util.HashSet;
+
+/**
+ * This is an assistant class for accomplishing type 6 and 7 shading.
+ * It describes a triangle actually, which is used to compose a patch. It contains 
+ * the degenerated cases, a triangle degenerates to a line or to a point.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class CoonsTriangle
+{
+    private final Point2D[] corner; // vertexes coordinates of a triangle
+    private final float[][] color;
+    private final double area; // area of the triangle
+    
+    /*
+    degree = 3 describes a normal triangle, degree = 2 when a triangle degenerates to a line,
+    degree = 1 when a triangle degenerates to a point
+    */
+    private final int degree;
+    
+    // describes a rasterized line when a trianlge degerates to a line, otherwise this parameter is null
+    private final Line line;
+    
+    // corner's edge (the opposite edge of a corner) equation value
+    private final double v0;
+    private final double v1;
+    private final double v2;
+    
+    /**
+     * Constructor of CoonsTriangle.
+     * @param p an array of the 3 vertexes of a triangle
+     * @param c an array of color corresponding the vertex array p
+     */
+    public CoonsTriangle(Point2D[] p, float[][] c)
+    {
+        corner = p.clone();
+        color = c.clone();
+        area = getArea(p[0], p[1], p[2]);
+        degree = getDeg(p);
+        
+        if (degree == 2)
+        {
+            if (overlaps(corner[1], corner[2]) && !overlaps(corner[0], corner[2]))
+            {
+                Point p0 = new Point((int)Math.round(corner[0].getX()), (int)Math.round(corner[0].getY()));
+                Point p1 = new Point((int)Math.round(corner[2].getX()), (int)Math.round(corner[2].getY()));
+                line = new Line(p0, p1, color[0], color[2]);
+            }
+            else
+            {
+                Point p0 = new Point((int)Math.round(corner[1].getX()), (int)Math.round(corner[1].getY()));
+                Point p1 = new Point((int)Math.round(corner[2].getX()), (int)Math.round(corner[2].getY()));
+                line = new Line(p0, p1, color[1], color[2]);
+            }
+        }
+        else
+        {
+            line = null;
+        }
+        
+        v0 = edgeEquationValue(p[0], p[1], p[2]);
+        v1 = edgeEquationValue(p[1], p[2], p[0]);
+        v2 = edgeEquationValue(p[2], p[0], p[1]);
+    }
+    
+    /**
+     * Get the degree value of a triangle.
+     * @param p 3 vertexes coordinates
+     * @return number of unique points in the 3 vertexes of a triangle, 3, 2 or 1
+     */
+    private int getDeg(Point2D[] p)
+    {
+        HashSet<Point> set = new HashSet<Point>();
+        for (Point2D itp : p)
+        {
+            Point np = new Point((int)Math.round(itp.getX() * 1000), (int)Math.round(itp.getY() * 1000));
+            set.add(np);
+        }
+        return set.size();
+    }
+    
+    /**
+     * Whether a point is contained in this CoonsTriangle.
+     * @param p the target point
+     * @return false if p is outside of this triangle, otherwise true
+     */
+    public boolean contains(Point2D p)
+    {
+        if (degree == 1)
+        {
+            return overlaps(corner[0], p) | overlaps(corner[1], p) | overlaps(corner[2], p);
+        }
+        else if (degree == 2)
+        {
+            Point tp = new Point((int)Math.round(p.getX()), (int)Math.round(p.getY()));
+            return line.linePoints.contains(tp);
+        }
+        
+        /*
+        the following code judges whether a point is contained in a normal trianlge, 
+        taking the on edge case as contained
+        */
+        double pv0 = edgeEquationValue(p, corner[1], corner[2]);
+        /*
+        if corner[0] and point p are on different sides of line from corner[1] to corner[2], 
+        p is outside of the triangle
+        */
+        if (pv0 * v0 < 0)
+        {
+            return false;
+        }
+        double pv1 = edgeEquationValue(p, corner[2], corner[0]);
+        /*
+        if vertex corner[1] and point p are on different sides of line from corner[2] to corner[0], 
+        p is outside of the triangle
+        */
+        if (pv1 * v1 < 0)
+        {
+            return false;
+        }
+        double pv2 = edgeEquationValue(p, corner[0], corner[1]);
+        /*
+        only left one case:
+        if corner[1] and point p are on different sides of line from corner[2] to corner[0], 
+        p is outside of the triangle, otherwise p is contained in the triangle
+        */
+        return pv2 * v2 >= 0; // !(pv2 * v2 < 0)
+    }
+    
+    /*
+    whether two points overlaps each other, as points' coordinates are double type, 
+    the coordinates' accuracy used here is 0.001
+    */
+    private boolean overlaps(Point2D p0, Point2D p1)
+    {
+        return Math.abs(p0.getX() - p1.getX()) < 0.001 && Math.abs(p0.getY() - p1.getY()) < 0.001;
+    }
+    
+    /*
+    two points can define a line equation, adjust the form of the equation to let the rhs equals 0, 
+    calculate the lhs value by plugging the coordinate of p in the lhs expression
+    */
+    private double edgeEquationValue(Point2D p, Point2D p1, Point2D p2)
+    {
+        return (p2.getY() - p1.getY()) * (p.getX() - p1.getX()) - (p2.getX() - p1.getX()) * (p.getY() - p1.getY());
+    }
+    
+    // calcuate the area of a triangle
+    private double getArea(Point2D a, Point2D b, Point2D c)
+    {
+        return Math.abs((c.getX() - b.getX()) * (c.getY() - a.getY()) - (c.getX() - a.getX()) * (c.getY() - b.getY())) / 2.0;
+    }
+    
+    /**
+     * Calculate color of a point.
+     * @param p the target point
+     * @return an array denotes the point's color
+     */
+    public float[] getColor(Point2D p)
+    {
+        int numberOfColorComponents = color[0].length;
+        float[] pCol = new float[numberOfColorComponents];
+        
+        if (degree == 1)
+        {
+            for (int i = 0; i < numberOfColorComponents; i++)
+            {
+                pCol[i] = (color[0][i] + color[1][i] + color[2][i]) / 3.0f; // average
+            }
+        }
+        else if (degree == 2)
+        {
+            Point tp = new Point((int)Math.round(p.getX()), (int)Math.round(p.getY())); // linear interpolation
+            return line.getColor(tp);
+        }
+        else
+        {
+            float aw = (float) (getArea(p, corner[1], corner[2]) / area);
+            float bw = (float) (getArea(p, corner[2], corner[0]) / area);
+            float cw = (float) (getArea(p, corner[0], corner[1]) / area);
+            for (int i = 0; i < numberOfColorComponents; i++)
+            {
+                pCol[i] = color[0][i] * aw + color[1][i] * bw + color[2][i] * cw; // barycentric interpolation
+            }
+        }
+        return pCol;
+    }
+    
+    @Override
+    public String toString()
+    {
+       return corner[0] + " " + corner[1] + " " + corner[2];
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoordinateColorPair.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoordinateColorPair.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoordinateColorPair.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CoordinateColorPair.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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;
+
+/**
+ * This class is used to store a point's coordinate and its corresponding color.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class CoordinateColorPair
+{
+    final Point2D coordinate;
+    final float[] color;
+
+    /**
+     * Constructor.
+     * @param p point
+     * @param c color
+     */
+    CoordinateColorPair(Point2D p, float[] c)
+    {
+        coordinate = p;
+        color = c.clone();
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CubicBezierCurve.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CubicBezierCurve.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CubicBezierCurve.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/CubicBezierCurve.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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;
+
+/**
+ * This class is used to describe the edge of each patch for type 6 shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+
+class CubicBezierCurve
+{
+    protected final Point2D[] controlPoints;
+    
+    private final int level;
+    private final Point2D[] curve;
+    
+    /**
+     * Constructor of CubicBezierCurve
+     * @param ctrlPnts, 4 control points [p0, p1, p2, p3]
+     * @param l, dividing level, if l = 0, one cubic Bezier curve is divided into 2^0 = 1 segments,
+     * if l = n, one cubic Bezier curve is divided into 2^n segments
+     */
+    public CubicBezierCurve(Point2D[] ctrlPnts, int l)
+    {
+        controlPoints = ctrlPnts.clone();
+        level = l;
+        curve = getPoints(level);
+    }
+    
+    /**
+     * Get level parameter
+     * @return level 
+     */
+    public int getLevel()
+    {
+        return level;
+    }
+    
+    // calculate sampled points on the cubic Bezier curve defined by the 4 given control points
+    private Point2D[] getPoints(int l)
+    {
+        if (l < 0)
+        {
+            l = 0;
+        }
+        int sz = (1 << l) + 1;
+        Point2D[] res = new Point2D[sz];
+        double step = (double) 1 / (sz - 1);
+        double t = - step;
+        for(int i = 0; i < sz; i++)
+        {
+            t += step;
+            double tmpX = (1 - t) * (1 - t)*( 1 - t) * controlPoints[0].getX() + 
+                    3 * t * (1 - t) * (1 - t) * controlPoints[1].getX() +
+                    3 * t * t * (1 - t) * controlPoints[2].getX() + 
+                    t * t * t * controlPoints[3].getX();
+            double tmpY = (1 - t) * (1 - t)*( 1 - t) * controlPoints[0].getY() + 
+                    3 * t * (1 - t) * (1 - t) * controlPoints[1].getY() +
+                    3 * t * t * (1 - t) * controlPoints[2].getY() + 
+                    t * t * t * controlPoints[3].getY();
+            res[i] = new Point2D.Double(tmpX, tmpY);
+        }
+        return res;
+    }
+    
+    /**
+     * Get sampled points of this cubic Bezier curve.
+     * @return sampled points
+     */
+    public Point2D[] getCubicBezierCurve()
+    {
+        return curve;
+    }
+    
+    @Override
+    public String toString()
+    {
+        String pointStr = "";
+        for (Point2D p : controlPoints)
+        {
+            if (!pointStr.isEmpty())
+            {
+                pointStr += " ";
+            }
+            pointStr += p;
+        }
+        return "Cubic Bezier curve{control points p0, p1, p2, p3: " + pointStr + "}";
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Line.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Line.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Line.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Line.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.Point;
+import java.util.HashSet;
+
+/**
+ * This class describes a rasterized line.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class Line
+{
+    private final Point point0;
+    private final Point point1;
+    private final float[] color0;
+    private final float[] color1;
+    
+    protected final HashSet<Point> linePoints; // all the points in this rasterized line
+    
+    /**
+     * Constructor of class Line.
+     * @param p0 one end of a line
+     * @param p1 the other end of the line
+     * @param c0 color of point p0
+     * @param c1 color of point p1
+     */
+    public Line(Point p0, Point p1, float[] c0, float[] c1)
+    {
+        point0 = p0;
+        point1 = p1;
+        color0 = c0.clone();
+        color1 = c1.clone();
+        linePoints = getLine();
+    }
+    
+    private HashSet<Point> getLine()
+    {
+        return getLine(point0.x, point0.y, point1.x, point1.y);
+    }
+    
+    /**
+     * Bresenham's line algorithm, http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
+     * @param x0 coordinate
+     * @param y0 coordinate
+     * @param x1 coordinate
+     * @param y1 coordinate
+     * @return all the points on the rasterized line from (x0, y0) to (x1, y1)
+     */
+    private HashSet<Point> getLine(int x0, int y0, int x1, int y1) 
+    {
+        HashSet<Point> points = new HashSet<Point>();
+        int dx = Math.abs(x1 - x0);
+        int dy = Math.abs(y1 - y0);
+        int sx = x0 < x1 ? 1 : -1;
+        int sy = y0 < y1 ? 1 : -1;
+        int err = dx - dy;	
+        while (true)
+        {
+            points.add(new Point(x0, y0));
+            if (x0 == x1 && y0 == y1)
+            {
+                break;
+            }
+            int e2 = 2 * err;
+            if (e2 > -dy)
+            {
+                err = err - dy;
+                x0 = x0 + sx;
+            }
+            if (e2 < dx)
+            {
+                err = err + dx;
+                y0 = y0 + sy;
+            }
+        }
+        return points;
+    }
+    
+    /**
+     * Calculate the color of a point on a rasterized line by linear interpolation.
+     * @param p target point, p should always be contained in linePoints
+     * @return color
+     */
+    protected float[] getColor(Point p)
+    {
+        int numberOfColorComponents = color0.length;
+        float[] pc = new float[numberOfColorComponents];
+        if (point0.x == point1.x && point0.y == point1.y)
+        {
+            return color0;
+        }
+        else if (point0.x == point1.x)
+        {
+            float l = point1.y - point0.y;
+            for (int i = 0; i < numberOfColorComponents; i++)
+            {
+                pc[i] = (float) (color0[i] * (point1.y - p.y) / l + color1[i] * (p.y - point0.y) / l);
+            }
+        }
+        else
+        {
+            float l = point1.x - point0.x;
+            for (int i = 0; i < numberOfColorComponents; i++)
+            {
+                pc[i] = (float) (color0[i] * (point1.x - p.x) / l + color1[i] * (p.x - point0.x) / l);
+            }
+        }
+        return pc;
+    }
+}

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

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java?rev=1607727&r1=1607726&r2=1607727&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType6.java Thu Jul  3 19:35:54 2014
@@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFac
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.util.Matrix;
 
-import java.awt.Color;
 import java.awt.Paint;
 
 /**
@@ -49,8 +48,6 @@ public class PDShadingType6 extends PDSh
     @Override
     public Paint toPaint(Matrix matrix, int pageHeight)
     {
-        // TODO ...
-        LOG.debug("Type 6 Shading not implemented");
-        return new Color(0, 0, 0, 0); // transparent
+        return new Type6ShadingPaint(this, matrix, pageHeight);
     }
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java?rev=1607727&r1=1607726&r2=1607727&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PDShadingType7.java Thu Jul  3 19:35:54 2014
@@ -21,7 +21,6 @@ import org.apache.commons.logging.LogFac
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.util.Matrix;
 
-import java.awt.Color;
 import java.awt.Paint;
 
 /**
@@ -49,8 +48,6 @@ public class PDShadingType7 extends PDSh
     @Override
     public Paint toPaint(Matrix matrix, int pageHeight)
     {
-        // TODO ...
-        LOG.debug("Type 7 Shading not implemented");
-        return new Color(0, 0, 0, 0); // transparent
+        return new Type7ShadingPaint(this, matrix, pageHeight);
     }
 }

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Patch.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Patch.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Patch.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Patch.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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;
+import java.util.ArrayList;
+
+/**
+ * Patch is extended by CoonsPatch and TensorPatch.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+abstract class Patch
+{
+    protected Point2D[][] controlPoints;
+    protected float[][] cornerColor;
+    
+    /*
+     level = {levelU, levelV}, levelU defines the patch's u direction edges should be 
+     divided into 2^levelU parts, level V defines the patch's v direction edges should
+     be divided into 2^levelV parts
+     */
+    protected int[] level;
+    protected ArrayList<CoonsTriangle> listOfCoonsTriangle;
+    
+    /**
+     * Constructor of Patch.
+     * @param ctl control points, size is 12 (for type 6 shading) or 16 (for type 7 shading)
+     * @param color 4 corner's colors
+     */
+    public Patch(Point2D[] ctl, float[][] color)
+    {
+        cornerColor = color.clone();
+    }
+    
+    /**
+     * Get the implicit edge for flag = 1.
+     * @return implicit control points
+     */
+    protected abstract Point2D[] getFlag1Edge();
+    
+    /**
+     * Get the implicit edge for flag = 2.
+     * @return implicit control points
+     */
+    protected abstract Point2D[] getFlag2Edge();
+    
+    /**
+     * Get the implicit edge for flag = 3.
+     * @return implicit control points
+     */
+    protected abstract Point2D[] getFlag3Edge();
+    
+    /**
+     * Get the implicit color for flag = 1.
+     * @return color
+     */
+    protected float[][] getFlag1Color()
+    {
+        int numberOfColorComponents = cornerColor[0].length;
+        float[][] implicitCornerColor = new float[2][numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; i++)
+        {
+            implicitCornerColor[0][i] = cornerColor[1][i];
+            implicitCornerColor[1][i] = cornerColor[2][i];
+        }
+        return implicitCornerColor;
+    }
+    
+    /**
+     * Get implicit color for flag = 2.
+     * @return color
+     */
+    protected float[][] getFlag2Color()
+    {
+        int numberOfColorComponents = cornerColor[0].length;
+        float[][] implicitCornerColor = new float[2][numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; i++)
+        {
+            implicitCornerColor[0][i] = cornerColor[2][i];
+            implicitCornerColor[1][i] = cornerColor[3][i];
+        }
+        return implicitCornerColor;
+    }
+    
+    /**
+     * Get implicit color for flag = 3.
+     * @return color
+     */
+    protected float[][] getFlag3Color()
+    {
+        int numberOfColorComponents = cornerColor[0].length;
+        float[][] implicitCornerColor = new float[2][numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; i++)
+        {
+            implicitCornerColor[0][i] = cornerColor[3][i];
+            implicitCornerColor[1][i] = cornerColor[0][i];
+        }
+        return implicitCornerColor;
+    }
+    
+    /**
+     * Calculate the distance from point ps to point pe.
+     * @param ps one end of a line
+     * @param pe the other end of the line
+     * @return length of the line
+     */
+    protected double getLen(Point2D ps, Point2D pe)
+    {
+        double x = pe.getX() - ps.getX();
+        double y = pe.getY() - ps.getY();
+        return Math.sqrt(x * x + y * y);
+    }
+    
+    /**
+     * Whether the for control points are on a line.
+     * @param ctl an edge's control points, the size of ctl is 4
+     * @return true when 4 control points are on a line, otherwise false
+     */
+    protected boolean isEdgeALine(Point2D[] ctl)
+    {
+        double ctl1 = Math.abs(edgeEquationValue(ctl[1], ctl[0], ctl[3]));
+        double ctl2 = Math.abs(edgeEquationValue(ctl[2], ctl[0], ctl[3]));
+        double x = Math.abs(ctl[0].getX() - ctl[3].getX());
+        double y = Math.abs(ctl[0].getY() - ctl[3].getY());
+        return (ctl1 <= x && ctl2 <= x) || (ctl1 <= y && ctl2 <= y);
+    }
+    
+    /**
+     * A line from point p1 to point p2 defines an equation, adjust the form of the equation 
+     * to let the rhs equals 0, then calculate the lhs value by plugging the coordinate of p 
+     * in the lhs expression.
+     * @param p target point
+     * @param p1 one end of a line
+     * @param p2 the other end of a line
+     * @return calculated value
+     */
+    protected double edgeEquationValue(Point2D p, Point2D p1, Point2D p2)
+    {
+        return (p2.getY() - p1.getY()) * (p.getX() - p1.getX()) - (p2.getX() - p1.getX()) * (p.getY() - p1.getY());
+    }
+    
+    /**
+     * An assistant method to accomplish type 6 and type 7 shading.
+     * @param patchCC all the crossing point coordinates and color of a grid
+     * @return a CoonsTriangle list which can compose the grid patch
+     */
+    protected ArrayList<CoonsTriangle> getCoonsTriangle(CoordinateColorPair[][] patchCC)
+    {
+        ArrayList<CoonsTriangle> list = new ArrayList<CoonsTriangle>();
+        int szV = patchCC.length;
+        int szU = patchCC[0].length;
+        for (int i = 1; i < szV; i++)
+        {
+            for (int j = 1; j < szU; j++)
+            {
+                Point2D p0 = patchCC[i-1][j-1].coordinate, p1 = patchCC[i-1][j].coordinate, p2 = patchCC[i][j].coordinate, 
+                                p3 = patchCC[i][j-1].coordinate;
+                boolean ll = true;
+                if (overlaps(p0, p1) || overlaps(p0, p3))
+                {
+                    ll = false;
+                }
+                else{
+                    // p0, p1 and p3 are in counter clock wise order, p1 has priority over p0, p3 has priority over p1
+                    Point2D[] llCorner = {p0, p1, p3};
+                    float[][] llColor = {patchCC[i-1][j-1].color, patchCC[i-1][j].color, patchCC[i][j-1].color};
+                    CoonsTriangle tmpll = new CoonsTriangle(llCorner, llColor); // lower left triangle
+                    list.add(tmpll);
+                }
+                if (ll && (overlaps(p2, p1) || overlaps(p2, p3)))
+                {
+                }
+                else
+                {
+                    // p3, p1 and p2 are in counter clock wise order, p1 has priority over p3, p2 has priority over p1
+                    Point2D[] urCorner = {p3, p1, p2};
+                    float[][] urColor = {patchCC[i][j-1].color, patchCC[i-1][j].color, patchCC[i][j].color};
+                    CoonsTriangle tmpur = new CoonsTriangle(urCorner, urColor); // upper right triangle
+                    list.add(tmpur);
+                }
+            }
+        }
+        return list;
+    }
+    
+    // whether two points p0 and p1 are degenerated into one point within the coordinates' accuracy 0.001
+    private boolean overlaps(Point2D p0, Point2D p1)
+    {
+        return Math.abs(p0.getX() - p1.getX()) < 0.001 && Math.abs(p0.getY() - p1.getY()) < 0.001;
+    }  
+}

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

Added: 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=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/PatchMeshesShadingContext.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.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.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.COSStream;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * This class is extended in Type6ShadingContext and Type7ShadingContext.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+abstract class PatchMeshesShadingContext implements PaintContext
+{
+    private static final Log LOG = LogFactory.getLog(PatchMeshesShadingContext.class);
+    
+    protected ColorModel outputColorModel;
+    protected PDColorSpace shadingColorSpace;
+    protected final int numberOfColorComponents; // number of color components
+    protected float[] background; // background values.
+    protected final boolean hasFunction;
+    protected final PDShading patchMeshesShadingType;
+    
+    // the following fields are not intialized in this abstract class
+    protected ArrayList<Patch> patchList; // patch list
+    protected int bitsPerCoordinate; // bits per coordinate
+    protected int bitsPerColorComponent; // bits per color component
+    protected int bitsPerFlag; // bits per flag
+    
+    /**
+     * Constructor creates an instance to be used for fill operations.
+     * @param shading the shading type to be used
+     * @param colorModel 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 PatchMeshesShadingContext(PDShading shading, ColorModel colorModel, AffineTransform xform,
+                                Matrix ctm, int pageHeight) throws IOException
+    {
+        patchMeshesShadingType = shading;
+        patchList = new ArrayList<Patch>();
+        hasFunction = shading.getFunction() != null;
+        shadingColorSpace = shading.getColorSpace();
+        
+        numberOfColorComponents = hasFunction ? 1 : shadingColorSpace.getNumberOfComponents();
+        
+        // create the output color model using RGB+alpha as color space
+        ColorSpace outputCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        outputColorModel = new ComponentColorModel(outputCS, true, false, Transparency.TRANSLUCENT,
+                DataBuffer.TYPE_BYTE);
+        
+        COSArray bg = shading.getBackground();
+        if (bg != null)
+        {
+            background = bg.toFloatArray();
+        }   
+    }
+    
+    // transform a point from source space to device space
+    private void transformPoint(Point2D p, Matrix ctm, AffineTransform xform)
+    {
+        if (ctm != null)
+        {
+            ctm.createAffineTransform().transform(p, p);
+        }
+        xform.transform(p, p);
+    }
+    
+    /**
+     * Create a patch list from a data stream, the returned list contains all the patches 
+     * contained in the data stream.
+     * @param xform transformation for user to device space
+     * @param ctm current transformation matrix
+     * @param cosDictionary dictionary object to give the image information
+     * @param rangeX range for coordinate x
+     * @param rangeY range for coordinate y
+     * @param colRange range for color
+     * @param numP 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
+     */
+    protected ArrayList<Patch> getPatchList(AffineTransform xform,Matrix ctm, COSDictionary cosDictionary, 
+                                PDRange rangeX, PDRange rangeY, PDRange[] colRange, int numP) throws IOException
+    {
+        ArrayList<Patch> list = new ArrayList<Patch>();
+        long maxSrcCoord = (long) Math.pow(2, bitsPerCoordinate) - 1;
+        long maxSrcColor = (long) Math.pow(2, bitsPerColorComponent) - 1;
+        COSStream cosStream = (COSStream) cosDictionary;
+        
+        ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.getUnfilteredStream());
+        
+        Point2D[] implicitEdge = new Point2D[4];
+        float[][] implicitCornerColor = new float[2][numberOfColorComponents];
+        
+        byte flag = (byte) 0;
+        
+        try
+        {
+            flag = (byte) (mciis.readBits(bitsPerFlag) & 3);
+        }
+        catch (EOFException ex)
+        {
+            LOG.error(ex);
+        }
+        
+        while (true)
+        {
+            try
+            {
+                boolean isFree = (flag == 0);
+                Patch current = readPatch(mciis, isFree, implicitEdge, implicitCornerColor,
+                                maxSrcCoord, maxSrcColor, rangeX, rangeY, colRange, ctm, xform, numP);
+                if (current == null)
+                {
+                    break;
+                }
+                list.add((Patch) 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)
+            {
+                break;
+            }
+        }
+        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 ctm current transformation matrix
+     * @param xform transformation for user to device space
+     * @param numP 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 ctm, AffineTransform xform, int numP) throws IOException
+    {
+        float[][] color = new float[4][numberOfColorComponents];
+        Point2D[] points = new Point2D[numP];
+        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 < numP; i++)
+            {
+                long x = input.readBits(bitsPerCoordinate);
+                long y = input.readBits(bitsPerCoordinate);
+                double px = interpolate(x, maxSrcCoord, rangeX.getMin(), rangeX.getMax());
+                double py = interpolate(y, maxSrcCoord, rangeY.getMin(), rangeY.getMax());
+                Point2D tmp = new Point2D.Double(px, py);
+                transformPoint(tmp, ctm, xform);
+                points[i] = tmp;
+            }
+            for (int i = cStart; i < 4; i++)
+            {
+                for (int j = 0; j < numberOfColorComponents; j++)
+                {
+                    long c = input.readBits(bitsPerColorComponent);
+                    color[i][j] = (float) 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 double interpolate(double x, long maxValue, float rangeMin, float rangeMax)
+    {
+        return rangeMin + (x / maxValue) * (rangeMax - rangeMin); 
+    }
+    
+    @Override
+    public void dispose()
+    {
+        patchList = null;
+        outputColorModel = null;
+        shadingColorSpace = null;
+    }
+    
+    @Override
+    public final ColorModel getColorModel()
+    {
+        return outputColorModel;
+    }
+    
+    @Override
+    public final Raster getRaster(int x, int y, int w, int h)
+    {
+        WritableRaster raster = getColorModel().createCompatibleWritableRaster(w, h);
+        int[] data = new int[w * h * 4];
+        
+        if (!patchList.isEmpty() || background != null)
+        {
+            for (int row = 0; row < h; row++)
+            {
+                for (int col = 0; col < w; col++)
+                {
+                    Point2D p = new Point(x + col, y + row);
+                    float[] values = null;
+                    for (Patch it : patchList)
+                    {
+                        for (CoonsTriangle tri : it.listOfCoonsTriangle)
+                        {
+                            if (tri.contains(p))
+                            {
+                                values = tri.getColor(p);
+                            }
+                        }
+                    }
+                    
+                    if (values == null)
+                    {
+                        if (background != null)
+                        {
+                            values = background;
+                        }
+                        else
+                        {
+                            continue;
+                        }
+                    }
+                    
+                    if (hasFunction)
+                    {
+                        try
+                        {
+                            values = patchMeshesShadingType.evalFunction(values);
+                        }
+                        catch (IOException exception)
+                        {
+                            LOG.error("error while processing a function", exception);
+                        }
+                    }
+                    
+                    try
+                    {
+                        values = shadingColorSpace.toRGB(values);
+                    }
+                    catch (IOException exception)
+                    {
+                        LOG.error("error processing color space", exception);
+                    }
+
+                    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/PatchMeshesShadingContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TensorPatch.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TensorPatch.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TensorPatch.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/TensorPatch.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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;
+import java.util.ArrayList;
+
+/**
+ * This class is used to describe a patch for type 7 shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class TensorPatch extends Patch
+{  
+    /**
+     * Constructor of a patch for type 7 shading.
+     * @param points 16 control points
+     * @param color  4 corner colors
+     */
+    protected TensorPatch(Point2D[] tcp, float[][] color)
+    {
+        super(tcp, color);
+        controlPoints = reshapeControlPoints(tcp);
+        level = calLevel();
+        listOfCoonsTriangle = getCoonsTriangle();
+    }
+    
+    /*
+    order the 16 1d points to a square matrix which is as the one described 
+    in p.199 of PDF3200_2008.pdf rotated 90 degrees clockwise
+    */
+    private Point2D[][] reshapeControlPoints(Point2D[] tcp)
+    {
+        Point2D[][] square = new Point2D[4][4];
+        for (int i = 0; i <= 3; i++)
+        {
+            square[0][i] = tcp[i];
+            square[3][i] = tcp[9 - i];
+        }
+        for (int i = 1; i <= 2; i++)
+        {
+            square[i][0] = tcp[12 - i];
+            square[i][2] = tcp[12 + i];
+            square[i][3] = tcp[3 + i];
+        }
+        square[1][1] = tcp[12];
+        square[2][1] = tcp[15];
+        return square;
+    }
+    
+    // calculate the dividing level from the control points
+    private int[] calLevel()
+    {
+        int[] l = {4, 4};
+        
+        Point2D[] ctlC1 = new Point2D[4];
+        Point2D[] ctlC2 = new Point2D[4];
+        for (int j = 0; j < 4; j++)
+        {
+            ctlC1[j] = controlPoints[j][0];
+            ctlC2[j] = controlPoints[j][3];
+        }
+        // if two opposite edges are both lines, there is a possibility to reduce the dividing level
+        if (isEdgeALine(ctlC1) & isEdgeALine(ctlC2))
+        {
+            /*
+            if any of the 4 inner control points is out of the patch formed by the 4 edges, keep the high dividing level, 
+            otherwise, determine the dividing level by the lengths of edges
+            */
+            if (isOnSameSideCC(controlPoints[1][1]) | isOnSameSideCC(controlPoints[1][2]) |
+                                isOnSameSideCC(controlPoints[2][1]) | isOnSameSideCC(controlPoints[2][2]))
+            {
+            }
+            else
+            {
+                // length's unit is one pixel in device space
+                double lc1 = getLen(ctlC1[0], ctlC1[3]), lc2 = getLen(ctlC2[0], ctlC2[3]);
+                if (lc1 > 800 || lc2 > 800)
+                {
+                }
+                else if (lc1 > 400 || lc2 > 400)
+                {
+                    l[0] = 3;
+                }
+                else if (lc1 > 200 || lc2 > 200)
+                {
+                    l[0] = 2;
+                }
+                else
+                {
+                    l[0] = 1;
+                }
+            }
+        }
+        
+        // the other two opposite edges
+        if (isEdgeALine(controlPoints[0]) & isEdgeALine(controlPoints[3]))
+        {
+            if (isOnSameSideDD(controlPoints[1][1]) | isOnSameSideDD(controlPoints[1][2]) |
+                                isOnSameSideDD(controlPoints[2][1]) | isOnSameSideDD(controlPoints[2][2]))
+            {
+            }
+            else
+            {
+                double ld1 = getLen(controlPoints[0][0], controlPoints[0][3]);
+                double ld2 = getLen(controlPoints[3][0], controlPoints[3][3]);
+                if (ld1 > 800 || ld2 > 800)
+                {
+                }
+                else if (ld1 > 400 || ld2 > 400)
+                {
+                    l[1] = 3;
+                }
+                else if (ld1 > 200 || ld2 > 200)
+                {
+                    l[1] = 2;
+                }
+                else
+                {
+                    l[1] = 1;
+                }
+            }
+        }
+        return l;
+    }
+    
+    // whether a point is on the same side of edge C1 and edge C2
+    private boolean isOnSameSideCC(Point2D p)
+    {
+        double cc = edgeEquationValue(p, controlPoints[0][0], controlPoints[3][0]) * 
+                                edgeEquationValue(p, controlPoints[0][3], controlPoints[3][3]);
+        return cc > 0;
+    }
+    
+    // whether a point is on the same side of edge D1 and edge D2
+    private boolean isOnSameSideDD(Point2D p)
+    {
+        double dd = edgeEquationValue(p, controlPoints[0][0], controlPoints[0][3]) * 
+                                edgeEquationValue(p, controlPoints[3][0], controlPoints[3][3]);
+        return dd > 0;
+    }
+    
+    // get a list of CoonsTriangles which compose this tensor patch
+    private ArrayList<CoonsTriangle> getCoonsTriangle()
+    {
+        CoordinateColorPair[][] patchCC = getPatchCoordinatesColor();
+        return getCoonsTriangle(patchCC);
+    }
+    
+    @Override
+    protected Point2D[] getFlag1Edge()
+    {
+        Point2D[] implicitEdge = new Point2D[4];
+        for (int i = 0; i < 4; i++)
+        {
+            implicitEdge[i] = controlPoints[i][3];
+        }
+        return implicitEdge;
+    }
+    
+    @Override
+    protected Point2D[] getFlag2Edge()
+    {
+        Point2D[] implicitEdge = new Point2D[4];
+        for (int i = 0; i < 4; i++)
+        {
+            implicitEdge[i] = controlPoints[3][3 - i];
+        }
+        return implicitEdge;
+    }
+    
+    @Override
+    protected Point2D[] getFlag3Edge()
+    {
+        Point2D[] implicitEdge = new Point2D[4];
+        for (int i = 0; i < 4; i++)
+        {
+            implicitEdge[i] = controlPoints[3 - i][0];
+        }
+        return implicitEdge;
+    }
+    
+    /*
+    dividing a patch into a grid according to level, then calculate the coordinate and color of 
+    each crossing point in the grid, the rule to calculate the coordinate is tensor-product which 
+    is defined in page 119 of PDF32000_2008.pdf, the method to calculate the cooresponding color is 
+    bilinear interpolation
+    */
+    private CoordinateColorPair[][] getPatchCoordinatesColor()
+    {
+        int numberOfColorComponents = cornerColor[0].length;
+        double[][] bernsteinPolyU = getBernsteinPolynomials(level[0]);
+        int szU = bernsteinPolyU[0].length;
+        double[][] bernsteinPolyV = getBernsteinPolynomials(level[1]);
+        int szV = bernsteinPolyV[0].length;
+        CoordinateColorPair[][] patchCC = new CoordinateColorPair[szV][szU];
+        
+        double stepU = 1.0 / (szU - 1);
+        double stepV = 1.0 / (szV - 1);
+        double v = -stepV;
+        for (int k = 0; k < szV; k++)
+        {
+            // v and u are the assistant parameters
+            v += stepV;
+            double u = - stepU;
+            for (int l = 0; l < szU; l++)
+            {
+                double tmpx = 0.0;
+                double tmpy = 0.0;
+                // these two "for" loops are for the equation to define the patch surface (coordinates)
+                for (int i = 0; i < 4; i++)
+                {
+                    for (int j = 0; j < 4; j++)
+                    {
+                        tmpx += controlPoints[i][j].getX() * bernsteinPolyU[i][l] * bernsteinPolyV[j][k];
+                        tmpy += controlPoints[i][j].getY() * bernsteinPolyU[i][l] * bernsteinPolyV[j][k];
+                    }
+                }
+                Point2D tmpC = new Point2D.Double(tmpx, tmpy);
+                
+                u += stepU;
+                float[] paramSC = new float[numberOfColorComponents];
+                for(int ci = 0; ci < numberOfColorComponents; ci++)
+                {
+                    paramSC[ci] = (float) ((1 - v) * ((1 - u) * cornerColor[0][ci] + u * cornerColor[3][ci]) 
+                            + v * ((1 - u) * cornerColor[1][ci] + u * cornerColor[2][ci])); // bilinear interpolation
+                }
+                patchCC[k][l] = new CoordinateColorPair(tmpC, paramSC);
+            }
+        }
+        return patchCC;
+    }
+    
+    // Bernstein polynomials which are defined in page 119 of PDF32000_2008.pdf
+    private double[][] getBernsteinPolynomials(int lvl)
+    {
+        int sz = (1 << lvl) + 1;
+        double[][] poly = new double[4][sz];
+        double step = 1.0 / (sz - 1);
+        double t = - step;
+        for (int i = 0; i < sz; i++)
+        {
+            t += step;
+            poly[0][i] = (1 - t) * (1 - t) * (1 - t);
+            poly[1][i] = 3 * t * (1 - t) * (1 - t);
+            poly[2][i] = 3 * t * t * (1 - t);
+            poly[3][i] = t * t * t;
+        }
+        return poly;
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingContext.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.IOException;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * AWT PaintContext for coons patch meshes (type 6) shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class Type6ShadingContext extends PatchMeshesShadingContext
+{
+    private static final Log LOG = LogFactory.getLog(Type6ShadingContext.class);
+    
+     /**
+     * Constructor creates an instance to be used for fill operations.
+     * @param shading the shading type to be used
+     * @param colorModel 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 Type6ShadingContext(PDShadingType6 shading, ColorModel colorModel, AffineTransform xform,
+                                Matrix ctm, int pageHeight) throws IOException
+    {
+        super(shading, colorModel, xform, ctm, pageHeight);
+        bitsPerColorComponent = shading.getBitsPerComponent();
+        bitsPerCoordinate = shading.getBitsPerCoordinate();
+        bitsPerFlag = shading.getBitsPerFlag();
+        patchList = getCoonsPatchList(xform, ctm);
+    }
+    
+    // get the patch list which forms the type 6 shading image from data stream
+    private ArrayList<Patch> getCoonsPatchList(AffineTransform xform,Matrix ctm) throws IOException
+    {
+        PDShadingType6 coonsShadingType = (PDShadingType6) patchMeshesShadingType;
+        COSDictionary cosDictionary = coonsShadingType.getCOSDictionary();
+        PDRange rangeX = coonsShadingType.getDecodeForParameter(0);
+        PDRange rangeY = coonsShadingType.getDecodeForParameter(1);
+        PDRange[] colRange = new PDRange[numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; ++i)
+        {
+            colRange[i] = coonsShadingType.getDecodeForParameter(2 + i);
+        }
+        return getPatchList(xform, ctm, cosDictionary, rangeX, rangeY, colRange, 12);
+    }
+    
+    @Override
+    protected Patch generatePatch(Point2D[] points, float[][] color)
+    {
+        return new CoonsPatch(points, color);
+    }
+    
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingPaint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingPaint.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingPaint.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type6ShadingPaint.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * AWT Paint for coons patch meshes (Type 6) shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class Type6ShadingPaint implements Paint
+{
+    private static final Log LOG = LogFactory.getLog(Type6ShadingPaint.class);
+
+    private final PDShadingType6 shading;
+    private final Matrix ctm;
+    private final int pageHeight;
+    
+    /**
+     * Constructor.
+     * @param shading the shading resources
+     * @param ctm current transformation matrix
+     * @param pageHeight the height of the page
+     */
+    public Type6ShadingPaint(PDShadingType6 shading, Matrix ctm, int pageHeight)
+    {
+        this.shading = shading;
+        this.ctm = ctm;
+        this.pageHeight = pageHeight;
+    }
+
+    @Override
+    public int getTransparency()
+    {
+        return 0;
+    }
+
+    @Override
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
+                                      AffineTransform xform, RenderingHints hints)
+    {
+        try
+        {
+            return new Type6ShadingContext(shading, cm, xform, ctm, pageHeight);
+        }
+        catch (IOException ex)
+        {
+            LOG.error(ex);
+            return null;
+        }
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingContext.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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.IOException;
+import java.util.ArrayList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.pdmodel.common.PDRange;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * AWT PaintContext for tensor-product patch meshes (type 7) shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class Type7ShadingContext extends PatchMeshesShadingContext
+{
+    private static final Log LOG = LogFactory.getLog(Type7ShadingContext.class);
+    
+    /**
+     * Constructor creates an instance to be used for fill operations.
+     * @param shading the shading type to be used
+     * @param colorModel 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 Type7ShadingContext(PDShadingType7 shading, ColorModel colorModel, AffineTransform xform,
+                                Matrix ctm, int pageHeight) throws IOException
+    {
+        super(shading, colorModel, xform, ctm, pageHeight);
+        bitsPerColorComponent = shading.getBitsPerComponent();
+        bitsPerCoordinate = shading.getBitsPerCoordinate();
+        bitsPerFlag = shading.getBitsPerFlag();
+        patchList = getTensorPatchList(xform, ctm);
+    }
+    
+    // get the patch list which forms the type 7 shading image from data stream
+    private ArrayList<Patch> getTensorPatchList(AffineTransform xform,Matrix ctm) throws IOException
+    {
+        PDShadingType7 tensorShadingType = (PDShadingType7) patchMeshesShadingType;
+        COSDictionary cosDictionary = tensorShadingType.getCOSDictionary();
+        PDRange rangeX = tensorShadingType.getDecodeForParameter(0);
+        PDRange rangeY = tensorShadingType.getDecodeForParameter(1);
+        PDRange[] colRange = new PDRange[numberOfColorComponents];
+        for (int i = 0; i < numberOfColorComponents; ++i)
+        {
+            colRange[i] = tensorShadingType.getDecodeForParameter(2 + i);
+        }
+        return getPatchList(xform, ctm, cosDictionary, rangeX, rangeY, colRange, 16);
+    }
+    
+    @Override
+    protected Patch generatePatch(Point2D[] points, float[][] color)
+    {
+        return new TensorPatch(points, color);
+    }
+    
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+    }
+}

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

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingPaint.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingPaint.java?rev=1607727&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingPaint.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/Type7ShadingPaint.java Thu Jul  3 19:35:54 2014
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.Matrix;
+
+/**
+ * AWT Paint for tensor-product patch meshes (Type 7) shading.
+ * This was done as part of GSoC2014, Tilman Hausherr is the mentor.
+ * @author Shaola Ren
+ */
+class Type7ShadingPaint implements Paint
+{
+    private static final Log LOG = LogFactory.getLog(Type7ShadingPaint.class);
+
+    private final PDShadingType7 shading;
+    private final Matrix ctm;
+    private final int pageHeight;
+    
+    /**
+     * Constructor.
+     * @param shading the shading resources
+     * @param ctm current transformation matrix
+     * @param pageHeight the height of the page
+     */
+    public Type7ShadingPaint(PDShadingType7 shading, Matrix ctm, int pageHeight)
+    {
+        this.shading = shading;
+        this.ctm = ctm;
+        this.pageHeight = pageHeight;
+    }
+
+    @Override
+    public int getTransparency()
+    {
+        return 0;
+    }
+
+    @Override
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
+                                      AffineTransform xform, RenderingHints hints)
+    {
+        try
+        {
+            return new Type7ShadingContext(shading, cm, xform, ctm, pageHeight);
+        }
+        catch (IOException ex)
+        {
+            LOG.error(ex);
+            return null;
+        }
+    }
+}

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



Mime
View raw message