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

View file

@ -1066,6 +1066,10 @@ class VirtualMachine
stack[sp] = ((e1 != 0) || (stack[sp] != 0)) ? 1 : 0;
break;
case 0x5C: // NOT
stack[sp] = (stack[sp] != 0) ? 0 : 1;
break;
case 0x5e: // SDB, Set Delta Base in the graphics state
deltaBase = stack[sp--];
break;
@ -1764,7 +1768,7 @@ class VirtualMachine
/* 50 */ "LT", "LTEQ", "GT", "GTEQ",
/* 54 */ "EQ", "NEQ", "INST_56", "INST_57",
/* 58 */ "IF", "EIF", "AND", "OR",
/* 5c */ "INST_5C", "INST_5D", "SDB", "SDS",
/* 5c */ "NOT", "INST_5D", "SDB", "SDS",
/* 60 */ "ADD", "SUB", "DIV", "MUL",
/* 64 */ "ABS", "NEG", "FLOOR", "CEILING",
/* 68 */ "ROUND[0]", "ROUND[1]", "ROUND[2]", "ROUND[3]",

View file

@ -1331,8 +1331,8 @@ public abstract class AbstractGraphics2D
{
AffineTransform t = new AffineTransform();
t.translate(x, y);
double scaleX = (double) image.getWidth(observer) / (double) width;
double scaleY = (double) image.getHeight(observer) / (double) height;
double scaleX = (double) width / (double) image.getWidth(observer);
double scaleY = (double) height / (double) image.getHeight(observer);
t.scale(scaleX, scaleY);
return drawImage(image, t, observer);
}
@ -1473,15 +1473,11 @@ public abstract class AbstractGraphics2D
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
}
double offs = 0.5;
if (antialias)
offs = offs / AA_SAMPLING;
Rectangle2D userBounds = s.getBounds2D();
Rectangle2D deviceBounds = new Rectangle2D.Double();
ArrayList segs = getSegments(s, transform, deviceBounds, false, offs);
ArrayList segs = getSegments(s, transform, deviceBounds, false);
Rectangle2D clipBounds = new Rectangle2D.Double();
ArrayList clipSegs = getSegments(clip, transform, clipBounds, true, offs);
ArrayList clipSegs = getSegments(clip, transform, clipBounds, true);
segs.addAll(clipSegs);
Rectangle2D inclClipBounds = new Rectangle2D.Double();
Rectangle2D.union(clipBounds, deviceBounds, inclClipBounds);
@ -1676,7 +1672,10 @@ public abstract class AbstractGraphics2D
// Scan all relevant lines.
int minYInt = (int) Math.ceil(icMinY);
for (int y = minYInt; y <= maxY; y++)
Rectangle devClip = getDeviceBounds();
int scanlineMax = (int) Math.min(maxY, devClip.getMaxY());
for (int y = minYInt; y < scanlineMax; y++)
{
ArrayList bucket = edgeTable[y - minYInt];
// Update all the x intersections in the current activeEdges table
@ -2169,8 +2168,7 @@ public abstract class AbstractGraphics2D
* @return a list of PolyEdge that form the shape in device space
*/
private ArrayList getSegments(Shape s, AffineTransform t,
Rectangle2D deviceBounds, boolean isClip,
double offs)
Rectangle2D deviceBounds, boolean isClip)
{
// Flatten the path. TODO: Determine the best flattening factor
// wrt to speed and quality.
@ -2213,14 +2211,14 @@ public abstract class AbstractGraphics2D
else if (segType == PathIterator.SEG_CLOSE)
{
// Close the polyline.
PolyEdge edge = new PolyEdge(segX, segY - offs,
polyX, polyY - offs, isClip);
PolyEdge edge = new PolyEdge(segX, segY,
polyX, polyY, isClip);
segs.add(edge);
}
else if (segType == PathIterator.SEG_LINETO)
{
PolyEdge edge = new PolyEdge(segX, segY - offs,
seg[0], seg[1] - offs, isClip);
PolyEdge edge = new PolyEdge(segX, segY,
seg[0], seg[1], isClip);
segs.add(edge);
segX = seg[0];
segY = seg[1];

View file

@ -118,6 +118,7 @@ public class PolyEdge
public String toString()
{
return "Edge: " + x0 + ", " + y0 + ", " + x1 + ", " + y1 + ", slope: "
+ slope + ", xIntersection: " + xIntersection;
+ slope + ", xIntersection: " + xIntersection
+ ", isClip: " + isClip;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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()

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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 );
}
}

View file

@ -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

View file

@ -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,

View file

@ -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()

View file

@ -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);
}
}

View file

@ -0,0 +1,177 @@
/* IndexListParser.java --
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.jar.JarFile;
/**
* The INDEX.LIST file contains sections each separated by a blank line.
* Each section defines the content of a jar, with a
* header defining the jar file path name, followed by a list of paths.
* The jar file paths are relative to the codebase of the root jar.
*
Specification
index file : version-info blankline section*
version-info : JarIndex-Version: version-number
version-number : digit+{.digit+}*
section : body blankline
body : header name*
header : char+.jar newline
name : char+ newline
* @author langel at redhat dot com
*/
public class IndexListParser
{
public static final String JAR_INDEX_FILE = "META-INF/INDEX.LIST";
public static final String JAR_INDEX_VERSION_KEY = "JarIndex-Version: ";
double versionNumber;
// Map each jar to the prefixes defined for the jar.
// This is intentionally kept in insertion order.
LinkedHashMap prefixes = new LinkedHashMap();
/**
* Parses the given jarfile's INDEX.LIST file if it exists.
*
* @param jarfile - the given jar file
* @param baseJarURL - the codebase of the jar file
* @param baseURL - the base url for the headers
*/
public IndexListParser(JarFile jarfile, URL baseJarURL, URL baseURL)
{
try
{
// Parse INDEX.LIST if it exists
if (jarfile.getEntry(JAR_INDEX_FILE) != null)
{
BufferedReader br = new BufferedReader(new InputStreamReader(new URL(baseJarURL,
JAR_INDEX_FILE).openStream()));
// Must start with version info
String line = br.readLine();
if (!line.startsWith(JAR_INDEX_VERSION_KEY))
return;
versionNumber = Double.parseDouble(line.substring(JAR_INDEX_VERSION_KEY.length()).trim());
// Blank line must be next
line = br.readLine();
if (! "".equals(line))
{
clearAll();
return;
}
// May contain sections.
while ((line = br.readLine()) != null)
{
URL jarURL = new URL(baseURL, line);
HashSet values = new HashSet();
// Read the names in the section.
while ((line = br.readLine()) != null)
{
// Stop at section boundary.
if ("".equals(line))
break;
values.add(line.trim());
}
prefixes.put(jarURL, values);
// Might have seen an early EOF.
if (line == null)
break;
}
br.close();
}
// else INDEX.LIST does not exist
}
catch (Exception ex)
{
clearAll();
}
}
/**
* Clears all the variables. This is called when parsing fails.
*/
void clearAll()
{
versionNumber = 0;
prefixes = null;
}
/**
* Gets the version info for the file.
*
* @return the version info.
*/
public String getVersionInfo()
{
return JAR_INDEX_VERSION_KEY + getVersionNumber();
}
/**
* Gets the version number of the file.
*
* @return the version number.
*/
public double getVersionNumber()
{
return versionNumber;
}
/**
* Gets the map of all the headers found in the file.
* The keys in the map are URLs of jars. The values in the map
* are Sets of package prefixes (and top-level file names), as
* specifed in INDEX.LIST.
*
* @return an map of all the headers, or null if no INDEX.LIST was found
*/
public LinkedHashMap getHeaders()
{
return prefixes;
}
}