This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[fyi] commit of classpath issue 2259, BitwiseXORComposite


hi,

I've just committed this cleaned-up version of sascha brawer's patch
to move BitwiseXORComposite to a separate class. see:

[patch #2259] Switch to gnu.java.awt.BitwiseXORComposite
http://savannah.gnu.org/patch/?func=detailitem&item_id=2259

this commit also included a couple 1-liners to GdkGraphics2D
which have accumulated in my local tree during recent development.

-graydon


2004-01-12 Graydon Hoare <graydon@redhat.com>


	* gnu/java/awt/gtk/GdkGraphics2D.java
	(static): Check GtkToolkit before initializing static state.
	(Graphics2D): Don't construct transform with 0.5 unit offset.

2003-11-06 Sascha Brawer <brawer@dandelis.ch>

	* gnu/java/awt/BitwiseXORComposite.java: Add.
	* gnu/java/awt/peer/gtk/GdkGraphics2D.java
	(setXORMode): Switch to gnu.java.awt.BitwiseXORComposite.
	(BitwiseXORComposite): Remove inner class.


--- gnu/java/awt/peer/gtk/GdkGraphics2D.java	20 Nov 2003 22:44:01 -0000	1.3
+++ gnu/java/awt/peer/gtk/GdkGraphics2D.java	12 Jan 2004 19:00:08 -0000
@@ -66,6 +66,8 @@
       {
         System.loadLibrary("gtkpeer");
       }
+
+    if (GtkToolkit.useGraphics2D ())
     initStaticState ();
   }
   native static void initStaticState ();
@@ -125,7 +127,7 @@
       clip = new Rectangle (g.getClipBounds ());
 
     if (g.transform == null)
-      transform = AffineTransform.getTranslateInstance (0.5, 0.5);
+      transform = new AffineTransform ();
     else
       transform = new AffineTransform (g.transform);
 
@@ -150,7 +152,7 @@
     setBackground (Color.black);
     setPaint (getColor());
     setFont (new Font("SansSerif", Font.PLAIN, 12));
-    setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
+    setTransform (new AffineTransform ());
     setStroke (new BasicStroke ());
 
     stateStack = new Stack();
@@ -165,7 +167,7 @@
     setBackground (new Color (rgb[3], rgb[4], rgb[5]));
     setPaint (getColor());
     setFont (new Font("SansSerif", Font.PLAIN, 12));
-    setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
+    setTransform (new AffineTransform ());
     setStroke (new BasicStroke ());
 
     stateStack = new Stack ();
@@ -546,7 +548,7 @@
 
   public void setXORMode (Color c) 
   { 
-    setComposite (new BitwiseXorComposite (c)); 
+    setComposite (new gnu.java.awt.BitwiseXORComposite(c)); 
   }
 
   public void setColor (Color c)
@@ -977,76 +979,6 @@
     }
   }
 
-
-  private class BitwiseXorComposite implements Composite
-  {
-    // this is a special class which does a bitwise XOR composite, for
-    // backwards compatibility sake. it does *not* implement the
-    // porter-duff XOR operator.  the porter-duff XOR is unrelated to
-    // bitwise XOR; it just happens to have a similar name but it
-    // represents a desire to composite the exclusive or of overlapping
-    // subpixel regions. bitwise XOR is for drawing "highlights" such as
-    // cursors (in a cheap oldskool bitblit fashion) by inverting colors
-    // temporarily and then inverting them back.
-
-    Color xorColor;
-    
-    class BitwiseXorCompositeContext implements CompositeContext
-    {
-      ColorModel srcColorModel;
-      ColorModel dstColorModel;
-      
-      public BitwiseXorCompositeContext (ColorModel s,
-                                         ColorModel d)
-      {
-        srcColorModel = s;
-        dstColorModel = d;
-      }
-
-      public void dispose () 
-      {
-      }
-
-      public void compose (Raster src,
-                           Raster dstIn,
-                           WritableRaster dstOut)
-      {
-        Rectangle srcRect = src.getBounds ();
-        Rectangle dstInRect = dstIn.getBounds ();
-        Rectangle dstOutRect = dstOut.getBounds ();
-        
-        int xp = xorColor.getRGB ();
-        int x = 0, y = 0;
-        int w = Math.min (Math.min (srcRect.width, dstOutRect.width), dstInRect.width);
-        int h = Math.min (Math.min (srcRect.height, dstOutRect.height), dstInRect.height);
-        Object srcPix = null, dstPix = null;
-
-        for (y = 0; y < h; y++)
-          for (x = 0; x < w; x++)
-            {
-              srcPix = src.getDataElements (x + srcRect.x, y + srcRect.y, srcPix);
-              dstPix = dstIn.getDataElements (x + dstInRect.x, y + dstInRect.y, dstPix);
-              int sp = srcColorModel.getRGB (srcPix);
-              int dp = dstColorModel.getRGB (dstPix);
-              int rp = sp ^ xp ^ dp;
-              dstOut.setDataElements (x + dstOutRect.x, y + dstOutRect.y, 
-                                      dstColorModel.getDataElements (rp, null));
-            }
-      }
-    }
-    
-    public BitwiseXorComposite (Color c)
-    {
-      xorColor = c;
-    }
-    
-    public CompositeContext createContext (ColorModel srcColorModel, 
-                                           ColorModel dstColorModel, 
-                                           RenderingHints hints) 
-    {
-      return new BitwiseXorCompositeContext (srcColorModel, dstColorModel);
-    }
-  }  
 
 
   ///////////////////////////////////////////////
--- gnu/java/awt/BitwiseXORComposite.java	2004-01-12 12:18:50.000000000 -0500
+++ gnu/java/awt/BitwiseXORComposite.java	2004-01-12 12:18:50.000000000 -0500
@@ -0,0 +1,296 @@
+/* BitwiseXORComposite.java -- Composite for emulating old-style XOR.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+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 gnu.java.awt;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+
+/**
+ * A composite for emulating traditional bitwise XOR of pixel values.
+ * Please note that this composite does <i>not</i> implement the Porter-Duff
+ * XOR operator, but an exclusive or of overlapping subpixel regions.
+ *
+ * <p><img src="doc-files/BitwiseXORComposite-1.png" width="545"
+ * height="138" alt="A screen shot of BitwiseXORComposite in action"
+ * />
+ *
+ * <p>The above screen shot shows the result of applying six different
+ * BitwiseXORComposites. They were constructed with the colors colors
+ * white, blue, black, orange, green, and brown, respectively. Each
+ * composite was used to paint a fully white rectangle on top of the
+ * blue bar in the background.
+ * 
+ * <p>The purpose of this composite is to support the {@link
+ * Graphics#setXORMode(Color)} method in composite-aware graphics
+ * implementations. Applications typically would use
+ * <code>setXORMode</code> for drawing &#x201c;highlights&#x201d; such
+ * as text selections or cursors by inverting colors temporarily and
+ * then inverting them back.
+ *
+ * <p>A concrete <code>Graphics</code> implementation may contain
+ * the following code:
+ *
+ * <p><pre> public void setXORMode(Color xorColor)
+ * {
+ *   setComposite(new gnu.java.awt.BitwiseXORComposite(xorColor));
+ * }
+ *
+ * public void setPaintMode()
+ * {
+ *   setComposite(java.awt.AlphaComposite.SrcOver);
+ * }</pre>
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public class BitwiseXORComposite
+  implements Composite
+{
+  /**
+   * The color whose RGB value is xor-ed with the values of each
+   * pixel.
+   */
+  protected Color xorColor;
+
+  
+  /**
+   * Constructs a new composite for xor-ing the pixel value.
+   *
+   * @param xorColor the color whose pixel value will be bitwise
+   * xor-ed with the source and destination pixels.
+   */
+  public BitwiseXORComposite(Color xorColor)
+  {
+    this.xorColor = xorColor;
+  }
+
+
+  /**
+   * Creates a context object for performing the compositing
+   * operation. Several contexts may co-exist for one composite; each
+   * context may simultaneously be called from concurrent threads.
+   *
+   * @param srcColorModel the color model of the source.
+   * @param dstColorModel the color model of the destination.
+   * @param hints hints for choosing between rendering alternatives.
+   */
+  public CompositeContext createContext(ColorModel srcColorModel,
+                                        ColorModel dstColorModel,
+                                        RenderingHints hints)
+  {
+    if (IntContext.isSupported(srcColorModel, dstColorModel, hints))
+      return new IntContext(srcColorModel, xorColor);
+
+    return new GeneralContext(srcColorModel, dstColorModel, xorColor);
+  }
+
+  
+  /**
+   * A fallback CompositeContext that performs bitwise XOR of pixel
+   * values with the pixel value of the specified <code>xorColor</code>.
+   *
+   * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of
+   * <code>TYPE_INT_RGB</code> took 611 ms on a lightly loaded 2.4 GHz
+   * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux
+   * 2.4.20. The timing is the average of ten runs on the same
+   * BufferedImage. Since the measurements were taken with {@link
+   * System#currentTimeMillis()}, they are rather inaccurate.
+   *
+   * @author Graydon Hoare (graydon@redhat.com)
+   */
+  private static class GeneralContext
+    implements CompositeContext
+  {
+    ColorModel srcColorModel;
+    ColorModel dstColorModel;
+    Color xorColor;
+
+    public GeneralContext(ColorModel srcColorModel,
+                          ColorModel dstColorModel,
+                          Color xorColor)
+    {
+      this.srcColorModel = srcColorModel;
+      this.dstColorModel = dstColorModel;
+      this.xorColor = xorColor;
+    }
+
+
+    public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
+    {
+      Rectangle srcRect = src.getBounds();
+      Rectangle dstInRect = dstIn.getBounds();
+      Rectangle dstOutRect = dstOut.getBounds();
+      
+      int xp = xorColor.getRGB();
+      int w = Math.min(Math.min(srcRect.width, dstOutRect.width),
+                       dstInRect.width);
+      int h = Math.min(Math.min(srcRect.height, dstOutRect.height),
+                       dstInRect.height);
+
+      Object srcPix = null, dstPix = null, rpPix = null;
+
+      // Re-using the rpPix object saved 1-2% of execution time in
+      // the 1024x1024 pixel benchmark.
+
+      for (int y = 0; y < h; y++)
+      {
+        for (int x = 0; x < w; x++)
+        {
+          srcPix = src.getDataElements(x + srcRect.x, y + srcRect.y, srcPix);
+          dstPix = dstIn.getDataElements(x + dstInRect.x, y + dstInRect.y,
+                                         dstPix);
+          int sp = srcColorModel.getRGB(srcPix);
+          int dp = dstColorModel.getRGB(dstPix);
+          int rp = sp ^ xp ^ dp;
+          dstOut.setDataElements(x + dstOutRect.x, y + dstOutRect.y, 
+                                 dstColorModel.getDataElements(rp, rpPix));
+        }
+      }
+    }
+
+
+    /**
+     * Disposes any cached resources. The default implementation does
+     * nothing because no resources are cached.
+     */
+    public void dispose()
+    {
+    }
+  }
+
+
+  /**
+   * An optimized CompositeContext that performs bitwise XOR of
+   * <code>int</code> pixel values with the pixel value of a specified
+   * <code>xorColor</code>.  This CompositeContext working only for
+   * rasters whose transfer format is {@link DataBuffer#TYPE_INT}.
+   *
+   * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of
+   * <code>TYPE_INT_RGB</code> took 69 ms on a lightly loaded 2.4 GHz
+   * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux
+   * 2.4.20. The timing is the average of ten runs on the same
+   * BufferedImage. Since the measurements were taken with {@link
+   * System#currentTimeMillis()}, they are rather inaccurate.
+   *
+   * @author Sascha Brawer (brawer@dandelis.ch)
+   */
+  private static class IntContext
+    extends GeneralContext
+  {
+    public IntContext(ColorModel colorModel, Color xorColor)
+    {
+      super(colorModel, colorModel, xorColor);
+    }
+
+
+    public void compose(Raster src, Raster dstIn,
+                        WritableRaster dstOut)
+    {
+      int aX, bX, dstX, aY, bY, dstY, width, height;
+      int xorPixel, transferType;
+      int[] srcLine, dstLine;
+
+      aX = src.getMinX();
+      aY = src.getMinY();
+      bX = dstIn.getMinX();
+      bY = dstIn.getMinY();
+      dstX = dstOut.getMinX();
+      dstY = dstOut.getMinY();
+      width = Math.min(Math.min(src.getWidth(), dstIn.getWidth()),
+                       dstOut.getWidth());
+      height = Math.min(Math.min(src.getHeight(), dstIn.getHeight()),
+                        dstOut.getHeight());
+      if ((width < 1) || (height < 1))
+        return;
+
+      srcLine = new int[width];
+      dstLine = new int[width];
+      
+      /* We need an int[] array with at least one element here;
+       * srcLine is as good as any other.
+       */
+      srcColorModel.getDataElements(this.xorColor.getRGB(), srcLine);
+      xorPixel = srcLine[0];
+
+      for (int y = 0; y < height; y++)
+      {
+        src.getDataElements(aX, y + aY, width, 1, srcLine);
+        dstIn.getDataElements(bX, y + bY, width, 1, dstLine);
+
+        for (int x = 0; x < width; x++)
+          dstLine[x] ^= srcLine[x] ^ xorPixel;
+
+        dstOut.setDataElements(dstX, y + dstY, width, 1, dstLine);
+      }
+    }
+
+    
+    /**
+     * Determines whether an instance of this CompositeContext would
+     * be able to process the specified color models.
+     */
+    public static boolean isSupported(ColorModel srcColorModel,
+                                      ColorModel dstColorModel,
+                                      RenderingHints hints)
+    {
+      // FIXME: It would be good if someone could review these checks.
+      // They probably need to be more restrictive.
+
+      int transferType;
+
+      transferType = srcColorModel.getTransferType();
+      if (transferType != dstColorModel.getTransferType())
+        return false;
+
+      if (transferType != DataBuffer.TYPE_INT)
+        return false;
+
+      return true;
+    }
+  }
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]