Hi,

This patch provides closer integration between cairo and our GTK peers, using an optimized cairo-backed Raster (and sharing a databuffer) when possible.

These changes result in a 30-50% speedup in rendering java2d operations on RGB/ARGB BufferedImage's.

Still a bit of a work in progress, but this seems like a good commit-point.

Cheers,
Francis


2007-02-16  Francis Kung  <[EMAIL PROTECTED]>

        * gnu/java/awt/ClasspathGraphicsEnvironment.java: New file.
        * gnu/java/awt/peer/gtk/CairoSurface.java
        (CairoDataBuffer): Removed inner class.
        (CairoSurface(int,int,int,int)): New constructor.
        (CairoSurface(int,int)): Delegate to new constructor.
        (CairoSurface(SampleModel,CairoSurface,Rectangle,Point)): New 
constructor
        for creating child rasters.
        (create): Added int[] parameter.
        (createChild): New method.
        (createCompatibleWritableRaster): New methods.
        (createTranslatedChild): New method.
        (createWritableChild): New method.
        (createWritableTranslatedChild): New method.
        (destroy): Added int[] parameter.
        (dispose): Only free native resources if this Surface has no parents.
        (isCompatibleColorModel): New method.
        (isCompatibleSampleModel): New method.
        * gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
        (draw): Set transform, smarter bounds generation.
        (drawComposite): Improved clipping.
        (drawImage): Fixed bounds translation.
        (drawRenderedImage): Set transform in buffer.
        (fill): Set transform in buffer.
        * gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
        (createRaster): New method.
        * java/awt/image/BufferedImage.java
        (BufferedImage(int,int,int)): Use optimized raster if possible.
        * include/gnu_java_awt_peer_gtk_CairoSurface.h: Regenerated.
        * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
        (Java_gnu_java_awt_peer_gtk_CairoSurface_create): Share data buffer 
between
        Cairo and Java.
        (Java_gnu_java_awt_peer_gtk_CairoSurface_destroy): Free data array.
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.23
diff -u -r1.23 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java	12 Feb 2007 21:39:20 -0000	1.23
+++ gnu/java/awt/peer/gtk/CairoSurface.java	16 Feb 2007 20:01:02 -0000
@@ -42,15 +42,20 @@
 
 import java.awt.Graphics2D;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
 import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
 import java.awt.image.WritableRaster;
 import java.nio.ByteOrder;
+import java.util.Arrays;
 import java.util.Hashtable;
 
 /**
@@ -98,12 +103,12 @@
    * @param width, height - the image size
    * @param stride - the buffer row stride. (in ints)
    */
-  private native void create(int width, int height, int stride);
+  private native void create(int width, int height, int stride, int[] buf);
 
   /**
    * Destroys the cairo surface and frees the buffer.
    */
-  private native void destroy(long surfacePointer, long bufferPointer);
+  private native void destroy(long surfacePointer, long bufferPointer, int[] buf);
 
   /**
    * Gets buffer elements
@@ -158,20 +163,40 @@
    */
   public CairoSurface(int width, int height)
   {
+    this(0, 0, width, height);
+  }
+  
+  public CairoSurface(int x, int y, int width, int height)
+  {
     super(createCairoSampleModel(width, height),
-	      null, new Point(0, 0));
+	      null, new Point(x, y));
 
     if(width <= 0 || height <= 0)
       throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
     
     this.width = width;
     this.height = height;
-    create(width, height, width);
+    dataBuffer = new DataBufferInt(width * height);
+    create(width, height, width, ((DataBufferInt)dataBuffer).getData());
 
     if(surfacePointer == 0 || bufferPointer == 0)
       throw new Error("Could not allocate bitmap.");
 
-    dataBuffer = new CairoDataBuffer();
+  }
+  
+  /**
+   * Create a Cairo Surface that is a subimage of another Cairo Surface
+   */
+  public CairoSurface(SampleModel sm, CairoSurface parent, Rectangle bounds,
+                      Point origin)
+  {
+    super(sm, parent.dataBuffer, bounds, origin, parent);
+    
+    this.width = parent.width;
+    this.height = parent.height;
+    this.bufferPointer = parent.bufferPointer;
+    this.surfacePointer = parent.surfacePointer;
+    this.dataBuffer = parent.dataBuffer;
   }
 
   /**
@@ -228,8 +253,9 @@
    */
   public void dispose()
   {
-    if(surfacePointer != 0)
-      destroy(surfacePointer, bufferPointer);
+    if(surfacePointer != 0 && parent == null)
+      destroy(surfacePointer, bufferPointer,
+              ((DataBufferInt)dataBuffer).getData());
   }
 
   /**
@@ -276,34 +302,6 @@
                              new Hashtable());
   }
 
-  private class CairoDataBuffer extends DataBuffer
-  {
-    public CairoDataBuffer()
-    {
-      super(DataBuffer.TYPE_INT, width * height);
-    }
-
-    /**
-     * DataBuffer.getElem implementation
-     */
-    public int getElem(int bank, int i)
-    {
-      if(bank != 0 || i < 0 || i >= width * height)
-        throw new IndexOutOfBoundsException(i+" size: "+width * height);
-      return nativeGetElem(bufferPointer, i);
-    }
-  
-    /**
-     * DataBuffer.setElem implementation
-     */
-    public void setElem(int bank, int i, int val)
-    {
-      if(bank != 0 || i < 0 || i >= width*height)
-        throw new IndexOutOfBoundsException(i+" size: "+width * height);
-      nativeSetElem(bufferPointer, i, val);
-    }
-  }
-
   /**
    * Return a Graphics2D drawing to the CairoSurface.
    */
@@ -345,4 +343,85 @@
                                             new int[]{0x00FF0000, 0x0000FF00,
                                                       0x000000FF, 0xFF000000});    
   }
+  
+  /**
+   * Returns whether this ColorModel is compatible with Cairo's native types.
+   * 
+   * @param cm The color model to check.
+   * @return Whether it is compatible.
+   */
+  public static boolean isCompatibleColorModel(ColorModel cm)
+  {
+    return (cm.equals(cairoCM_pre) || cm.equals(cairoCM_opaque) ||
+            cm.equals(cairoColorModel));
+  }
+  
+  /**
+   * Returns whether this SampleModel is compatible with Cairo's native types.
+   * 
+   * @param sm The sample model to check.
+   * @return Whether it is compatible.
+   */
+  public static boolean isCompatibleSampleModel(SampleModel sm)
+  {
+    return (sm instanceof SinglePixelPackedSampleModel
+        && sm.getDataType() == DataBuffer.TYPE_INT
+        && Arrays.equals(((SinglePixelPackedSampleModel)sm).getBitMasks(),
+                         new int[]{0x00FF0000, 0x0000FF00,
+                                   0x000000FF, 0xFF000000}));
+  }
+
+  ///// Methods interhited from Raster and WritableRaster /////
+  public Raster createChild(int parentX, int parentY, int width, int height,
+                            int childMinX, int childMinY, int[] bandList)
+  {
+    return createWritableChild(parentX, parentY, width, height,
+                               childMinX, childMinY, bandList);
+  }
+  
+  public WritableRaster createCompatibleWritableRaster()
+  {
+    return new CairoSurface(width, height);
+  }
+  
+  public WritableRaster createCompatibleWritableRaster (int x, int y,
+                                                        int w, int h)
+  {
+    return new CairoSurface(x, y, w, h);
+  }
+  
+  public Raster createTranslatedChild(int childMinX, int childMinY)
+  {
+    return createWritableTranslatedChild(childMinX, childMinY);
+  }
+  
+  public WritableRaster createWritableChild(int parentX, int parentY,
+                                            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");
+    
+    SampleModel sm = (bandList == null) ?
+      sampleModel :
+      sampleModel.createSubsetSampleModel(bandList);
+
+    return new CairoSurface(sm, this,
+                            new Rectangle(childMinX, childMinY, w, h),
+                            new Point(sampleModelTranslateX + childMinX - parentX,
+                                      sampleModelTranslateY + childMinY - parentY));
+  }
+  
+  public WritableRaster createWritableTranslatedChild(int x, int y)
+  {
+    int tcx = sampleModelTranslateX - minX + x;
+    int tcy = sampleModelTranslateY - minY + y;
+    
+    return new CairoSurface(sampleModel, this,
+                      new Rectangle(x, y, width, height),
+                      new Point(tcx, tcy));
+  }
 }
Index: gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java,v
retrieving revision 1.8
diff -u -r1.8 CairoSurfaceGraphics.java
--- gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java	18 Oct 2006 19:00:31 -0000	1.8
+++ gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java	16 Feb 2007 20:01:02 -0000
@@ -40,6 +40,7 @@
 
 import java.awt.AlphaComposite;
 import java.awt.Color;
+import java.awt.Composite;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.GraphicsConfiguration;
@@ -50,7 +51,6 @@
 import java.awt.Toolkit;
 import java.awt.font.GlyphVector;
 import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
@@ -116,6 +116,15 @@
    */
   public void draw(Shape s)
   {
+    // Find total bounds of shape
+    Rectangle r = findStrokedBounds(s);
+    if (shiftDrawCalls)
+      {
+        r.width++;
+        r.height++;
+      }
+    
+    // Do the drawing
     if (comp == null || comp instanceof AlphaComposite)
       super.draw(s);
     
@@ -126,9 +135,10 @@
         Graphics2D g2d = (Graphics2D)buffer.getGraphics();
         g2d.setStroke(this.getStroke());
         g2d.setColor(this.getColor());
+        g2d.setTransform(transform);
         g2d.draw(s);
         
-        drawComposite(s.getBounds2D(), null);
+        drawComposite(r.getBounds2D(), null);
       }
   }
 
@@ -144,6 +154,7 @@
         Graphics2D g2d = (Graphics2D)buffer.getGraphics();
         g2d.setPaint(this.getPaint());
         g2d.setColor(this.getColor());
+        g2d.setTransform(transform);
         g2d.fill(s);
         
         drawComposite(s.getBounds2D(), null);
@@ -161,6 +172,7 @@
 
         Graphics2D g2d = (Graphics2D)buffer.getGraphics();
         g2d.setRenderingHints(this.getRenderingHints());
+        g2d.setTransform(transform);
         g2d.drawRenderedImage(image, xform);
         
         drawComposite(buffer.getRaster().getBounds(), null);
@@ -187,14 +199,10 @@
         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());
+        Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
+                                           bImg.getWidth(), bImg.getHeight());
         if (xform != null)
-          {
-            origin = xform.transform(origin, origin);
-            pt = xform.transform(pt, pt);
-          }
+          bounds = getTransformedBounds(bounds, xform);
         
         // Create buffer and draw image
         createBuffer();
@@ -204,10 +212,7 @@
         g2d.drawImage(img, xform, obs);
 
         // Perform compositing
-        return drawComposite(new Rectangle2D.Double(origin.getX(),
-                                                    origin.getY(),
-                                                    pt.getX(), pt.getY()),
-                             obs);
+        return drawComposite(bounds, obs);
       }
   }
 
@@ -234,47 +239,58 @@
   
   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);
+    // Find bounds in device space
+    bounds = getTransformedBounds(bounds, transform);
+
+    // Clip bounds by the stored clip, and by the internal buffer
+    Rectangle2D devClip = this.getClipInDevSpace();
+    Rectangle2D.intersect(bounds, devClip, bounds);
+    devClip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
+                            buffer.getWidth(), buffer.getHeight());
+    Rectangle2D.intersect(bounds, devClip, bounds);
+    
+    // Round bounds as needed, but be careful in our rounding
+    // (otherwise it may leave unpainted stripes)
+    double x = bounds.getX();
+    double y = bounds.getY();
+    double maxX = x + bounds.getWidth();
+    double maxY = y + bounds.getHeight();
+    x = Math.round(x);
+    y = Math.round(y);
+    bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));
     
+    // Find subimage of internal buffer for updating
     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);
-    
+
+    // Find subimage of main image for updating
     BufferedImage current = CairoSurface.getBufferedImage(surface);
-    current = current.getSubimage((int)deviceBounds.getX(),
-                                  (int)deviceBounds.getY(),
-                                  (int)deviceBounds.getWidth(),
-                                  (int)deviceBounds.getHeight());
+    current = current.getSubimage((int)bounds.getX(), (int)bounds.getY(),
+                                  (int)bounds.getWidth(),
+                                  (int)bounds.getHeight());
 
     // Perform actual composite operation
     compCtx.compose(buffer2.getRaster(), current.getRaster(),
                     buffer2.getRaster());
     
+    // Set cairo's composite to direct SRC, since we've already done our own
+    // compositing   
+    Composite oldcomp = comp;
+    setComposite(AlphaComposite.Src);
+    
     // 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(buffer2,
-                                 AffineTransform.getTranslateInstance(bounds.getX(),
-                                                                      bounds.getY()),
-                                 new Color(0,0,0,0), null);
+//                                 AffineTransform.getTranslateInstance(bounds.getX(),
+//                                                                      bounds.getY()),
+                               AffineTransform.getTranslateInstance(0,0),
+                                 null, null);
+    setComposite(oldcomp);
+    updateColor();
     return rv;
   }
   
Index: gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java,v
retrieving revision 1.15
diff -u -r1.15 GdkGraphicsEnvironment.java
--- gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java	8 Aug 2006 22:30:52 -0000	1.15
+++ gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java	16 Feb 2007 20:01:02 -0000
@@ -38,16 +38,21 @@
 
 package gnu.java.awt.peer.gtk;
 
+import gnu.java.awt.ClasspathGraphicsEnvironment;
+
 import java.awt.Font;
 import java.awt.Graphics2D;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
 import java.awt.HeadlessException;
 import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
 import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
 import java.util.Locale;
 
-public class GdkGraphicsEnvironment extends GraphicsEnvironment
+public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
 {
   private final int native_state = GtkGenericPeer.getUniqueInteger ();
   
@@ -139,4 +144,13 @@
    * Used by GtkMouseInfoPeer.
    */ 
   native int[] getMouseCoordinates();
+  
+  public WritableRaster createRaster(ColorModel cm, SampleModel sm)
+  {
+    if (CairoSurface.isCompatibleSampleModel(sm)
+        && CairoSurface.isCompatibleColorModel(cm))
+      return new CairoSurface(sm.getWidth(), sm.getHeight());
+    else
+      return null;
+  }
 }
Index: java/awt/image/BufferedImage.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/image/BufferedImage.java,v
retrieving revision 1.25
diff -u -r1.25 BufferedImage.java
--- java/awt/image/BufferedImage.java	12 Feb 2007 21:39:20 -0000	1.25
+++ java/awt/image/BufferedImage.java	16 Feb 2007 20:01:02 -0000
@@ -39,7 +39,9 @@
 package java.awt.image;
 
 import gnu.java.awt.Buffers;
+import gnu.java.awt.ClasspathGraphicsEnvironment;
 import gnu.java.awt.ComponentDataBlitOp;
+import gnu.java.awt.peer.gtk.CairoSurface;
 
 import java.awt.Graphics;
 import java.awt.Graphics2D;
@@ -273,11 +275,20 @@
                                       Transparency.OPAQUE, buftype );
       }
 
-      init( cm,
-            Raster.createWritableRaster(sm, new Point( 0, 0 ) ),
-            premultiplied,
-            null, // no properties
-            type );
+    WritableRaster rst = null;
+    
+    // Attempt to create an accelerated backend for this image
+    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+    if (env instanceof ClasspathGraphicsEnvironment)
+      rst = ((ClasspathGraphicsEnvironment)env).createRaster(cm, sm);
+    
+    // Default to a standard Java raster & databuffer if needed
+    if (rst == null)
+      rst = Raster.createWritableRaster(sm, new Point( 0, 0 ) );
+    
+    init(cm, rst, premultiplied,
+         null, // no properties
+         type );
   }
 
   public BufferedImage(int w, int h, int type, IndexColorModel indexcolormodel)
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,v
retrieving revision 1.21
diff -u -r1.21 gnu_java_awt_peer_gtk_CairoSurface.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c	14 Sep 2006 18:30:59 -0000	1.21
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c	16 Feb 2007 20:01:02 -0000
@@ -56,11 +56,14 @@
  * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
  */
 JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject obj, jint width, jint height, jint stride)
+Java_gnu_java_awt_peer_gtk_CairoSurface_create
+(JNIEnv *env, jobject obj, jint width, jint height, jint stride,
+ jintArray buf )
 {
   cairo_surface_t* surface;
-  void *data = g_malloc(stride * height * 4);
-  memset(data, 0, stride * height * 4);
+  jboolean isCopy;
+  void *data = (*env)->GetIntArrayElements (env, buf, &isCopy);
+/*  FIXME: provide fallback if (isCopy == true) */
   setNativeObject(env, obj, data, BUFFER);
 
   surface = cairo_image_surface_create_for_data
@@ -75,16 +78,16 @@
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_CairoSurface_destroy
 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong surfacePointer, jlong bufferPointer)
+ jlong surfacePointer, jlong bufferPointer, jintArray buf)
 {
   void *buffer;
   cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+  buffer = JLONG_TO_PTR(void, bufferPointer);
   if( surface != NULL )
+  {
+  	(*env)->ReleaseIntArrayElements (env, buf, buffer, 0);
     cairo_surface_destroy(surface);
-
-  buffer = JLONG_TO_PTR(void, bufferPointer);
-  if( buffer != NULL )
-    g_free(buffer);
+  }
 }
 
 /**
Index: include/gnu_java_awt_peer_gtk_CairoSurface.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h,v
retrieving revision 1.7
diff -u -r1.7 gnu_java_awt_peer_gtk_CairoSurface.h
--- include/gnu_java_awt_peer_gtk_CairoSurface.h	15 Sep 2006 17:58:22 -0000	1.7
+++ include/gnu_java_awt_peer_gtk_CairoSurface.h	16 Feb 2007 20:01:02 -0000
@@ -10,8 +10,8 @@
 {
 #endif
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject, jlong, jlong);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject, jint, jint, jint, jintArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject, jlong, jlong, jintArray);
 JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem (JNIEnv *env, jobject, jlong, jint);
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem (JNIEnv *env, jobject, jlong, jint, jint);
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface (JNIEnv *env, jobject, jlong, jlong, jdoubleArray, jdouble, jint);
Index: gnu/java/awt/ClasspathGraphicsEnvironment.java
===================================================================
RCS file: gnu/java/awt/ClasspathGraphicsEnvironment.java
diff -N gnu/java/awt/ClasspathGraphicsEnvironment.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/awt/ClasspathGraphicsEnvironment.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,67 @@
+/* ClasspathGraphicsEnvironment.java
+   Copyright (C) 2007 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;
+
+import java.awt.GraphicsEnvironment;
+import java.awt.image.ColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class extends the GraphicsEnvironment API with some Classpath-specific
+ * methods, in order to provide optimized graphics handling.
+ * 
+ * @author Francis Kung <[EMAIL PROTECTED]>
+ */
+public abstract class ClasspathGraphicsEnvironment
+    extends GraphicsEnvironment
+{
+  /**
+   * Returns an appropriate Raster that can efficiently back a
+   * BufferedImage with the given ColorModel and SampleModel.
+   * 
+   * @param cm The color model.
+   * @param sm The samepl model.
+   * @return An appropriate WritableRaster, or null if acceleration/optimization
+   *         is not available for the given colour model / sample model.
+   */
+  public WritableRaster createRaster(ColorModel cm, SampleModel sm)
+  {
+    return null;
+  }
+}

Reply via email to