You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by de...@apache.org on 2001/07/12 17:07:57 UTC

cvs commit: xml-batik/sources/org/apache/batik/ext/awt/image ImageLoader.java

deweese     01/07/12 08:07:56

  Modified:    samples/tests radialGradient.svg radialGradient2.svg
               sources/org/apache/batik/bridge CSSUtilities.java
               sources/org/apache/batik/ext/awt
                        LinearGradientPaintContext.java
                        MultipleGradientPaintContext.java
                        RadialGradientPaint.java
                        RadialGradientPaintContext.java
  Added:       samples/tests radialGradient3.svg
  Removed:     sources/org/apache/batik/ext/awt/image ImageLoader.java
  Log:
  1) Added a new radial Gradient test
  1a) Modified the radial gradient tests so they use they
      test handling of color-rendering hints.
  2) Fixed a bug in CSSUtilities with the parsing of color-rendering property.
  3) Made RadialGradientPaintContext pay attention to the rendering hints.
  4) Modified out MultipleGradientPaintContext builds gradient lut, so
     it can use the simple version more often.
  5) Removed ImageLoader since it is no longer used anywhere (functionality
     is now provided by ext/awt/image/spi package).
  
  Revision  Changes    Path
  1.2       +46 -9     xml-batik/samples/tests/radialGradient.svg
  
  Index: radialGradient.svg
  ===================================================================
  RCS file: /home/cvs/xml-batik/samples/tests/radialGradient.svg,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- radialGradient.svg	2001/04/25 21:52:40	1.1
  +++ radialGradient.svg	2001/07/12 15:07:33	1.2
  @@ -12,22 +12,60 @@
   
   <!-- ========================================================================= -->
   <!-- @author vhardy@apache.org                                                 -->
  -<!-- @version $Id: radialGradient.svg,v 1.1 2001/04/25 21:52:40 vhardy Exp $ -->
  +<!-- @version $Id: radialGradient.svg,v 1.2 2001/07/12 15:07:33 deweese Exp $ -->
   <!-- ========================================================================= -->
   <?xml-stylesheet type="text/css" href="test.css" ?>  
   
   <svg id="body" width="450" height="500" viewBox="0 0 450 500">
  -<title>&lt;radialGradient&gt; Test A</title>
   
  +    <title>&lt;radialGradient&gt; Test 1 (Simple)</title>
  +    <text class="title" x="50%" y="40">
  +        &lt;radialGradient&gt; Test 1 (Simple)
  +    </text>
  +
  +    <style type="text/css"><![CDATA[
  +        .speed   { clip-path:url(#speedClip); color-rendering:optimizeSpeed; }
  +        .default { clip-path:url(#defaultClip); color-rendering:auto; }
  +        .quality { clip-path:url(#qualityClip); 
  +                   color-rendering:optimizeQuality; }
  +        .saqLabel {  font-family: Verdana, Helvetica; 
  +                     font-size: 5;
  +                     text-anchor: middle; 
  +                     fill:black; stroke:none;}
  +        .line { fill:none; stroke:black; stroke-width:0.25; } 
  +    ]]></style>
   
  -    <text class="title" x="50%" y="40">&lt;radialGradient&gt; Test</text>
  -
       <defs>
           <!-- Shape filled by radial gradients -->
           <g id="testShape">
  -            <rect x="-25" y="-20" width="50" height="40" />
  -        </g>
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="quality" />
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="default" />
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="speed" />
  +
  +            <text x="-16.5" y="24" class="saqLabel">Q</text>
  +            <line x1="-8" x2="-8" y1="20" y2="25" class="line" />
  +            <text x="0" y="24" class="saqLabel">A</text>
  +            <line x1="8" x2="8" y1="20" y2="25" class="line" />
  +            <text x="16.5" y="24" class="saqLabel">S</text>
  +        </g>
  +
  +        <!-- Clip paths for the various color-rendering settings... -->
  +        <clipPath id="qualityClip">
  +            <rect x="-25" y="-20" width="17" height="40"/>
  +        </clipPath>
  +
  +        <clipPath id="defaultClip">
  +            <rect x="-8" y="-20" width="16" height="40"/>
  +        </clipPath>
  +
  +        <clipPath id="speedClip">
  +            <rect x="8" y="-20" width="17" height="40"/>
  +        </clipPath>
   
  +
           <!-- ========================================== -->
           <!-- Two gradients, one with no values defined  -->
           <!-- and one with the default values specified  -->
  @@ -100,7 +138,7 @@
               cx="0%" cy="0%" gradientTransform="translate(.5, .5)" />
   
           <radialGradient id="rgTxfC" xlink:href="#rgDefaults"
  -            cx="0%" cy="0%" gradientTransform="translate(.5, .5) scale(.25, 1.5)" />
  +            cx="0%" cy="0%" gradientTransform="translate(.5, .5) scale(1.5, .25)" />
   
           <radialGradient id="rgTxfD" xlink:href="#rgFxFyD"
               gradientTransform="scale(.5, .5)" />
  @@ -110,7 +148,6 @@
       <g class="legend">
    
           <g transform="translate(70, 0)">
  -
           <g transform="translate(0, 100)">
               <use xlink:href="#testShape" fill="url(#rgDefaults)" />
               <text y="-30">Defaults</text>
  @@ -187,7 +224,7 @@
   
           <g transform="translate(0, 240)">
               <use xlink:href="#testShape" fill="url(#rgTxfC)" />
  -            <text y="-30">scale(.25,.5)</text>
  +            <text y="-30">scale(1.5,.25)</text>
           </g>
   
           <g transform="translate(0, 310)">
  
  
  
  1.2       +58 -17    xml-batik/samples/tests/radialGradient2.svg
  
  Index: radialGradient2.svg
  ===================================================================
  RCS file: /home/cvs/xml-batik/samples/tests/radialGradient2.svg,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- radialGradient2.svg	2001/07/11 12:24:01	1.1
  +++ radialGradient2.svg	2001/07/12 15:07:34	1.2
  @@ -2,31 +2,72 @@
   <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000802//EN"
   "http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd">
   
  -<!-- ========================================================================= -->
  -<!-- Copyright (C) The Apache Software Foundation. All rights reserved.        -->
  -<!--                                                                           -->
  -<!-- This software is published under the terms of the Apache Software License -->
  -<!-- version 1.1, a copy of which has been included with this distribution in  -->
  -<!-- the LICENSE file.                                                         -->
  -<!-- ========================================================================= -->
  -
  -<!-- ========================================================================= -->
  -<!-- @author vhardy@apache.org                                                 -->
  -<!-- @version $Id: radialGradient2.svg,v 1.1 2001/07/11 12:24:01 deweese Exp $ -->
  -<!-- ========================================================================= -->
  +<!-- ====================================================================== -->
  +<!-- Copyright (C) The Apache Software Foundation. All rights reserved.     -->
  +<!--                                                                        -->
  +<!-- This software is published under the terms of the Apache Software      -->
  +<!-- License version 1.1, a copy of which has been included with this       -->
  +<!-- distribution in  the LICENSE file.                                     -->
  +<!-- ====================================================================== -->
  +
  +<!-- ====================================================================== -->
  +<!-- @author deweese@apache.org                                             -->
  +<!-- @author vhardy@apache.org                                              -->
  +<!-- @version $Id: radialGradient2.svg,v 1.2 2001/07/12 15:07:34 deweese Exp $ -->
  +<!-- ====================================================================== -->
  +
   <?xml-stylesheet type="text/css" href="test.css" ?>  
   
   <svg id="body" width="450" height="500" viewBox="0 0 450 500">
  -<title>&lt;radialGradient&gt; Test A</title>
   
  +    <title>&lt;radialGradient&gt; Test 2 (Discontinuity)</title>
  +    <text class="title" x="50%" y="40">
  +        &lt;radialGradient&gt; Test 2 (Discontinuity)
  +    </text>
  +
  +    <style type="text/css"><![CDATA[
  +        .speed   { clip-path:url(#speedClip); color-rendering:optimizeSpeed; }
  +        .default { clip-path:url(#defaultClip); }
  +        .quality { clip-path:url(#qualityClip); 
  +                   color-rendering:optimizeQuality; }
  +
  +        .saqLabel {  font-family: Verdana, Helvetica; 
  +                     font-size: 5;
  +                     text-anchor: middle; 
  +                     fill:black; stroke:none;}
  +        .line { fill:none; stroke:black; stroke-width:0.25; } 
  +    ]]></style>
   
  -    <text class="title" x="50%" y="40">&lt;radialGradient&gt; Test</text>
   
       <defs>
           <!-- Shape filled by radial gradients -->
           <g id="testShape">
  -            <rect x="-25" y="-20" width="50" height="40" />
  -        </g>
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="quality" />
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="default" />
  +            <rect x="-25" y="-20" width="50" height="40" 
  +                  class="speed" />
  +
  +            <text x="-16.5" y="24" class="saqLabel">Q</text>
  +            <line x1="-8" x2="-8" y1="20" y2="25" class="line" />
  +            <text x="0" y="24" class="saqLabel">A</text>
  +            <line x1="8" x2="8" y1="20" y2="25" class="line" />
  +            <text x="16.5" y="24" class="saqLabel">S</text>
  +        </g>
  +
  +        <!-- Clip paths for the various color-rendering settings... -->
  +        <clipPath id="qualityClip">
  +            <rect x="-25" y="-20" width="17" height="40"/>
  +        </clipPath>
  +
  +        <clipPath id="defaultClip">
  +            <rect x="-8" y="-20" width="16" height="40"/>
  +        </clipPath>
  +
  +        <clipPath id="speedClip">
  +            <rect x="8" y="-20" width="17" height="40"/>
  +        </clipPath>
   
           <!-- ========================================== -->
           <!-- Two gradients, one with no values defined  -->
  @@ -102,7 +143,7 @@
               cx="0%" cy="0%" gradientTransform="translate(.5, .5)" />
   
           <radialGradient id="rgTxfC" xlink:href="#rgDefaults"
  -            cx="0%" cy="0%" gradientTransform="translate(.5, .5) scale(.25, 1.5)" />
  +            cx="0%" cy="0%" gradientTransform="translate(.5, .5) scale(1.5, .25)" />
   
           <radialGradient id="rgTxfD" xlink:href="#rgFxFyD"
               gradientTransform="scale(.5, .5)" />
  @@ -189,7 +230,7 @@
   
           <g transform="translate(0, 240)">
               <use xlink:href="#testShape" fill="url(#rgTxfC)" />
  -            <text y="-30">scale(.25,.5)</text>
  +            <text y="-30">scale(1.5,.25)</text>
           </g>
   
           <g transform="translate(0, 310)">
  
  
  
  1.1                  xml-batik/samples/tests/radialGradient3.svg
  
  Index: radialGradient3.svg
  ===================================================================
  <?xml version="1.0" standalone="no"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000802//EN"
  "http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd">
  
  <!-- ====================================================================== -->
  <!-- Copyright (C) The Apache Software Foundation. All rights reserved.     -->
  <!--                                                                        -->
  <!-- This software is published under the terms of the Apache Software      -->
  <!-- License version 1.1, a copy of which has been included with this       -->
  <!-- distribution in  the LICENSE file.                                     -->
  <!-- ====================================================================== -->
  
  <!-- ====================================================================== -->
  <!-- @author deweese@apache.org                                             -->
  <!-- @author vhardy@apache.org                                              -->
  <!-- @version $Id: radialGradient3.svg,v 1.1 2001/07/12 15:07:35 deweese Exp $ -->
  <!-- ====================================================================== -->
  <?xml-stylesheet type="text/css" href="test.css" ?>  
  
  <svg id="body" width="450" height="500" viewBox="0 0 450 500">
  
      <title>&lt;radialGradient&gt; Test 3 (Complex lookup)</title>
      <text class="title" x="50%" y="40">
          &lt;radialGradient&gt; Test 3 (Complex lookup)
      </text>
  
      <style type="text/css"><![CDATA[
          .speed   { clip-path:url(#speedClip); color-rendering:optimizeSpeed; }
          .default { clip-path:url(#defaultClip); color-rendering:auto; }
          .quality { clip-path:url(#qualityClip); 
                     color-rendering:optimizeQuality; }
          .saqLabel {  font-family: Verdana, Helvetica; 
                       font-size: 5;
                       text-anchor: middle; 
                       fill:black; stroke:none;}
          .line { fill:none; stroke:black; stroke-width:0.25; } 
      ]]></style>
  
      <defs>
          <!-- Shape filled by radial gradients -->
          <g id="testShape">
              <rect x="-25" y="-20" width="50" height="40" 
                    class="quality" />
              <rect x="-25" y="-20" width="50" height="40" 
                    class="default" />
              <rect x="-25" y="-20" width="50" height="40" 
                    class="speed" />
  
              <text x="-16.5" y="24" class="saqLabel">Q</text>
              <line x1="-8" x2="-8" y1="20" y2="25" class="line" />
              <text x="0" y="24" class="saqLabel">A</text>
              <line x1="8" x2="8" y1="20" y2="25" class="line" />
              <text x="16.5" y="24" class="saqLabel">S</text>
          </g>
  
          <!-- Clip paths for the various color-rendering settings... -->
          <clipPath id="qualityClip">
              <rect x="-25" y="-20" width="17" height="40"/>
          </clipPath>
  
          <clipPath id="defaultClip">
              <rect x="-8" y="-20" width="16" height="40"/>
          </clipPath>
  
          <clipPath id="speedClip">
              <rect x="8" y="-20" width="17" height="40"/>
          </clipPath>
  
  
          <!-- ========================================== -->
          <!-- Two gradients, one with no values defined  -->
          <!-- and one with the default values specified  -->
          <!-- They should create the same pattern        -->
          <!-- ========================================== -->
          <radialGradient id="rgDefaults">
              <stop offset=".0" stop-color="gold" />
              <stop offset=".49" stop-color="crimson" />
              <stop offset=".51" stop-color="gold" />
              <stop offset="1." stop-color="crimson" />
          </radialGradient>
  
          <radialGradient id="rgSpecifiedDefaults" 
                          gradientUnits="objectBoundingBox"
                          cx="50%" cy="50%"
                          r="50%"
                          fx="50%" fy="50%"
                          spreadMethod="pad" xlink:href="#rgDefaults" />
  
          <!-- ========================================== -->
          <!-- gradientUnits. The following gradients     -->
          <!-- is defined so as to produce the same       -->
          <!-- result as with the default settings        -->
          <!-- For example, cx default is 50% in object   -->
          <!-- bounding box, which is .5*50 = 25          -->
          <!-- r = sqrt(50*50 + 40*40) = 22.63846284534354156643452041746 -->
          <!-- ========================================== -->
          <radialGradient id="rgUserSpaceOnUse" 
              cx="0" cy="0" r="22.63846284534354156643452041746"
              fx="0" fy="0" xlink:href="#rdDefaults" />
  
          <radialGradient id="rgCxCyA" xlink:href="#rgDefaults"
              cx="0%" cy="100%">
          </radialGradient>
  
          <radialGradient id="rgCxCyB" xlink:href="#rgDefaults"
              cx="75%" cy="25%">
          </radialGradient>
  
          <radialGradient id="rgFxFyA" xlink:href="#rgCxCyA"
              fx="0%" fy="100%">
          </radialGradient>
  
          <radialGradient id="rgFxFyB" xlink:href="#rgDefaults"
              fx="60%" fy="40%">
          </radialGradient>
  
          <radialGradient id="rgFxFyC" xlink:href="#rgDefaults"
              fx="0%" fy="50%">
          </radialGradient>
  
          <radialGradient id="rgFxFyD" xlink:href="#rgDefaults"
              fx="0%" fy="0%">
          </radialGradient>
  
          <radialGradient id="rgSpreadA" xlink:href="#rgDefaults"
              r=".125">
          </radialGradient>
  
          <radialGradient id="rgSpreadB" xlink:href="#rgDefaults"
              r=".125" spreadMethod="reflect">
          </radialGradient>
  
          <radialGradient id="rgSpreadC" xlink:href="#rgDefaults"
              r=".125" spreadMethod="repeat">
          </radialGradient>
  
          <radialGradient id="rgTxfA" xlink:href="#rgDefaults"
              gradientTransform="translate(.5, .5)" />
  
          <radialGradient id="rgTxfB" xlink:href="#rgDefaults"
              cx="0%" cy="0%" gradientTransform="translate(.5, .5)" />
  
          <radialGradient id="rgTxfC" xlink:href="#rgDefaults"
              cx="0%" cy="0%" gradientTransform="translate(.5, .5) scale(1.5,.25)" />
  
          <radialGradient id="rgTxfD" xlink:href="#rgFxFyD"
              gradientTransform="scale(.5, .5)" />
      </defs>
  
      <g class="legend">
   
          <g transform="translate(70, 0)">
  
          <g transform="translate(0, 100)">
              <use xlink:href="#testShape" fill="url(#rgDefaults)" />
              <text y="-30">Defaults</text>
          </g>
  
          <g transform="translate(0, 170)">
              <use xlink:href="#testShape" fill="url(#rgSpecifiedDefaults)" />
              <text y="-30">Forced Defaults</text>
          </g>
  
          <g transform="translate(0, 240)">
              <use xlink:href="#testShape" fill="url(#rgSpecifiedDefaults)" />
              <text y="-30">userSpaceOnUse</text>
          </g>
  
          <g transform="translate(0, 310)">
              <use xlink:href="#testShape" fill="url(#rgCxCyA)" />
              <text y="-30">(cx,cy) = (0%, 100%)</text>
          </g>
  
          <g transform="translate(0, 380)">
              <use xlink:href="#testShape" fill="url(#rgCxCyB)" />
              <text y="-30">(cx,cy) = (75%, 25%)</text>
          </g>
  
          </g>
  
          <g transform="translate(200, 0)">
  
          <g transform="translate(0, 100)">
              <use xlink:href="#testShape" fill="url(#rgFxFyB)" />
              <text y="-30">(fx,fy)=(60%,40%)</text>
          </g>
  
          <g transform="translate(0, 170)">
              <use xlink:href="#testShape" fill="url(#rgFxFyC)" />
              <text y="-30">(fx,fy)=(0%,50%)</text>
          </g>
  
          <g transform="translate(0, 240)">
              <use xlink:href="#testShape" fill="url(#rgFxFyD)" />
              <text y="-30">(fx,fy)=(0%,0%)</text>
          </g>
  
          <g transform="translate(0, 310)">
              <use xlink:href="#testShape" fill="url(#rgSpreadA)" />
              <text y="-30">r=.125, spread=default</text>
          </g>
  
          <g transform="translate(0, 380)">
              <use xlink:href="#testShape" fill="url(#rgSpreadB)" />
              <text y="-30">r=.125, spread=reflect</text>
          </g>
  
          <g transform="translate(0, 450)">
              <use xlink:href="#testShape" fill="url(#rgSpreadC)" />
              <text y="-30">r=.125, spread=repeat</text>
          </g>
  
          </g>
  
  
          <g transform="translate(330, 0)">
  
          <g transform="translate(0, 100)">
              <use xlink:href="#testShape" fill="url(#rgTxfA)" />
              <text y="-30">translate(.5,.5)</text>
          </g>
  
          <g transform="translate(0, 170)">
              <use xlink:href="#testShape" fill="url(#rgTxfB)" />
              <text y="-30">(cx,cy)=(0%,0%) translate(.5,.5)</text>
          </g>
  
          <g transform="translate(0, 240)">
              <use xlink:href="#testShape" fill="url(#rgTxfC)" />
              <text y="-30">scale(1.5,.25)</text>
          </g>
  
          <g transform="translate(0, 310)">
              <use xlink:href="#testShape" fill="url(#rgTxfD)" />
              <text y="-30">(fx,fy)=(0,0) scale(.5, .5)</text>
          </g>
  
          <g transform="translate(0, 380)">
              <use xlink:href="#testShape" fill="url(#rgFxFyA)" />
              <text y="-30">(fx,fy)=(cx, cy)=(0%, 100%)</text>
          </g>
  
  
          </g>
  
      </g>
  </svg>
  
  
  1.27      +5 -4      xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java
  
  Index: CSSUtilities.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- CSSUtilities.java	2001/05/02 16:16:55	1.26
  +++ CSSUtilities.java	2001/07/12 15:07:40	1.27
  @@ -66,7 +66,7 @@
    * concrete objects regarding to CSS properties.
    *
    * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
  - * @version $Id: CSSUtilities.java,v 1.26 2001/05/02 16:16:55 tkormann Exp $
  + * @version $Id: CSSUtilities.java,v 1.27 2001/07/12 15:07:40 deweese Exp $
    */
   public abstract class CSSUtilities implements CSSConstants, ErrorConstants {
   
  @@ -326,15 +326,16 @@
           if (s.charAt(0) == 'a') { // auto
               return null;
           }
  +        // System.out.println("Str: " + s + "[8] = '" + s.charAt(8) + "'");
           Map hints = new HashMap();
  -        switch(v.getStringValue().charAt(9)) {
  -        case 'S': // optimizeSpeed
  +        switch(s.charAt(8)) {
  +        case 's': // optimizeSpeed
               hints.put(RenderingHints.KEY_COLOR_RENDERING,
                         RenderingHints.VALUE_COLOR_RENDER_SPEED);
               hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
                         RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
               break;
  -        case 'Q': // optimizeQuality
  +        case 'q': // optimizeQuality
               hints.put(RenderingHints.KEY_COLOR_RENDERING,
                         RenderingHints.VALUE_COLOR_RENDER_QUALITY);
               hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
  
  
  
  1.5       +1 -4      xml-batik/sources/org/apache/batik/ext/awt/LinearGradientPaintContext.java
  
  Index: LinearGradientPaintContext.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/LinearGradientPaintContext.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LinearGradientPaintContext.java	2001/02/03 16:26:05	1.4
  +++ LinearGradientPaintContext.java	2001/07/12 15:07:43	1.5
  @@ -18,7 +18,7 @@
    * 
    * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
    * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
  - * @version $Id: LinearGradientPaintContext.java,v 1.4 2001/02/03 16:26:05 deweese Exp $
  + * @version $Id: LinearGradientPaintContext.java,v 1.5 2001/07/12 15:07:43 deweese Exp $
    * @see java.awt.PaintContext
    * @see java.awt.Paint
    * @see java.awt.GradientPaint
  @@ -83,9 +83,6 @@
           super(cm, deviceBounds, userBounds, t, hints, fractions, 
                 colors, cycleMethod, colorSpace);
           
  -      	//call superclass method to calculate the gradients
  -        calculateGradientFractions();
  -
           // Use single precision floating points
           Point2D.Float start = new Point2D.Float((float)dStart.getX(),
                                                   (float)dStart.getY());
  
  
  
  1.8       +135 -172  xml-batik/sources/org/apache/batik/ext/awt/MultipleGradientPaintContext.java
  
  Index: MultipleGradientPaintContext.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/MultipleGradientPaintContext.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- MultipleGradientPaintContext.java	2001/07/11 12:23:57	1.7
  +++ MultipleGradientPaintContext.java	2001/07/12 15:07:45	1.8
  @@ -23,7 +23,7 @@
    *
    * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
    * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
  - * @version $Id: MultipleGradientPaintContext.java,v 1.7 2001/07/11 12:23:57 deweese Exp $
  + * @version $Id: MultipleGradientPaintContext.java,v 1.8 2001/07/12 15:07:45 deweese Exp $
    *
    */
   abstract class MultipleGradientPaintContext implements PaintContext {
  @@ -89,9 +89,14 @@
        */
       protected boolean isSimpleLookup = true;
   
  -    /** Size of gradients array for scaling the 0-1 index when looking up
  -     *  colors the fast way.
  +    /** This boolean indicates if the gradient appears to have sudden
  +     *  discontinuities in it, this may be because of multiple stops
  +     *  at the same location or use of the REPEATE mode.  
        */
  +    protected boolean hasDiscontinuity = false;
  +
  +    /** Size of gradients array for scaling the 0-1 index when looking up
  +     *  colors the fast way.  */
       protected int fastGradientArraySize;
   
       /**
  @@ -121,12 +126,6 @@
       /** fractions array */
       protected float[] fractions;
   
  -    /** Non-normalized intervals array */
  -    protected float[] intervals;
  -
  -    /** Gradient colors */
  -    private Color[] colors;
  -
       /** Used to determine if gradient colors are all opaque */
       private int transparencyTest;
   
  @@ -181,111 +180,60 @@
   
           boolean fixFirst = false;
           boolean fixLast = false;
  +        int len = fractions.length;
   
           //if the first gradient stop is not equal to zero, fix this condition
           if (fractions[0] != 0f) {
               fixFirst = true;
  +            len++;
           }
   
           //if the first gradient stop is not equal to one, fix this condition
           if (fractions[fractions.length - 1] != 1f) {
               fixLast = true;
  -        }
  -
  -        //copy the arrays, leaving room for the new first and last stops
  -        if (fixFirst && fixLast) {
  -            this.fractions = new float[fractions.length + 2];
  -            System.arraycopy(fractions, 0, this.fractions,
  -                             1, fractions.length);
  -            this.fractions[0] = 0f;
  -            this.fractions[this.fractions.length - 1] = 1f;
  -
  -            this.colors = new Color[colors.length + 2];
  -            System.arraycopy(colors, 0, this.colors,
  -                             1, colors.length);
  -
  -            this.colors[0] = colors[0];
  -            this.colors[this.colors.length - 1] = colors[colors.length - 1];
  +            len++;
           }
  -        //copy the arrays, shifting over to make room for the new first stops
  -        else if (fixFirst) {
  -            this.fractions = new float[fractions.length + 1];
  -            System.arraycopy(fractions, 0, this.fractions,
  -                             1, fractions.length);
  -            this.fractions[0] = 0f;
  -
  -            this.colors = new Color[colors.length + 1];
  -            System.arraycopy(colors, 0, this.colors,
  -                             1, colors.length);
  -            this.colors[0] = colors[0];
  -        }
  -        //copy the arrays, leaving room for the new last stops
  -        else if (fixLast) {
  -            this.fractions = new float[fractions.length + 1];
  -            System.arraycopy(fractions, 0, this.fractions,
  -                             0, fractions.length);
  -            this.fractions[this.fractions.length - 1] = 1f;
  -
  -            this.colors = new Color[colors.length + 1];
  -            System.arraycopy(colors, 0, this.colors,
  -                             0, colors.length);
  -            this.colors[this.colors.length - 1] = colors[colors.length - 1];
  -        }
  -        else { //don't fix anything, just copy the arrays.
  -            this.fractions = new float[fractions.length];
  -            System.arraycopy(fractions, 0, this.fractions,
  -                             0, fractions.length);
  -
  -            this.colors = new Color[colors.length];
  -            System.arraycopy(colors, 0, this.colors,
  -                             0, colors.length);
  -        }
  -
  -        //this will store the intervals (distances) between gradient stops
  -        intervals = new float[this.fractions.length - 1];
  -
  -        float currentPosition = this.fractions[0];
  -        float previousPosition = 0;
  -
  -        //convert from fractions into intervals, check that values are in
  -        //the proper range and progress in increasing order from 0 to 1
  -        for (int i = 1; i < this.fractions.length; i++) {
  -
  -            if (currentPosition < 0f || currentPosition > 1f) {
  -                throw new IllegalArgumentException("Keyframe values should " +
  -                                                   "be in the range 0 to 1: " +
  -                                                   currentPosition);
  -            }
  -
  -            previousPosition = currentPosition;
  -            currentPosition = this.fractions[i];
  -
  -            if (currentPosition < previousPosition) {
  -                throw
  -                    new IllegalArgumentException("Keyframe fractions must be" +
  -                                                 " increasing: " +
  -                                                 currentPosition);
  +        
  +        for (int i=0; i<fractions.length-1; i++)
  +            if (fractions[i] == fractions[i+1])
  +                len--;
  +
  +        this.fractions      = new float[len];
  +        Color [] loColors   = new Color[len-1];
  +        Color [] hiColors   = new Color[len-1];
  +        normalizedIntervals = new float[len-1];
  +
  +        int idx = 0;
  +        if (fixFirst) {
  +            this.fractions[0] = 0;
  +            loColors[0] = colors[0];
  +            hiColors[0] = colors[0];
  +            normalizedIntervals[0] = fractions[0];
  +            idx++;
  +        }
  +
  +        for (int i=0; i<fractions.length-1; i++) {
  +            if (fractions[i] == fractions[i+1]) {
  +                // System.out.println("EQ Fracts");
  +                if (!colors[i].equals(colors[i+1])) {
  +                    hasDiscontinuity = true;
  +                }
  +                continue;
               }
  -
  -            //interval distance is equal to the difference in positions
  -            intervals[i-1] = currentPosition - previousPosition;
  +            this.fractions[idx] = fractions[i];
  +            loColors[idx] = colors[i];
  +            hiColors[idx] = colors[i+1];
  +            normalizedIntervals[idx] = fractions[i+1]-fractions[i];
  +            idx++;
           }
  -
  -        //copy the non-normalized intervals array
  -        normalizedIntervals = new float[intervals.length];
  -        System.arraycopy(intervals, 0,
  -                         normalizedIntervals, 0,
  -                         intervals.length);
  -
  -        // Normalize intervals and check values are positive.
  -        float sum = 0;
  -
  -        for(int i = 0; i < intervals.length; i++) {
  -            sum += intervals[i];
  -        }
  +            
  +        this.fractions[idx] = fractions[fractions.length-1];
   
  -        for(int i = 0; i < normalizedIntervals.length; i++) {
  -            normalizedIntervals[i] /= sum;
  +        if (fixLast) {
  +            loColors[idx] = hiColors[idx] = colors[colors.length-1];
  +            normalizedIntervals[idx] = 1-fractions[fractions.length-1];
  +            idx++;
  +            this.fractions[idx] = 1;
           }
   
           // The inverse transform is needed to from device to user space.
  @@ -304,7 +252,6 @@
           this.cycleMethod = cycleMethod;
           this.colorSpace = colorSpace;
   
  -
           // Setup an example Model, we may refine it later.
           if (cm.getColorSpace() == lrgbmodel_A.getColorSpace())
               dataModel = lrgbmodel_A;
  @@ -314,6 +261,8 @@
               throw new IllegalArgumentException
                   ("Unsupported ColorSpace for interpolation");
   
  +        calculateGradientFractions(loColors, hiColors);
  +
           model = GraphicsUtil.coerceColorModel(dataModel,
                                                 cm.isAlphaPremultiplied());
       }
  @@ -323,15 +272,22 @@
        * gradient colors based on an array of fractions and color values at those
        * fractions.
        */
  -    protected final void calculateGradientFractions() {
  +    protected final void calculateGradientFractions
  +        (Color []loColors, Color []hiColors) {
   
           //if interpolation should occur in Linear RGB space, convert the
           //colors using the lookup table
           if (colorSpace == LinearGradientPaint.LINEAR_RGB) {
  -            for (int i = 0; i < colors.length; i++) {
  -                colors[i] = new Color(SRGBtoLinearRGB[colors[i].getRed()],
  -                                      SRGBtoLinearRGB[colors[i].getGreen()],
  -                                      SRGBtoLinearRGB[colors[i].getBlue()]);
  +            for (int i = 0; i < loColors.length; i++) {
  +                loColors[i] = 
  +                    new Color(SRGBtoLinearRGB[loColors[i].getRed()],
  +                              SRGBtoLinearRGB[loColors[i].getGreen()],
  +                              SRGBtoLinearRGB[loColors[i].getBlue()]);
  +                
  +                hiColors[i] = 
  +                    new Color(SRGBtoLinearRGB[hiColors[i].getRed()],
  +                              SRGBtoLinearRGB[hiColors[i].getGreen()],
  +                              SRGBtoLinearRGB[hiColors[i].getBlue()]);
               }
           }
   
  @@ -361,18 +317,27 @@
   
           if (Imin == 0) {
               estimatedSize = Integer.MAX_VALUE;
  +            hasDiscontinuity = true;
           } else {
               for (int i = 0; i < normalizedIntervals.length; i++) {
                   estimatedSize += (normalizedIntervals[i]/Imin) * GRADIENT_SIZE;
               }
           }
   
  +
           if (estimatedSize > MAX_GRADIENT_ARRAY_SIZE) {
               //slow method
  -            calculateMultipleArrayGradient();
  +            calculateMultipleArrayGradient(loColors, hiColors);
  +            if ((cycleMethod == MultipleGradientPaint.REPEAT) &&
  +                (gradients[0][0] != 
  +                 gradients[gradients.length-1][GRADIENT_SIZE_INDEX]))
  +                hasDiscontinuity = true;
           } else {
               //fast method
  -            calculateSingleArrayGradient(Imin);
  +            calculateSingleArrayGradient(loColors, hiColors, Imin);
  +            if ((cycleMethod == MultipleGradientPaint.REPEAT) &&
  +                (gradient[0] != gradient[fastGradientArraySize]))
  +                hasDiscontinuity = true;
           }
   
           // Use the most 'economical' model (no alpha).
  @@ -410,7 +375,8 @@
        * @param Imin the size of the smallest interval
        *
        */
  -    private void calculateSingleArrayGradient(float Imin) {
  +    private void calculateSingleArrayGradient
  +        (Color [] loColors, Color [] hiColors, float Imin) {
   
           //set the flag so we know later it is a non-simple lookup
           isSimpleLookup = true;
  @@ -436,8 +402,8 @@
               gradients[i] = new int[nGradients];
   
               //the the 2 colors (keyframes) to interpolate between
  -            rgb1 = colors[i].getRGB();
  -            rgb2 = colors[i+1].getRGB();
  +            rgb1 = loColors[i].getRGB();
  +            rgb2 = hiColors[i].getRGB();
   
               //fill this array with the colors in between rgb1 and rgb2
               interpolate(rgb1, rgb2, gradients[i]);
  @@ -468,7 +434,7 @@
                                curOffset, gradients[i].length);
               curOffset += gradients[i].length;
           }
  -        gradient[gradient.length-1] = colors[colors.length-1].getRGB();
  +        gradient[gradient.length-1] = hiColors[hiColors.length-1].getRGB();
   
           //if interpolation occurred in Linear RGB space, convert the
           //gradients back to SRGB using the lookup table
  @@ -513,7 +479,8 @@
        * time-space tradeoff.
        *
        */
  -    private void calculateMultipleArrayGradient() {
  +    private void calculateMultipleArrayGradient
  +        (Color [] loColors, Color [] hiColors) {
   
           //set the flag so we know later it is a non-simple lookup
           isSimpleLookup = false;
  @@ -530,12 +497,16 @@
           //for every interval (transition between 2 colors)
           for(int i=0; i < gradients.length; i++){
   
  +            // This interval will never actually be used (zero size)
  +            if (normalizedIntervals[i] == 0)
  +                continue;
  +
               //create an array of the maximum theoretical size for each interval
               gradients[i] = new int[GRADIENT_SIZE];
   
               //get the the 2 colors
  -            rgb1 = colors[i].getRGB();
  -            rgb2 = colors[i+1].getRGB();
  +            rgb1 = loColors[i].getRGB();
  +            rgb2 = hiColors[i].getRGB();
   
               //fill this array with the colors in between rgb1 and rgb2
               interpolate(rgb1, rgb2, gradients[i]);
  @@ -822,7 +793,6 @@
        * @returns ARGB integer color to display
        */
       protected final int indexGradientAntiAlias(float position, float sz) {
  -
           //first, manipulate position value depending on the cycle method.
           if (cycleMethod == MultipleGradientPaint.NO_CYCLE) {
               if (DEBUG) System.out.println("NO_CYCLE");
  @@ -1000,20 +970,15 @@
               int idx1 = (int)p1;
               int idx2 = (int)p2;
   
  -            // Simpliest case we just take the average value.
  -            // Note that this may not be correct in all cases,
  -            // but saves us always doing the summation between idx1 and idx2.
  -            if ((idx1 <= idx2) && p1_up && !p2_up)
  -                return gradient[(idx1+idx2)>>1];
  +            int i, pix;
   
  -            if (DEBUG) System.out.println( "P1: " + p1 + " " + p1_up +
  -                                           " P2: " + p2 + " " + p2_up);
  +            if (p1_up && !p2_up && (idx1 <= idx2)) {
   
  -            // Do the bulk of the work, all the whole gradient entries
  -            // for idx1 and idx2.
  -            int pix, norm;
  -            if (p1_up) {
  -                for (int i=idx1+1; i<fastGradientArraySize; i++) {
  +                if (idx1 == idx2)
  +                    return gradient[idx1];
  +
  +                // Sum between idx1 and idx2.
  +                for (i=idx1+1; i<idx2; i++) {
                       pix  = gradient[i];
                       ach += ((pix>>>20)&0xFF0);
                       rch += ((pix>>>12)&0xFF0);
  @@ -1021,55 +986,65 @@
                       bch += ((pix<<  4)&0xFF0);
                   }
               } else {
  -                for (int i=0; i<idx1; i++) {
  -                    pix  = gradient[i];
  -                    ach += ((pix>>>20)&0xFF0);
  -                    rch += ((pix>>>12)&0xFF0);
  -                    gch += ((pix>>> 4)&0xFF0);
  -                    bch += ((pix<<  4)&0xFF0);
  +                // Do the bulk of the work, all the whole gradient entries
  +                // for idx1 and idx2.
  +                if (p1_up) {
  +                    for (i=idx1+1; i<fastGradientArraySize; i++) {
  +                        pix  = gradient[i];
  +                        ach += ((pix>>>20)&0xFF0);
  +                        rch += ((pix>>>12)&0xFF0);
  +                        gch += ((pix>>> 4)&0xFF0);
  +                        bch += ((pix<<  4)&0xFF0);
  +                    }
  +                } else {
  +                    for (i=0; i<idx1; i++) {
  +                        pix  = gradient[i];
  +                        ach += ((pix>>>20)&0xFF0);
  +                        rch += ((pix>>>12)&0xFF0);
  +                        gch += ((pix>>> 4)&0xFF0);
  +                        bch += ((pix<<  4)&0xFF0);
  +                    }
                   }
  -            }
   
  -            if (p2_up) {
  -                for (int i=idx2+1; i<fastGradientArraySize; i++) {
  -                    pix  = gradient[i];
  -                    ach += ((pix>>>20)&0xFF0);
  -                    rch += ((pix>>>12)&0xFF0);
  -                    gch += ((pix>>> 4)&0xFF0);
  -                    bch += ((pix<<  4)&0xFF0);
  -                }
  -            } else {
  -                for (int i=0; i<idx2; i++) {
  -                    pix  = gradient[i];
  -                    ach += ((pix>>>20)&0xFF0);
  -                    rch += ((pix>>>12)&0xFF0);
  -                    gch += ((pix>>> 4)&0xFF0);
  -                    bch += ((pix<<  4)&0xFF0);
  +                if (p2_up) {
  +                    for (i=idx2+1; i<fastGradientArraySize; i++) {
  +                        pix  = gradient[i];
  +                        ach += ((pix>>>20)&0xFF0);
  +                        rch += ((pix>>>12)&0xFF0);
  +                        gch += ((pix>>> 4)&0xFF0);
  +                        bch += ((pix<<  4)&0xFF0);
  +                    }
  +                } else {
  +                    for (i=0; i<idx2; i++) {
  +                        pix  = gradient[i];
  +                        ach += ((pix>>>20)&0xFF0);
  +                        rch += ((pix>>>12)&0xFF0);
  +                        gch += ((pix>>> 4)&0xFF0);
  +                        bch += ((pix<<  4)&0xFF0);
  +                    }
                   }
               }
   
  +            int norm, isz;
  +
               // Normalize the summation so far...
  -            int isz = (int)((1<<16)/(sz*fastGradientArraySize));
  +            isz = (int)((1<<16)/(sz*fastGradientArraySize));
               ach = (ach*isz)>>16;
               rch = (rch*isz)>>16;
               gch = (gch*isz)>>16;
               bch = (bch*isz)>>16;
   
               // Clean up with the partial buckets at each end.
  -            if (p1_up) norm = (int)(((1-(p1-idx1))*(1<<16))
  -                                    /(sz*fastGradientArraySize));
  -            else       norm = (int)(((p1-idx1)*(1<<16))
  -                                    /(sz*fastGradientArraySize));
  +            if (p1_up) norm = (int)((1-(p1-idx1))*isz);
  +            else       norm = (int)(   (p1-idx1) *isz);
               pix = gradient[idx1];
               ach += (((pix>>>20)&0xFF0) *norm)>>16;
               rch += (((pix>>>12)&0xFF0) *norm)>>16;
               gch += (((pix>>> 4)&0xFF0) *norm)>>16;
               bch += (((pix<<  4)&0xFF0) *norm)>>16;
   
  -            if (p2_up) norm = (int)(((1-(p2-idx2))*(1<<16))
  -                                    /(sz*fastGradientArraySize));
  -            else       norm = (int)(((p2-idx2)*(1<<16))
  -                                    /(sz*fastGradientArraySize));
  +            if (p2_up) norm = (int)((1-(p2-idx2))*isz);
  +            else       norm = (int)(   (p2-idx2) *isz);
               pix = gradient[idx2];
               ach += (((pix>>>20)&0xFF0) *norm)>>16;
               rch += (((pix>>>12)&0xFF0) *norm)>>16;
  @@ -1262,18 +1237,6 @@
               gch = ((gch*iw)+aveG)>>16;
               bch = ((bch*iw)+aveB)>>16;
           }
  -        // If any high bits are set we are not in range.
  -              // If the highest bit is set then we are negative so
  -              // clamp to zero else we are > 255 so clamp to 255.
  -        if ((ach & 0xFFFFFF00) != 0)
  -            ach = ((ach & 0x80000000) != 0)?0:255;
  -        if ((rch & 0xFFFFFF00) != 0)
  -            rch = ((rch & 0x80000000) != 0)?0:255;
  -        if ((gch & 0xFFFFFF00) != 0)
  -            gch = ((gch & 0x80000000) != 0)?0:255;
  -        if ((bch & 0xFFFFFF00) != 0)
  -            bch = ((bch & 0x80000000) != 0)?0:255;
  -
                 
           return ((ach<<24) | (rch<<16) | (gch<<8) | bch);
       }
  
  
  
  1.2       +6 -14     xml-batik/sources/org/apache/batik/ext/awt/RadialGradientPaint.java
  
  Index: RadialGradientPaint.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/RadialGradientPaint.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RadialGradientPaint.java	2001/01/23 17:06:57	1.1
  +++ RadialGradientPaint.java	2001/07/12 15:07:47	1.2
  @@ -81,7 +81,7 @@
    *
    * @author  Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
    * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
  - * @version $Id: RadialGradientPaint.java,v 1.1 2001/01/23 17:06:57 tkormann Exp $
  + * @version $Id: RadialGradientPaint.java,v 1.2 2001/07/12 15:07:47 deweese Exp $
    *
    */
   
  @@ -444,19 +444,11 @@
           transform.concatenate(gradientTransform);
   
           try{
  -            return 
  -                new RadialGradientPaintContext(cm, 
  -                                               deviceBounds,
  -                                               userBounds, 
  -                                               transform,
  -                                               hints,
  -                                               (float)center.getX(), (float)center.getY(),
  -                                               radius,
  -                                               (float)focus.getX(), (float)focus.getY(),
  -                                               fractions,
  -                                               colors,
  -                                               cycleMethod, 
  -                                               colorSpace);       	    
  +            return new RadialGradientPaintContext
  +                (cm, deviceBounds, userBounds, transform, hints,
  +                 (float)center.getX(), (float)center.getY(), radius,
  +                 (float)focus.getX(), (float)focus.getY(),
  +                 fractions, colors, cycleMethod, colorSpace);       	    
           }
   	
           catch(NoninvertibleTransformException e){
  
  
  
  1.5       +210 -116  xml-batik/sources/org/apache/batik/ext/awt/RadialGradientPaintContext.java
  
  Index: RadialGradientPaintContext.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/RadialGradientPaintContext.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- RadialGradientPaintContext.java	2001/07/11 12:23:58	1.4
  +++ RadialGradientPaintContext.java	2001/07/12 15:07:48	1.5
  @@ -21,13 +21,11 @@
    *
    * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
    * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
  - * @version $Id: RadialGradientPaintContext.java,v 1.4 2001/07/11 12:23:58 deweese Exp $
  + * @version $Id: RadialGradientPaintContext.java,v 1.5 2001/07/12 15:07:48 deweese Exp $
    *
    */
   final class RadialGradientPaintContext extends MultipleGradientPaintContext {  
       
  -    private static final boolean USE_ANTI_ALIAS = false;
  -
       /** True when (focus == center)  */
       private boolean isSimpleFocus = false;
   
  @@ -50,6 +48,12 @@
        * trivial because it is easier to calculate than the general case.
        */
       private float trivial;       
  +
  +    private static final int FIXED_POINT_IMPL = 1;
  +    private static final int DEFAULT_IMPL     = 2;
  +    private static final int ANTI_ALIAS_IMPL  = 3;
  +
  +    private int fillMethod;
       
       /** Amount for offset when clamping focus. */
       private static final float SCALEBACK = .97f;
  @@ -119,9 +123,6 @@
           super(cm, deviceBounds, userBounds, t, hints, fractions, colors, 
                 cycleMethod, colorSpace);
   
  -        //call superclass method to calculate the gradients
  -        calculateGradientFractions();
  -	
           //copy some parameters.
           centerX = cx;
           centerY = cy;	
  @@ -160,8 +161,48 @@
           constA = a02 - centerX;
           constB = a12 - centerY;
   
  -        this.calculateFixedPointSqrtLookupTable();
  -    }   
  +        Object colorRend = hints.get(RenderingHints.KEY_COLOR_RENDERING);
  +        Object rend      = hints.get(RenderingHints.KEY_RENDERING);
  +
  +        fillMethod = 0;
  +
  +        if ((rend      == RenderingHints.VALUE_RENDER_QUALITY) ||
  +            (colorRend == RenderingHints.VALUE_COLOR_RENDER_QUALITY)) {
  +            // System.out.println("AAHints set: " + rend + ", " + colorRend);
  +            fillMethod = ANTI_ALIAS_IMPL;
  +        }
  +
  +        if ((rend      == RenderingHints.VALUE_RENDER_SPEED) ||
  +            (colorRend == RenderingHints.VALUE_COLOR_RENDER_SPEED)) {
  +            // System.out.println("SPHints set: " + rend + ", " + colorRend);
  +            fillMethod = DEFAULT_IMPL;
  +        }
  +
  +        // We are in the 'default' case, no hint or hint set to
  +        // DEFAULT values...
  +        if (fillMethod == 0) {
  +            // For now we will always use the 'default' impl if 
  +            // one is not specified.
  +            fillMethod = DEFAULT_IMPL;
  +
  +            if (false) {
  +                // This could be used for a 'smart' choice in
  +                // the default case, if the gradient has obvious
  +                // discontinuites use AA, otherwise default
  +                if (hasDiscontinuity) {
  +                    fillMethod = ANTI_ALIAS_IMPL;
  +                } else {
  +                    fillMethod = DEFAULT_IMPL;
  +                }
  +            }
  +        }
  +
  +        if ((fillMethod == DEFAULT_IMPL) &&
  +            (isSimpleFocus && isNonCyclic && isSimpleLookup)) {
  +            this.calculateFixedPointSqrtLookupTable();
  +            fillMethod = FIXED_POINT_IMPL;
  +        }
  +    }
       
       /**
        * Return a Raster containing the colors generated for the graphics
  @@ -171,16 +212,21 @@
        */
       protected void fillRaster(int pixels[], int off, int adjust,
                                 int x, int y, int w, int h) {
  -	
  -        if (isSimpleFocus && isNonCyclic && isSimpleLookup) {
  +        switch(fillMethod) {
  +        case FIXED_POINT_IMPL:
  +            // System.out.println("Calling FP");
               fixedPointSimplestCaseNonCyclicFillRaster(pixels, off, adjust, x, 
                                                         y, w, h);
  -        }      
  -	
  -        else {
  +            break;
  +        case ANTI_ALIAS_IMPL:
  +            // System.out.println("Calling AA");
  +            antiAliasFillRaster(pixels, off, adjust, x, y, w, h);
  +            break;
  +        case DEFAULT_IMPL:
  +        default:
  +            // System.out.println("Calling Default");
               cyclicCircularGradientFillRaster(pixels, off, adjust, x, y, w, h);
           }
  -	
       }    
       
       /**
  @@ -203,14 +249,15 @@
           final float deltaX = indexFactor * a00; //incremental change in dX
           final float deltaY = indexFactor * a10; //incremental change in dY
           float dX, dY; //the current distance from center
  -        int indexer = off;//used to index pixels array
  -        int i, j; //indexing variables
           final int fixedArraySizeSq=
               (fastGradientArraySize * fastGradientArraySize);
           float g, gDelta, gDeltaDelta, temp; //gradient square value
           int gIndex; // integer number used to index gradient array
           int iSqInt; // Square distance index       		   
   	
  +        int end, j; //indexing variables
  +        int indexer = off;//used to index pixels array
  +
           // For every point in the raster, calculate the color at that point
           for(j = 0; j < h; j++){ //for every row
               //x and y (in user space) of the first pixel of this row
  @@ -228,7 +275,7 @@
               gDeltaDelta = ((temp * 2));
   	    
               //for every column (inner loop begins here)
  -            for (i = 0; i < w; i++) {	       
  +            for (end = indexer+w; indexer < end; indexer++) {	       
                   //determine the distance to the center
   		
                   //since this is a non cyclic fill raster, crop at "1" and 0
  @@ -243,7 +290,7 @@
                   // }
   		
                   else {
  -                    iSq = (g / sqStepFloat);
  +                    iSq = (g * invSqStepFloat);
                       
                       iSqInt = (int)iSq; //chop off fractional part
                       iSq -= iSqInt;		    
  @@ -251,7 +298,7 @@
                                      ((1-iSq) * sqrtLutFixed[iSqInt]));
                   }
   		
  -                pixels[indexer++] = gradient[gIndex]; 
  +                pixels[indexer] = gradient[gIndex]; 
   				
                   //incremental calculation
                   g += gDelta;
  @@ -261,97 +308,12 @@
           }
       }
   
  -    /**
  -     * This code works in the simplest of cases, where the focus == center 
  -     * point, the gradient is noncyclic, and the gradient lookup method is 
  -     * fast (single array index, no conversion necessary).
  -     *
  -     */         
  -    private void fixedPointSimplestCaseNonCyclicFillRasterOriginal(int pixels[], 
  -                                                           int off,
  -                                                           int adjust, 
  -                                                           int x, int y, 
  -                                                           int w, int h) {
  -        // float g;//value between 0 and 1 specifying position in the gradient
  -        float iSq;  // Square distance index
  -        float p;  // Squrare root penetration in square root interval
  -        //this factor is used to scale the index calculation by the array size
  -        //and 1/radius (normalize the distance)
  -        float indexFactor = fastGradientArraySize / radius;      
  -        float factor = 16;  //2^16 factor for converting to/from floating point
  -	
  -        //constant part of X and Y coordinates for the entire raster
  -        float constX = (a00*x) + (a01*y) + constA;
  -        float constY = (a10*x) + (a11*y) + constB;
  -        float deltaX = indexFactor * a00; //incremental change in dX
  -        float deltaY = indexFactor * a10; //incremental change in dY
  -        float dX, dY; //the current distance from center
  -        int indexer = off;//used to index pixels array
  -        int i, j; //indexing variables
  -        int precalc = w+adjust;  //precalculate this number
  -        int fixedArraySizeSq=
  -            (fastGradientArraySize * fastGradientArraySize) << 4;
  -        int gFixed;//fixed point integer
  -        int gIndex;//non-fixed-pt integer number used to index gradient array
  -        int iSqInt; // Square distance index       		   
  -	
  -        // For every point in the raster, calculate the color at that point
  -        for(j = 0; j < h; j++){ //for every row
  -	    
  -            //constants from column to column
  -	    
  -            //x and y (in user space) of the first pixel of this row
  -            dX = indexFactor * ((a01*j) + constX);
  -            dY = indexFactor * ((a11*j) + constY);	   	   
  -
  -            // these values below here allow for an incremental calculation
  -            // of dX^2 + dY^2 
  -            int temp = (int)((deltaX * deltaX) + (deltaY * deltaY));
  -            //initialize to be equal to distance squared
  -            gFixed = (int)(((dY * dY) + (dX * dX)) * factor);
  -            int gFixeddelta =  (int)(((((deltaY * dY) + (deltaX * dX))* 2) + 
  -                                      temp) * factor);	 
  -            int gFixeddeltadelta =(int)((temp * 2) * factor);
  -	    
  -            //for every column (inner loop begins here)
  -            for (i = 0; i < w; i++) {	       
  -                //determine the distance to the center
  -		
  -                //since this is a non cyclic fill raster, crop at "1" and 0
  -                if (gFixed > fixedArraySizeSq) {
  -                    gIndex = fastGradientArraySize;
  -                }
  -		
  -                else if (gFixed < 0) {
  -                    gIndex = 0;		    
  -                }
  -		
  -                else {
  -                    iSq = (gFixed >>> 4) / sqStepFloat;
  -		    		  
  -                    iSqInt = (int)iSq; //chop off fractional part
  -		    
  -                    p = iSq - iSqInt;		    
  -                    gIndex = (int)((p * sqrtLutFixed[iSqInt + 1]) + 
  -                                   ((1-p) * sqrtLutFixed[iSqInt]));
  -                }
  -		
  -                pixels[indexer + i] = gradient[gIndex]; 
  -				
  -                //incremental calculation
  -                gFixed += gFixeddelta;
  -                gFixeddelta += gFixeddeltadelta;		
  -            }	  
  -            indexer += precalc;
  -        }
  -    }
  +    /** Length of a square distance intervale in the lookup table */
  +    private float invSqStepFloat; 
       
       /** Used to limit the size of the square root lookup table */
       private int MAX_PRECISION = 256;
       
  -    /** Length of a square distance intervale in the lookup table */
  -    private float sqStepFloat; 
  -    
       /** Square root lookup table */
       private int sqrtLutFixed[] = new int[MAX_PRECISION];
       
  @@ -359,8 +321,9 @@
        * Build square root lookup table
        */       
       private void calculateFixedPointSqrtLookupTable() {	      
  -        sqStepFloat = (fastGradientArraySize  * fastGradientArraySize) 
  -            / (MAX_PRECISION - 2);
  +        float sqStepFloat;
  +        sqStepFloat = ((fastGradientArraySize  * fastGradientArraySize) 
  +                       / (MAX_PRECISION - 2));
   	
           // The last two values are the same so that linear square root 
           // interpolation can happen on the maximum reachable element in the 
  @@ -370,6 +333,7 @@
               sqrtLutFixed[i] = (int)(Math.sqrt(i*sqStepFloat));
           }
           sqrtLutFixed[i] = sqrtLutFixed[i-1];	
  +        invSqStepFloat = 1/sqStepFloat;
       }
       
       /** Fill the raster, cycling the gradient colors when a point falls outside
  @@ -421,8 +385,6 @@
           int i, j; //indexing variables for FOR loops
           int pixInc = w+adjust;//incremental index change for pixels array
   
  -        float delta, pixSzSq = (float)(a00*a00+a01*a01+a10*a10+a11*a11);
  -	
           for (j = 0; j < h; j++) { //for every row
   	    
               X = (a01*j) + constX; //constants from column to column
  @@ -495,17 +457,149 @@
                   g = (float)Math.sqrt(currentToFocusSq / intersectToFocusSq);
   
                   //Get the color at this point
  -                if (USE_ANTI_ALIAS) {
  -                    delta = (float)Math.sqrt(pixSzSq/intersectToFocusSq);
  -                    pixels[indexer + i] = indexGradientAntiAlias(g, delta);
  -                } else {
  -                    pixels[indexer + i] = indexIntoGradientsArrays(g);
  -                }
  +                pixels[indexer + i] = indexIntoGradientsArrays(g);
   		
                   X += a00; //incremental change in X, Y
                   Y += a10;	
               } //end inner loop
               indexer += pixInc;
  +        } //end outer loop
  +    }
  +
  +
  +    /** Fill the raster, cycling the gradient colors when a point
  +     *  falls outside of the perimeter of the 100% stop circle. Use
  +     *  the anti-aliased gradient lookup.
  +     *
  +     *  This calculation first computes the intersection point of the line
  +     *  from the focus through the current point in the raster, and the
  +     *  perimeter of the gradient circle.
  +     * 
  +     *  Then it determines the percentage distance of the current point along
  +     *  that line (focus is 0%, perimeter is 100%). 
  +     *
  +     *  Equation of a circle centered at (a,b) with radius r:
  +     *  (x-a)^2 + (y-b)^2 = r^2
  +     *  Equation of a line with slope m and y-intercept b
  +     *  y = mx + b
  +     *  replacing y in the cirlce equation and solving using the quadratic
  +     *  formula produces the following set of equations.  Constant factors have
  +     *  been extracted out of the inner loop.
  +     * */
  +    private void antiAliasFillRaster(int pixels[], int off, 
  +                                     int adjust, 
  +                                     int x, int y, 
  +                                     int w, int h) {
  +        // Constant part of the C factor of the quadratic equation
  +        final double constC = 
  +            -(radiusSq) + (centerX * centerX) + (centerY * centerY);
  +        //coefficients of the quadratic equation (Ax^2 + Bx + C = 0)
  +        double A, B, C; 
  +        double slope; //slope of the focus-perimeter line
  +        double yintcpt; //y-intercept of the focus-perimeter line
  +        double solutionX;//intersection with circle X coordinate
  +        double solutionY;//intersection with circle Y coordinate       
  +       	final float constX = (a00*x) + (a01*y) + a02;//const part of X coord
  +        final float constY = (a10*x) + (a11*y) + a12; //const part of Y coord
  +       	final float precalc2 = 2 * centerY;//const in inner loop quad. formula
  +        final float precalc3 =-2 * centerX;//const in inner loop quad. formula
  +        float det; //determinant of quadratic formula (should always be >0)
  +
  +        float X; // User space point X coordinate 
  +        float Y; // User space point Y coordinate
  +        float g;//value specifying position in the gradient
  +        float delta; // range around g to average for anti-aliasing
  +
  +        float currentToFocusSq;//sq distance from the current pt. to focus
  +        float intersectToFocusSq;//sq distance from the intersect pt. to focus
  +        float deltaXSq; //temp variable for a change in X squared.
  +        float deltaYSq; //temp variable for a change in Y squared.
  +
  +        int j, end; //indexing variables for FOR loops
  +        int indexer = off; //index variable for pixels array
  +
  +        // Size of a pixel in user space.
  +        float pixSzSq = (float)(a00*a00+a01*a01+a10*a10+a11*a11);
  +	
  +        for (j = 0; j < h; j++) { //for every row
  +	    
  +            X = (a01*j) + constX; //constants from column to column
  +            Y = (a11*j) + constY;
  +	    
  +            //for every column (inner loop begins here)
  +            for (end = indexer + w; indexer < end; indexer++) {
  +	
  +                // special case to avoid divide by zero or very near zero
  +                if (((X-focusX)>-0.000001) &&
  +                    ((X-focusX)< 0.000001)) {		   
  +                    solutionX = focusX;
  +		    
  +                    solutionY = centerY;
  +		    
  +                    solutionY += (Y > focusY)?trivial:-trivial;
  +                }
  +		
  +                else {    
  +		    
  +                    //slope of the focus-current line
  +                    slope =   (Y - focusY) / (X - focusX);
  +		    
  +                    yintcpt = Y - (slope * X); //y-intercept of that same line
  +		    
  +                    //use the quadratic formula to calculate the intersection
  +                    //point		  
  +                    A = (slope * slope) + 1; 
  +		    
  +                    B =  precalc3 + (-2 * slope * (centerY - yintcpt));
  +		    
  +                    C =  constC + (yintcpt* (yintcpt - precalc2));
  +		    
  +                    det = (float)Math.sqrt((B * B) - ( 4 * A * C));
  +		    
  +                    solutionX = -B;
  +		    
  +                    //choose the positive or negative root depending
  +                    //on where the X coord lies with respect to the focus.
  +                    solutionX += (X < focusX)?-det:det;
  +		    
  +                    solutionX = solutionX / (2 * A);//divisor
  +		    
  +                    solutionY = (slope * solutionX) + yintcpt;
  +                }	                    	
  +
  +                //calculate the square of the distance from the current point 
  +                //to the focus and the square of the distance from the 
  +                //intersection point to the focus. Want the squares so we can
  +                //do 1 square root after division instead of 2 before.
  +
  +                deltaXSq = (float)solutionX - focusX;
  +                deltaXSq = deltaXSq * deltaXSq;
  +
  +                deltaYSq = (float)solutionY - focusY;
  +                deltaYSq = deltaYSq * deltaYSq;
  +
  +                intersectToFocusSq = deltaXSq + deltaYSq;
  +
  +                deltaXSq = X - focusX;
  +                deltaXSq = deltaXSq * deltaXSq;
  +
  +                deltaYSq = Y - focusY;
  +                deltaYSq = deltaYSq * deltaYSq;
  +
  +                currentToFocusSq = deltaXSq + deltaYSq;
  +
  +                //want the percentage (0-1) of the current point along the 
  +                //focus-circumference line
  +                g = (float)Math.sqrt(currentToFocusSq / intersectToFocusSq);
  +
  +                //Get the color at this point
  +                delta = (float)Math.sqrt(pixSzSq/intersectToFocusSq);
  +                pixels[indexer] = indexGradientAntiAlias(g, delta);
  +		
  +                X += a00; //incremental change in X, Y
  +                Y += a10;	
  +            } //end inner loop
  +            indexer += adjust;
           } //end outer loop
       }
       
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org