Hi,
This patch optimizes the drawing of a CairoSurface onto another cairo
context, and adds support for drawing subimages/subraster in this way.
Cheers,
Francis
2007-02-23 Francis Kung <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/CairoGraphics2D.java
(drawCairoSurface): New method.
(drawImage(Image,AffineTransform,Color,ImageObserver)): Use new
drawCairoSurface() method.
* gnu/java/awt/peer/gtk/CairoSurface.java
(CairoSurface(SampleModel,CairoSurface,Rectangle,Point)): Copy correct
width/height values, and copy sharedBuffer value.
(createWritableChild): Remove debug line.
(drawSurface): Removed method.
* gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
(drawComposite): Translate image when drawing.
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.26
diff -u -r1.26 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java 22 Feb 2007 21:18:43 -0000 1.26
+++ gnu/java/awt/peer/gtk/CairoSurface.java 23 Feb 2007 22:15:41 -0000
@@ -43,7 +43,9 @@
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.Shape;
import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
@@ -135,20 +137,6 @@
native void syncJavaToNative(long surfacePointer, int[] buffer);
/**
- * Draw this CairoSurface image onto a given Cairo context.
- *
- * @param contextPointer A pointer to the context to draw onto.
- * @param i2u The transformation matrix (cannot be null).
- * @param alpha The alpha value to paint with ( 0 <= alpha <= 1).
- * @param interpolation The interpolation type, as defined in CairoGraphcs2D.
- */
- public void drawSurface(long contextPointer, double[] i2u, double alpha,
- int interpolation)
- {
- nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha, interpolation);
- }
-
- /**
* Return the buffer, with the sample values of each pixel reversed
* (ie, in ABGR instead of ARGB).
*
@@ -191,9 +179,10 @@
{
super(sm, parent.dataBuffer, bounds, origin, parent);
- this.width = parent.width;
- this.height = parent.height;
+ this.width = super.width;
+ this.height = super.height;
this.surfacePointer = parent.surfacePointer;
+ this.sharedBuffer = parent.sharedBuffer;
this.dataBuffer = parent.dataBuffer;
}
@@ -414,8 +403,6 @@
int w, int h, int childMinX,
int childMinY, int[] bandList)
{
- if (true)
- return this;
if (parentX < minX || parentX + w > minX + width
|| parentY < minY || parentY + h > minY + height)
throw new RasterFormatException("Child raster extends beyond parent");
Index: gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java,v
retrieving revision 1.10
diff -u -r1.10 CairoSurfaceGraphics.java
--- gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java 21 Feb 2007 21:47:36 -0000 1.10
+++ gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java 23 Feb 2007 22:15:41 -0000
@@ -317,9 +317,8 @@
// not one of the wrappers, to ensure that the composite isn't processed
// more than once!
boolean rv = super.drawImage(buffer2,
-// AffineTransform.getTranslateInstance(bounds.getX(),
-// bounds.getY()),
- AffineTransform.getTranslateInstance(0,0),
+ AffineTransform.getTranslateInstance(bounds.getX(),
+ bounds.getY()),
null, null);
setComposite(oldcomp);
updateColor();
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.64
diff -u -r1.64 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java 21 Feb 2007 21:47:37 -0000 1.64
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java 23 Feb 2007 22:15:41 -0000
@@ -1521,11 +1521,9 @@
alpha = ((AlphaComposite) comp).getAlpha();
if(raster instanceof CairoSurface
- && ((CairoSurface)raster).getParent() == null
&& ((CairoSurface)raster).sharedBuffer == true)
{
- ((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha,
- getInterpolation());
+ drawCairoSurface((CairoSurface)raster, xform, alpha, getInterpolation());
updateColor();
return true;
}
@@ -1671,6 +1669,67 @@
{
return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer);
}
+
+ /**
+ * Optimized method for drawing a CairoSurface onto this graphics context.
+ *
+ * @param surface The surface to draw.
+ * @param tx The transformation matrix (cannot be null).
+ * @param alpha The alpha value to paint with ( 0 <= alpha <= 1).
+ * @param interpolation The interpolation type.
+ */
+ private void drawCairoSurface(CairoSurface surface, AffineTransform tx,
+ double alpha, int interpolation)
+ {
+ // Find offset required if this surface is a sub-raster, and append offset
+ // to transformation.
+ if (surface.getSampleModelTranslateX() != 0
+ || surface.getSampleModelTranslateY() != 0)
+ {
+ Point2D origin = new Point2D.Double(0, 0);
+ Point2D offset = new Point2D.Double(surface.getSampleModelTranslateX(),
+ surface.getSampleModelTranslateY());
+
+ tx.transform(origin, origin);
+ tx.transform(offset, offset);
+
+ tx.translate(offset.getX() - origin.getX(),
+ offset.getY() - origin.getY());
+ }
+
+ // Find dimensions of this surface relative to the root parent surface
+ Rectangle bounds = new Rectangle(-surface.getSampleModelTranslateX(),
+ -surface.getSampleModelTranslateY(),
+ surface.width, surface.height);
+
+ // Clip to the translated image
+ // We use direct cairo methods to avoid the overhead of maintaining a
+ // java copy of the clip, since we will be reverting it immediately
+ // after drawing
+ Shape newBounds = tx.createTransformedShape(bounds);
+ cairoSave(nativePointer);
+ cairoResetClip(nativePointer);
+ walkPath(newBounds.getPathIterator(null), false);
+ cairoClip(nativePointer);
+
+ // Draw the surface
+ try
+ {
+ double[] i2u = new double[6];
+ tx.createInverse().getMatrix(i2u);
+ surface.nativeDrawSurface(surface.surfacePointer, nativePointer, i2u,
+ alpha, interpolation);
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // This should never happen(?), so we don't need to do anything here.
+ ;
+ }
+
+ // Restore clip
+ cairoRestore(nativePointer);
+ }
+
///////////////////////// TEXT METHODS ////////////////////////////////////