summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Kung <fkung@redhat.com>2006-11-21 16:34:03 +0000
committerFrancis Kung <fkung@redhat.com>2006-11-21 16:34:03 +0000
commit488fa0077a655f3152140e74355b11b897352b1e (patch)
tree3e9eda675efa4542c6df0f4920e263946f8699a7
parent03970a6b3aac93b82ebf1fa6f3467e35cf721aeb (diff)
downloadclasspath-488fa0077a655f3152140e74355b11b897352b1e.tar.gz
2006-11-21 Francis Kung <fkung@redhat.com>
* gnu/java/awt/java2d/TexturePaintContext.java (getRaster): Handle negative coordinate values. * gnu/java/awt/peer/gtk/CairoGraphics2D.java (setPaint): Moved custom paint processing to a new method. (setPaintPixels): Added x, y parameters. (getRealBounds): Added documentation. (copy): Copy clipping information. (drawLine): Process custom paints. (setCustomPaint): New method. (fill): Process custom paints. (drawGlyphVector): Process custom paints. (drawRect): Process custom paints. (draw): Process custom paints. * gnu/java/awt/peer/gtk/CairoSurface.java (cairoCM_opaque): New constant. * gnu/java/awt/peer/gtk/BufferedImageGraphics.java (argb32): Removed constant. (rgb32): Removed constant. (BufferedImageGraphics(BufferedImage)): Updated constant names. (BufferedImageGraphics(BufferedImageGraphics)): Copy color model flags. (updateBufferedImage): Transform to device-space before updating. * include/gnu_java_awt_peer_gtk_CairoGraphics2D.h (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels): Added x, y parameters. * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels): Set pattern source at designated x, y origin.
-rw-r--r--ChangeLog30
-rw-r--r--gnu/java/awt/java2d/TexturePaintContext.java6
-rw-r--r--gnu/java/awt/peer/gtk/BufferedImageGraphics.java23
-rw-r--r--gnu/java/awt/peer/gtk/CairoGraphics2D.java150
-rw-r--r--gnu/java/awt/peer/gtk/CairoSurface.java5
-rw-r--r--include/gnu_java_awt_peer_gtk_CairoGraphics2D.h2
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c11
7 files changed, 176 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 5ea805975..45cc62a39 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2006-11-21 Francis Kung <fkung@redhat.com>
+
+ * gnu/java/awt/java2d/TexturePaintContext.java
+ (getRaster): Handle negative coordinate values.
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (setPaint): Moved custom paint processing to a new method.
+ (setPaintPixels): Added x, y parameters.
+ (getRealBounds): Added documentation.
+ (copy): Copy clipping information.
+ (drawLine): Process custom paints.
+ (setCustomPaint): New method.
+ (fill): Process custom paints.
+ (drawGlyphVector): Process custom paints.
+ (drawRect): Process custom paints.
+ (draw): Process custom paints.
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ (cairoCM_opaque): New constant.
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (argb32): Removed constant.
+ (rgb32): Removed constant.
+ (BufferedImageGraphics(BufferedImage)): Updated constant names.
+ (BufferedImageGraphics(BufferedImageGraphics)): Copy color model flags.
+ (updateBufferedImage): Transform to device-space before updating.
+ * include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
+ (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels): Added x, y
+ parameters.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels): Set pattern
+ source at designated x, y origin.
+
2006-11-21 Roman Kennke <kennke@aicas.com>
* java/awt/text/TextLayout.java
diff --git a/gnu/java/awt/java2d/TexturePaintContext.java b/gnu/java/awt/java2d/TexturePaintContext.java
index 840b61456..db0a2e658 100644
--- a/gnu/java/awt/java2d/TexturePaintContext.java
+++ b/gnu/java/awt/java2d/TexturePaintContext.java
@@ -177,6 +177,12 @@ public class TexturePaintContext
// The modulo operation gives us the replication effect.
dx = ((dx - minX) % width) + minX;
dy = ((dy - minY) % height) + minY;
+
+ // Handle possible negative values (replicating above the top-left)
+ if (dx < 0)
+ dx += width;
+ if (dy < 0)
+ dy += height;
// Copy the pixel.
pixel = source.getDataElements(dx, dy, pixel);
diff --git a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
index 341fa2a4e..f83be870d 100644
--- a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+++ b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
@@ -54,7 +54,6 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
-import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.Raster;
@@ -100,12 +99,6 @@ public class BufferedImageGraphics extends CairoGraphics2D
*/
private long cairo_t;
- /**
- * Colormodels we recognize for fast copying.
- */
- static ColorModel rgb32 = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
- static ColorModel argb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF,
- 0xFF000000);
private boolean hasFastCM;
private boolean hasAlpha;
@@ -117,12 +110,12 @@ public class BufferedImageGraphics extends CairoGraphics2D
imageHeight = bi.getHeight();
locked = false;
- if(bi.getColorModel().equals(rgb32))
+ if(bi.getColorModel().equals(CairoSurface.cairoCM_opaque))
{
hasFastCM = true;
hasAlpha = false;
}
- else if(bi.getColorModel().equals(argb32))
+ else if(bi.getColorModel().equals(CairoSurface.cairoColorModel))
{
hasFastCM = true;
hasAlpha = true;
@@ -176,8 +169,11 @@ public class BufferedImageGraphics extends CairoGraphics2D
imageWidth = copyFrom.imageWidth;
imageHeight = copyFrom.imageHeight;
locked = false;
+
+ hasFastCM = copyFrom.hasFastCM;
+ hasAlpha = copyFrom.hasAlpha;
+
copy( copyFrom, cairo_t );
- setClip(0, 0, surface.width, surface.height);
}
/**
@@ -188,6 +184,13 @@ public class BufferedImageGraphics extends CairoGraphics2D
if (locked)
return;
+ double[] points = new double[]{x, y, width+x, height+y};
+ transform.transform(points, 0, points, 0, 2);
+ x = (int)points[0];
+ y = (int)points[1];
+ width = (int)(points[2] - x);
+ height = (int)(points[3] - y);
+
int[] pixels = surface.getPixels(imageWidth * imageHeight);
if( x > imageWidth || y > imageHeight )
diff --git a/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
index 68ada66fb..bb4debbf9 100644
--- a/gnu/java/awt/peer/gtk/CairoGraphics2D.java
+++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
@@ -134,6 +134,7 @@ public abstract class CairoGraphics2D extends Graphics2D
* The current paint
*/
Paint paint;
+ boolean customPaint;
/**
* The current stroke
@@ -255,6 +256,8 @@ public abstract class CairoGraphics2D extends Graphics2D
bg = new Color(g.bg.getRGB());
}
+ firstClip = g.firstClip;
+ originalClip = g.originalClip;
clip = g.getClip();
if (g.transform == null)
@@ -311,6 +314,11 @@ public abstract class CairoGraphics2D extends Graphics2D
int width, int height, int dx, int dy);
+ /**
+ * Find the bounds of this graphics context, in device space.
+ *
+ * @return the bounds in device-space
+ */
protected abstract Rectangle2D getRealBounds();
////// Native Methods ////////////////////////////////////////////////////
@@ -336,7 +344,8 @@ public abstract class CairoGraphics2D extends Graphics2D
int g2, int b2, int a2, boolean cyclic);
private native void setPaintPixels(long pointer, int[] pixels, int w,
- int h, int stride, boolean repeat);
+ int h, int stride, boolean repeat,
+ int x, int y);
/**
* Set the current transform matrix
@@ -691,6 +700,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (paint instanceof Color)
{
setColor((Color) paint);
+ customPaint = false;
}
else if (paint instanceof TexturePaint)
{
@@ -708,7 +718,8 @@ public abstract class CairoGraphics2D extends Graphics2D
AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
BufferedImage texture = op.filter(img, null);
int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
- setPaintPixels(nativePointer, pixels, width, height, width, true);
+ setPaintPixels(nativePointer, pixels, width, height, width, true, 0, 0);
+ customPaint = false;
}
else if (paint instanceof GradientPaint)
{
@@ -721,36 +732,90 @@ public abstract class CairoGraphics2D extends Graphics2D
c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha(),
c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha(),
gp.isCyclic());
+ customPaint = false;
}
else
{
- // Get bounds in device space
- int minX = 0;
- int minY = 0;
- int width = (int)getRealBounds().getWidth();
- int height = (int)getRealBounds().getHeight();
-
- Point2D origin = transform.transform(new Point2D.Double(minX, minY),
- null);
- Point2D extreme = transform.transform(new Point2D.Double(width + minX,
- height + minY),
- null);
- minX = (int)origin.getX();
- minY = (int)origin.getY();
- width = (int)extreme.getX() - minX;
- height = (int)extreme.getY() - minY;
-
- // Get raster of the paint background
- PaintContext pc = paint.createContext(ColorModel.getRGBdefault(),
- new Rectangle(minX, minY,
- width, height),
- getRealBounds(),
- transform, hints);
+ customPaint = true;
+ }
+ }
+
+ /**
+ * Sets a custom paint
+ *
+ * @param bounds the bounding box, in user space
+ */
+ protected void setCustomPaint(Rectangle bounds)
+ {
+ if (paint instanceof Color || paint instanceof TexturePaint
+ || paint instanceof GradientPaint)
+ return;
+
+ int userX = bounds.x;
+ int userY = bounds.y;
+ int userWidth = bounds.width;
+ int userHeight = bounds.height;
+
+ // Find bounds in device space
+ Point2D origin = transform.transform(new Point2D.Double(userX, userY),
+ null);
+ Point2D extreme = transform.transform(new Point2D.Double(userWidth + userX,
+ userHeight + userY),
+ null);
+ int deviceX = (int)origin.getX();
+ int deviceY = (int)origin.getY();
+ int deviceWidth = (int)extreme.getX() - deviceX;
+ int deviceHeight = (int)extreme.getY() - deviceY;
+
+ // Get raster of the paint background
+ PaintContext pc = paint.createContext(CairoSurface.cairoColorModel,
+ new Rectangle(deviceX, deviceY,
+ deviceWidth,
+ deviceHeight),
+ bounds,
+ transform, hints);
+
+ Raster raster = pc.getRaster(deviceX, deviceY, deviceWidth,
+ deviceHeight);
+
+ // Clear the transform matrix in Cairo, since the raster returned by the
+ // PaintContext is already in device-space
+ AffineTransform oldTx = new AffineTransform(transform);
+ setTransformImpl(new AffineTransform());
+
+ // Set pixels in cairo, aligning the top-left of the background image
+ // to the top-left corner in device space
+ if (pc.getColorModel().equals(CairoSurface.cairoColorModel)
+ && raster.getSampleModel().getTransferType() == DataBuffer.TYPE_INT)
+ {
+ // Use a fast copy if the paint context can uses a Cairo-compatible
+ // color model
+ setPaintPixels(nativePointer,
+ (int[])raster.getDataElements(0, 0, deviceWidth,
+ deviceHeight, null),
+ deviceWidth, deviceHeight, deviceWidth, false,
+ deviceX, deviceY);
+ }
+
+ else if (pc.getColorModel().equals(CairoSurface.cairoCM_opaque)
+ && raster.getSampleModel().getTransferType() == DataBuffer.TYPE_INT)
+ {
+ // We can also optimize if the context uses a similar color model
+ // but without an alpha channel; we just add the alpha
+ int[] pixels = (int[])raster.getDataElements(0, 0, deviceWidth,
+ deviceHeight, null);
- Raster raster = pc.getRaster(minX, minY, width, height);
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = 0xff000000 | (pixels[i] & 0x00ffffff);
- // Work around colorspace issues, and force use of the
- // BufferedImage.getRGB method... this can be improved upon.
+ setPaintPixels(nativePointer, pixels, deviceWidth, deviceHeight,
+ deviceWidth, false, deviceX, deviceY);
+ }
+
+ else
+ {
+ // Fall back on wrapping the raster in a BufferedImage, and
+ // use BufferedImage.getRGB() to do color-model conversion
WritableRaster wr = Raster.createWritableRaster(raster.getSampleModel(),
new Point(raster.getMinX(),
raster.getMinY()));
@@ -760,15 +825,15 @@ public abstract class CairoGraphics2D extends Graphics2D
pc.getColorModel().isAlphaPremultiplied(),
null);
- // Set pixels in cairo
setPaintPixels(nativePointer,
- img2.getRGB(0, 0, width, height, null, 0, width),
- width, height, width, false);
- // setPaintPixels(nativePointer,
- // raster.getPixels(0, 0, width, height, (int[])null),
- // width, height, width, false);
- // doesn't work... but would be much more efficient!
+ img2.getRGB(0, 0, deviceWidth, deviceHeight, null, 0,
+ deviceWidth),
+ deviceWidth, deviceHeight, deviceWidth, false,
+ deviceX, deviceY);
}
+
+ // Restore transform
+ setTransformImpl(oldTx);
}
public Stroke getStroke()
@@ -1023,6 +1088,9 @@ public abstract class CairoGraphics2D extends Graphics2D
return;
}
+ if (customPaint)
+ setCustomPaint(s.getBounds());
+
createPath(s, true);
cairoStroke(nativePointer);
}
@@ -1031,6 +1099,9 @@ public abstract class CairoGraphics2D extends Graphics2D
{
createPath(s, false);
+ if (customPaint)
+ setCustomPaint(s.getBounds());
+
double alpha = 1.0;
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
@@ -1132,6 +1203,9 @@ public abstract class CairoGraphics2D extends Graphics2D
// The coordinates being pairwise identical means one wants
// to draw a single pixel. This is emulated by drawing
// a one pixel sized rectangle.
+ if (customPaint)
+ setCustomPaint(new Rectangle(x1, y1, x2 - x1, y2 - y1));
+
if (x1 == x2 && y1 == y2)
cairoFillRect(nativePointer, x1, y1, 1, 1);
else
@@ -1140,6 +1214,9 @@ public abstract class CairoGraphics2D extends Graphics2D
public void drawRect(int x, int y, int width, int height)
{
+ if (customPaint)
+ setCustomPaint(new Rectangle(x, y, width, height));
+
cairoDrawRect(nativePointer, shifted(x, shiftDrawCalls),
shifted(y, shiftDrawCalls), width, height);
}
@@ -1550,6 +1627,9 @@ public abstract class CairoGraphics2D extends Graphics2D
if( gv.getNumGlyphs() <= 0 )
return;
+ if (customPaint)
+ setCustomPaint(gv.getOutline().getBounds());
+
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
if (gv instanceof FreetypeGlyphVector && alpha == 1.0)
@@ -1908,4 +1988,4 @@ public abstract class CairoGraphics2D extends Graphics2D
return rect;
}
-}
+} \ No newline at end of file
diff --git a/gnu/java/awt/peer/gtk/CairoSurface.java b/gnu/java/awt/peer/gtk/CairoSurface.java
index d3b3d4504..5b63e62e7 100644
--- a/gnu/java/awt/peer/gtk/CairoSurface.java
+++ b/gnu/java/awt/peer/gtk/CairoSurface.java
@@ -88,6 +88,11 @@ public class CairoSurface extends WritableRaster
0xFF000000,
true,
Buffers.smallestAppropriateTransferType(32));
+
+ // This CM corresponds to the CAIRO_FORMAT_RGB24 type in Cairo
+ static ColorModel cairoCM_opaque = new DirectColorModel(24, 0x00FF0000,
+ 0x0000FF00,
+ 0x000000FF);
/**
* Allocates and clears the buffer and creates the cairo surface.
* @param width, height - the image size
diff --git a/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h b/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
index f32b9381b..c4a7f1b02 100644
--- a/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
+++ b/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
@@ -14,7 +14,7 @@ JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init (JNIEnv
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_disposeNative (JNIEnv *env, jobject, jlong);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels (JNIEnv *env, jobject, jlong, jintArray, jint, jint, jint, jdoubleArray, jdouble, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient (JNIEnv *env, jobject, jlong, jdouble, jdouble, jdouble, jdouble, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels (JNIEnv *env, jobject, jlong, jintArray, jint, jint, jint, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels (JNIEnv *env, jobject, jlong, jintArray, jint, jint, jint, jboolean, jint, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetMatrix (JNIEnv *env, jobject, jlong, jdoubleArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoScale (JNIEnv *env, jobject, jlong, jdouble, jdouble);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator (JNIEnv *env, jobject, jlong, jint);
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
index 11b0426c6..bd63ac366 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
@@ -148,7 +148,8 @@ Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong pointer, jintArray jarr, jint w, jint h, jint stride, jboolean repeat)
+ jlong pointer, jintArray jarr, jint w, jint h, jint stride, jboolean repeat,
+ jint x, jint y)
{
struct cairographics2d *gr = NULL;
jint *jpixels = NULL;
@@ -184,12 +185,12 @@ Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setPaintPixels
gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
g_assert (gr->pattern != NULL);
+ cairo_set_source_surface(gr->cr, gr->pattern_surface, x, y);
+
if (repeat)
- cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
+ cairo_pattern_set_extend(cairo_get_source(gr->cr), CAIRO_EXTEND_REPEAT);
else
- cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_NONE);
-
- cairo_set_source (gr->cr, gr->pattern);
+ cairo_pattern_set_extend(cairo_get_source(gr->cr), CAIRO_EXTEND_NONE);
}
JNIEXPORT void JNICALL