pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From til...@apache.org
Subject svn commit: r1566032 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading: GouraudShadingContext.java GouraudTriangle.java
Date Sat, 08 Feb 2014 15:41:03 GMT
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
+        };
     }
 
 }



Mime
View raw message