summaryrefslogtreecommitdiff
path: root/gnu/java/awt/peer/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/java/awt/peer/gtk')
-rw-r--r--gnu/java/awt/peer/gtk/CairoGraphics2D.java21
-rw-r--r--gnu/java/awt/peer/gtk/ComponentGraphics.java225
-rw-r--r--gnu/java/awt/peer/gtk/GtkImageConsumer.java43
-rw-r--r--gnu/java/awt/peer/gtk/VolatileImageGraphics.java4
4 files changed, 258 insertions, 35 deletions
diff --git a/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
index 7f55747c6..ce3041d73 100644
--- a/gnu/java/awt/peer/gtk/CairoGraphics2D.java
+++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
@@ -985,10 +985,6 @@ public abstract class CairoGraphics2D extends Graphics2D
if (sm != null)
sm.checkPermission(new AWTPermission("readDisplayPixels"));
- // FIXME: implement general Composite support
- //throw new java.lang.UnsupportedOperationException();
- // this is in progress! yay!
- //compCtx = comp.createContext(getNativeCM(), getNativeCM(), hints);
compCtx = comp.createContext(getBufferCM(), getNativeCM(), hints);
}
}
@@ -1000,18 +996,17 @@ public abstract class CairoGraphics2D extends Graphics2D
*
* @return ColorModel the ColorModel of native data in this peer
*/
- /* protected abstract ColorModel getNativeCM(); */
- protected ColorModel getNativeCM()
- {
- // This stub should be removed and the method made abstract once I'm done
- // implementing custom composites across all the peers... but we need it
- // for now, so that the build doesn't break.
- return null;
- }
+ protected abstract ColorModel getNativeCM();
- // This may be overridden by some subclasses
+ /**
+ * Returns the Color Model describing the buffer that this peer uses
+ * for custom composites.
+ *
+ * @return ColorModel the ColorModel of the composite buffer in this peer.
+ */
protected ColorModel getBufferCM()
{
+ // This may be overridden by some subclasses
return getNativeCM();
}
diff --git a/gnu/java/awt/peer/gtk/ComponentGraphics.java b/gnu/java/awt/peer/gtk/ComponentGraphics.java
index d9d173118..c8ec2c95e 100644
--- a/gnu/java/awt/peer/gtk/ComponentGraphics.java
+++ b/gnu/java/awt/peer/gtk/ComponentGraphics.java
@@ -38,22 +38,31 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
+import gnu.classpath.Pointer;
+
+import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
import java.awt.image.RenderedImage;
-import gnu.classpath.Pointer;
+import java.awt.image.WritableRaster;
+import java.util.Hashtable;
/**
* ComponentGraphics - context for drawing directly to a component,
@@ -67,6 +76,7 @@ public class ComponentGraphics extends CairoGraphics2D
private GtkComponentPeer component;
protected long cairo_t;
+ private BufferedImage buffer, componentBuffer;
private static ThreadLocal hasLock = new ThreadLocal();
private static Integer ONE = Integer.valueOf(1);
@@ -227,7 +237,20 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.draw(s);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.draw(s);
+
+ else
+ {
+ createBuffer();
+
+ Graphics2D g2d = (Graphics2D)buffer.getGraphics();
+ g2d.setStroke(this.getStroke());
+ g2d.setColor(this.getColor());
+ g2d.draw(s);
+
+ drawComposite(s.getBounds2D(), null);
+ }
}
finally
{
@@ -240,7 +263,20 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.fill(s);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.fill(s);
+
+ else
+ {
+ createBuffer();
+
+ Graphics2D g2d = (Graphics2D)buffer.getGraphics();
+ g2d.setPaint(this.getPaint());
+ g2d.setColor(this.getColor());
+ g2d.fill(s);
+
+ drawComposite(s.getBounds2D(), null);
+ }
}
finally
{
@@ -253,7 +289,19 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.drawRenderedImage(image, xform);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.drawRenderedImage(image, xform);
+
+ else
+ {
+ createBuffer();
+
+ Graphics2D g2d = (Graphics2D)buffer.getGraphics();
+ g2d.setRenderingHints(this.getRenderingHints());
+ g2d.drawRenderedImage(image, xform);
+
+ drawComposite(buffer.getRaster().getBounds(), null);
+ }
}
finally
{
@@ -268,7 +316,44 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- rv = super.drawImage(img, xform, bgcolor, obs);
+ if (comp == null || comp instanceof AlphaComposite)
+ rv = super.drawImage(img, xform, bgcolor, obs);
+
+ else
+ {
+ // Get buffered image of source
+ if( !(img instanceof BufferedImage) )
+ {
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ img = Toolkit.getDefaultToolkit().createImage(source);
+ }
+ BufferedImage bImg = (BufferedImage) img;
+
+ // Find translated bounds
+ Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY());
+ Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(),
+ bImg.getHeight() + bImg.getMinY());
+ if (xform != null)
+ {
+ origin = xform.transform(origin, origin);
+ pt = xform.transform(pt, pt);
+ }
+
+ // Create buffer and draw image
+ createBuffer();
+
+ Graphics2D g2d = (Graphics2D)buffer.getGraphics();
+ g2d.setRenderingHints(this.getRenderingHints());
+ g2d.drawImage(img, xform, obs);
+
+ // Perform compositing
+ rv = drawComposite(new Rectangle2D.Double(origin.getX(),
+ origin.getY(),
+ pt.getX(), pt.getY()),
+ obs);
+ }
}
finally
{
@@ -282,7 +367,23 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.drawGlyphVector(gv, x, y);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.drawGlyphVector(gv, x, y);
+
+ else
+ {
+ createBuffer();
+
+ Graphics2D g2d = (Graphics2D)buffer.getGraphics();
+ g2d.setPaint(this.getPaint());
+ g2d.setStroke(this.getStroke());
+ g2d.drawGlyphVector(gv, x, y);
+
+ Rectangle2D bounds = gv.getLogicalBounds();
+ bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(),
+ bounds.getWidth(), bounds.getHeight());
+ drawComposite(bounds, null);
+ }
}
finally
{
@@ -384,7 +485,11 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.drawLine(x1, y1, x2, y2);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.drawLine(x1, y1, x2, y2);
+
+ else
+ draw(new Line2D.Double(x1, y1, x2, y2));
}
finally
{
@@ -397,7 +502,11 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.drawRect(x, y, width, height);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.drawRect(x, y, width, height);
+
+ else
+ draw(new Rectangle2D.Double(x, y, width, height));
}
finally
{
@@ -410,7 +519,11 @@ public class ComponentGraphics extends CairoGraphics2D
lock();
try
{
- super.fillRect(x, y, width, height);
+ if (comp == null || comp instanceof AlphaComposite)
+ super.fillRect(x, y, width, height);
+
+ else
+ fill(new Rectangle2D.Double(x, y, width, height));
}
finally
{
@@ -431,5 +544,99 @@ public class ComponentGraphics extends CairoGraphics2D
}
}
+
+ private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
+ {
+ // Clip source to visible areas that need updating
+ Rectangle2D clip = this.getClipBounds();
+ Rectangle2D.intersect(bounds, clip, bounds);
+ clip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
+ buffer.getWidth(), buffer.getHeight());
+ Rectangle2D.intersect(bounds, clip, bounds);
+
+ BufferedImage buffer2 = buffer;
+ if (!bounds.equals(buffer2.getRaster().getBounds()))
+ buffer2 = buffer2.getSubimage((int)bounds.getX(), (int)bounds.getY(),
+ (int)bounds.getWidth(),
+ (int)bounds.getHeight());
+
+ // Get destination clip to bounds
+ double[] points = new double[] {bounds.getX(), bounds.getY(),
+ bounds.getMaxX(), bounds.getMaxY()};
+ transform.transform(points, 0, points, 0, 2);
+
+ Rectangle2D deviceBounds = new Rectangle2D.Double(points[0], points[1],
+ points[2] - points[0],
+ points[3] - points[1]);
+
+ Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds);
+
+ // Get current image on the component
+ unlock();
+ GtkImage img = grab(component);
+ Graphics gr = componentBuffer.createGraphics();
+ gr.drawImage(img, 0, 0, null);
+ gr.dispose();
+ lock();
+
+ BufferedImage cBuffer = componentBuffer;
+ if (!deviceBounds.equals(cBuffer.getRaster().getBounds()))
+ cBuffer = cBuffer.getSubimage((int)deviceBounds.getX(),
+ (int)deviceBounds.getY(),
+ (int)deviceBounds.getWidth(),
+ (int)deviceBounds.getHeight());
+
+ // Perform actual composite operation
+ compCtx.compose(buffer2.getRaster(), cBuffer.getRaster(),
+ cBuffer.getRaster());
+
+ // This MUST call directly into the "action" method in CairoGraphics2D,
+ // not one of the wrappers, to ensure that the composite isn't processed
+ // more than once!
+ boolean rv = super.drawImage(cBuffer,
+ AffineTransform.getTranslateInstance(bounds.getX(),
+ bounds.getY()),
+ null, null);
+ return rv;
+ }
+
+ private void createBuffer()
+ {
+ if (buffer == null)
+ {
+ WritableRaster rst;
+ rst = Raster.createWritableRaster(GtkVolatileImage.createGdkSampleModel(component.awtComponent.getWidth(),
+ component.awtComponent.getHeight()),
+ new Point(0,0));
+
+ buffer = new BufferedImage(GtkVolatileImage.gdkColorModel, rst,
+ GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(),
+ new Hashtable());
+ }
+ else
+ {
+ Graphics2D g2d = ((Graphics2D)buffer.getGraphics());
+
+ g2d.setBackground(new Color(0,0,0,0));
+ g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
+ }
+
+ if (componentBuffer == null)
+ {
+ WritableRaster rst;
+ rst = Raster.createWritableRaster(GtkVolatileImage.createGdkSampleModel(component.awtComponent.getWidth(),
+ component.awtComponent.getHeight()),
+ new Point(0,0));
+
+ componentBuffer = new BufferedImage(GtkVolatileImage.gdkColorModel, rst,
+ GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(),
+ new Hashtable());
+ }
+ }
+
+ protected ColorModel getNativeCM()
+ {
+ return GtkVolatileImage.gdkColorModel;
+ }
}
diff --git a/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/gnu/java/awt/peer/gtk/GtkImageConsumer.java
index f1a74b8cc..53e97bb1a 100644
--- a/gnu/java/awt/peer/gtk/GtkImageConsumer.java
+++ b/gnu/java/awt/peer/gtk/GtkImageConsumer.java
@@ -42,6 +42,7 @@ import java.awt.image.ColorModel;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageProducer;
import java.awt.image.MemoryImageSource;
+import java.nio.ByteOrder;
import java.util.Hashtable;
/**
@@ -103,7 +104,7 @@ public class GtkImageConsumer implements ImageConsumer
scansize);
}
- public synchronized void setPixels (int x, int y, int width, int height,
+ public synchronized void setPixels (int x, int y, int width, int height,
ColorModel cm, int[] pixels,
int offset, int scansize)
{
@@ -117,18 +118,34 @@ public class GtkImageConsumer implements ImageConsumer
width);
else
{
- for (int i = 0; i < height; i++)
- for (int j = 0; j < width; j++)
- {
- // get in AARRGGBB and convert to AABBGGRR
- int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
- byte b = (byte)(pix & 0xFF);
- byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF);
- pix &= 0xFF00FF00;
- pix |= ((b & 0xFF) << 16);
- pix |= (r & 0xFF);
- pixelCache[(y + i) * this.width + x + j] = pix;
- }
+ if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
+ {
+ for (int i = 0; i < height; i++)
+ for (int j = 0; j < width; j++)
+ {
+ // get in RRGGBBAA and convert to AARRGGBB
+ int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
+ int a = ((pix & 0xFF000000) >> 24) & 0xFF;
+ int rgb = (pix & 0x00FFFFFF) << 8;
+ pix = rgb | a;
+ pixelCache[(y + i) * this.width + x + j] = pix;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < height; i++)
+ for (int j = 0; j < width; j++)
+ {
+ // get in AARRGGBB and convert to AABBGGRR
+ int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
+ byte b = (byte)(pix & 0xFF);
+ byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF);
+ pix &= 0xFF00FF00;
+ pix |= ((b & 0xFF) << 16);
+ pix |= (r & 0xFF);
+ pixelCache[(y + i) * this.width + x + j] = pix;
+ }
+ }
}
}
diff --git a/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
index 3a9f9d693..62dbb45d8 100644
--- a/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
+++ b/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
@@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk;
import java.awt.AlphaComposite;
import java.awt.Color;
+import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -269,10 +270,13 @@ public class VolatileImageGraphics extends ComponentGraphics
// This MUST call directly into the "action" method in CairoGraphics2D,
// not one of the wrappers, to ensure that the composite isn't processed
// more than once!
+ Composite oldComp = comp; // so that ComponentGraphics doesn't
+ comp = null; // process the composite again
boolean rv = super.drawImage(buffer2,
AffineTransform.getTranslateInstance(bounds.getX(),
bounds.getY()),
null, null);
+ comp = oldComp;
return rv;
}