diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c5c273ac9ee..1952bfe6037 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2004-01-12 Graydon Hoare + + * 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 + + * gnu/java/awt/BitwiseXORComposite.java: Add. + * gnu/java/awt/peer/gtk/GdkGraphics2D.java + (setXORMode): Switch to gnu.java.awt.BitwiseXORComposite. + (BitwiseXORComposite): Remove inner class. + 2004-01-11 Michael Koch * gnu/java/lang/reflect/TypeSignature.java diff --git a/libjava/gnu/java/awt/BitwiseXORComposite.java b/libjava/gnu/java/awt/BitwiseXORComposite.java new file mode 100644 index 00000000000..675c225bbfa --- /dev/null +++ b/libjava/gnu/java/awt/BitwiseXORComposite.java @@ -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 not implement the Porter-Duff + * XOR operator, but an exclusive or of overlapping subpixel regions. + * + *

A screen shot of BitwiseXORComposite in action + * + *

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. + * + *

The purpose of this composite is to support the {@link + * Graphics#setXORMode(Color)} method in composite-aware graphics + * implementations. Applications typically would use + * setXORMode for drawing “highlights” such + * as text selections or cursors by inverting colors temporarily and + * then inverting them back. + * + *

A concrete Graphics implementation may contain + * the following code: + * + *

 public void setXORMode(Color xorColor)
+ * {
+ *   setComposite(new gnu.java.awt.BitwiseXORComposite(xorColor));
+ * }
+ *
+ * public void setPaintMode()
+ * {
+ *   setComposite(java.awt.AlphaComposite.SrcOver);
+ * }
+ * + * @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 xorColor. + * + *

Applying this CompositeContext on a 1024x1024 BufferedImage of + * TYPE_INT_RGB 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 + * int pixel values with the pixel value of a specified + * xorColor. This CompositeContext working only for + * rasters whose transfer format is {@link DataBuffer#TYPE_INT}. + * + *

Applying this CompositeContext on a 1024x1024 BufferedImage of + * TYPE_INT_RGB 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; + } + } +} diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 036e40f972d..cb6ccba61b4 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -66,7 +66,9 @@ public class GdkGraphics2D extends Graphics2D { System.loadLibrary("gtkpeer"); } - initStaticState (); + + if (GtkToolkit.useGraphics2D ()) + initStaticState (); } native static void initStaticState (); private final int native_state = GtkGenericPeer.getUniqueInteger(); @@ -125,7 +127,7 @@ public class GdkGraphics2D extends Graphics2D 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 @@ public class GdkGraphics2D extends Graphics2D 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 @@ public class GdkGraphics2D extends Graphics2D 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 class GdkGraphics2D extends Graphics2D public void setXORMode (Color c) { - setComposite (new BitwiseXorComposite (c)); + setComposite (new gnu.java.awt.BitwiseXORComposite(c)); } public void setColor (Color c) @@ -978,76 +980,6 @@ public class GdkGraphics2D extends Graphics2D } - 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); - } - } - /////////////////////////////////////////////// ////// Unimplemented Stubs and Overloads //////