/* 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;
    }
  }
}
