summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-05-03 11:24:49 +0000
committerRoman Kennke <roman@kennke.org>2006-05-03 11:24:49 +0000
commit599111bb1dca0a877817a013db4f409d2522c8b0 (patch)
tree084128adc4edcee48c220f900eaac143a7f5b295
parente8dd7c508b7b488035f18fa81648af35542b8986 (diff)
downloadclasspath-599111bb1dca0a877817a013db4f409d2522c8b0.tar.gz
2006-05-03 Roman Kennke <kennke@aicas.com>
* gnu/java/awt/java2d/AlphaCompositeContext.java: New class. * java/awt/AlphaComposite.java (createContext): Implemented.
-rw-r--r--ChangeLog6
-rw-r--r--gnu/java/awt/java2d/AlphaCompositeContext.java356
-rw-r--r--java/awt/AlphaComposite.java20
3 files changed, 377 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 2f90a9faa..695789f20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-05-03 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AlphaCompositeContext.java: New class.
+ * java/awt/AlphaComposite.java
+ (createContext): Implemented.
+
2006-05-03 Audrius Meskauskas <AudriusA@Bioinformatics.org>
* gnu/java/awt/peer/gtk/GdkGraphics2D.java (drawRaster):
diff --git a/gnu/java/awt/java2d/AlphaCompositeContext.java b/gnu/java/awt/java2d/AlphaCompositeContext.java
new file mode 100644
index 000000000..e01296f2d
--- /dev/null
+++ b/gnu/java/awt/java2d/AlphaCompositeContext.java
@@ -0,0 +1,356 @@
+/* AlphaCompositeContext.java -- CompositeContext impl for AlphaComposite
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.java2d;
+
+import java.awt.AWTError;
+import java.awt.AlphaComposite;
+import java.awt.CompositeContext;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * A CompositeContext implementation for {@link AlphaComposite}.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class AlphaCompositeContext
+ implements CompositeContext
+{
+
+ /**
+ * The Composite object for which we perform compositing.
+ */
+ private AlphaComposite composite;
+
+ /**
+ * The source color model.
+ */
+ private ColorModel srcColorModel;
+
+ /**
+ * The destination color model.
+ */
+ private ColorModel dstColorModel;
+
+ /**
+ * The blending factor for the source.
+ */
+ private float fs;
+
+ /**
+ * The blending factor for the destination.
+ */
+ private float fd;
+
+ /**
+ * Creates a new AlphaCompositeContext.
+ *
+ * @param aComp the AlphaComposite object
+ * @param srcCM the source color model
+ * @param dstCM the destination color model
+ */
+ public AlphaCompositeContext(AlphaComposite aComp, ColorModel srcCM,
+ ColorModel dstCM)
+ {
+ composite = aComp;
+ srcColorModel = srcCM;
+ dstColorModel = dstCM;
+
+
+ // Determine the blending factors according to the rule in the
+ // AlphaComposite. For some rules the factors must be determined
+ // dynamically because they depend on the actual pixel value.
+ switch (composite.getRule())
+ {
+ case AlphaComposite.CLEAR:
+ fs = 0.F;
+ fd= 0.F;
+ break;
+ case AlphaComposite.DST:
+ fs = 0.F;
+ fd= 1.F;
+ break;
+ case AlphaComposite.DST_ATOP:
+ fs = 1.F; // Determined later as 1 - alpha_dst;
+ fd = 1.F; // Determined later as alpha_src;
+ break;
+ case AlphaComposite.DST_IN:
+ fs = 0.F;
+ fd = 0.F; // Determined later as alpha_src;
+ break;
+ case AlphaComposite.DST_OUT:
+ fs = 0.F;
+ fd = 0.F; // Determined later as 1 - alpha_src;
+ break;
+ case AlphaComposite.DST_OVER:
+ fs = 1.F; // Determined later as 1 - alpha_dst.
+ fd= 1.F;
+ break;
+ case AlphaComposite.SRC:
+ fs = 1.F;
+ fd= 0.F;
+ break;
+ case AlphaComposite.SRC_ATOP:
+ fs = 1.F; // Determined later as alpha_dst;
+ fd = 1.F; // Determined later as 1 - alpha_src;
+ break;
+ case AlphaComposite.SRC_IN:
+ fs = 0.F; // Determined later as alpha_dst;
+ fd = 0.F;
+ break;
+ case AlphaComposite.SRC_OUT:
+ fs = 0.F; // Determined later as 1 - alpha_dst;
+ fd = 0.F;
+ break;
+ case AlphaComposite.SRC_OVER:
+ fs = 1.F;
+ fd= 1.F; // Determined later as 1 - alpha_src.
+ break;
+ case AlphaComposite.XOR:
+ fs = 1.F; // Determined later as 1 - alpha_dst.
+ fd= 1.F; // Determined later as 1 - alpha_src.
+ break;
+ default:
+ throw new AWTError("Illegal AlphaComposite rule");
+ }
+
+ }
+
+ /**
+ * Releases all resources held by this composite object.
+ */
+ public void dispose()
+ {
+ // Nothing to do here yet.
+ }
+
+ /**
+ * Performs compositing according to the rules specified in the
+ * AlphaComposite from the constructor.
+ */
+ public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
+ {
+
+ // TODO: This implementation is very general and highly inefficient. There
+ // are two possible ways to optimize this:
+ // 1. Special cased implementations for common ColorModels and transfer
+ // types.
+ // 2. Native implementation.
+
+ int x0 = src.getMinX();
+ int y0 = src.getMinY();
+ int width = src.getWidth();
+ int height = src.getHeight();
+ int x1 = x0 + width;
+ int y1 = x0 + height;
+
+ Object srcPixel = null;
+ Object dstPixel = null;
+
+ // Prepare the array that holds the color and alpha components of the
+ // source pixels.
+ float[] srcComponents;
+ int srcComponentsLength = srcColorModel.getNumComponents();
+ if (! srcColorModel.hasAlpha())
+ srcComponentsLength += 1;
+ srcComponents = new float[srcComponentsLength];
+
+ // Prepare the array that holds the color and alpha components of the
+ // destination pixels.
+ float[] dstComponents;
+ int dstComponentsLength = dstColorModel.getNumComponents();
+ if (! dstColorModel.hasAlpha())
+ dstComponentsLength += 1;
+ dstComponents = new float[dstComponentsLength];
+
+ if (srcComponentsLength != dstComponentsLength)
+ throw new AWTError("The color models of the source and destination have"
+ + "incompatible number of color components");
+
+ int srcTransferType = srcColorModel.getTransferType();
+ int dstTransferType = dstColorModel.getTransferType();
+
+ for (int y = y0; y < y1; y++)
+ {
+ for (int x = x0; x < x1; x++)
+ {
+ // Fetch source pixel.
+ switch (srcTransferType)
+ {
+ case DataBuffer.TYPE_INT:
+ srcPixel = src.getPixel(x, y, (int[]) srcPixel);
+ break;
+ case DataBuffer.TYPE_FLOAT:
+ srcPixel = src.getPixel(x, y, (float[]) srcPixel);
+ break;
+ case DataBuffer.TYPE_DOUBLE:
+ srcPixel = src.getPixel(x, y, (double[]) srcPixel);
+ break;
+ default:
+ throw new AWTError("Invalid transfer type for source raster");
+ }
+ // Fetch destination pixel.
+ switch (dstTransferType)
+ {
+ case DataBuffer.TYPE_INT:
+ dstPixel = dstIn.getPixel(x, y, (int[]) dstPixel);
+ break;
+ case DataBuffer.TYPE_FLOAT:
+ dstPixel = dstIn.getPixel(x, y, (float[]) dstPixel);
+ break;
+ case DataBuffer.TYPE_DOUBLE:
+ dstPixel = dstIn.getPixel(x, y, (double[]) dstPixel);
+ break;
+ default:
+ throw new AWTError("Invalid transfer type for source raster");
+ }
+
+ // Get normalized components. This is the only type that is
+ // guaranteed to be supported by all ColorModels.
+ srcComponents =
+ srcColorModel.getNormalizedComponents(srcPixel, srcComponents, 0);
+ if (! srcColorModel.hasAlpha())
+ srcComponents[srcComponentsLength - 1] = 1.0F;
+ dstComponents =
+ dstColorModel.getNormalizedComponents(dstPixel, srcComponents, 0);
+ if (! dstColorModel.hasAlpha())
+ dstComponents[dstComponentsLength - 1] = 1.0F;
+
+ // Prepare the input.
+ float compositeAlpha = composite.getAlpha();
+ srcComponents[srcComponentsLength - 1] *= compositeAlpha;
+ if (srcColorModel.isAlphaPremultiplied())
+ {
+ for (int i = srcComponentsLength - 2; i >= 0; i++)
+ srcComponents[i] *= compositeAlpha;
+ }
+ else
+ {
+ for (int i = srcComponentsLength - 2; i >= 0; i++)
+ srcComponents[i] *= srcComponents[srcComponentsLength - 1];
+ }
+ if (! dstColorModel.isAlphaPremultiplied())
+ {
+ for (int i = dstComponentsLength - 2; i >= 0; i++)
+ dstComponents[i] *= dstComponents[dstComponents.length - 1];
+ }
+
+ // Determine the blending factors according to the rule in the
+ // AlphaComposite. For some rules the factors must be determined
+ // dynamically because they depend on the actual pixel value.
+ float srcAlpha = srcComponents[srcComponentsLength - 1];
+ float dstAlpha = dstComponents[dstComponentsLength - 1];
+ switch (composite.getRule())
+ {
+ case AlphaComposite.DST_ATOP:
+ fs = 1.F - dstAlpha;
+ fd = srcAlpha;
+ break;
+ case AlphaComposite.DST_IN:
+ fd = srcAlpha;
+ break;
+ case AlphaComposite.DST_OUT:
+ fd = 1.F - srcAlpha;
+ break;
+ case AlphaComposite.DST_OVER:
+ fs = 1.F - dstAlpha;
+ break;
+ case AlphaComposite.SRC_ATOP:
+ fs = srcAlpha;
+ fd = 1.F - srcAlpha;
+ break;
+ case AlphaComposite.SRC_IN:
+ fs = dstAlpha;
+ break;
+ case AlphaComposite.SRC_OUT:
+ fs = 1.F - dstAlpha;
+ break;
+ case AlphaComposite.SRC_OVER:
+ fd= 1.F - srcAlpha;
+ break;
+ case AlphaComposite.XOR:
+ fs = 1.F - dstAlpha;
+ fd= 1.F - srcAlpha;
+ break;
+ default:
+ // For the other cases the factors have already been determined
+ // in the constructor.
+ }
+
+ // Apply the blending equation to the pixels.
+ for (int i = 0; i < srcComponentsLength; i++)
+ {
+ dstComponents[i] = srcComponents[i] * fs
+ + dstComponents[i] * fd;
+ }
+
+ // Convert the result back when the destination is not
+ // alpha-premultiplied.
+ dstAlpha = dstComponents[dstComponentsLength - 1];
+ if (!dstColorModel.isAlphaPremultiplied() && dstAlpha != 0.F)
+ {
+ for (int i = 0; i < dstComponentsLength - 1; i++)
+ {
+ dstComponents[i] = dstComponents[i] / dstAlpha;
+ }
+ }
+
+ // Store the result in the destination raster.
+ dstPixel = dstColorModel.getDataElements(dstComponents, 0,
+ dstPixel);
+ switch (dstTransferType)
+ {
+ case DataBuffer.TYPE_INT:
+ dstOut.setPixel(x, y, (int[] ) dstPixel);
+ break;
+ case DataBuffer.TYPE_FLOAT:
+ dstOut.setPixel(x, y, (float[] ) dstPixel);
+ break;
+ case DataBuffer.TYPE_DOUBLE:
+ dstOut.setPixel(x, y, (double[] ) dstPixel);
+ break;
+ }
+
+ } // End X loop.
+ } // End Y loop.
+ }
+
+}
diff --git a/java/awt/AlphaComposite.java b/java/awt/AlphaComposite.java
index d6e1842d9..92b9e09a6 100644
--- a/java/awt/AlphaComposite.java
+++ b/java/awt/AlphaComposite.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
+import gnu.java.awt.java2d.AlphaCompositeContext;
import java.awt.image.ColorModel;
import java.util.LinkedHashMap;
@@ -139,15 +139,25 @@ public final class AlphaComposite implements Composite
}
return a;
}
+
+ /**
+ * Creates a {@link CompositeContext} that can be used to perform
+ * compositing operations according to this AlphaComposite settings.
+ *
+ * @param srcColorModel the color model of the source raster
+ * @param dstColorModel the color model of the destination raster
+ * @param hints the rendering hints to use
+ *
+ * @return a {@link CompositeContext} that can be used to perform
+ * compositing operations according to this AlphaComposite settings
+ */
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel,
RenderingHints hints)
- throws NotImplementedException
{
- // XXX Implement. Sun uses undocumented implementation class
- // sun.java2d.SunCompositeContext.
- throw new Error("not implemented");
+ return new AlphaCompositeContext(this, srcColorModel, dstColorModel);
}
+
public float getAlpha()
{
return alpha;