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/07/16 08:40:48 UTC

svn commit: r1610917 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java

Author: tilman
Date: Wed Jul 16 06:40:48 2014
New Revision: 1610917

URL: http://svn.apache.org/r1610917
Log:
PDFBOX-1915: Optimization of radial shading by Shaola Ren as part of GSoC2014

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java?rev=1610917&r1=1610916&r2=1610917&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/shading/RadialShadingContext.java Wed Jul 16 06:40:48 2014
@@ -37,6 +37,12 @@ import org.apache.pdfbox.util.Matrix;
 
 /**
  * AWT PaintContext for radial shading.
+ *
+ * Performance improvement done as part of GSoC2014, Tilman Hausherr is the
+ * mentor.
+ *
+ * @author Andreas Lehmkühler
+ * @author Shaola Ren 
  */
 public class RadialShadingContext implements PaintContext
 {
@@ -49,6 +55,7 @@ public class RadialShadingContext implem
     private float[] coords;
     private float[] domain;
     private float[] background;
+    private int rgbBackground;
     private boolean[] extend;
     private double x1x0; 
     private double y1y0;
@@ -59,6 +66,9 @@ public class RadialShadingContext implem
 
     private float d1d0;
     private double denom;
+    
+    private final double longestDistance;
+    private int[] colorTable;
 
     /**
      * Constructor creates an instance to be used for fill operations.
@@ -68,7 +78,7 @@ public class RadialShadingContext implem
      * @param ctm the transformation matrix
      * @param pageHeight height of the current page
      */
-    RadialShadingContext(PDShadingType3 shading, ColorModel cm, AffineTransform xform,
+    public RadialShadingContext(PDShadingType3 shading, ColorModel cm, AffineTransform xform,
                                 Matrix ctm, int pageHeight) throws IOException
     {
         this.shading = shading;
@@ -134,8 +144,93 @@ public class RadialShadingContext implem
         if (bg != null)
         {
             background = bg.toFloatArray();
+            rgbBackground = convertToRGB(background);
+        }
+        longestDistance = getLongestDis();
+        colorTable = calcColorTable();
+    }
+    
+    // get the longest distance of two points which are located on these two circles
+    private double getLongestDis()
+    {
+        double centerToCenter = Math.sqrt(x1x0pow2 + y1y0pow2);
+        double rmin, rmax;
+        if (coords[2] < coords[5])
+        {
+            rmin = coords[2];
+            rmax = coords[5];
+        }
+        else
+        {
+            rmin = coords[5];
+            rmax = coords[2];
+        }
+        if (centerToCenter + rmin <= rmax)
+        {
+            return 2 * rmax;
+        }
+        else
+        {
+            return rmin + centerToCenter + coords[5];
         }
     }
+    
+    /**
+     * Calculate the color on the line connects two circles' centers and store the result in an array.
+     * @return an array, index denotes the relative position, the corresponding value the color
+     */
+    private int[] calcColorTable()
+    {
+        int[] map = new int[(int) longestDistance + 1];
+        if (longestDistance == 0 || d1d0 == 0)
+        {
+            try
+            {
+                float[] values = shading.evalFunction(domain[0]);
+                map[0] = convertToRGB(values);
+            }
+            catch (IOException exception)
+            {
+                LOG.error("error while processing a function", exception);
+            }
+        }
+        else
+        {
+            for (int i = 0; i <= longestDistance; i++)
+            {
+                float t = domain[0] + d1d0 * i / (float)longestDistance;
+                try
+                {
+                    float[] values = shading.evalFunction(t);
+                    map[i] = convertToRGB(values);
+                }
+                catch (IOException exception)
+                {
+                    LOG.error("error while processing a function", exception);
+                }
+            }
+        }
+        return map;
+    }
+    
+    // convert color to RGB color values
+    private int convertToRGB(float[] values)
+    {
+        float[] rgbValues;
+        int normRGBValues = 0;
+        try
+        {
+            rgbValues = shadingColorSpace.toRGB(values);
+            normRGBValues = (int) (rgbValues[0] * 255);
+            normRGBValues |= (((int) (rgbValues[1] * 255)) << 8);
+            normRGBValues |= (((int) (rgbValues[2] * 255)) << 16);
+        }
+        catch (IOException exception)
+        {
+            LOG.error("error processing color space", exception);
+        }
+        return normRGBValues;
+    }
 
     @Override
     public void dispose() 
@@ -265,37 +360,23 @@ public class RadialShadingContext implem
                         }
                     }
                 }
-                float[] values = null;
-                int index = (j * w + i) * 4;
+                int value;
                 if (useBackground)
                 {
                     // use the given backgound color values
-                    values = background;
+                    value = rgbBackground;
                 }
                 else
                 {
-                    try
-                    {
-                        float input = (domain[0] + (d1d0 * inputValue));
-                        values = shading.evalFunction(input);
-                    }
-                    catch (IOException exception)
-                    {
-                        LOG.error("error while processing a function", exception);
-                    }
+                    int key = (int) (inputValue * longestDistance);
+                    value = colorTable[key];
                 }
-                // convert color values from shading color space to RGB
-                try
-                {
-                    values = shadingColorSpace.toRGB(values);
-                }
-                catch (IOException exception)
-                {
-                    LOG.error("error processing color space", exception);
-                }
-                data[index] = (int) (values[0] * 255);
-                data[index + 1] = (int) (values[1] * 255);
-                data[index + 2] = (int) (values[2] * 255);
+                int index = (j * w + i) * 4;
+                data[index] = value & 255;
+                value >>= 8;
+                data[index + 1] = value & 255;
+                value >>= 8;
+                data[index + 2] = value & 255;
                 data[index + 3] = 255;
             }
         }