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
This commit is contained in:
Thomas Fitzsimmons
2006-06-14 03:38:34 +00:00
committed by Thomas Fitzsimmons
parent e3d437c056
commit 648e8d6dd3
102 changed files with 3933 additions and 4458 deletions
@@ -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,163 +307,186 @@ 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 ///////////////////////////////////
/**
* Set the current transform
*/
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;
clip = s;
cairoResetClip(nativePointer);
cairoResetClip();
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;
}
}
@@ -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);
native long getFlippedBuffer(int size);
public void setPixels(int[] pixels)
{
nativeSetPixels(bufferPointer, pixels);
}
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);
}
}
@@ -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()
@@ -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)
{
drawVolatile( component, img, x, y - 20,
width, height );
return true;
}
return super.drawImage( img, x, y, width, height, observer );
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
{
ImageProducer source = img.getSource();
if (source == null)
return false;
bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
}
return super.drawImage(bimg, x, y, width, height, observer);
}
}
@@ -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,10 +84,21 @@ 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;
@@ -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;
}
}
@@ -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 );
}
}
@@ -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
@@ -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,
@@ -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 copyArea( int x, int y, int w, int h, int dx, int dy );
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 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()
@@ -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);
}
}