diff options
author | Francis Kung <fkung@redhat.com> | 2006-11-06 21:28:38 +0000 |
---|---|---|
committer | Francis Kung <fkung@redhat.com> | 2006-11-06 21:28:38 +0000 |
commit | 62cdb9d9aa03c88302aa1053853f21c2a9515421 (patch) | |
tree | ea3945d4b6e062cd440136d1368ed9e6ad84da1a | |
parent | 6769214440be81b812e30cee4eabe162dd525c5b (diff) | |
download | classpath-62cdb9d9aa03c88302aa1053853f21c2a9515421.tar.gz |
2006-11-06 Francis Kung <fkung@redhat.com>
* gnu/java/awt/peer/gtk/ComponentGraphics.java
(fillRect): Handle custom composites.
(drawRenderedImage): Handle custom composites.
(drawImage): Handle custom composites.
(createBuffer): New method.
(drawLine): Handle custom composites.
(drawComposite): New method.
(fill): Handle custom composites.
(getNativeCM): New method.
(drawGlyphVector): Handle custom composites.
(drawRect): Handle custom composites.
(draw): Handle custom composites.
* gnu/java/awt/peer/gtk/VolatileImageGraphics.java
(drawComposite): Unset composite during draw call, to prevent parent
from handling composite again.
* gnu/java/awt/peer/gtk/CairoGraphics2D.java
(getBufferCM): Added comments.
(getNativeCM): Made abstract.
(setComposite): Removed comments.
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/CairoGraphics2D.java | 21 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/ComponentGraphics.java | 225 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/VolatileImageGraphics.java | 4 |
4 files changed, 250 insertions, 22 deletions
@@ -1,3 +1,25 @@ +2006-11-06 Francis Kung <fkung@redhat.com> + + * gnu/java/awt/peer/gtk/ComponentGraphics.java + (fillRect): Handle custom composites. + (drawRenderedImage): Handle custom composites. + (drawImage): Handle custom composites. + (createBuffer): New method. + (drawLine): Handle custom composites. + (drawComposite): New method. + (fill): Handle custom composites. + (getNativeCM): New method. + (drawGlyphVector): Handle custom composites. + (drawRect): Handle custom composites. + (draw): Handle custom composites. + * gnu/java/awt/peer/gtk/VolatileImageGraphics.java + (drawComposite): Unset composite during draw call, to prevent parent + from handling composite again. + * gnu/java/awt/peer/gtk/CairoGraphics2D.java + (getBufferCM): Added comments. + (getNativeCM): Made abstract. + (setComposite): Removed comments. + 2006-11-06 Roman Kennke <kennke@aicas.com> * examples/gnu/classpath/examples/swing/HtmlDemo.java: 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/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; } |