I implemented the Swing gradient painting on top of the Graphics2D
gradient functions.

2006-06-21  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/plaf/metal/MetalUtils.java
        (paintHorizontalGradient): Use paintHorizontalGradient2D when
        Graphics2D is available. Use fillRect instead of drawLine, this
        is much faster.
        (paintVerticalGradient): Use paintHorizontalGradient2D when
        Graphics2D is available. Use fillRect instead of drawLine, this
        is much faster.
        (paintHorizontalGradient2D): New method. Paints gradient
        using Graphics2D functions.
        (paintVerticalGradient2D): New method. Paints gradient
        using Graphics2D functions.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/plaf/metal/MetalUtils.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalUtils.java,v
retrieving revision 1.13
diff -u -1 -0 -r1.13 MetalUtils.java
--- javax/swing/plaf/metal/MetalUtils.java	11 May 2006 17:05:55 -0000	1.13
+++ javax/swing/plaf/metal/MetalUtils.java	21 Jun 2006 13:21:44 -0000
@@ -34,20 +34,21 @@
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 package javax.swing.plaf.metal;
 
 import gnu.classpath.SystemProperties;
 
 import java.awt.Color;
 import java.awt.Component;
+import java.awt.GradientPaint;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.TexturePaint;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.util.List;
 
 import javax.swing.SwingConstants;
 import javax.swing.UIManager;
 
@@ -298,20 +299,29 @@
    * @param c1 the color 1
    * @param c2 the color 2
    * @param c3 the color 3
    * @param mask the mask that should be used when painting the gradient as
    *        described above
    */
   static void paintHorizontalGradient(Graphics g, int x, int y, int w, int h,
                                       float g1, float g2, Color c1, Color c2,
                                       Color c3, int[][] mask)
   {
+    
+    if (g instanceof Graphics2D
+        && SystemProperties.getProperty("gnu.javax.swing.noGraphics2D") == null)
+      {
+        paintHorizontalGradient2D((Graphics2D) g, x, y, w, h, g1, g2, c1, c2,
+                                  c3, mask);
+        return;
+      }
+
     // Calculate the coordinates.
     int y0 = y;
     int y1 = y + h;
     // The size of the first gradient area (c1->2).
     int w1 = (int) (w * g1);
     // The size of the solid c2 area.
     int w2 = (int) (w * g2);
     int x0 = x;
     int x1 = x0 + w1;
     int x2 = x1 + w2;
@@ -332,35 +342,35 @@
             + c1.getGreen());
         int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor
             + c1.getBlue());
         Color interpolated = new Color(rInt, gInt, bInt);
         g.setColor(interpolated);
         if (mask != null)
           {
             y0 = mask[xc - x0][0] + y;
             y1 = mask[xc - x0][1] + y;
           }
-        g.drawLine(xc, y0, xc, y1);
+        g.fillRect(xc, y0, 1, y1 - y0);
       }
     // Paint solid c2 area.
     g.setColor(c2);
     if (mask == null)
       {
         g.fillRect(x1, y, x2 - x1, h);
       }
     else
       {
         for (xc = x1; xc < x2; xc++)
           {
             y0 = mask[xc - x0][0] + y;
             y1 = mask[xc - x0][1] + y;
-            g.drawLine(xc, y0, xc, y1);
+            g.fillRect(xc, y0, 1, y1 - y0);
           }
       }
 
     // Paint second gradient area (c2->c1).
     for (xc = x2; xc < x3; xc++)
       {
         if (xc > x + w)
           break;
 
         // Perform color interpolation;
@@ -370,21 +380,21 @@
             + c2.getGreen());
         int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor
             + c2.getBlue());
         Color interpolated = new Color(rInt, gInt, bInt);
         g.setColor(interpolated);
         if (mask != null)
           {
             y0 = mask[xc - x0][0] + y;
             y1 = mask[xc - x0][1] + y;
           }
-        g.drawLine(xc, y0, xc, y1);
+        g.fillRect(xc, y0, 1, y1 - y0);
       }
 
     // Paint third gradient area (c1->c3).
     for (xc = x3; xc < x4; xc++)
       {
         if (xc > x + w)
           break;
 
         // Perform color interpolation;
         double factor = (xc - x3) / (double) (x4 - x3);
@@ -414,23 +424,31 @@
    * @param h the height of the rectangle
    * @param g1 the relative width of the c1->c2 gradients
    * @param g2 the relative width of the c2 solid area
    * @param c1 the color 1
    * @param c2 the color 2
    * @param c3 the color 3
    * @param mask the mask that should be used when painting the gradient as
    *        described above
    */
   static void paintVerticalGradient(Graphics g, int x, int y, int w, int h,
-                                    double g1, double g2, Color c1, Color c2,
+                                    float g1, float g2, Color c1, Color c2,
                                     Color c3, int[][] mask)
   {
+    if (g instanceof Graphics2D
+        && SystemProperties.getProperty("gnu.javax.swing.noGraphics2D") == null)
+       {
+         paintVerticalGradient2D((Graphics2D) g, x, y, w, h, g1, g2, c1, c2,
+                                   c3, mask);
+         return;
+       }
+
     // Calculate the coordinates.
     int x0 = x;
     int x1 = x + w;
     // The size of the first gradient area (c1->2).
     int w1 = (int) (h * g1);
     // The size of the solid c2 area.
     int w2 = (int) (h * g2);
     int y0 = y;
     int y1 = y0 + w1;
     int y2 = y1 + w2;
@@ -451,35 +469,35 @@
             + c1.getGreen());
         int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor
             + c1.getBlue());
         Color interpolated = new Color(rInt, gInt, bInt);
         g.setColor(interpolated);
         if (mask != null)
           {
             x0 = mask[yc - y0][0] + x;
             x1 = mask[yc - y0][1] + x;
           }
-        g.drawLine(x0, yc, x1, yc);
+        g.fillRect(x0, yc, x1 - x0, 1);
       }
     // Paint solid c2 area.
     g.setColor(c2);
     if (mask == null)
       {
         g.fillRect(x, y1, w, y2 - y1);
       }
     else
       {
         for (yc = y1; yc < y2; yc++)
           {
             x0 = mask[yc - y0][0] + x;
             x1 = mask[yc - y0][1] + x;
-            g.drawLine(x0, yc, x1, yc);
+            g.fillRect(x0, yc, x1 - x0, 1);
           }
       }
 
     // Paint second gradient area (c2->c1).
     for (yc = y2; yc < y3; yc++)
       {
         if (yc > y + h)
           break;
 
         // Perform color interpolation;
@@ -489,21 +507,21 @@
             + c2.getGreen());
         int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor
             + c2.getBlue());
         Color interpolated = new Color(rInt, gInt, bInt);
         g.setColor(interpolated);
         if (mask != null)
           {
             x0 = mask[yc - y0][0] + x;
             x1 = mask[yc - y0][1] + x;
           }
-        g.drawLine(x0, yc, x1, yc);
+        g.fillRect(x0, yc, x1 - x0, 1);
       }
 
     // Paint third gradient area (c1->c3).
     for (yc = y3; yc < y4; yc++)
       {
         if (yc > y + h)
           break;
 
         // Perform color interpolation;
         double factor = (yc - y3) / (double) (y4 - y3);
@@ -512,14 +530,68 @@
             + c1.getGreen());
         int bInt = (int) ((c3.getBlue() - c1.getBlue()) * factor
             + c1.getBlue());
         Color interpolated = new Color(rInt, gInt, bInt);
         g.setColor(interpolated);
         if (mask != null)
           {
             x0 = mask[yc - y0][0] + x;
             x1 = mask[yc - y0][1] + x;
           }
-        g.drawLine(x0, yc, x1, yc);
+        g.fillRect(x0, yc, x1 - x0, 1);
       }
   }
+
+  /**
+   * Paints a horizontal gradient using Graphics2D functionality.
+   *
+   * @param g the Graphics2D instance
+   * @param x the X coordinate of the upper left corner of the rectangle
+   * @param y the Y coordinate of the upper left corner of the rectangle
+   * @param w the width of the rectangle
+   * @param h the height of the rectangle
+   * @param g1 the relative width of the c1->c2 gradients
+   * @param g2 the relative width of the c2 solid area
+   * @param c1 the color 1
+   * @param c2 the color 2
+   * @param c3 the color 3
+   * @param mask the mask that should be used when painting the gradient as
+   *        described above
+   */
+  private static void paintHorizontalGradient2D(Graphics2D g, int x, int y,
+                                                int w, int h, float g1,
+                                                float g2, Color c1,
+                                                Color c2, Color c3,
+                                                int[][] mask)
+  {
+    // FIXME: Handle the mask somehow, or do Graphics2D clipping instead.
+    GradientPaint p1 = new GradientPaint(x, y, c1, x + w * g1, y, c2);
+    g.setPaint(p1);
+    // This fills the first gradient and the solid area in one go.
+    g.fillRect(x, y, (int) (w * (g1 + g2)), h);
+
+    GradientPaint p2 = new GradientPaint(x + (w * (g1 + g2)), y, c2, x + w, y,
+                                         c3);
+    g.setPaint(p2);
+    g.fillRect((int) (x + (w * (g1 + g2))), y,
+               (int) (w * (1. - (g1 + g2))), h);
+  }
+
+  private static void paintVerticalGradient2D(Graphics2D g, int x, int y,
+                                              int w, int h, float g1,
+                                              float g2, Color c1,
+                                              Color c2, Color c3,
+                                              int[][] mask)
+  {
+    // FIXME: Handle the mask somehow, or do Graphics2D clipping instead.
+    GradientPaint p1 = new GradientPaint(x, y, c1, x, y + h * g1, c2);
+    g.setPaint(p1);
+    // This fills the first gradient and the solid area in one go.
+    g.fillRect(x, y, w, (int) (h * (g1 + g2)));
+
+    GradientPaint p2 = new GradientPaint(x, y + (h * (g1 + g2)), c2, x, y + h,
+                                         c3);
+    g.setPaint(p2);
+    g.fillRect(x, (int) (y + (h * (g1 + g2))), w,
+               (int) (h * (1. - (g1 + g2))));
+  }
 }

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

Reply via email to