aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt/peer
diff options
context:
space:
mode:
authorThomas Fitzsimmons <fitzsim@redhat.com>2006-06-14 03:38:34 +0000
committerThomas Fitzsimmons <fitzsim@gcc.gnu.org>2006-06-14 03:38:34 +0000
commit648e8d6dd39f9bb1a61b7886007088e1064f7dae (patch)
tree4ead311615cefc89deebca761f0deb7edf23dcb8 /libjava/classpath/gnu/java/awt/peer
parente3d437c0561389c39a8232327982baba7e9dfe46 (diff)
downloadgcc-648e8d6dd39f9bb1a61b7886007088e1064f7dae.zip
gcc-648e8d6dd39f9bb1a61b7886007088e1064f7dae.tar.gz
gcc-648e8d6dd39f9bb1a61b7886007088e1064f7dae.tar.bz2
configure: Regenerate.
2006-06-13 Thomas Fitzsimmons <fitzsim@redhat.com> * configure: Regenerate. * Makefile.in: Regenerate. * configure.ac (--enable-plugin): New option. (ac_configure_args): Add --enable-tool-wrappers. (ac_configure_args): Add --disable-plugin unless --enable-plugin was specified. * gcj/Makefile.in: Regenerate. * sources.am (gnu_java_net_source_files): Add classpath/gnu/java/net/IndexListParser.java. (property_files): Remove classpath/resource/gnu/classpath/tools/jarsigner/MessageBundle.properties, classpath/resource/gnu/classpath/tools/keytool/MessageBundle.properties. Add classpath/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties, classpath/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties, classpath/resource/gnu/classpath/tools/getopt/Messages.properties, classpath/resource/gnu/classpath/tools/jar/messages.properties, classpath/resource/gnu/classpath/tools/jarsigner/messages.properties, classpath/resource/gnu/classpath/tools/keytool/messages.properties, classpath/resource/gnu/classpath/tools/native2ascii/messages.properties, classpath/resource/gnu/classpath/tools/serialver/messages.properties. * classpath/Makefile.in: Regenerate. * classpath/native/jni/gtk-peer/cairographics2d.h, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c: Merge from GNU Classpath. * classpath/native/Makefile.in: Regenerate. * classpath/native/jawt/Makefile.in: Regenerate. * classpath/native/jawt/Makefile.am: Install libjawt.so in GCJ's versioned library directory. * classpath/native/Makefile.am: Add plugin directory if --enable-plugin was specified. * classpath/native/plugin/Makefile.in: Regenerate. * classpath/native/plugin/Makefile.am: Install libgcjwebplugin.so in GCJ's versioned library directory. * classpath/resource/gnu/classpath/tools/native2ascii/messages.properties: New file. * classpath/resource/gnu/classpath/tools/getopt/Messages.properties: Likewise. * classpath/resource/gnu/classpath/tools/jarsigner/messages.properties: Likewise. * classpath/resource/gnu/classpath/tools/jarsigner/MessageBundle.properties: Remove file. * classpath/resource/gnu/classpath/tools/keytool/messages.properties: New file. * classpath/resource/gnu/classpath/tools/keytool/MessageBundle.properties: Remove file. * classpath/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties: New file. * classpath/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties: Likewise. * classpath/resource/gnu/classpath/tools/jar/messages.properties: Likewise. * classpath/resource/gnu/classpath/tools/serialver/messages.properties: Likewise. * classpath/gnu/java/net/IndexListParser.java: Likewise. * classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java, classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java, classpath/gnu/java/awt/peer/gtk/CairoSurface.java, classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java, classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java, classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java, classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java, classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java, classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java, classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java, classpath/gnu/java/awt/font/opentype/truetype/VirtualMachine.java, classpath/gnu/java/awt/java2d/PolyEdge.java, classpath/gnu/java/awt/java2d/AbstractGraphics2D.java: Merge from GNU Classpath. * classpath/tools/toolwrapper.c: Replace tools.zip reference with libgcj-tools-4.2.0.jar. * classpath/tools/Makefile.in: Regenerate. * classpath/tools/Makefile.am: Rename tools.zip to libgcj-tools-4.2.0.jar. Install libgcj-tools-4.2.0.jar in $(datadir)/java. * classpath/javax/swing/JTabbedPane.java, classpath/javax/swing/text/DefaultStyledDocument.java, classpath/javax/swing/text/html/HTMLDocument.java, classpath/javax/swing/text/GapContent.java, classpath/javax/swing/JComponent.java, classpath/javax/swing/RepaintManager.java, classpath/javax/swing/plaf/basic/BasicComboBoxRenderer.java, classpath/javax/swing/plaf/basic/BasicScrollBarUI.java, classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java, classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java, classpath/javax/swing/plaf/basic/BasicLookAndFeel.java, classpath/javax/swing/plaf/metal/MetalButtonUI.java, classpath/java/text/Bidi.java, classpath/java/awt/image/BufferedImage.java, classpath/java/awt/datatransfer/DataFlavor.java, classpath/java/awt/geom/AffineTransform.java, classpath/java/awt/dnd/DropTargetDropEvent.java, classpath/java/awt/dnd/DropTargetContext.java, classpath/java/awt/font/TextLayout.java, classpath/include/gnu_java_awt_peer_gtk_ComponentGraphics.h, classpath/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h, classpath/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h, classpath/include/gnu_java_awt_peer_gtk_GdkTextLayout.h, classpath/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h, classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h: Merge from GNU Classpath. * classpath/include/gnu_java_awt_peer_gtk_GdkGraphics.h, classpath/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c, classpath/native/jni/gtk-peer/gtkcairopeer.h, classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c: Remove files. * classpath/Makefile.am (SUBDIRS, DIST_SUBDIRS): Include tools directory. * include/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. From-SVN: r114633
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer')
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java432
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java63
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java5
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java180
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java104
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java60
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java107
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java6
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java26
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java9
10 files changed, 744 insertions, 248 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
index 3179d33..9f8f494 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
@@ -38,14 +38,12 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
-import gnu.classpath.Configuration;
import gnu.java.awt.ClasspathToolkit;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
-import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
@@ -63,11 +61,12 @@ import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
+import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
-import java.awt.geom.Line2D;
import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
@@ -77,12 +76,11 @@ import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
-import java.awt.image.CropImageFilter;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
-import java.awt.image.FilteredImageSource;
import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
import java.awt.image.ImagingOpException;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
@@ -94,7 +92,6 @@ import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.HashMap;
import java.util.Map;
-import java.util.Stack;
/**
* This is an abstract implementation of Graphics2D on Cairo.
@@ -241,13 +238,10 @@ public abstract class CairoGraphics2D extends Graphics2D
bg = new Color(g.bg.getRGB());
}
- if (g.clip == null)
- clip = null;
- else
- clip = new Rectangle(g.getClipBounds());
+ clip = g.getClip();
if (g.transform == null)
- transform = new AffineTransform();
+ transform = null;
else
transform = new AffineTransform(g.transform);
@@ -257,7 +251,8 @@ public abstract class CairoGraphics2D extends Graphics2D
setBackground(bg);
setPaint(paint);
setStroke(stroke);
- setTransform(transform);
+ setTransformImpl(transform);
+ setClip(clip);
}
/**
@@ -275,8 +270,8 @@ public abstract class CairoGraphics2D extends Graphics2D
* they have additional native structures.
*/
public void dispose()
- {
- disposeNative();
+ {
+ disposeNative(nativePointer);
nativePointer = 0;
}
@@ -304,7 +299,7 @@ public abstract class CairoGraphics2D extends Graphics2D
/**
* Dispose of allocate native resouces.
*/
- public native void disposeNative();
+ public native void disposeNative(long pointer);
/**
* Draw pixels as an RGBA int matrix
@@ -312,119 +307,125 @@ public abstract class CairoGraphics2D extends Graphics2D
* @param stride - stride of the array width
* @param i2u - affine transform array
*/
- private native void drawPixels(int[] pixels, int w, int h, int stride,
- double[] i2u);
+ private native void drawPixels(long pointer, int[] pixels, int w, int h,
+ int stride, double[] i2u, double alpha);
- private native void setGradient(double x1, double y1, double x2, double y2,
+ private native void setGradient(long pointer, double x1, double y1,
+ double x2, double y2,
int r1, int g1, int b1, int a1, int r2,
int g2, int b2, int a2, boolean cyclic);
- private native void setTexturePixels(int[] pixels, int w, int h, int stride);
+ private native void setTexturePixels(long pointer, int[] pixels, int w,
+ int h, int stride);
/**
* Set the current transform matrix
*/
- private native void cairoSetMatrix(double[] m);
+ private native void cairoSetMatrix(long pointer, double[] m);
/**
* Set the compositing operator
*/
- private native void cairoSetOperator(int cairoOperator);
+ private native void cairoSetOperator(long pointer, int cairoOperator);
/**
* Sets the current color in RGBA as a 0.0-1.0 double
*/
- private native void cairoSetRGBAColor(double red, double green,
+ private native void cairoSetRGBAColor(long pointer, double red, double green,
double blue, double alpha);
/**
* Sets the current winding rule in Cairo
*/
- private native void cairoSetFillRule(int cairoFillRule);
+ private native void cairoSetFillRule(long pointer, int cairoFillRule);
/**
* Set the line style, cap, join and miter limit.
* Cap and join parameters are in the BasicStroke enumerations.
*/
- private native void cairoSetLine(double width, int cap, int join, double miterLimit);
+ private native void cairoSetLine(long pointer, double width, int cap,
+ int join, double miterLimit);
/**
* Set the dash style
*/
- private native void cairoSetDash(double[] dashes, int ndash, double offset);
+ private native void cairoSetDash(long pointer, double[] dashes, int ndash,
+ double offset);
/*
* Draws a Glyph Vector
*/
- native void cairoDrawGlyphVector(GdkFontPeer font,
+ native void cairoDrawGlyphVector(long pointer, GdkFontPeer font,
float x, float y, int n,
int[] codes, float[] positions);
- private native void cairoRelCurveTo(double dx1, double dy1, double dx2,
- double dy2, double dx3, double dy3);
+ private native void cairoRelCurveTo(long pointer, double dx1, double dy1,
+ double dx2, double dy2, double dx3,
+ double dy3);
/**
* Appends a rectangle to the current path
*/
- private native void cairoRectangle(double x, double y, double width,
- double height);
+ private native void cairoRectangle(long pointer, double x, double y,
+ double width, double height);
/**
* New current path
*/
- private native void cairoNewPath();
+ private native void cairoNewPath(long pointer);
/**
* Close current path
*/
- private native void cairoClosePath();
+ private native void cairoClosePath(long pointer);
/** moveTo */
- private native void cairoMoveTo(double x, double y);
+ private native void cairoMoveTo(long pointer, double x, double y);
/** relative moveTo */
- private native void cairoRelMoveTo(double dx, double dy);
+ private native void cairoRelMoveTo(long pointer, double dx, double dy);
/** lineTo */
- private native void cairoLineTo(double x, double y);
+ private native void cairoLineTo(long pointer, double x, double y);
/** relative lineTo */
- private native void cairoRelLineTo(double dx, double dy);
+ private native void cairoRelLineTo(long pointer, double dx, double dy);
/** Cubic curve-to */
- private native void cairoCurveTo(double x1, double y1, double x2, double y2,
+ private native void cairoCurveTo(long pointer, double x1, double y1,
+ double x2, double y2,
double x3, double y3);
/**
* Stroke current path
*/
- private native void cairoStroke();
+ private native void cairoStroke(long pointer);
/**
* Fill current path
*/
- private native void cairoFill();
+ private native void cairoFill(long pointer, double alpha);
/**
* Clip current path
*/
- private native void cairoClip();
+ private native void cairoClip(long pointer);
/**
* Save clip
*/
- private native void cairoPreserveClip();
+ private native void cairoPreserveClip(long pointer);
/**
* Save clip
*/
- private native void cairoResetClip();
+ private native void cairoResetClip(long pointer);
/**
* Set interpolation types
*/
- private native void cairoSurfaceSetFilter(int filter);
+ private native void cairoSurfaceSetFilter(long pointer, int filter);
///////////////////////// TRANSFORMS ///////////////////////////////////
/**
@@ -432,43 +433,60 @@ public abstract class CairoGraphics2D extends Graphics2D
*/
public void setTransform(AffineTransform tx)
{
+ // Transform clip into target space using the old transform.
+ updateClip(transform);
+
+ // Update the native transform.
+ setTransformImpl(tx);
+
+ // Transform the clip back into user space using the inverse new transform.
+ try
+ {
+ updateClip(transform.createInverse());
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // TODO: How can we deal properly with this?
+ ex.printStackTrace();
+ }
+
+ if (clip != null)
+ setClip(clip);
+ }
+
+ private void setTransformImpl(AffineTransform tx)
+ {
transform = tx;
if (transform != null)
{
- double[] m = new double[6];
- transform.getMatrix(m);
- cairoSetMatrix(m);
+ double[] m = new double[6];
+ transform.getMatrix(m);
+ cairoSetMatrix(nativePointer, m);
}
}
-
+
public void transform(AffineTransform tx)
{
if (transform == null)
transform = new AffineTransform(tx);
else
transform.concatenate(tx);
- setTransform(transform);
+
if (clip != null)
{
- // FIXME: this should actuall try to transform the shape
- // rather than degrade to bounds.
- Rectangle2D r = clip.getBounds2D();
- double[] coords = new double[]
- {
- r.getX(), r.getY(), r.getX() + r.getWidth(),
- r.getY() + r.getHeight()
- };
- try
- {
- tx.createInverse().transform(coords, 0, coords, 0, 2);
- r.setRect(coords[0], coords[1], coords[2] - coords[0],
- coords[3] - coords[1]);
- clip = r;
- }
- catch (java.awt.geom.NoninvertibleTransformException e)
- {
- }
+ try
+ {
+ AffineTransform clipTransform = tx.createInverse();
+ updateClip(clipTransform);
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // TODO: How can we deal properly with this?
+ ex.printStackTrace();
+ }
}
+
+ setTransformImpl(transform);
}
public void rotate(double theta)
@@ -501,18 +519,21 @@ public abstract class CairoGraphics2D extends Graphics2D
{
// FIXME: this should actuall try to transform the shape
// rather than degrade to bounds.
- Rectangle2D r;
-
if (clip instanceof Rectangle2D)
- r = (Rectangle2D) clip;
+ {
+ Rectangle2D r = (Rectangle2D) clip;
+ r.setRect(r.getX() - tx, r.getY() - ty, r.getWidth(),
+ r.getHeight());
+ }
else
- r = clip.getBounds2D();
-
- r.setRect(r.getX() - tx, r.getY() - ty, r.getWidth(), r.getHeight());
- clip = r;
+ {
+ AffineTransform clipTransform =
+ AffineTransform.getTranslateInstance(-tx, -ty);
+ updateClip(clipTransform);
+ }
}
- setTransform(transform);
+ setTransformImpl(transform);
}
public void translate(int x, int y)
@@ -531,19 +552,27 @@ public abstract class CairoGraphics2D extends Graphics2D
{
// Do not touch clip when s == null.
if (s == null)
- return;
+ {
+ // The spec says this should clear the clip. The reference
+ // implementation throws a NullPointerException instead. I think,
+ // in this case we should conform to the specs, as it shouldn't
+ // affect compatibility.
+ setClip(null);
+ return;
+ }
// If the current clip is still null, initialize it.
if (clip == null)
- clip = originalClip;
-
- // This is so common, let's optimize this.
- else if (clip instanceof Rectangle2D && s instanceof Rectangle2D)
+ {
+ clip = getRealBounds();
+ }
+
+ // This is so common, let's optimize this.
+ if (clip instanceof Rectangle2D && s instanceof Rectangle2D)
{
Rectangle2D clipRect = (Rectangle2D) clip;
Rectangle2D r = (Rectangle2D) s;
Rectangle2D.intersect(clipRect, r, clipRect);
- // Call setClip so that subclasses get notified.
setClip(clipRect);
}
else
@@ -603,7 +632,7 @@ 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);
- setTexturePixels(pixels, width, height, width);
+ setTexturePixels(nativePointer, pixels, width, height, width);
}
else if (paint instanceof GradientPaint)
{
@@ -612,9 +641,10 @@ public abstract class CairoGraphics2D extends Graphics2D
Point2D p2 = gp.getPoint2();
Color c1 = gp.getColor1();
Color c2 = gp.getColor2();
- setGradient(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(),
- c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(),
- c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic());
+ setGradient(nativePointer, p1.getX(), p1.getY(), p2.getX(), p2.getY(),
+ c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha(),
+ c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha(),
+ gp.isCyclic());
}
else
throw new java.lang.UnsupportedOperationException();
@@ -631,7 +661,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (stroke instanceof BasicStroke)
{
BasicStroke bs = (BasicStroke) stroke;
- cairoSetLine(bs.getLineWidth(), bs.getEndCap(),
+ cairoSetLine(nativePointer, bs.getLineWidth(), bs.getEndCap(),
bs.getLineJoin(), bs.getMiterLimit());
float[] dashes = bs.getDashArray();
@@ -640,11 +670,11 @@ public abstract class CairoGraphics2D extends Graphics2D
double[] double_dashes = new double[dashes.length];
for (int i = 0; i < dashes.length; i++)
double_dashes[i] = dashes[i];
- cairoSetDash(double_dashes, double_dashes.length,
+ cairoSetDash(nativePointer, double_dashes, double_dashes.length,
(double) bs.getDashPhase());
}
else
- cairoSetDash(new double[0], 0, 0.0);
+ cairoSetDash(nativePointer, new double[0], 0, 0.0);
}
}
@@ -675,8 +705,9 @@ public abstract class CairoGraphics2D extends Graphics2D
{
if (fg == null)
fg = Color.BLACK;
- cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0,
- fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
+ cairoSetRGBAColor(nativePointer, fg.getRed() / 255.0,
+ fg.getGreen() / 255.0,fg.getBlue() / 255.0,
+ fg.getAlpha() / 255.0);
}
public Color getColor()
@@ -686,15 +717,30 @@ public abstract class CairoGraphics2D extends Graphics2D
public void clipRect(int x, int y, int width, int height)
{
- clip(new Rectangle(x, y, width, height));
+ if (clip == null)
+ setClip(new Rectangle(x, y, width, height));
+ else if (clip instanceof Rectangle)
+ {
+ computeIntersection(x, y, width, height, (Rectangle) clip);
+ setClip(clip);
+ }
+ else
+ clip(new Rectangle(x, y, width, height));
}
public Shape getClip()
{
if (clip == null)
return null;
- else
+ else if (clip instanceof Rectangle2D)
return clip.getBounds2D(); //getClipInDevSpace();
+ else
+ {
+ GeneralPath p = new GeneralPath();
+ PathIterator pi = clip.getPathIterator(new AffineTransform());
+ p.append(pi, false);
+ return p;
+ }
}
public Rectangle getClipBounds()
@@ -734,7 +780,7 @@ public abstract class CairoGraphics2D extends Graphics2D
}
public void setClip(Shape s)
- {
+ {
// The first time the clip is set, save it as the original clip
// to reset to on s == null. We can rely on this being non-null
// because the constructor in subclasses is expected to set the
@@ -745,23 +791,23 @@ public abstract class CairoGraphics2D extends Graphics2D
firstClip = false;
}
- if (s == null)
- clip = originalClip;
- else
- clip = s;
-
- cairoResetClip();
+ clip = s;
+ cairoResetClip(nativePointer);
- cairoNewPath();
- if (clip instanceof Rectangle2D)
+ if (clip != null)
{
- Rectangle2D r = (Rectangle2D) clip;
- cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ cairoNewPath(nativePointer);
+ if (clip instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) clip;
+ cairoRectangle(nativePointer, r.getX(), r.getY(), r.getWidth(),
+ r.getHeight());
+ }
+ else
+ walkPath(clip.getPathIterator(null), false);
+
+ cairoClip(nativePointer);
}
- else
- walkPath(clip.getPathIterator(null), false);
-
- cairoClip();
}
public void setBackground(Color c)
@@ -797,10 +843,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (comp instanceof AlphaComposite)
{
AlphaComposite a = (AlphaComposite) comp;
- cairoSetOperator(a.getRule());
- Color c = getColor();
- setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(),
- (int) (a.getAlpha() * ((float) c.getAlpha()))));
+ cairoSetOperator(nativePointer, a.getRule());
}
else
{
@@ -813,38 +856,55 @@ public abstract class CairoGraphics2D extends Graphics2D
public void draw(Shape s)
{
- if (stroke != null && ! (stroke instanceof BasicStroke))
+ if ((stroke != null && ! (stroke instanceof BasicStroke))
+ || (comp instanceof AlphaComposite
+ && ((AlphaComposite) comp).getAlpha() != 1.0))
{
+ // FIXME: This is a hack to work around BasicStrokes's current
+ // limitations wrt cubic curves.
+ // See CubicSegment.getDisplacedSegments().
+ if (stroke instanceof BasicStroke)
+ {
+ PathIterator flatten = s.getPathIterator(new AffineTransform(),
+ 1.0);
+ GeneralPath p = new GeneralPath();
+ p.append(flatten, false);
+ s = p;
+ }
fill(stroke.createStrokedShape(s));
return;
}
- cairoNewPath();
+ cairoNewPath(nativePointer);
if (s instanceof Rectangle2D)
{
Rectangle2D r = (Rectangle2D) s;
- cairoRectangle(shifted(r.getX(), shiftDrawCalls),
+ cairoRectangle(nativePointer, shifted(r.getX(), shiftDrawCalls),
shifted(r.getY(), shiftDrawCalls), r.getWidth(),
r.getHeight());
}
else
walkPath(s.getPathIterator(null), shiftDrawCalls);
- cairoStroke();
+ cairoStroke(nativePointer);
}
public void fill(Shape s)
{
- cairoNewPath();
+ cairoNewPath(nativePointer);
if (s instanceof Rectangle2D)
{
Rectangle2D r = (Rectangle2D) s;
- cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ cairoRectangle(nativePointer, r.getX(), r.getY(), r.getWidth(),
+ r.getHeight());
}
else
walkPath(s.getPathIterator(null), false);
- cairoFill();
+ double alpha = 1.0;
+ if (comp instanceof AlphaComposite)
+ alpha = ((AlphaComposite) comp).getAlpha();
+ cairoFill(nativePointer, alpha);
}
/**
@@ -856,8 +916,8 @@ public abstract class CairoGraphics2D extends Graphics2D
public void clearRect(int x, int y, int width, int height)
{
if (bg != null)
- cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0,
- bg.getBlue() / 255.0, 1.0);
+ cairoSetRGBAColor(nativePointer, bg.getRed() / 255.0,
+ bg.getGreen() / 255.0, bg.getBlue() / 255.0, 1.0);
fillRect(x, y, width, height);
updateColor();
}
@@ -1005,19 +1065,19 @@ public abstract class CairoGraphics2D extends Graphics2D
|| hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION))
{
if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
- cairoSurfaceSetFilter(0);
+ cairoSurfaceSetFilter(nativePointer, 0);
else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
- cairoSurfaceSetFilter(1);
+ cairoSurfaceSetFilter(nativePointer, 1);
else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
- cairoSurfaceSetFilter(2);
+ cairoSurfaceSetFilter(nativePointer, 2);
else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
- cairoSurfaceSetFilter(3);
+ cairoSurfaceSetFilter(nativePointer, 3);
else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
- cairoSurfaceSetFilter(4);
+ cairoSurfaceSetFilter(nativePointer, 4);
}
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
@@ -1037,22 +1097,22 @@ public abstract class CairoGraphics2D extends Graphics2D
if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
{
if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
- cairoSurfaceSetFilter(0);
+ cairoSurfaceSetFilter(nativePointer, 0);
else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
- cairoSurfaceSetFilter(1);
+ cairoSurfaceSetFilter(nativePointer, 1);
}
if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
{
if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
- cairoSurfaceSetFilter(2);
+ cairoSurfaceSetFilter(nativePointer, 2);
else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
- cairoSurfaceSetFilter(3);
+ cairoSurfaceSetFilter(nativePointer, 3);
else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
- cairoSurfaceSetFilter(4);
+ cairoSurfaceSetFilter(nativePointer, 4);
}
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
@@ -1084,7 +1144,7 @@ public abstract class CairoGraphics2D extends Graphics2D
// other way around. Therefore to get the "user -> pixel" transform
// that cairo wants from "image -> user" transform that we currently
// have, we will need to invert the transformation matrix.
- AffineTransform invertedXform = new AffineTransform();
+ AffineTransform invertedXform;
try
{
@@ -1096,11 +1156,17 @@ public abstract class CairoGraphics2D extends Graphics2D
+ xform.toString());
}
- // Unrecognized image - convert to a BufferedImage and come back.
+ // Unrecognized image - convert to a BufferedImage
+ // Note - this can get us in trouble when the gdk lock is re-acquired.
+ // for example by VolatileImage. See ComponentGraphics for how we work
+ // around this.
if( !(img instanceof BufferedImage) )
- return this.drawImage(Toolkit.getDefaultToolkit().
- createImage(img.getSource()),
- xform, bgcolor, obs);
+ {
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ img = Toolkit.getDefaultToolkit().createImage(source);
+ }
BufferedImage b = (BufferedImage) img;
DataBuffer db;
@@ -1117,9 +1183,13 @@ public abstract class CairoGraphics2D extends Graphics2D
invertedXform.getMatrix(i2u);
+ double alpha = 1.0;
+ if (comp instanceof AlphaComposite)
+ alpha = ((AlphaComposite) comp).getAlpha();
+
if(db instanceof CairoSurface)
{
- ((CairoSurface)db).drawSurface(this, i2u);
+ ((CairoSurface)db).drawSurface(nativePointer, i2u, alpha);
return true;
}
@@ -1155,7 +1225,7 @@ public abstract class CairoGraphics2D extends Graphics2D
null, 0, width);
}
- drawPixels(pixels, width, height, width, i2u);
+ drawPixels(nativePointer, pixels, width, height, width, i2u, alpha);
// Cairo seems to lose the current color which must be restored.
updateColor();
@@ -1271,8 +1341,8 @@ public abstract class CairoGraphics2D extends Graphics2D
{
if (str == null || str.length() == 0)
return;
-
- drawGlyphVector(getFont().createGlyphVector(null, str), x, y);
+ (new TextLayout( str, getFont(), getFontRenderContext() )).
+ draw(this, x, y);
}
public void drawString(String str, int x, int y)
@@ -1287,12 +1357,25 @@ public abstract class CairoGraphics2D extends Graphics2D
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
- int n = gv.getNumGlyphs ();
- int[] codes = gv.getGlyphCodes (0, n, null);
- float[] positions = gv.getGlyphPositions (0, n, null);
-
- setFont (gv.getFont ());
- cairoDrawGlyphVector( (GdkFontPeer)getFont().getPeer(), x, y, n, codes, positions);
+ double alpha = 1.0;
+ if (comp instanceof AlphaComposite)
+ alpha = ((AlphaComposite) comp).getAlpha();
+ if (gv instanceof FreetypeGlyphVector && alpha == 1.0)
+ {
+ int n = gv.getNumGlyphs ();
+ int[] codes = gv.getGlyphCodes (0, n, null);
+ float[] positions = gv.getGlyphPositions (0, n, null);
+
+ setFont (gv.getFont ());
+ cairoDrawGlyphVector(nativePointer, (GdkFontPeer)getFont().getPeer(),
+ x, y, n, codes, positions);
+ }
+ else
+ {
+ translate(x, y);
+ fill(gv.getOutline());
+ translate(-x, -y);
+ }
}
public void drawString(AttributedCharacterIterator ci, float x, float y)
@@ -1445,7 +1528,11 @@ public abstract class CairoGraphics2D extends Graphics2D
for (int i = 0; i < pixels.length; i++)
pixels[i] |= 0xFF000000;
- drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
+ double alpha = 1.0;
+ if (comp instanceof AlphaComposite)
+ alpha = ((AlphaComposite) comp).getAlpha();
+ drawPixels(nativePointer, pixels, r.getWidth(), r.getHeight(),
+ r.getWidth(), i2u, alpha);
// Cairo seems to lose the current color which must be restored.
updateColor();
@@ -1473,7 +1560,7 @@ public abstract class CairoGraphics2D extends Graphics2D
double y = 0;
double[] coords = new double[6];
- cairoSetFillRule(p.getWindingRule());
+ cairoSetFillRule(nativePointer, p.getWindingRule());
for (; ! p.isDone(); p.next())
{
int seg = p.currentSegment(coords);
@@ -1482,12 +1569,12 @@ public abstract class CairoGraphics2D extends Graphics2D
case PathIterator.SEG_MOVETO:
x = shifted(coords[0], doShift);
y = shifted(coords[1], doShift);
- cairoMoveTo(x, y);
+ cairoMoveTo(nativePointer, x, y);
break;
case PathIterator.SEG_LINETO:
x = shifted(coords[0], doShift);
y = shifted(coords[1], doShift);
- cairoLineTo(x, y);
+ cairoLineTo(nativePointer, x, y);
break;
case PathIterator.SEG_QUADTO:
// splitting a quadratic bezier into a cubic:
@@ -1500,18 +1587,18 @@ public abstract class CairoGraphics2D extends Graphics2D
x = shifted(coords[2], doShift);
y = shifted(coords[3], doShift);
- cairoCurveTo(x1, y1, x2, y2, x, y);
+ cairoCurveTo(nativePointer, x1, y1, x2, y2, x, y);
break;
case PathIterator.SEG_CUBICTO:
x = shifted(coords[4], doShift);
y = shifted(coords[5], doShift);
- cairoCurveTo(shifted(coords[0], doShift),
+ cairoCurveTo(nativePointer, shifted(coords[0], doShift),
shifted(coords[1], doShift),
shifted(coords[2], doShift),
shifted(coords[3], doShift), x, y);
break;
case PathIterator.SEG_CLOSE:
- cairoClosePath();
+ cairoClosePath(nativePointer);
break;
}
}
@@ -1583,4 +1670,47 @@ public abstract class CairoGraphics2D extends Graphics2D
return db.getData();
}
+
+ /**
+ * Helper method to transform the clip. This is called by the various
+ * transformation-manipulation methods to update the clip (which is in
+ * userspace) accordingly.
+ *
+ * The transform usually is the inverse transform that was applied to the
+ * graphics object.
+ *
+ * @param t the transform to apply to the clip
+ */
+ private void updateClip(AffineTransform t)
+ {
+ if (clip == null)
+ return;
+
+ if (! (clip instanceof GeneralPath))
+ clip = new GeneralPath(clip);
+
+ GeneralPath p = (GeneralPath) clip;
+ p.transform(t);
+ }
+
+ private static Rectangle computeIntersection(int x, int y, int w, int h,
+ Rectangle rect)
+ {
+ int x2 = (int) rect.x;
+ int y2 = (int) rect.y;
+ int w2 = (int) rect.width;
+ int h2 = (int) rect.height;
+
+ int dx = (x > x2) ? x : x2;
+ int dy = (y > y2) ? y : y2;
+ int dw = (x + w < x2 + w2) ? (x + w - dx) : (x2 + w2 - dx);
+ int dh = (y + h < y2 + h2) ? (y + h - dy) : (y2 + h2 - dy);
+
+ if (dw >= 0 && dh >= 0)
+ rect.setBounds(dx, dy, dw, dh);
+ else
+ rect.setBounds(0, 0, 0, 0);
+
+ return rect;
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
index e19c9b9..5ccd2e1 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
@@ -88,49 +88,65 @@ public class CairoSurface extends DataBuffer
/**
* Allocates and clears the buffer and creates the cairo surface.
* @param width, height - the image size
- * @param stride - the buffer row stride.
+ * @param stride - the buffer row stride. (in ints)
*/
private native void create(int width, int height, int stride);
/**
* Destroys the cairo surface and frees the buffer.
*/
- private native void destroy();
+ private native void destroy(long surfacePointer, long bufferPointer);
/**
* Gets buffer elements
*/
- private native int nativeGetElem(int i);
+ private native int nativeGetElem(long bufferPointer, int i);
/**
* Sets buffer elements.
*/
- private native void nativeSetElem(int i, int val);
+ private native void nativeSetElem(long bufferPointer, int i, int val);
/**
* Draws this image to a given CairoGraphics context,
* with an affine transform given by i2u.
*/
- public native void drawSurface(CairoGraphics2D context, double[] i2u);
+ public native void nativeDrawSurface(long surfacePointer, long contextPointer,
+ double[] i2u, double alpha);
+
+ public void drawSurface(long contextPointer, double[] i2u, double alpha)
+ {
+ nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha);
+ }
/**
* getPixels -return the pixels as a java array.
*/
- native int[] getPixels(int size);
+ native int[] nativeGetPixels(long bufferPointer, int size);
+
+ public int[] getPixels(int size)
+ {
+ return nativeGetPixels(bufferPointer, size);
+ }
/**
* getPixels -return the pixels as a java array.
*/
- native void setPixels(int[] pixels);
+ native void nativeSetPixels(long bufferPointer, int[] pixels);
+
+ public void setPixels(int[] pixels)
+ {
+ nativeSetPixels(bufferPointer, pixels);
+ }
- native long getFlippedBuffer(int size);
+ native long getFlippedBuffer(long bufferPointer, int size);
/**
* Create a cairo_surface_t with specified width and height.
* The format will be ARGB32 with premultiplied alpha and native bit
* and word ordering.
*/
- CairoSurface(int width, int height)
+ public CairoSurface(int width, int height)
{
super(DataBuffer.TYPE_INT, width * height);
@@ -140,7 +156,7 @@ public class CairoSurface extends DataBuffer
this.width = width;
this.height = height;
- create(width, height, width * 4);
+ create(width, height, width);
if(surfacePointer == 0 || bufferPointer == 0)
throw new Error("Could not allocate bitmap.");
@@ -160,7 +176,7 @@ public class CairoSurface extends DataBuffer
width = image.width;
height = image.height;
- create(width, height, width * 4);
+ create(width, height, width);
if(surfacePointer == 0 || bufferPointer == 0)
throw new Error("Could not allocate bitmap.");
@@ -195,7 +211,7 @@ public class CairoSurface extends DataBuffer
public void dispose()
{
if(surfacePointer != 0)
- destroy();
+ destroy(surfacePointer, bufferPointer);
}
/**
@@ -211,7 +227,8 @@ public class CairoSurface extends DataBuffer
*/
public GtkImage getGtkImage()
{
- return new GtkImage( width, height, getFlippedBuffer( width * height ));
+ return new GtkImage( width, height,
+ getFlippedBuffer(bufferPointer, width * height ));
}
/**
@@ -251,7 +268,7 @@ public class CairoSurface extends DataBuffer
{
if(bank != 0 || i < 0 || i >= width*height)
throw new IndexOutOfBoundsException(i+" size: "+width*height);
- return nativeGetElem(i);
+ return nativeGetElem(bufferPointer, i);
}
/**
@@ -261,7 +278,7 @@ public class CairoSurface extends DataBuffer
{
if(bank != 0 || i < 0 || i >= width*height)
throw new IndexOutOfBoundsException(i+" size: "+width*height);
- nativeSetElem(i, val);
+ nativeSetElem(bufferPointer, i, val);
}
/**
@@ -277,12 +294,22 @@ public class CairoSurface extends DataBuffer
* Creates a cairo_t drawing context, returns the pointer as a long.
* Used by CairoSurfaceGraphics.
*/
- native long newCairoContext();
+ native long nativeNewCairoContext(long surfacePointer);
+
+ public long newCairoContext()
+ {
+ return nativeNewCairoContext(surfacePointer);
+ }
/**
* Copy an area of the surface. Expects parameters must be within bounds.
* Count on a segfault otherwise.
*/
- native void copyAreaNative(int x, int y, int width, int height,
- int dx, int dy, int stride);
+ native void copyAreaNative2(long bufferPointer, int x, int y, int width,
+ int height, int dx, int dy, int stride);
+ public void copyAreaNative(int x, int y, int width,
+ int height, int dx, int dy, int stride)
+ {
+ copyAreaNative2(bufferPointer, x, y, width, height, dx, dy, stride);
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
index 38c549d..91f0b49 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
@@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk;
import java.awt.Graphics;
import java.awt.Color;
+import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Graphics2D;
@@ -63,7 +64,6 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
this.surface = surface;
cairo_t = surface.newCairoContext();
setup( cairo_t );
- setClip(0, 0, surface.width, surface.height);
}
/**
@@ -75,7 +75,6 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
surface = copyFrom.surface;
cairo_t = surface.newCairoContext();
copy( copyFrom, cairo_t );
- setClip(0, 0, surface.width, surface.height);
}
public Graphics create()
@@ -85,7 +84,7 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
public GraphicsConfiguration getDeviceConfiguration()
{
- throw new UnsupportedOperationException();
+ return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
protected Rectangle2D getRealBounds()
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
index c6cf494..d1d3c28 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
@@ -46,6 +46,7 @@ import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.awt.Toolkit;
import java.awt.Point;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
@@ -53,6 +54,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
import java.awt.image.ImagingOpException;
import java.awt.image.RenderedImage;
@@ -67,6 +69,35 @@ public class ComponentGraphics extends CairoGraphics2D
private GtkComponentPeer component;
protected long cairo_t;
+ private static ThreadLocal hasLock = new ThreadLocal();
+ private static Integer ONE = Integer.valueOf(1);
+
+ private void lock()
+ {
+ Integer i = (Integer) hasLock.get();
+ if (i == null)
+ {
+ start_gdk_drawing();
+ hasLock.set(ONE);
+ }
+ else
+ hasLock.set(Integer.valueOf(i.intValue() + 1));
+ }
+
+ private void unlock()
+ {
+ Integer i = (Integer) hasLock.get();
+ if (i == null)
+ throw new IllegalStateException();
+ if (i == ONE)
+ {
+ hasLock.set(null);
+ end_gdk_drawing();
+ }
+ else
+ hasLock.set(Integer.valueOf(i.intValue() - 1));
+ }
+
ComponentGraphics()
{
}
@@ -104,8 +135,8 @@ public class ComponentGraphics extends CairoGraphics2D
*/
public void dispose()
{
- disposeSurface(nativePointer);
super.dispose();
+ disposeSurface(nativePointer);
}
/**
@@ -138,7 +169,7 @@ public class ComponentGraphics extends CairoGraphics2D
int width, int height, int dx, int dy);
private native void drawVolatile(GtkComponentPeer component,
- Image vimg, int x, int y,
+ long vimg, int x, int y,
int width, int height);
/**
@@ -180,63 +211,152 @@ public class ComponentGraphics extends CairoGraphics2D
*/
public void draw(Shape s)
{
- start_gdk_drawing();
- super.draw(s);
- end_gdk_drawing();
+ lock();
+ try
+ {
+ super.draw(s);
+ }
+ finally
+ {
+ unlock();
+ }
}
public void fill(Shape s)
{
- start_gdk_drawing();
- super.fill(s);
- end_gdk_drawing();
+ lock();
+ try
+ {
+ super.fill(s);
+ }
+ finally
+ {
+ unlock();
+ }
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
- start_gdk_drawing();
- super.drawRenderedImage(image, xform);
- end_gdk_drawing();
+ lock();
+ try
+ {
+ super.drawRenderedImage(image, xform);
+ }
+ finally
+ {
+ unlock();
+ }
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
- start_gdk_drawing();
- boolean rv = super.drawImage(img, xform, bgcolor, obs);
- end_gdk_drawing();
+ boolean rv;
+ lock();
+ try
+ {
+ rv = super.drawImage(img, xform, bgcolor, obs);
+ }
+ finally
+ {
+ unlock();
+ }
return rv;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
- start_gdk_drawing();
- super.drawGlyphVector(gv, x, y);
- end_gdk_drawing();
+ lock();
+ try
+ {
+ super.drawGlyphVector(gv, x, y);
+ }
+ finally
+ {
+ unlock();
+ }
}
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
- if( img instanceof GtkVolatileImage )
+ // If it is a GtkVolatileImage with an "easy" transform then
+ // draw directly. Always pass a BufferedImage to super to avoid
+ // deadlock (see Note in CairoGraphics.drawImage()).
+ if (img instanceof GtkVolatileImage)
{
- drawVolatile( component, img, x, y - 20,
- ((GtkVolatileImage)img).width,
- ((GtkVolatileImage)img).height );
- return true;
- }
- return super.drawImage( img, x, y, observer );
+ GtkVolatileImage vimg = (GtkVolatileImage) img;
+ int type = transform.getType();
+ if (type == AffineTransform.TYPE_IDENTITY)
+ {
+ drawVolatile(component, vimg.nativePointer,
+ x, y, vimg.width, vimg.height);
+ return true;
+ }
+ else if (type == AffineTransform.TYPE_TRANSLATION)
+ {
+ x += transform.getTranslateX();
+ y += transform.getTranslateY();
+ drawVolatile(component, vimg.nativePointer,
+ x, y, vimg.width, vimg.height);
+ return true;
+ }
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y, observer);
+ }
+
+ BufferedImage bimg;
+ if (img instanceof BufferedImage)
+ bimg = (BufferedImage) img;
+ else
+ {
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
+ }
+ return super.drawImage(bimg, x, y, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
- if( img instanceof GtkVolatileImage )
+ // If it is a GtkVolatileImage with an "easy" transform then
+ // draw directly. Always pass a BufferedImage to super to avoid
+ // deadlock (see Note in CairoGraphics.drawImage()).
+ if (img instanceof GtkVolatileImage)
+ {
+ GtkVolatileImage vimg = (GtkVolatileImage) img;
+ int type = transform.getType();
+ if (type == AffineTransform.TYPE_IDENTITY)
+ {
+ drawVolatile(component, vimg.nativePointer,
+ x, y, width, height);
+ return true;
+ }
+ else if (type == AffineTransform.TYPE_TRANSLATION)
+ {
+ x += transform.getTranslateX();
+ y += transform.getTranslateY();
+ drawVolatile(component, vimg.nativePointer,
+ x, y, width, height);
+ return true;
+ }
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y,
+ width, height, observer);
+ }
+
+ BufferedImage bimg;
+ if (img instanceof BufferedImage)
+ bimg = (BufferedImage) img;
+ else
{
- drawVolatile( component, img, x, y - 20,
- width, height );
- return true;
- }
- return super.drawImage( img, x, y, width, height, observer );
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
+ }
+ return super.drawImage(bimg, x, y, width, height, observer);
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
index 0f8ce6d..4978c6a 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
@@ -56,6 +56,9 @@ public class FreetypeGlyphVector extends GlyphVector
private Font font;
private GdkFontPeer peer; // ATTN: Accessed from native code.
+ private Rectangle2D logicalBounds;
+
+ private float[] glyphPositions;
/**
* The string represented by this GlyphVector.
*/
@@ -81,11 +84,22 @@ public class FreetypeGlyphVector extends GlyphVector
*/
private AffineTransform[] glyphTransforms;
+ private GlyphMetrics[] metricsCache;
+
/**
* Create a glyphvector from a given (Freetype) font and a String.
*/
public FreetypeGlyphVector(Font f, String s, FontRenderContext frc)
{
+ this(f, s, frc, Font.LAYOUT_LEFT_TO_RIGHT);
+ }
+
+ /**
+ * Create a glyphvector from a given (Freetype) font and a String.
+ */
+ public FreetypeGlyphVector(Font f, String s, FontRenderContext frc,
+ int flags)
+ {
this.s = s;
this.font = f;
this.frc = frc;
@@ -94,6 +108,14 @@ public class FreetypeGlyphVector extends GlyphVector
peer = (GdkFontPeer)font.getPeer();
getGlyphs();
+ if( flags == Font.LAYOUT_RIGHT_TO_LEFT )
+ {
+ // reverse the glyph ordering.
+ int[] temp = new int[ nGlyphs ];
+ for(int i = 0; i < nGlyphs; i++)
+ temp[ i ] = glyphCodes[ nGlyphs - i - 1];
+ glyphCodes = temp;
+ }
performDefaultLayout();
}
@@ -121,21 +143,25 @@ public class FreetypeGlyphVector extends GlyphVector
{
nGlyphs = s.codePointCount( 0, s.length() );
glyphCodes = new int[ nGlyphs ];
+ int[] codePoints = new int[ nGlyphs ];
int stringIndex = 0;
+
for(int i = 0; i < nGlyphs; i++)
{
- glyphCodes[i] = getGlyph( s.codePointAt(stringIndex) );
+ codePoints[i] = s.codePointAt( stringIndex );
// UTF32 surrogate handling
- if( s.codePointAt( stringIndex ) != (int)s.charAt( stringIndex ) )
+ if( codePoints[i] != (int)s.charAt( stringIndex ) )
stringIndex ++;
stringIndex ++;
}
+
+ glyphCodes = getGlyphs( codePoints );
}
/**
* Returns the glyph code within the font for a given character
*/
- public native int getGlyph(int codepoint);
+ public native int[] getGlyphs(int[] codepoints);
/**
* Returns the kerning of a glyph pair
@@ -180,12 +206,15 @@ public class FreetypeGlyphVector extends GlyphVector
*/
public void performDefaultLayout()
{
+ logicalBounds = null; // invalidate caches.
+ glyphPositions = null;
+
glyphTransforms = new AffineTransform[ nGlyphs ];
double x = 0;
+
for(int i = 0; i < nGlyphs; i++)
{
GlyphMetrics gm = getGlyphMetrics( i );
- Rectangle2D r = gm.getBounds2D();
glyphTransforms[ i ] = AffineTransform.getTranslateInstance(x, 0);
x += gm.getAdvanceX();
if( i > 0 )
@@ -235,19 +264,48 @@ public class FreetypeGlyphVector extends GlyphVector
gm.getAdvanceX(), r.getHeight() );
}
+ /*
+ * FIXME: Not all glyph types are supported.
+ * (The JDK doesn't really seem to do so either)
+ */
+ public void setupGlyphMetrics()
+ {
+ metricsCache = new GlyphMetrics[ nGlyphs ];
+
+ for(int i = 0; i < nGlyphs; i++)
+ {
+ GlyphMetrics gm = (GlyphMetrics)
+ peer.getGlyphMetrics( glyphCodes[ i ] );
+ if( gm == null )
+ {
+ double[] val = getMetricsNative( glyphCodes[ i ] );
+ if( val == null )
+ gm = null;
+ else
+ {
+ gm = new GlyphMetrics( true,
+ (float)val[1],
+ (float)val[2],
+ new Rectangle2D.Double
+ ( val[3], val[4],
+ val[5], val[6] ),
+ GlyphMetrics.STANDARD );
+ peer.putGlyphMetrics( glyphCodes[ i ], gm );
+ }
+ }
+ metricsCache[ i ] = gm;
+ }
+ }
+
/**
* Returns the metrics of a single glyph.
*/
public GlyphMetrics getGlyphMetrics(int glyphIndex)
{
- double[] val = getMetricsNative( glyphCodes[ glyphIndex ] );
- if( val == null )
- return null;
-
- return new GlyphMetrics( true, (float)val[1], (float)val[2],
- new Rectangle2D.Double( val[3], val[4],
- val[5], val[6] ),
- GlyphMetrics.STANDARD );
+ if( metricsCache == null )
+ setupGlyphMetrics();
+
+ return metricsCache[ glyphIndex ];
}
/**
@@ -275,6 +333,9 @@ public class FreetypeGlyphVector extends GlyphVector
public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
float[] positionReturn)
{
+ if( glyphPositions != null )
+ return glyphPositions;
+
float[] rval;
if( positionReturn == null )
@@ -289,6 +350,7 @@ public class FreetypeGlyphVector extends GlyphVector
rval[i * 2 + 1] = (float)p.getY();
}
+ glyphPositions = rval;
return rval;
}
@@ -316,11 +378,19 @@ public class FreetypeGlyphVector extends GlyphVector
{
if( nGlyphs == 0 )
return new Rectangle2D.Double(0, 0, 0, 0);
+ if( logicalBounds != null )
+ return logicalBounds;
Rectangle2D rect = (Rectangle2D)getGlyphLogicalBounds( 0 );
for( int i = 1; i < nGlyphs; i++ )
- rect = rect.createUnion( (Rectangle2D)getGlyphLogicalBounds( i ) );
+ {
+ Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i );
+ Point2D p = getGlyphPosition( i );
+ r2.setRect( p.getX(), p.getY(), r2.getWidth(), r2.getHeight() );
+ rect = rect.createUnion( r2 );
+ }
+ logicalBounds = rect;
return rect;
}
@@ -360,7 +430,9 @@ public class FreetypeGlyphVector extends GlyphVector
public Shape getOutline(float x, float y)
{
AffineTransform tx = AffineTransform.getTranslateInstance( x, y );
- return tx.createTransformedShape( getOutline() );
+ GeneralPath gp = (GeneralPath)getOutline();
+ gp.transform( tx );
+ return gp;
}
/**
@@ -380,6 +452,8 @@ public class FreetypeGlyphVector extends GlyphVector
// FIXME: Scaling, etc.?
glyphTransforms[ glyphIndex ].setToTranslation( newPos.getX(),
newPos.getY() );
+ logicalBounds = null;
+ glyphPositions = null;
}
/**
@@ -388,5 +462,7 @@ public class FreetypeGlyphVector extends GlyphVector
public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
{
glyphTransforms[ glyphIndex ].setTransform( newTX );
+ logicalBounds = null;
+ glyphPositions = null;
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
index 7aa5e7a..f5ed8a7 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
@@ -57,12 +57,18 @@ import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.nio.ByteBuffer;
+import java.util.HashMap;
public class GdkFontPeer extends ClasspathFontPeer
{
static native void initStaticState();
private final int native_state = GtkGenericPeer.getUniqueInteger ();
private static ResourceBundle bundle;
+
+ /**
+ * Cache GlyphMetrics objects.
+ */
+ private HashMap metricsCache;
static
{
@@ -145,6 +151,7 @@ public class GdkFontPeer extends ClasspathFontPeer
super(name, style, size);
initState ();
setFont (this.familyName, this.style, (int)this.size);
+ metricsCache = new HashMap();
}
public GdkFontPeer (String name, Map attributes)
@@ -152,6 +159,7 @@ public class GdkFontPeer extends ClasspathFontPeer
super(name, attributes);
initState ();
setFont (this.familyName, this.style, (int)this.size);
+ metricsCache = new HashMap();
}
/**
@@ -252,18 +260,25 @@ public class GdkFontPeer extends ClasspathFontPeer
public byte getBaselineFor (Font font, char c)
{
- throw new UnsupportedOperationException ();
+ // FIXME: Actually check.
+ return Font.ROMAN_BASELINE;
}
- protected class GdkFontLineMetrics extends LineMetrics
+ private static class GdkFontLineMetrics extends LineMetrics
{
- FontMetrics fm;
- int nchars;
+ private FontMetrics fm;
+ private int nchars;
+ private float strikethroughOffset, strikethroughThickness,
+ underlineOffset, underlineThickness;
- public GdkFontLineMetrics (FontMetrics m, int n)
+ public GdkFontLineMetrics (GdkFontPeer fp, FontMetrics m, int n)
{
fm = m;
nchars = n;
+ strikethroughOffset = 0f;
+ underlineOffset = 0f;
+ strikethroughThickness = ((float)fp.getSize(null)) / 12f;
+ underlineThickness = strikethroughThickness;
}
public float getAscent()
@@ -272,7 +287,8 @@ public class GdkFontPeer extends ClasspathFontPeer
}
public int getBaselineIndex()
- {
+ {
+ // FIXME
return Font.ROMAN_BASELINE;
}
@@ -303,7 +319,7 @@ public class GdkFontPeer extends ClasspathFontPeer
public LineMetrics getLineMetrics (Font font, CharacterIterator ci,
int begin, int limit, FontRenderContext rc)
{
- return new GdkFontLineMetrics (getFontMetrics (font), limit - begin);
+ return new GdkFontLineMetrics (this, getFontMetrics (font), limit - begin);
}
public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc)
@@ -350,20 +366,15 @@ public class GdkFontPeer extends ClasspathFontPeer
char[] chars, int start, int limit,
int flags)
{
- int nchars = (limit - start) + 1;
- char[] nc = new char[nchars];
-
- for (int i = 0; i < nchars; ++i)
- nc[i] = chars[start + i];
-
- return createGlyphVector (font, frc,
- new StringCharacterIterator (new String (nc)));
+ return new FreetypeGlyphVector( font, new String( chars, start,
+ limit - start),
+ frc, flags);
}
public LineMetrics getLineMetrics (Font font, String str,
FontRenderContext frc)
{
- return new GdkFontLineMetrics (getFontMetrics (font), str.length ());
+ return new GdkFontLineMetrics (this, getFontMetrics (font), str.length ());
}
public FontMetrics getFontMetrics (Font font)
@@ -372,4 +383,21 @@ public class GdkFontPeer extends ClasspathFontPeer
// the metrics cache.
return Toolkit.getDefaultToolkit().getFontMetrics (font);
}
+
+ /**
+ * Returns a cached GlyphMetrics object for a given glyphcode,
+ * or null if it doesn't exist in the cache.
+ */
+ GlyphMetrics getGlyphMetrics( int glyphCode )
+ {
+ return (GlyphMetrics)metricsCache.get( new Integer( glyphCode ) );
+ }
+
+ /**
+ * Put a GlyphMetrics object in the cache.
+ */
+ void putGlyphMetrics( int glyphCode, Object metrics )
+ {
+ metricsCache.put( new Integer( glyphCode ), metrics );
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
index 4e6181f..cd047f2 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -103,8 +103,15 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
native void pumpBytes (byte[] bytes, int len) throws IOException;
native void pumpDone () throws IOException;
native void finish (boolean needsClose);
- static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink);
-
+
+ /**
+ * Converts given image to bytes.
+ * Will call the GdkPixbufWriter for each chunk.
+ */
+ static native void streamImage(int[] bytes, String format,
+ int width, int height,
+ boolean hasAlpha, GdkPixbufWriter writer);
+
// gdk-pixbuf provids data in RGBA format
static final ColorModel cm = new DirectColorModel (32, 0xff000000,
0x00ff0000,
@@ -461,7 +468,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
}
private static class GdkPixbufWriter
- extends ImageWriter
+ extends ImageWriter implements Runnable
{
String ext;
public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext)
@@ -519,14 +526,106 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
model = img.getColorModel();
}
+ Thread workerThread = new Thread(this, "GdkPixbufWriter");
+ workerThread.start();
processImageStarted(1);
synchronized(pixbufLock)
{
streamImage(pixels, this.ext, width, height, model.hasAlpha(),
- (DataOutput) this.getOutput());
+ this);
}
+ synchronized(data)
+ {
+ data.add(DATADONE);
+ data.notifyAll();
+ }
+
+ while (workerThread.isAlive())
+ {
+ try
+ {
+ workerThread.join();
+ }
+ catch (InterruptedException ioe)
+ {
+ // Ignored.
+ }
+ }
+
+ if (exception != null)
+ throw exception;
+
processImageComplete();
}
+
+ /**
+ * Object marking end of data from native streamImage code.
+ */
+ private static final Object DATADONE = new Object();
+
+ /**
+ * Holds the data gotten from the native streamImage code.
+ * A worker thread will pull data out.
+ * Needs to be synchronized for access.
+ * The special object DATADONE is added when all data has been delivered.
+ */
+ private ArrayList data = new ArrayList();
+
+ /**
+ * Holds any IOException thrown by the run method that needs
+ * to be rethrown by the write method.
+ */
+ private IOException exception;
+
+ /** Callback for streamImage native code. **/
+ private void write(byte[] bs)
+ {
+ synchronized(data)
+ {
+ data.add(bs);
+ data.notifyAll();
+ }
+ }
+
+ public void run()
+ {
+ boolean done = false;
+ while (!done)
+ {
+ synchronized(data)
+ {
+ while (data.isEmpty())
+ {
+ try
+ {
+ data.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ /* ignore */
+ }
+ }
+
+ Object o = data.remove(0);
+ if (o == DATADONE)
+ done = true;
+ else
+ {
+ DataOutput out = (DataOutput) getOutput();
+ try
+ {
+ out.write((byte[]) o);
+ }
+ catch (IOException ioe)
+ {
+ // We are only interested in the first exception.
+ if (exception == null)
+ exception = ioe;
+ }
+ }
+ }
+ }
+ }
}
private static class GdkPixbufReader
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java
index d6b3de8..a876522 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java
@@ -1,5 +1,5 @@
/* GdkTextLayout.java
- Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -84,7 +84,7 @@ public class GdkTextLayout
private native void dispose ();
- private native void cairoDrawGdkTextLayout(CairoGraphics2D g, float x, float y);
+ private native void cairoDrawGdkTextLayout(long cg2d, float x, float y);
static native void initStaticState();
@@ -216,7 +216,7 @@ public class GdkTextLayout
public void draw (Graphics2D g2, float x, float y)
{
- cairoDrawGdkTextLayout((CairoGraphics2D)g2, x, y);
+ cairoDrawGdkTextLayout(((CairoGraphics2D) g2).nativePointer, x, y);
}
public TextHitInfo getStrongCaret (TextHitInfo hit1,
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java
index 53bcd73..f38007f 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java
@@ -57,14 +57,28 @@ public class GtkVolatileImage extends VolatileImage
native long init(GtkComponentPeer component, int width, int height);
- native void destroy();
+ native void destroy(long pointer);
- native int[] getPixels();
+ native int[] nativeGetPixels(long pointer);
+ public int[] getPixels()
+ {
+ return nativeGetPixels(nativePointer);
+ }
+
+ native void nativeCopyArea(long pointer, int x, int y, int w, int h, int dx,
+ int dy );
+ public void copyArea(int x, int y, int w, int h, int dx, int dy)
+ {
+ nativeCopyArea(nativePointer, x, y, w, h, dx, dy);
+ }
- native void copyArea( int x, int y, int w, int h, int dx, int dy );
+ native void nativeDrawVolatile(long pointer, long srcPtr, int x, int y,
+ int w, int h );
+ public void drawVolatile(long srcPtr, int x, int y, int w, int h )
+ {
+ nativeDrawVolatile(nativePointer, srcPtr, x, y, w, h);
+ }
- native void drawVolatile( long ptr, int x, int y, int w, int h );
-
public GtkVolatileImage(GtkComponentPeer component,
int width, int height, ImageCapabilities caps)
{
@@ -91,7 +105,7 @@ public class GtkVolatileImage extends VolatileImage
public void dispose()
{
- destroy();
+ destroy(nativePointer);
}
public BufferedImage getSnapshot()
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
index d5adfcf..fa84ea0 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
@@ -67,14 +67,12 @@ public class VolatileImageGraphics extends ComponentGraphics
this.owner = img;
cairo_t = initFromVolatile( owner.nativePointer, img.width, img.height );
setup( cairo_t );
- setClip( new Rectangle( 0, 0, img.width, img.height) );
}
private VolatileImageGraphics(VolatileImageGraphics copy)
{
this.owner = copy.owner;
- initFromVolatile( owner.nativePointer, owner.width, owner.height );
- setClip( new Rectangle( 0, 0, owner.width, owner.height) );
+ cairo_t = initFromVolatile(owner.nativePointer, owner.width, owner.height);
copy( copy, cairo_t );
}
@@ -118,5 +116,10 @@ public class VolatileImageGraphics extends ComponentGraphics
}
return super.drawImage( img, x, y, width, height, observer );
}
+
+ protected Rectangle2D getRealBounds()
+ {
+ return new Rectangle2D.Double(0, 0, owner.width, owner.height);
+ }
}