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:
parent
e3d437c056
commit
648e8d6dd3
102 changed files with 3933 additions and 4458 deletions
|
@ -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]",
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
177
libjava/classpath/gnu/java/net/IndexListParser.java
Normal file
177
libjava/classpath/gnu/java/net/IndexListParser.java
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue