You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2014/02/08 16:41:03 UTC

svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Author: tilman
Date: Sat Feb  8 15:41:03 2014
New Revision: 1566032

URL: http://svn.apache.org/r1566032
Log:
PDFBOX-1887: Bugfixes + Optimization of Gouraud Shading

Modified:
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1566032&r1=1566031&r2=1566032&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Sat Feb  8 15:41:03 2014
@@ -152,7 +152,7 @@ public abstract class GouraudShadingCont
      *
      * @throws IOException if something went wrong
      */
-    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor, 
+    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
             PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
     {
         float[] colorComponentTab = new float[numberOfColorComponents];
@@ -165,7 +165,7 @@ public abstract class GouraudShadingCont
         {
             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) 
+            LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
                     + "-> color[" + n + "]: " + colorComponentTab[n]);
         }
         return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
@@ -192,8 +192,6 @@ public abstract class GouraudShadingCont
                 // transform from shading to user space
                 ctm.createAffineTransform().transform(v.point, v.point);
                 // transform from user to device space
-                // move the 0,0-reference including the y-translation from user to device space
-                v.point.setLocation(v.point.getX(), pageHeight - v.point.getY());
                 xform.transform(v.point, v.point);
             }
             else
@@ -222,6 +220,7 @@ public abstract class GouraudShadingCont
     /**
      * {@inheritDoc}
      */
+    @Override
     public void dispose()
     {
         triangleList = null;
@@ -234,6 +233,7 @@ public abstract class GouraudShadingCont
     /**
      * {@inheritDoc}
      */
+    @Override
     public final ColorModel getColorModel()
     {
         return outputColorModel;
@@ -248,7 +248,7 @@ public abstract class GouraudShadingCont
      * @param dstMax max dst value
      * @return interpolated value
      */
-    private float interpolate(float src, float srcMax, float dstMin, float dstMax)
+    private float interpolate(float src, long srcMax, float dstMin, float dstMax)
     {
         return dstMin + (src * (dstMax - dstMin) / srcMax);
     }
@@ -256,71 +256,72 @@ public abstract class GouraudShadingCont
     /**
      * {@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++)
         {
-            int[] data = new int[w * h * 4];
-            for (int row = 0; row < h; row++)
+            for (int col = 0; col < w; col++)
             {
-                for (int col = 0; col < w; col++)
+                Point2D p = new Point(x + col, y + row);
+                GouraudTriangle triangle = null;
+                for (GouraudTriangle tryTriangle : triangleList)
+                {
+                    if (tryTriangle.contains(p))
+                    {
+                        triangle = tryTriangle;
+                        break;
+                    }
+                }
+                float[] values;
+                if (triangle != null)
                 {
-                    Point2D p = new Point(x + col, y + row);
+                    double[] weights = triangle.getWeights(p);
+                    values = new float[numberOfColorComponents];
+                    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]);
+                    }
+                }
+                else
+                {
+                    if (background != null)
+                    {
+                        values = background;
+                    }
+                    else
+                    {
+                        continue;
+                    }
+                }
 
-                    //TODO test optmization after ch14.pdf works:
-                    // check whether point is in combined java area
-                    for (GouraudTriangle triangle : triangleList)
+                //TODO handle function
+                // convert color values from shading colorspace to RGB
+                if (shadingColorSpace != null)
+                {
+                    if (shadingTinttransform != null)
                     {
-                        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
+                        try
                         {
-                            if (background != null)
-                            {
-                                values = background;
-                            }
-                            else
-                            {
-                                continue;
-                            }
+                            values = shadingTinttransform.eval(values);
                         }
-
-                        //TODO handle function
-                        // convert color values from shading colorspace to RGB
-                        if (shadingColorSpace != null)
+                        catch (IOException exception)
                         {
-                            if (shadingTinttransform != null)
-                            {
-                                try
-                                {
-                                    values = shadingTinttransform.eval(values);
-                                }
-                                catch (IOException exception)
-                                {
-                                    LOG.error("error while processing a function", exception);
-                                }
-                            }
-                            values = shadingColorSpace.toRGB(values);
+                            LOG.error("error while processing a function", 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;
                     }
-
+                    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);
         }

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1566032&r1=1566031&r2=1566032&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Sat Feb  8 15:41:03 2014
@@ -22,7 +22,7 @@ import java.awt.geom.Point2D;
 
 /**
  * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
- * 
+ *
  * @author Tilman Hausherr
  */
 public class GouraudTriangle
@@ -31,34 +31,45 @@ 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;
-    
-    
+
+    /*
+     * intermediate constants
+     */
+    private final double xBminusA;
+    private final double yBminusA;
+    private final double xCminusA;
+    private final double yCminusA;
+    private final double xCminusB;
+    private final double yCminusB;
+    private final double area;
+
     /**
      * 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
@@ -74,6 +85,16 @@ public class GouraudTriangle
         colorA = aColor;
         colorB = bColor;
         colorC = cColor;
+
+        // calculate constants
+        xBminusA = pointB.getX() - pointA.getX();
+        yBminusA = pointB.getY() - pointA.getY();
+        xCminusA = pointC.getX() - pointA.getX();
+        yCminusA = pointC.getY() - pointA.getY();
+        xCminusB = pointC.getX() - pointB.getX();
+        yCminusB = pointC.getY() - pointB.getY();
+        area = getArea(pointA, pointB, pointC);
+
         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()));
@@ -81,17 +102,36 @@ public class GouraudTriangle
 
     /**
      * 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
+        // inspiration:
         // http://stackoverflow.com/a/9755252/535646
+        // see also:
         // http://math.stackexchange.com/q/51326
-        return polygon.contains(p);
+        // http://www.gamedev.net/topic/295943-is-this-a-better-point-in-triangle-test-2d/
+        // java function can't be used because polygon takes integer coordinates
+
+        double xPminusA = p.getX() - pointA.getX();
+        double yPminusA = p.getY() - pointA.getY();
+
+        boolean signAB = (xBminusA * yPminusA - yBminusA * xPminusA) > 0;
+
+        if ((xCminusA * yPminusA - yCminusA * xPminusA > 0) == signAB)
+        {
+            return false;
+        }
+
+        if ((xCminusB * (p.getY() - pointB.getY()) - yCminusB * (p.getX() - pointB.getX()) > 0) != signAB)
+        {
+            return false;
+        }
+
+        return true;
     }
 
     /**
@@ -102,13 +142,13 @@ public class GouraudTriangle
     {
         // 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()) 
+        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
@@ -116,9 +156,11 @@ public class GouraudTriangle
     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};
+        return new double[]
+        {
+            getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p)
+            / area, getArea(pointA, pointB, p) / area
+        };
     }
 
 }



Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Andreas Lehmkuehler <an...@lehmi.de>.
Hi,

Am 08.02.2014 18:22, schrieb John Hewson:
> You mean Java 5 :)
Ups, of course Java 5 ...

> Tilman, you can specify 1.5 as the language version you are using in Netbeans, see https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1
>
> -- John
>
>> On 8 Feb 2014, at 08:22, Andreas Lehmkuehler <an...@lehmi.de> wrote:
>>
>> Hi,
>>
>> ~Tilman the 1.8 branch relies on Java 6 which doesn't support @Override annotations for methods inherited when implementing an interface.
>>
>> BR
>> Andreas Lehmkühler
>>
>> Am 08.02.2014 16:41, schrieb tilman@apache.org:
>>> Author: tilman
>>> Date: Sat Feb  8 15:41:03 2014
>>> New Revision: 1566032
>>>
>>> URL: http://svn.apache.org/r1566032
>>> Log:
>>> PDFBOX-1887: Bugfixes + Optimization of Gouraud Shading
>>>
>>> Modified:
>>>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>>>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>>>
>>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>>> ==============================================================================
>>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
>>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Sat Feb  8 15:41:03 2014
>>> @@ -152,7 +152,7 @@ public abstract class GouraudShadingCont
>>>        *
>>>        * @throws IOException if something went wrong
>>>        */
>>> -    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>>> +    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>>>               PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
>>>       {
>>>           float[] colorComponentTab = new float[numberOfColorComponents];
>>> @@ -165,7 +165,7 @@ public abstract class GouraudShadingCont
>>>           {
>>>               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)
>>> +            LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
>>>                       + "-> color[" + n + "]: " + colorComponentTab[n]);
>>>           }
>>>           return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
>>> @@ -192,8 +192,6 @@ public abstract class GouraudShadingCont
>>>                   // transform from shading to user space
>>>                   ctm.createAffineTransform().transform(v.point, v.point);
>>>                   // transform from user to device space
>>> -                // move the 0,0-reference including the y-translation from user to device space
>>> -                v.point.setLocation(v.point.getX(), pageHeight - v.point.getY());
>>>                   xform.transform(v.point, v.point);
>>>               }
>>>               else
>>> @@ -222,6 +220,7 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@inheritDoc}
>>>        */
>>> +    @Override
>>>       public void dispose()
>>>       {
>>>           triangleList = null;
>>> @@ -234,6 +233,7 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@inheritDoc}
>>>        */
>>> +    @Override
>>>       public final ColorModel getColorModel()
>>>       {
>>>           return outputColorModel;
>>> @@ -248,7 +248,7 @@ public abstract class GouraudShadingCont
>>>        * @param dstMax max dst value
>>>        * @return interpolated value
>>>        */
>>> -    private float interpolate(float src, float srcMax, float dstMin, float dstMax)
>>> +    private float interpolate(float src, long srcMax, float dstMin, float dstMax)
>>>       {
>>>           return dstMin + (src * (dstMax - dstMin) / srcMax);
>>>       }
>>> @@ -256,71 +256,72 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@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++)
>>>           {
>>> -            int[] data = new int[w * h * 4];
>>> -            for (int row = 0; row < h; row++)
>>> +            for (int col = 0; col < w; col++)
>>>               {
>>> -                for (int col = 0; col < w; col++)
>>> +                Point2D p = new Point(x + col, y + row);
>>> +                GouraudTriangle triangle = null;
>>> +                for (GouraudTriangle tryTriangle : triangleList)
>>> +                {
>>> +                    if (tryTriangle.contains(p))
>>> +                    {
>>> +                        triangle = tryTriangle;
>>> +                        break;
>>> +                    }
>>> +                }
>>> +                float[] values;
>>> +                if (triangle != null)
>>>                   {
>>> -                    Point2D p = new Point(x + col, y + row);
>>> +                    double[] weights = triangle.getWeights(p);
>>> +                    values = new float[numberOfColorComponents];
>>> +                    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]);
>>> +                    }
>>> +                }
>>> +                else
>>> +                {
>>> +                    if (background != null)
>>> +                    {
>>> +                        values = background;
>>> +                    }
>>> +                    else
>>> +                    {
>>> +                        continue;
>>> +                    }
>>> +                }
>>>
>>> -                    //TODO test optmization after ch14.pdf works:
>>> -                    // check whether point is in combined java area
>>> -                    for (GouraudTriangle triangle : triangleList)
>>> +                //TODO handle function
>>> +                // convert color values from shading colorspace to RGB
>>> +                if (shadingColorSpace != null)
>>> +                {
>>> +                    if (shadingTinttransform != null)
>>>                       {
>>> -                        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
>>> +                        try
>>>                           {
>>> -                            if (background != null)
>>> -                            {
>>> -                                values = background;
>>> -                            }
>>> -                            else
>>> -                            {
>>> -                                continue;
>>> -                            }
>>> +                            values = shadingTinttransform.eval(values);
>>>                           }
>>> -
>>> -                        //TODO handle function
>>> -                        // convert color values from shading colorspace to RGB
>>> -                        if (shadingColorSpace != null)
>>> +                        catch (IOException exception)
>>>                           {
>>> -                            if (shadingTinttransform != null)
>>> -                            {
>>> -                                try
>>> -                                {
>>> -                                    values = shadingTinttransform.eval(values);
>>> -                                }
>>> -                                catch (IOException exception)
>>> -                                {
>>> -                                    LOG.error("error while processing a function", exception);
>>> -                                }
>>> -                            }
>>> -                            values = shadingColorSpace.toRGB(values);
>>> +                            LOG.error("error while processing a function", 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;
>>>                       }
>>> -
>>> +                    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);
>>>           }
>>>
>>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>>> ==============================================================================
>>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (original)
>>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Sat Feb  8 15:41:03 2014
>>> @@ -22,7 +22,7 @@ import java.awt.geom.Point2D;
>>>
>>>   /**
>>>    * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
>>> - *
>>> + *
>>>    * @author Tilman Hausherr
>>>    */
>>>   public class GouraudTriangle
>>> @@ -31,34 +31,45 @@ 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;
>>> -
>>> -
>>> +
>>> +    /*
>>> +     * intermediate constants
>>> +     */
>>> +    private final double xBminusA;
>>> +    private final double yBminusA;
>>> +    private final double xCminusA;
>>> +    private final double yCminusA;
>>> +    private final double xCminusB;
>>> +    private final double yCminusB;
>>> +    private final double area;
>>> +
>>>       /**
>>>        * 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
>>> @@ -74,6 +85,16 @@ public class GouraudTriangle
>>>           colorA = aColor;
>>>           colorB = bColor;
>>>           colorC = cColor;
>>> +
>>> +        // calculate constants
>>> +        xBminusA = pointB.getX() - pointA.getX();
>>> +        yBminusA = pointB.getY() - pointA.getY();
>>> +        xCminusA = pointC.getX() - pointA.getX();
>>> +        yCminusA = pointC.getY() - pointA.getY();
>>> +        xCminusB = pointC.getX() - pointB.getX();
>>> +        yCminusB = pointC.getY() - pointB.getY();
>>> +        area = getArea(pointA, pointB, pointC);
>>> +
>>>           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()));
>>> @@ -81,17 +102,36 @@ public class GouraudTriangle
>>>
>>>       /**
>>>        * 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
>>> +        // inspiration:
>>>           // http://stackoverflow.com/a/9755252/535646
>>> +        // see also:
>>>           // http://math.stackexchange.com/q/51326
>>> -        return polygon.contains(p);
>>> +        // http://www.gamedev.net/topic/295943-is-this-a-better-point-in-triangle-test-2d/
>>> +        // java function can't be used because polygon takes integer coordinates
>>> +
>>> +        double xPminusA = p.getX() - pointA.getX();
>>> +        double yPminusA = p.getY() - pointA.getY();
>>> +
>>> +        boolean signAB = (xBminusA * yPminusA - yBminusA * xPminusA) > 0;
>>> +
>>> +        if ((xCminusA * yPminusA - yCminusA * xPminusA > 0) == signAB)
>>> +        {
>>> +            return false;
>>> +        }
>>> +
>>> +        if ((xCminusB * (p.getY() - pointB.getY()) - yCminusB * (p.getX() - pointB.getX()) > 0) != signAB)
>>> +        {
>>> +            return false;
>>> +        }
>>> +
>>> +        return true;
>>>       }
>>>
>>>       /**
>>> @@ -102,13 +142,13 @@ public class GouraudTriangle
>>>       {
>>>           // 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())
>>> +        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
>>> @@ -116,9 +156,11 @@ public class GouraudTriangle
>>>       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};
>>> +        return new double[]
>>> +        {
>>> +            getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p)
>>> +            / area, getArea(pointA, pointB, p) / area
>>> +        };
>>>       }
>>>
>>>   }
>>


Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by John Hewson <jo...@jahewson.com>.
Hmm, it think if maven is building against JDK 6 then you won't see error about @Override on your local machine. That would explain why your getting errors on Jenkins only...

-- John

> On 8 Feb 2014, at 12:10, Thomas Chojecki <in...@rayman2200.de> wrote:
> 
> Am Sat, 08 Feb 2014 20:53:13 +0100
> schrieb Tilman Hausherr <TH...@t-online.de>:
> 
>> Not sure what you mean - I do build PDFBOX with maven, which is
>> included with netbeans and works very well.
>> Tilman
> What I mean is, that maybe the IDE client does not compile with the
> settings that are used in the pom.xml. You can see in the jenkins log
> that maven tries to compile the source and fail. It was just a
> recommendation to do the same as jenkins do, just running the
> native maven client ;-) 
> 
> I do run into the same problems if I use the eclipse embedded client.
> The embedded client use the IDE settings not the pom.xml
> settings.
> 
> Best regards
> Thomas
> 
> 
>> Am 08.02.2014 19:28, schrieb Thomas Chojecki:
>>> Am Sat, 08 Feb 2014 19:18:57 +0100
>>> schrieb Tilman Hausherr <TH...@t-online.de>:
>>> 
>>>> This is set up when checking out the project. No error appeared
>>>> when building the project. The real solution would probably be to
>>>> install another JDK on the computer :-(
>>> I think netbeans has no helper plugin for maven builds like eclipse
>>> has, so I would recommend you to run "mvn compile" or "mvn test" on
>>> console to test the source for compile errors and maybe regressions.
>>> 
>>>> Tilman
>>> Best regards
>>> Thomas
>>> 
>>> 
>>>> Am 08.02.2014 18:22, schrieb John Hewson:
>>>>> You mean Java 5 :)
>>>>> 
>>>>> Tilman, you can specify 1.5 as the language version you are using
>>>>> in Netbeans, see
>>>>> https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1
>>>> 
>>>> [SNIP]
> 

Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Thomas Chojecki <in...@rayman2200.de>.
Am Sat, 08 Feb 2014 20:53:13 +0100
schrieb Tilman Hausherr <TH...@t-online.de>:

> Not sure what you mean - I do build PDFBOX with maven, which is
> included with netbeans and works very well.
> Tilman
What I mean is, that maybe the IDE client does not compile with the
settings that are used in the pom.xml. You can see in the jenkins log
that maven tries to compile the source and fail. It was just a
recommendation to do the same as jenkins do, just running the
native maven client ;-) 

I do run into the same problems if I use the eclipse embedded client.
The embedded client use the IDE settings not the pom.xml
settings.

Best regards
Thomas


> Am 08.02.2014 19:28, schrieb Thomas Chojecki:
> > Am Sat, 08 Feb 2014 19:18:57 +0100
> > schrieb Tilman Hausherr <TH...@t-online.de>:
> >
> >> This is set up when checking out the project. No error appeared
> >> when building the project. The real solution would probably be to
> >> install another JDK on the computer :-(
> > I think netbeans has no helper plugin for maven builds like eclipse
> > has, so I would recommend you to run "mvn compile" or "mvn test" on
> > console to test the source for compile errors and maybe regressions.
> >
> >> Tilman
> > Best regards
> > Thomas
> >
> >
> >> Am 08.02.2014 18:22, schrieb John Hewson:
> >>> You mean Java 5 :)
> >>>
> >>> Tilman, you can specify 1.5 as the language version you are using
> >>> in Netbeans, see
> >>> https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1
> >>
> >> [SNIP]
> 


Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Tilman Hausherr <TH...@t-online.de>.
Not sure what you mean - I do build PDFBOX with maven, which is included 
with netbeans and works very well.
Tilman

Am 08.02.2014 19:28, schrieb Thomas Chojecki:
> Am Sat, 08 Feb 2014 19:18:57 +0100
> schrieb Tilman Hausherr <TH...@t-online.de>:
>
>> This is set up when checking out the project. No error appeared when
>> building the project. The real solution would probably be to install
>> another JDK on the computer :-(
> I think netbeans has no helper plugin for maven builds like eclipse
> has, so I would recommend you to run "mvn compile" or "mvn test" on
> console to test the source for compile errors and maybe regressions.
>
>> Tilman
> Best regards
> Thomas
>
>
>> Am 08.02.2014 18:22, schrieb John Hewson:
>>> You mean Java 5 :)
>>>
>>> Tilman, you can specify 1.5 as the language version you are using
>>> in Netbeans, see
>>> https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1
>>
>> [SNIP]


Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Thomas Chojecki <in...@rayman2200.de>.
Am Sat, 08 Feb 2014 19:18:57 +0100
schrieb Tilman Hausherr <TH...@t-online.de>:

> This is set up when checking out the project. No error appeared when 
> building the project. The real solution would probably be to install 
> another JDK on the computer :-(

I think netbeans has no helper plugin for maven builds like eclipse
has, so I would recommend you to run "mvn compile" or "mvn test" on
console to test the source for compile errors and maybe regressions.

> 
> Tilman

Best regards 
Thomas


> 
> Am 08.02.2014 18:22, schrieb John Hewson:
> > You mean Java 5 :)
> >
> > Tilman, you can specify 1.5 as the language version you are using
> > in Netbeans, see
> > https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1
> 
> 
> [SNIP]

Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Tilman Hausherr <TH...@t-online.de>.
This is set up when checking out the project. No error appeared when 
building the project. The real solution would probably be to install 
another JDK on the computer :-(

Tilman


Am 08.02.2014 18:22, schrieb John Hewson:
> You mean Java 5 :)
>
> Tilman, you can specify 1.5 as the language version you are using in Netbeans, see https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1


>
> -- John
>
>> On 8 Feb 2014, at 08:22, Andreas Lehmkuehler <an...@lehmi.de> wrote:
>>
>> Hi,
>>
>> ~Tilman the 1.8 branch relies on Java 6 which doesn't support @Override annotations for methods inherited when implementing an interface.
>>
>> BR
>> Andreas Lehmkühler
>>
>> Am 08.02.2014 16:41, schrieb tilman@apache.org:
>>> Author: tilman
>>> Date: Sat Feb  8 15:41:03 2014
>>> New Revision: 1566032
>>>
>>> URL: http://svn.apache.org/r1566032
>>> Log:
>>> PDFBOX-1887: Bugfixes + Optimization of Gouraud Shading
>>>
>>> Modified:
>>>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>>>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>>>
>>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>>> ==============================================================================
>>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
>>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Sat Feb  8 15:41:03 2014
>>> @@ -152,7 +152,7 @@ public abstract class GouraudShadingCont
>>>        *
>>>        * @throws IOException if something went wrong
>>>        */
>>> -    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>>> +    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>>>               PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
>>>       {
>>>           float[] colorComponentTab = new float[numberOfColorComponents];
>>> @@ -165,7 +165,7 @@ public abstract class GouraudShadingCont
>>>           {
>>>               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)
>>> +            LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
>>>                       + "-> color[" + n + "]: " + colorComponentTab[n]);
>>>           }
>>>           return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
>>> @@ -192,8 +192,6 @@ public abstract class GouraudShadingCont
>>>                   // transform from shading to user space
>>>                   ctm.createAffineTransform().transform(v.point, v.point);
>>>                   // transform from user to device space
>>> -                // move the 0,0-reference including the y-translation from user to device space
>>> -                v.point.setLocation(v.point.getX(), pageHeight - v.point.getY());
>>>                   xform.transform(v.point, v.point);
>>>               }
>>>               else
>>> @@ -222,6 +220,7 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@inheritDoc}
>>>        */
>>> +    @Override
>>>       public void dispose()
>>>       {
>>>           triangleList = null;
>>> @@ -234,6 +233,7 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@inheritDoc}
>>>        */
>>> +    @Override
>>>       public final ColorModel getColorModel()
>>>       {
>>>           return outputColorModel;
>>> @@ -248,7 +248,7 @@ public abstract class GouraudShadingCont
>>>        * @param dstMax max dst value
>>>        * @return interpolated value
>>>        */
>>> -    private float interpolate(float src, float srcMax, float dstMin, float dstMax)
>>> +    private float interpolate(float src, long srcMax, float dstMin, float dstMax)
>>>       {
>>>           return dstMin + (src * (dstMax - dstMin) / srcMax);
>>>       }
>>> @@ -256,71 +256,72 @@ public abstract class GouraudShadingCont
>>>       /**
>>>        * {@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++)
>>>           {
>>> -            int[] data = new int[w * h * 4];
>>> -            for (int row = 0; row < h; row++)
>>> +            for (int col = 0; col < w; col++)
>>>               {
>>> -                for (int col = 0; col < w; col++)
>>> +                Point2D p = new Point(x + col, y + row);
>>> +                GouraudTriangle triangle = null;
>>> +                for (GouraudTriangle tryTriangle : triangleList)
>>> +                {
>>> +                    if (tryTriangle.contains(p))
>>> +                    {
>>> +                        triangle = tryTriangle;
>>> +                        break;
>>> +                    }
>>> +                }
>>> +                float[] values;
>>> +                if (triangle != null)
>>>                   {
>>> -                    Point2D p = new Point(x + col, y + row);
>>> +                    double[] weights = triangle.getWeights(p);
>>> +                    values = new float[numberOfColorComponents];
>>> +                    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]);
>>> +                    }
>>> +                }
>>> +                else
>>> +                {
>>> +                    if (background != null)
>>> +                    {
>>> +                        values = background;
>>> +                    }
>>> +                    else
>>> +                    {
>>> +                        continue;
>>> +                    }
>>> +                }
>>>
>>> -                    //TODO test optmization after ch14.pdf works:
>>> -                    // check whether point is in combined java area
>>> -                    for (GouraudTriangle triangle : triangleList)
>>> +                //TODO handle function
>>> +                // convert color values from shading colorspace to RGB
>>> +                if (shadingColorSpace != null)
>>> +                {
>>> +                    if (shadingTinttransform != null)
>>>                       {
>>> -                        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
>>> +                        try
>>>                           {
>>> -                            if (background != null)
>>> -                            {
>>> -                                values = background;
>>> -                            }
>>> -                            else
>>> -                            {
>>> -                                continue;
>>> -                            }
>>> +                            values = shadingTinttransform.eval(values);
>>>                           }
>>> -
>>> -                        //TODO handle function
>>> -                        // convert color values from shading colorspace to RGB
>>> -                        if (shadingColorSpace != null)
>>> +                        catch (IOException exception)
>>>                           {
>>> -                            if (shadingTinttransform != null)
>>> -                            {
>>> -                                try
>>> -                                {
>>> -                                    values = shadingTinttransform.eval(values);
>>> -                                }
>>> -                                catch (IOException exception)
>>> -                                {
>>> -                                    LOG.error("error while processing a function", exception);
>>> -                                }
>>> -                            }
>>> -                            values = shadingColorSpace.toRGB(values);
>>> +                            LOG.error("error while processing a function", 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;
>>>                       }
>>> -
>>> +                    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);
>>>           }
>>>
>>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>>> ==============================================================================
>>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (original)
>>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Sat Feb  8 15:41:03 2014
>>> @@ -22,7 +22,7 @@ import java.awt.geom.Point2D;
>>>
>>>   /**
>>>    * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
>>> - *
>>> + *
>>>    * @author Tilman Hausherr
>>>    */
>>>   public class GouraudTriangle
>>> @@ -31,34 +31,45 @@ 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;
>>> -
>>> -
>>> +
>>> +    /*
>>> +     * intermediate constants
>>> +     */
>>> +    private final double xBminusA;
>>> +    private final double yBminusA;
>>> +    private final double xCminusA;
>>> +    private final double yCminusA;
>>> +    private final double xCminusB;
>>> +    private final double yCminusB;
>>> +    private final double area;
>>> +
>>>       /**
>>>        * 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
>>> @@ -74,6 +85,16 @@ public class GouraudTriangle
>>>           colorA = aColor;
>>>           colorB = bColor;
>>>           colorC = cColor;
>>> +
>>> +        // calculate constants
>>> +        xBminusA = pointB.getX() - pointA.getX();
>>> +        yBminusA = pointB.getY() - pointA.getY();
>>> +        xCminusA = pointC.getX() - pointA.getX();
>>> +        yCminusA = pointC.getY() - pointA.getY();
>>> +        xCminusB = pointC.getX() - pointB.getX();
>>> +        yCminusB = pointC.getY() - pointB.getY();
>>> +        area = getArea(pointA, pointB, pointC);
>>> +
>>>           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()));
>>> @@ -81,17 +102,36 @@ public class GouraudTriangle
>>>
>>>       /**
>>>        * 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
>>> +        // inspiration:
>>>           // http://stackoverflow.com/a/9755252/535646
>>> +        // see also:
>>>           // http://math.stackexchange.com/q/51326
>>> -        return polygon.contains(p);
>>> +        // http://www.gamedev.net/topic/295943-is-this-a-better-point-in-triangle-test-2d/
>>> +        // java function can't be used because polygon takes integer coordinates
>>> +
>>> +        double xPminusA = p.getX() - pointA.getX();
>>> +        double yPminusA = p.getY() - pointA.getY();
>>> +
>>> +        boolean signAB = (xBminusA * yPminusA - yBminusA * xPminusA) > 0;
>>> +
>>> +        if ((xCminusA * yPminusA - yCminusA * xPminusA > 0) == signAB)
>>> +        {
>>> +            return false;
>>> +        }
>>> +
>>> +        if ((xCminusB * (p.getY() - pointB.getY()) - yCminusB * (p.getX() - pointB.getX()) > 0) != signAB)
>>> +        {
>>> +            return false;
>>> +        }
>>> +
>>> +        return true;
>>>       }
>>>
>>>       /**
>>> @@ -102,13 +142,13 @@ public class GouraudTriangle
>>>       {
>>>           // 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())
>>> +        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
>>> @@ -116,9 +156,11 @@ public class GouraudTriangle
>>>       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};
>>> +        return new double[]
>>> +        {
>>> +            getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p)
>>> +            / area, getArea(pointA, pointB, p) / area
>>> +        };
>>>       }
>>>
>>>   }


Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by John Hewson <jo...@jahewson.com>.
You mean Java 5 :)

Tilman, you can specify 1.5 as the language version you are using in Netbeans, see https://blogs.oracle.com/roumen/entry/netbeans_4_1_tip_1

-- John

> On 8 Feb 2014, at 08:22, Andreas Lehmkuehler <an...@lehmi.de> wrote:
> 
> Hi,
> 
> ~Tilman the 1.8 branch relies on Java 6 which doesn't support @Override annotations for methods inherited when implementing an interface.
> 
> BR
> Andreas Lehmkühler
> 
> Am 08.02.2014 16:41, schrieb tilman@apache.org:
>> Author: tilman
>> Date: Sat Feb  8 15:41:03 2014
>> New Revision: 1566032
>> 
>> URL: http://svn.apache.org/r1566032
>> Log:
>> PDFBOX-1887: Bugfixes + Optimization of Gouraud Shading
>> 
>> Modified:
>>     pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>>     pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>> 
>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>> ==============================================================================
>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Sat Feb  8 15:41:03 2014
>> @@ -152,7 +152,7 @@ public abstract class GouraudShadingCont
>>       *
>>       * @throws IOException if something went wrong
>>       */
>> -    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>> +    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>>              PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
>>      {
>>          float[] colorComponentTab = new float[numberOfColorComponents];
>> @@ -165,7 +165,7 @@ public abstract class GouraudShadingCont
>>          {
>>              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)
>> +            LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
>>                      + "-> color[" + n + "]: " + colorComponentTab[n]);
>>          }
>>          return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
>> @@ -192,8 +192,6 @@ public abstract class GouraudShadingCont
>>                  // transform from shading to user space
>>                  ctm.createAffineTransform().transform(v.point, v.point);
>>                  // transform from user to device space
>> -                // move the 0,0-reference including the y-translation from user to device space
>> -                v.point.setLocation(v.point.getX(), pageHeight - v.point.getY());
>>                  xform.transform(v.point, v.point);
>>              }
>>              else
>> @@ -222,6 +220,7 @@ public abstract class GouraudShadingCont
>>      /**
>>       * {@inheritDoc}
>>       */
>> +    @Override
>>      public void dispose()
>>      {
>>          triangleList = null;
>> @@ -234,6 +233,7 @@ public abstract class GouraudShadingCont
>>      /**
>>       * {@inheritDoc}
>>       */
>> +    @Override
>>      public final ColorModel getColorModel()
>>      {
>>          return outputColorModel;
>> @@ -248,7 +248,7 @@ public abstract class GouraudShadingCont
>>       * @param dstMax max dst value
>>       * @return interpolated value
>>       */
>> -    private float interpolate(float src, float srcMax, float dstMin, float dstMax)
>> +    private float interpolate(float src, long srcMax, float dstMin, float dstMax)
>>      {
>>          return dstMin + (src * (dstMax - dstMin) / srcMax);
>>      }
>> @@ -256,71 +256,72 @@ public abstract class GouraudShadingCont
>>      /**
>>       * {@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++)
>>          {
>> -            int[] data = new int[w * h * 4];
>> -            for (int row = 0; row < h; row++)
>> +            for (int col = 0; col < w; col++)
>>              {
>> -                for (int col = 0; col < w; col++)
>> +                Point2D p = new Point(x + col, y + row);
>> +                GouraudTriangle triangle = null;
>> +                for (GouraudTriangle tryTriangle : triangleList)
>> +                {
>> +                    if (tryTriangle.contains(p))
>> +                    {
>> +                        triangle = tryTriangle;
>> +                        break;
>> +                    }
>> +                }
>> +                float[] values;
>> +                if (triangle != null)
>>                  {
>> -                    Point2D p = new Point(x + col, y + row);
>> +                    double[] weights = triangle.getWeights(p);
>> +                    values = new float[numberOfColorComponents];
>> +                    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]);
>> +                    }
>> +                }
>> +                else
>> +                {
>> +                    if (background != null)
>> +                    {
>> +                        values = background;
>> +                    }
>> +                    else
>> +                    {
>> +                        continue;
>> +                    }
>> +                }
>> 
>> -                    //TODO test optmization after ch14.pdf works:
>> -                    // check whether point is in combined java area
>> -                    for (GouraudTriangle triangle : triangleList)
>> +                //TODO handle function
>> +                // convert color values from shading colorspace to RGB
>> +                if (shadingColorSpace != null)
>> +                {
>> +                    if (shadingTinttransform != null)
>>                      {
>> -                        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
>> +                        try
>>                          {
>> -                            if (background != null)
>> -                            {
>> -                                values = background;
>> -                            }
>> -                            else
>> -                            {
>> -                                continue;
>> -                            }
>> +                            values = shadingTinttransform.eval(values);
>>                          }
>> -
>> -                        //TODO handle function
>> -                        // convert color values from shading colorspace to RGB
>> -                        if (shadingColorSpace != null)
>> +                        catch (IOException exception)
>>                          {
>> -                            if (shadingTinttransform != null)
>> -                            {
>> -                                try
>> -                                {
>> -                                    values = shadingTinttransform.eval(values);
>> -                                }
>> -                                catch (IOException exception)
>> -                                {
>> -                                    LOG.error("error while processing a function", exception);
>> -                                }
>> -                            }
>> -                            values = shadingColorSpace.toRGB(values);
>> +                            LOG.error("error while processing a function", 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;
>>                      }
>> -
>> +                    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);
>>          }
>> 
>> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1566032&r1=1566031&r2=1566032&view=diff
>> ==============================================================================
>> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (original)
>> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Sat Feb  8 15:41:03 2014
>> @@ -22,7 +22,7 @@ import java.awt.geom.Point2D;
>> 
>>  /**
>>   * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
>> - *
>> + *
>>   * @author Tilman Hausherr
>>   */
>>  public class GouraudTriangle
>> @@ -31,34 +31,45 @@ 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;
>> -
>> -
>> +
>> +    /*
>> +     * intermediate constants
>> +     */
>> +    private final double xBminusA;
>> +    private final double yBminusA;
>> +    private final double xCminusA;
>> +    private final double yCminusA;
>> +    private final double xCminusB;
>> +    private final double yCminusB;
>> +    private final double area;
>> +
>>      /**
>>       * 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
>> @@ -74,6 +85,16 @@ public class GouraudTriangle
>>          colorA = aColor;
>>          colorB = bColor;
>>          colorC = cColor;
>> +
>> +        // calculate constants
>> +        xBminusA = pointB.getX() - pointA.getX();
>> +        yBminusA = pointB.getY() - pointA.getY();
>> +        xCminusA = pointC.getX() - pointA.getX();
>> +        yCminusA = pointC.getY() - pointA.getY();
>> +        xCminusB = pointC.getX() - pointB.getX();
>> +        yCminusB = pointC.getY() - pointB.getY();
>> +        area = getArea(pointA, pointB, pointC);
>> +
>>          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()));
>> @@ -81,17 +102,36 @@ public class GouraudTriangle
>> 
>>      /**
>>       * 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
>> +        // inspiration:
>>          // http://stackoverflow.com/a/9755252/535646
>> +        // see also:
>>          // http://math.stackexchange.com/q/51326
>> -        return polygon.contains(p);
>> +        // http://www.gamedev.net/topic/295943-is-this-a-better-point-in-triangle-test-2d/
>> +        // java function can't be used because polygon takes integer coordinates
>> +
>> +        double xPminusA = p.getX() - pointA.getX();
>> +        double yPminusA = p.getY() - pointA.getY();
>> +
>> +        boolean signAB = (xBminusA * yPminusA - yBminusA * xPminusA) > 0;
>> +
>> +        if ((xCminusA * yPminusA - yCminusA * xPminusA > 0) == signAB)
>> +        {
>> +            return false;
>> +        }
>> +
>> +        if ((xCminusB * (p.getY() - pointB.getY()) - yCminusB * (p.getX() - pointB.getX()) > 0) != signAB)
>> +        {
>> +            return false;
>> +        }
>> +
>> +        return true;
>>      }
>> 
>>      /**
>> @@ -102,13 +142,13 @@ public class GouraudTriangle
>>      {
>>          // 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())
>> +        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
>> @@ -116,9 +156,11 @@ public class GouraudTriangle
>>      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};
>> +        return new double[]
>> +        {
>> +            getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p)
>> +            / area, getArea(pointA, pointB, p) / area
>> +        };
>>      }
>> 
>>  }
> 

Re: svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java

Posted by Andreas Lehmkuehler <an...@lehmi.de>.
Hi,

~Tilman the 1.8 branch relies on Java 6 which doesn't support @Override 
annotations for methods inherited when implementing an interface.

BR
Andreas Lehmkühler

Am 08.02.2014 16:41, schrieb tilman@apache.org:
> Author: tilman
> Date: Sat Feb  8 15:41:03 2014
> New Revision: 1566032
>
> URL: http://svn.apache.org/r1566032
> Log:
> PDFBOX-1887: Bugfixes + Optimization of Gouraud Shading
>
> Modified:
>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
>      pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
>
> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java
> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java?rev=1566032&r1=1566031&r2=1566032&view=diff
> ==============================================================================
> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java (original)
> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudShadingContext.java Sat Feb  8 15:41:03 2014
> @@ -152,7 +152,7 @@ public abstract class GouraudShadingCont
>        *
>        * @throws IOException if something went wrong
>        */
> -    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
> +    protected Vertex readVertex(ImageInputStream input, byte flag, long maxSrcCoord, long maxSrcColor,
>               PDRange rangeX, PDRange rangeY, PDRange[] colRangeTab) throws IOException
>       {
>           float[] colorComponentTab = new float[numberOfColorComponents];
> @@ -165,7 +165,7 @@ public abstract class GouraudShadingCont
>           {
>               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)
> +            LOG.debug("color[" + n + "]: " + color + "/" + String.format("%02x", color)
>                       + "-> color[" + n + "]: " + colorComponentTab[n]);
>           }
>           return new Vertex(flag, new Point2D.Double(dstX, dstY), colorComponentTab);
> @@ -192,8 +192,6 @@ public abstract class GouraudShadingCont
>                   // transform from shading to user space
>                   ctm.createAffineTransform().transform(v.point, v.point);
>                   // transform from user to device space
> -                // move the 0,0-reference including the y-translation from user to device space
> -                v.point.setLocation(v.point.getX(), pageHeight - v.point.getY());
>                   xform.transform(v.point, v.point);
>               }
>               else
> @@ -222,6 +220,7 @@ public abstract class GouraudShadingCont
>       /**
>        * {@inheritDoc}
>        */
> +    @Override
>       public void dispose()
>       {
>           triangleList = null;
> @@ -234,6 +233,7 @@ public abstract class GouraudShadingCont
>       /**
>        * {@inheritDoc}
>        */
> +    @Override
>       public final ColorModel getColorModel()
>       {
>           return outputColorModel;
> @@ -248,7 +248,7 @@ public abstract class GouraudShadingCont
>        * @param dstMax max dst value
>        * @return interpolated value
>        */
> -    private float interpolate(float src, float srcMax, float dstMin, float dstMax)
> +    private float interpolate(float src, long srcMax, float dstMin, float dstMax)
>       {
>           return dstMin + (src * (dstMax - dstMin) / srcMax);
>       }
> @@ -256,71 +256,72 @@ public abstract class GouraudShadingCont
>       /**
>        * {@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++)
>           {
> -            int[] data = new int[w * h * 4];
> -            for (int row = 0; row < h; row++)
> +            for (int col = 0; col < w; col++)
>               {
> -                for (int col = 0; col < w; col++)
> +                Point2D p = new Point(x + col, y + row);
> +                GouraudTriangle triangle = null;
> +                for (GouraudTriangle tryTriangle : triangleList)
> +                {
> +                    if (tryTriangle.contains(p))
> +                    {
> +                        triangle = tryTriangle;
> +                        break;
> +                    }
> +                }
> +                float[] values;
> +                if (triangle != null)
>                   {
> -                    Point2D p = new Point(x + col, y + row);
> +                    double[] weights = triangle.getWeights(p);
> +                    values = new float[numberOfColorComponents];
> +                    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]);
> +                    }
> +                }
> +                else
> +                {
> +                    if (background != null)
> +                    {
> +                        values = background;
> +                    }
> +                    else
> +                    {
> +                        continue;
> +                    }
> +                }
>
> -                    //TODO test optmization after ch14.pdf works:
> -                    // check whether point is in combined java area
> -                    for (GouraudTriangle triangle : triangleList)
> +                //TODO handle function
> +                // convert color values from shading colorspace to RGB
> +                if (shadingColorSpace != null)
> +                {
> +                    if (shadingTinttransform != null)
>                       {
> -                        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
> +                        try
>                           {
> -                            if (background != null)
> -                            {
> -                                values = background;
> -                            }
> -                            else
> -                            {
> -                                continue;
> -                            }
> +                            values = shadingTinttransform.eval(values);
>                           }
> -
> -                        //TODO handle function
> -                        // convert color values from shading colorspace to RGB
> -                        if (shadingColorSpace != null)
> +                        catch (IOException exception)
>                           {
> -                            if (shadingTinttransform != null)
> -                            {
> -                                try
> -                                {
> -                                    values = shadingTinttransform.eval(values);
> -                                }
> -                                catch (IOException exception)
> -                                {
> -                                    LOG.error("error while processing a function", exception);
> -                                }
> -                            }
> -                            values = shadingColorSpace.toRGB(values);
> +                            LOG.error("error while processing a function", 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;
>                       }
> -
> +                    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);
>           }
>
> Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java
> URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java?rev=1566032&r1=1566031&r2=1566032&view=diff
> ==============================================================================
> --- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java (original)
> +++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/GouraudTriangle.java Sat Feb  8 15:41:03 2014
> @@ -22,7 +22,7 @@ import java.awt.geom.Point2D;
>
>   /**
>    * Helper class to deal with Gouraud triangles for type 4 and 5 shading.
> - *
> + *
>    * @author Tilman Hausherr
>    */
>   public class GouraudTriangle
> @@ -31,34 +31,45 @@ 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;
> -
> -
> +
> +    /*
> +     * intermediate constants
> +     */
> +    private final double xBminusA;
> +    private final double yBminusA;
> +    private final double xCminusA;
> +    private final double yCminusA;
> +    private final double xCminusB;
> +    private final double yCminusB;
> +    private final double area;
> +
>       /**
>        * 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
> @@ -74,6 +85,16 @@ public class GouraudTriangle
>           colorA = aColor;
>           colorB = bColor;
>           colorC = cColor;
> +
> +        // calculate constants
> +        xBminusA = pointB.getX() - pointA.getX();
> +        yBminusA = pointB.getY() - pointA.getY();
> +        xCminusA = pointC.getX() - pointA.getX();
> +        yCminusA = pointC.getY() - pointA.getY();
> +        xCminusB = pointC.getX() - pointB.getX();
> +        yCminusB = pointC.getY() - pointB.getY();
> +        area = getArea(pointA, pointB, pointC);
> +
>           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()));
> @@ -81,17 +102,36 @@ public class GouraudTriangle
>
>       /**
>        * 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
> +        // inspiration:
>           // http://stackoverflow.com/a/9755252/535646
> +        // see also:
>           // http://math.stackexchange.com/q/51326
> -        return polygon.contains(p);
> +        // http://www.gamedev.net/topic/295943-is-this-a-better-point-in-triangle-test-2d/
> +        // java function can't be used because polygon takes integer coordinates
> +
> +        double xPminusA = p.getX() - pointA.getX();
> +        double yPminusA = p.getY() - pointA.getY();
> +
> +        boolean signAB = (xBminusA * yPminusA - yBminusA * xPminusA) > 0;
> +
> +        if ((xCminusA * yPminusA - yCminusA * xPminusA > 0) == signAB)
> +        {
> +            return false;
> +        }
> +
> +        if ((xCminusB * (p.getY() - pointB.getY()) - yCminusB * (p.getX() - pointB.getX()) > 0) != signAB)
> +        {
> +            return false;
> +        }
> +
> +        return true;
>       }
>
>       /**
> @@ -102,13 +142,13 @@ public class GouraudTriangle
>       {
>           // 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())
> +        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
> @@ -116,9 +156,11 @@ public class GouraudTriangle
>       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};
> +        return new double[]
> +        {
> +            getArea(pointB, pointC, p) / area, getArea(pointA, pointC, p)
> +            / area, getArea(pointA, pointB, p) / area
> +        };
>       }
>
>   }
>
>