|
From: <ls...@us...> - 2007-01-07 18:41:28
|
Revision: 3043
http://jnode.svn.sourceforge.net/jnode/?rev=3043&view=rev
Author: lsantha
Date: 2007-01-07 10:41:27 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/AWTEvent.java
trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java
trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java
trunk/core/src/classpath/java/java/awt/BasicStroke.java
trunk/core/src/classpath/java/java/awt/CardLayout.java
trunk/core/src/classpath/java/java/awt/FileDialog.java
trunk/core/src/classpath/java/java/awt/FlowLayout.java
trunk/core/src/classpath/java/java/awt/GridBagLayout.java
trunk/core/src/classpath/java/java/awt/GridLayout.java
trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java
trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java
trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java
trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java
trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java
trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java
trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java
trunk/core/src/classpath/java/java/awt/font/TextLayout.java
trunk/core/src/classpath/java/java/awt/font/TextMeasurer.java
trunk/core/src/classpath/java/java/awt/geom/Arc2D.java
trunk/core/src/classpath/java/java/awt/geom/GeneralPath.java
trunk/core/src/classpath/java/java/awt/geom/RectangularShape.java
trunk/core/src/classpath/java/java/awt/geom/RoundRectangle2D.java
trunk/core/src/classpath/java/java/awt/print/PrinterJob.java
trunk/core/src/classpath/java/java/lang/Package.java
trunk/core/src/classpath/java/java/lang/Void.java
trunk/core/src/classpath/java/java/math/BigDecimal.java
trunk/core/src/classpath/java/java/math/BigInteger.java
trunk/core/src/classpath/java/java/math/MathContext.java
trunk/core/src/classpath/java/java/net/MimeTypeMapper.java
trunk/core/src/classpath/java/java/nio/channels/Channel.java
trunk/core/src/classpath/java/java/nio/channels/Selector.java
trunk/core/src/classpath/java/java/nio/channels/spi/AbstractSelectableChannel.java
trunk/core/src/classpath/java/java/nio/channels/spi/AbstractSelector.java
trunk/core/src/classpath/java/java/nio/charset/Charset.java
trunk/core/src/classpath/java/java/nio/charset/spi/CharsetProvider.java
trunk/core/src/classpath/java/java/security/AlgorithmParametersSpi.java
trunk/core/src/classpath/java/java/security/BasicPermission.java
trunk/core/src/classpath/java/java/security/IdentityScope.java
trunk/core/src/classpath/java/java/security/KeyFactorySpi.java
trunk/core/src/classpath/java/java/security/KeyStoreSpi.java
trunk/core/src/classpath/java/java/security/PermissionCollection.java
trunk/core/src/classpath/java/java/security/Permissions.java
trunk/core/src/classpath/java/java/security/Security.java
trunk/core/src/classpath/java/java/util/jar/Attributes.java
trunk/core/src/classpath/java/java/util/jar/JarEntry.java
trunk/core/src/classpath/java/java/util/jar/JarFile.java
trunk/core/src/classpath/java/java/util/jar/Manifest.java
trunk/core/src/classpath/java/java/util/regex/Matcher.java
trunk/core/src/classpath/java/java/util/regex/Pattern.java
trunk/core/src/classpath/java/java/util/zip/DeflaterEngine.java
trunk/core/src/classpath/java/java/util/zip/Inflater.java
trunk/core/src/classpath/java/java/util/zip/ZipFile.java
trunk/core/src/classpath/java/java/util/zip/ZipInputStream.java
Modified: trunk/core/src/classpath/java/java/awt/AWTEvent.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTEvent.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTEvent.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -262,9 +262,17 @@
*/
public String toString ()
{
+ String src;
+ if (source instanceof Component)
+ src = ((Component) source).getName();
+ else if (source instanceof MenuComponent)
+ src = ((MenuComponent) source).getName();
+ else if (source != null)
+ src = source.toString();
+ else
+ src = "null";
String string = getClass ().getName () + "[" + paramString () + "] on "
- + source;
-
+ + src;
return string;
}
Modified: trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1175,16 +1175,17 @@
* @throws IllegalArgumentException if type is Void.TYPE
* @since 1.4
*/
- public static EventListener[] getListeners(EventListener l, Class type)
+ public static <T extends EventListener> T[] getListeners(EventListener l,
+ Class<T> type)
{
- ArrayList list = new ArrayList();
+ ArrayList<EventListener> list = new ArrayList<EventListener>();
if (l instanceof AWTEventMulticaster)
((AWTEventMulticaster) l).getListeners(list, type);
else if (type.isInstance(l))
list.add(l);
EventListener[] r = (EventListener[]) Array.newInstance(type, list.size());
list.toArray(r);
- return r;
+ return (T[]) r;
}
/**
Modified: trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* AWTKeyStroke.java -- an immutable key stroke
- Copyright (C) 2002, 2004, 2005 Free Software Foundation
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -65,6 +65,7 @@
* no-arg constructor (of any accessibility).
*
* @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
* @see #getAWTKeyStroke(char)
* @since 1.4
* @status updated to 1.4
@@ -85,14 +86,16 @@
* under the assumption that garbage collection of a new keystroke is
* easy when we find the old one that it matches in the cache.
*/
- private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true)
+ private static final LinkedHashMap<AWTKeyStroke,AWTKeyStroke> cache =
+ new LinkedHashMap<AWTKeyStroke,AWTKeyStroke>(11, 0.75f, true)
{
/** The largest the keystroke cache can grow. */
private static final int MAX_CACHE_SIZE = 2048;
/** Prune stale entries. */
- protected boolean removeEldestEntry(Map.Entry eldest)
- { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround.
+ protected boolean removeEldestEntry(Entry<AWTKeyStroke,AWTKeyStroke>
+ eldest)
+ {
return size() > MAX_CACHE_SIZE;
}
};
@@ -114,7 +117,7 @@
*
* @see #getAWTKeyStroke(String)
*/
- static final HashMap vktable = new HashMap();
+ static final HashMap<String,Object> vktable = new HashMap<String,Object>();
static
{
// Using reflection saves the hassle of keeping this in sync with KeyEvent,
@@ -229,7 +232,7 @@
* @throws IllegalArgumentException subclass doesn't have no-arg constructor
* @throws ClassCastException subclass doesn't extend AWTKeyStroke
*/
- protected static void registerSubclass(final Class subclass)
+ protected static void registerSubclass(final Class<?> subclass)
{
if (subclass == null)
throw new IllegalArgumentException();
@@ -252,7 +255,8 @@
throws NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException
{
- Constructor c = subclass.getDeclaredConstructor(null);
+ Constructor<?> c =
+ subclass.getDeclaredConstructor((Class<?>[])null);
c.setAccessible(true);
// Create a new instance, to make sure that we can, and
// to cause any ClassCastException.
@@ -595,7 +599,7 @@
*/
protected Object readResolve() throws ObjectStreamException
{
- AWTKeyStroke s = (AWTKeyStroke) cache.get(this);
+ AWTKeyStroke s = cache.get(this);
if (s != null)
return s;
cache.put(this, this);
Modified: trunk/core/src/classpath/java/java/awt/BasicStroke.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/BasicStroke.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/BasicStroke.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -761,9 +761,13 @@
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
dx = p1[0] - p0[0];
dy = p1[1] - p0[1];
+ if (dx != 0 && dy != 0)
+ {
l = Math.sqrt(dx * dx + dy * dy);
dx = (2.0/3.0)*width*dx/l;
dy = (2.0/3.0)*width*dy/l;
+ }
+
c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
c2 = new Point2D.Double(b.P1.getX() + dx, b.P1.getY() + dy);
a.add(new CubicSegment(a.last.P2, c1, c2, b.P1));
Modified: trunk/core/src/classpath/java/java/awt/CardLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/CardLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/CardLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -225,6 +225,8 @@
*/
public Dimension maximumLayoutSize (Container target)
{
+ if (target == null || target.ncomponents == 0)
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
// The JCL says that this returns Integer.MAX_VALUE for both
// dimensions. But that just seems wrong to me.
return getSize (target, MAX);
@@ -350,6 +352,7 @@
}
}
((Component) target).setVisible (true);
+ parent.validate();
}
}
@@ -360,7 +363,7 @@
*/
public String toString ()
{
- return getClass ().getName () + "[" + hgap + "," + vgap + "]";
+ return getClass ().getName () + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
/**
@@ -400,11 +403,11 @@
{
if (comps[i].isVisible ())
{
- if (what == NEXT)
+ if (choice == i)
{
- choice = i + 1;
- if (choice == num)
- choice = 0;
+ // Do nothing if we're already looking at the right
+ // component.
+ return;
}
else if (what == PREV)
{
@@ -412,16 +415,19 @@
if (choice < 0)
choice = num - 1;
}
- else if (choice == i)
+ else if (what == NEXT)
{
- // Do nothing if we're already looking at the right
- // component.
- return;
+ choice = i + 1;
+ if (choice == num)
+ choice = 0;
}
comps[i].setVisible (false);
if (choice >= 0)
break;
+ } else
+ {
+ comps[i].setVisible(true);
}
}
Modified: trunk/core/src/classpath/java/java/awt/FileDialog.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/FileDialog.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/FileDialog.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -95,6 +95,11 @@
*/
private int mode;
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_file_dialog_number;
+
/*************************************************************************/
/*
@@ -300,7 +305,11 @@
public synchronized void
setFile(String file)
{
+ if ("".equals(file))
+ this.file = null;
+ else
this.file = file;
+
if (peer != null)
{
FileDialogPeer f = (FileDialogPeer) peer;
@@ -366,5 +375,22 @@
",mode=" + mode + "," + super.paramString());
}
+/**
+ * Generate a unique name for this <code>FileDialog</code>.
+ *
+ * @return A unique name for this <code>FileDialog</code>.
+ */
+String
+generateName()
+{
+ return "filedlg" + getUniqueLong();
+}
+
+private static synchronized long
+getUniqueLong()
+{
+ return next_file_dialog_number++;
+}
+
} // class FileDialog
Modified: trunk/core/src/classpath/java/java/awt/FlowLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/FlowLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/FlowLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -337,6 +337,9 @@
Insets ins = parent.getInsets ();
+ if (num == 0)
+ w += 2 * hgap + ins.left + ins.right;
+ else
w += (num + 1) * hgap + ins.left + ins.right;
h += 2 * vgap + ins.top + ins.bottom;
Modified: trunk/core/src/classpath/java/java/awt/GridBagLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/GridBagLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/GridBagLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* GridBagLayout - Layout manager for components according to GridBagConstraints
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@
package java.awt;
-import gnu.classpath.NotImplementedException;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -48,6 +46,7 @@
/**
* @author Michael Koch (kon...@gm...)
* @author Jeroen Frijters (je...@fr...)
+ * @author Andrew John Hughes (gnu...@me...)
*/
public class GridBagLayout
implements Serializable, LayoutManager2
@@ -64,8 +63,8 @@
// REMAINDER constraints.
// Constraints kept in comptable are never modified, and constraints
// kept in internalcomptable can be modified internally only.
- protected Hashtable comptable;
- private Hashtable internalcomptable;
+ protected Hashtable<Component,GridBagConstraints> comptable;
+ private Hashtable<Component,GridBagConstraints> internalcomptable;
protected GridBagLayoutInfo layoutInfo;
protected GridBagConstraints defaultConstraints;
@@ -76,8 +75,8 @@
public GridBagLayout ()
{
- this.comptable = new Hashtable();
- this.internalcomptable = new Hashtable();
+ this.comptable = new Hashtable<Component,GridBagConstraints>();
+ this.internalcomptable = new Hashtable<Component,GridBagConstraints>();
this.defaultConstraints= new GridBagConstraints();
}
@@ -322,14 +321,35 @@
}
/**
- * Obsolete.
+ * Return a string representation of this GridBagLayout.
+ *
+ * @return a string representation
*/
- protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
- throws NotImplementedException
+ public String toString()
{
- // FIXME
- throw new Error ("Not implemented");
+ return getClass().getName();
}
+
+ /**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ */
+ protected void AdjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
+ {
+ Insets insets = constraints.insets;
+ if (insets != null)
+ {
+ r.x += insets.left;
+ r.y += insets.top;
+ r.width -= insets.left + insets.right;
+ r.height -= insets.top + insets.bottom;
+ }
+ }
/**
* Obsolete.
@@ -353,10 +373,9 @@
// layoutInfo. So we wait until after this for loop to set
// layoutInfo.
Component lastComp = null;
- int cellx = 0;
- int celly = 0;
- int cellw = 0;
- int cellh = 0;
+
+ Rectangle cell = new Rectangle();
+
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
@@ -370,29 +389,23 @@
if (lastComp != null
&& constraints.gridheight == GridBagConstraints.REMAINDER)
- celly += cellh;
+ cell.y += cell.height;
else
- celly = sumIntArray(info.rowHeights, constraints.gridy);
+ cell.y = sumIntArray(info.rowHeights, constraints.gridy);
if (lastComp != null
&& constraints.gridwidth == GridBagConstraints.REMAINDER)
- cellx += cellw;
+ cell.x += cell.width;
else
- cellx = sumIntArray(info.colWidths, constraints.gridx);
+ cell.x = sumIntArray(info.colWidths, constraints.gridx);
- cellw = sumIntArray(info.colWidths, constraints.gridx
- + constraints.gridwidth) - cellx;
- cellh = sumIntArray(info.rowHeights, constraints.gridy
- + constraints.gridheight) - celly;
+ cell.width = sumIntArray(info.colWidths, constraints.gridx
+ + constraints.gridwidth) - cell.x;
+ cell.height = sumIntArray(info.rowHeights, constraints.gridy
+ + constraints.gridheight) - cell.y;
- Insets insets = constraints.insets;
- if (insets != null)
- {
- cellx += insets.left;
- celly += insets.top;
- cellw -= insets.left + insets.right;
- cellh -= insets.top + insets.bottom;
- }
+ // Adjust for insets.
+ AdjustForGravity( constraints, cell );
// Note: Documentation says that padding is added on both sides, but
// visual inspection shows that the Sun implementation only adds it
@@ -403,14 +416,14 @@
switch (constraints.fill)
{
case GridBagConstraints.HORIZONTAL:
- dim.width = cellw;
+ dim.width = cell.width;
break;
case GridBagConstraints.VERTICAL:
- dim.height = cellh;
+ dim.height = cell.height;
break;
case GridBagConstraints.BOTH:
- dim.width = cellw;
- dim.height = cellh;
+ dim.width = cell.width;
+ dim.height = cell.height;
break;
}
@@ -420,40 +433,40 @@
switch (constraints.anchor)
{
case GridBagConstraints.NORTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y;
break;
case GridBagConstraints.SOUTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + cellh - dim.height;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.WEST:
- x = cellx;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.EAST:
- x = cellx + cellw - dim.width;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.NORTHEAST:
- x = cellx + cellw - dim.width;
- y = celly;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y;
break;
case GridBagConstraints.NORTHWEST:
- x = cellx;
- y = celly;
+ x = cell.x;
+ y = cell.y;
break;
case GridBagConstraints.SOUTHEAST:
- x = cellx + cellw - dim.width;
- y = celly + cellh - dim.height;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.SOUTHWEST:
- x = cellx;
- y = celly + cellh - dim.height;
+ x = cell.x;
+ y = cell.y + cell.height - dim.height;
break;
default:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
}
component.setBounds(info.pos_x + x, info.pos_y + y, dim.width,
@@ -487,16 +500,18 @@
// Guaranteed to contain the last component added to the given row
// or column, whose gridwidth/height is not REMAINDER.
- HashMap lastInRow = new HashMap();
- HashMap lastInCol = new HashMap();
+ HashMap<Integer,Component> lastInRow = new HashMap<Integer,Component>();
+ HashMap<Integer,Component> lastInCol = new HashMap<Integer,Component>();
Component[] components = parent.getComponents();
// Components sorted by gridwidths/heights,
// smallest to largest, with REMAINDER and RELATIVE at the end.
// These are useful when determining sizes and weights.
- ArrayList sortedByWidth = new ArrayList(components.length);
- ArrayList sortedByHeight = new ArrayList(components.length);
+ ArrayList<Component> sortedByWidth =
+ new ArrayList<Component>(components.length);
+ ArrayList<Component> sortedByHeight =
+ new ArrayList<Component>(components.length);
// STEP 1: first we figure out how many rows/columns
for (int i = 0; i < components.length; i++)
@@ -761,7 +776,7 @@
// STEP 3: Determine sizes and weights for columns.
for (int i = 0; i < sortedByWidth.size(); i++)
{
- Component component = (Component) sortedByWidth.get(i);
+ Component component = sortedByWidth.get(i);
// If component is not visible we dont have to care about it.
if (!component.isVisible())
@@ -875,7 +890,8 @@
* width. Otherwise, sort by height.
* FIXME: Use a better sorting algorithm.
*/
- private void sortBySpan (Component component, int span, ArrayList list, boolean sortByWidth)
+ private void sortBySpan (Component component, int span,
+ ArrayList<Component> list, boolean sortByWidth)
{
if (span == GridBagConstraints.REMAINDER
|| span == GridBagConstraints.RELATIVE)
@@ -1082,10 +1098,18 @@
}
/**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ *
* @since 1.4
*/
- protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ protected void adjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- AdjustForGravity (gbc, rect);
+ AdjustForGravity (constraints, r);
}
}
Modified: trunk/core/src/classpath/java/java/awt/GridLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/GridLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/GridLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -289,7 +289,7 @@
public String toString ()
{
return (getClass ().getName () + "["
- + ",hgap=" + hgap + ",vgap=" + vgap
+ + "hgap=" + hgap + ",vgap=" + vgap
+ ",rows=" + rows + ",cols=" + cols
+ "]");
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,14 +38,13 @@
package java.awt.datatransfer;
-import gnu.classpath.NotImplementedException;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.OptionalDataException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
@@ -76,8 +75,7 @@
* deals with bytes not chars. Use <code>getRederForText()</code>.
*/
public static final DataFlavor plainTextFlavor =
- new DataFlavor(java.io.InputStream.class,
- "text/plain; charset=unicode",
+ new DataFlavor("text/plain; charset=unicode; class=java.io.InputStream",
"plain unicode text");
/**
@@ -94,8 +92,7 @@
* element of the list being a <code>java.io.File</code>.
*/
public static final DataFlavor javaFileListFlavor =
- new DataFlavor(java.util.List.class,
- "application/x-java-file-list; class=java.util.List",
+ new DataFlavor("application/x-java-file-list; class=java.util.List",
"Java File List");
/**
@@ -132,10 +129,10 @@
*/
// The MIME type for this flavor
- private final String mimeType;
+ private MimeType mimeType;
// The representation class for this flavor
- private final Class representationClass;
+ private Class<?> representationClass;
// The human readable name of this flavor
private String humanPresentableName;
@@ -156,7 +153,7 @@
*
* @exception ClassNotFoundException If the class cannot be loaded.
*/
- protected static final Class tryToLoadClass(String className,
+ protected static final Class<?> tryToLoadClass(String className,
ClassLoader classLoader)
throws ClassNotFoundException
{
@@ -198,63 +195,7 @@
throw new ClassNotFoundException(className);
}
- private static Class getRepresentationClassFromMimeThrows(String mimeString,
- ClassLoader classLoader)
- throws ClassNotFoundException
- {
- String classname = getParameter("class", mimeString);
- if (classname != null)
- return tryToLoadClass(classname, classLoader);
- else
- return java.io.InputStream.class;
- }
-
- // Same as above, but wraps any ClassNotFoundExceptions
- private static Class getRepresentationClassFromMime(String mimeString,
- ClassLoader classLoader)
- {
- try
- {
- return getRepresentationClassFromMimeThrows(mimeString, classLoader);
- }
- catch(ClassNotFoundException cnfe)
- {
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("mimeString: "
- + mimeString
- + " classLoader: "
- + classLoader);
- iae.initCause(cnfe);
- throw iae;
- }
- }
-
/**
- * Returns the value of the named MIME type parameter, or <code>null</code>
- * if the parameter does not exist. Given the parameter name and the mime
- * string.
- *
- * @param paramName The name of the parameter.
- * @param mimeString The mime string from where the name should be found.
- *
- * @return The value of the parameter or null.
- */
- private static String getParameter(String paramName, String mimeString)
- {
- int idx = mimeString.indexOf(paramName + "=");
- if (idx == -1)
- return(null);
-
- String value = mimeString.substring(idx + paramName.length() + 1);
-
- idx = value.indexOf(";");
- if (idx == -1)
- return(value);
- else
- return(value.substring(0, idx));
- }
-
- /**
* XXX - Currently returns <code>plainTextFlavor</code>.
*/
public static final DataFlavor getTextPlainUnicodeFlavor()
@@ -321,35 +262,10 @@
*/
public DataFlavor()
{
- mimeType = null;
- representationClass = null;
- humanPresentableName = null;
+ // Used for deserialization only, nothing to do here.
}
/**
- * Private constructor.
- */
- private DataFlavor(Class representationClass,
- String mimeType,
- String humanPresentableName)
- {
- this.representationClass = representationClass;
- this.mimeType = mimeType;
-
- // Do some simple validity checks
- String type = getPrimaryType() + "/" + getSubType();
- if (type.indexOf(' ') != -1
- || type.indexOf('=') != -1
- || type.indexOf(';') != -1)
- throw new IllegalArgumentException(mimeType);
-
- if (humanPresentableName != null)
- this.humanPresentableName = humanPresentableName;
- else
- this.humanPresentableName = mimeType;
- }
-
- /**
* Initializes a new instance of <code>DataFlavor</code>. The class
* and human readable name are specified, the MIME type will be
* "application/x-java-serialized-object". If the human readable name
@@ -359,13 +275,23 @@
* @param representationClass The representation class for this object.
* @param humanPresentableName The display name of the object.
*/
- public DataFlavor(Class representationClass, String humanPresentableName)
+ public DataFlavor(Class<?> representationClass, String humanPresentableName)
{
- this(representationClass,
- "application/x-java-serialized-object"
- + "; class="
- + representationClass.getName(),
- humanPresentableName);
+ if (representationClass == null)
+ throw new NullPointerException("representationClass must not be null");
+ try
+ {
+ mimeType = new MimeType(javaSerializedObjectMimeType);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Must not happen as we use a constant string.
+ assert false;
+ }
+ if (humanPresentableName == null)
+ humanPresentableName = javaSerializedObjectMimeType;
+ this.humanPresentableName = humanPresentableName;
+ this.representationClass = representationClass;
}
/**
@@ -390,8 +316,7 @@
ClassLoader classLoader)
throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, classLoader),
- mimeType, humanPresentableName);
+ init(mimeType, humanPresentableName, classLoader);
}
/**
@@ -412,8 +337,17 @@
*/
public DataFlavor(String mimeType, String humanPresentableName)
{
- this(getRepresentationClassFromMime (mimeType, null),
- mimeType, humanPresentableName);
+ try
+ {
+ init(mimeType, humanPresentableName, getClass().getClassLoader());
+ }
+ catch (ClassNotFoundException ex)
+ {
+ IllegalArgumentException iae =
+ new IllegalArgumentException("Class not found: " + ex.getMessage());
+ iae.initCause(ex);
+ throw iae;
+ }
}
/**
@@ -432,18 +366,64 @@
*/
public DataFlavor(String mimeType) throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, null),
- mimeType, null);
+ init(mimeType, null, getClass().getClassLoader());
}
/**
+ * Called by various constructors to initialize this object.
+ *
+ * @param mime the mime string
+ * @param humanPresentableName the human presentable name
+ * @param loader the class loader to use for loading the representation
+ * class
+ */
+ private void init(String mime, String humanPresentableName,
+ ClassLoader loader)
+ throws ClassNotFoundException
+ {
+ if (mime == null)
+ throw new NullPointerException("The mime type must not be null");
+ try
+ {
+ mimeType = new MimeType(mime);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ IllegalArgumentException iae =
+ new IllegalArgumentException("Invalid mime type");
+ iae.initCause(ex);
+ throw iae;
+ }
+ String className = mimeType.getParameter("class");
+ if (className == null)
+ {
+ if (mimeType.getBaseType().equals(javaSerializedObjectMimeType))
+ throw new IllegalArgumentException("Serialized object type must have"
+ + " a representation class parameter");
+ else
+ representationClass = java.io.InputStream.class;
+ }
+ else
+ representationClass = tryToLoadClass(className, loader);
+ mimeType.addParameter("class", representationClass.getName());
+
+ if (humanPresentableName == null)
+ {
+ humanPresentableName = mimeType.getParameter("humanPresentableName");
+ if (humanPresentableName == null)
+ humanPresentableName = mimeType.getBaseType();
+ }
+ this.humanPresentableName = humanPresentableName;
+ }
+
+ /**
* Returns the MIME type of this flavor.
*
* @return The MIME type for this flavor.
*/
public String getMimeType()
{
- return(mimeType);
+ return(mimeType.toString());
}
/**
@@ -451,7 +431,7 @@
*
* @return The representation class for this flavor.
*/
- public Class getRepresentationClass()
+ public Class<?> getRepresentationClass()
{
return(representationClass);
}
@@ -473,11 +453,7 @@
*/
public String getPrimaryType()
{
- int idx = mimeType.indexOf("/");
- if (idx == -1)
- return(mimeType);
-
- return(mimeType.substring(0, idx));
+ return(mimeType.getPrimaryType());
}
/**
@@ -487,15 +463,7 @@
*/
public String getSubType()
{
- int start = mimeType.indexOf("/");
- if (start == -1)
- return "";
-
- int end = mimeType.indexOf(";", start + 1);
- if (end == -1)
- return mimeType.substring(start + 1);
- else
- return mimeType.substring(start + 1, end);
+ return mimeType.getSubType();
}
/**
@@ -511,7 +479,7 @@
if ("humanPresentableName".equals(paramName))
return getHumanPresentableName();
- return getParameter(paramName, mimeType);
+ return mimeType.getParameter(paramName);
}
/**
@@ -537,16 +505,22 @@
*/
public boolean isMimeTypeEqual(String mimeType)
{
- String mime = getMimeType();
- int i = mime.indexOf(";");
- if (i != -1)
- mime = mime.substring(0, i);
-
- i = mimeType.indexOf(";");
- if (i != -1)
- mimeType = mimeType.substring(0, i);
-
- return mime.equals(mimeType);
+ if (mimeType == null)
+ throw new NullPointerException("mimeType must not be null");
+ boolean equal = false;
+ try
+ {
+ if (this.mimeType != null)
+ {
+ MimeType other = new MimeType(mimeType);
+ equal = this.mimeType.matches(other);
+ }
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Return false in this case.
+ }
+ return equal;
}
/**
@@ -571,7 +545,7 @@
*/
public boolean isMimeTypeSerializedObject()
{
- return mimeType.startsWith(javaSerializedObjectMimeType);
+ return isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -617,8 +591,8 @@
*/
public boolean isFlavorSerializedObjectType()
{
- // FIXME: What is the diff between this and isMimeTypeSerializedObject?
- return(mimeType.startsWith(javaSerializedObjectMimeType));
+ return isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -629,7 +603,9 @@
*/
public boolean isFlavorRemoteObjectType()
{
- return(mimeType.startsWith(javaRemoteObjectMimeType));
+ return isRepresentationClassRemote()
+ && isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaRemoteObjectMimeType);
}
/**
@@ -770,7 +746,7 @@
*/
public int hashCode()
{
- return mimeType.toLowerCase().hashCode() ^ representationClass.hashCode();
+ return mimeType.toString().hashCode() ^ representationClass.hashCode();
}
/**
@@ -822,9 +798,17 @@
* @exception IOException If an error occurs.
*/
public void writeExternal(ObjectOutput stream)
- throws IOException, NotImplementedException
+ throws IOException
{
- // FIXME: Implement me
+ if (mimeType != null)
+ {
+ mimeType.addParameter("humanPresentableName", humanPresentableName);
+ stream.writeObject(mimeType);
+ mimeType.removeParameter("humanPresentableName");
+ }
+ else
+ stream.writeObject(null);
+ stream.writeObject(representationClass);
}
@@ -838,9 +822,34 @@
* cannot be found.
*/
public void readExternal(ObjectInput stream)
- throws IOException, ClassNotFoundException, NotImplementedException
+ throws IOException, ClassNotFoundException
{
- // FIXME: Implement me
+ mimeType = (MimeType) stream.readObject();
+ String className = null;
+ if (mimeType != null)
+ {
+ humanPresentableName =
+ mimeType.getParameter("humanPresentableName");
+ mimeType.removeParameter("humanPresentableName");
+ className = mimeType.getParameter("class");
+ if (className == null)
+ throw new IOException("No class in mime type");
+ }
+ try
+ {
+ representationClass = (Class) stream.readObject();
+ }
+ catch (OptionalDataException ex)
+ {
+ if (ex.eof && ex.length == 0)
+ {
+ if (className != null)
+ representationClass = tryToLoadClass(className,
+ getClass().getClassLoader());
+ }
+ else
+ throw ex;
+ }
}
/**
@@ -861,7 +870,7 @@
*
* @since 1.3
*/
- public final Class getDefaultRepresentationClass()
+ public final Class<?> getDefaultRepresentationClass()
{
return java.io.InputStream.class;
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -58,7 +58,7 @@
*
* @return A <code>Map</code> of native data types.
*/
- Map getNativesForFlavors (DataFlavor[] flavors);
+ Map<DataFlavor, String> getNativesForFlavors (DataFlavor[] flavors);
/**
* Maps the specified native type names to <code>DataFlavor</code>'s.
@@ -71,5 +71,5 @@
*
* @return A <code>Map</code> of data flavors.
*/
- Map getFlavorsForNatives (String[] natives);
+ Map<String, DataFlavor> getFlavorsForNatives (String[] natives);
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -59,7 +59,7 @@
* @param flavor the flavor to look up, or null to return all natives
* @return the sorted list of natives
*/
- List getNativesForFlavor(DataFlavor flavor);
+ List<String> getNativesForFlavor(DataFlavor flavor);
/**
* Returns a list of flavors corresponding to the given String native. The
@@ -69,5 +69,5 @@
* @param name the native name to look up, or null to return all flavors
* @return the sorted list of flavors
*/
- List getFlavorsForNative(String name);
+ List<DataFlavor> getFlavorsForNative(String name);
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,12 +38,21 @@
package java.awt.datatransfer;
-import gnu.classpath.NotImplementedException;
-
+import java.awt.Toolkit;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.WeakHashMap;
/**
@@ -72,22 +81,105 @@
* This map maps native <code>String</code>s to lists of
* <code>DataFlavor</code>s
*/
- private HashMap nativeToFlavorMap = new HashMap();
+ private HashMap<String,List<DataFlavor>> nativeToFlavorMap =
+ new HashMap<String,List<DataFlavor>>();
/**
* This map maps <code>DataFlavor</code>s to lists of native
* <code>String</code>s
*/
- private HashMap flavorToNativeMap = new HashMap();
+ private HashMap<DataFlavor, List<String>> flavorToNativeMap =
+ new HashMap<DataFlavor, List<String>>();
/**
* Private constructor.
*/
private SystemFlavorMap ()
{
+ AccessController.doPrivileged
+ (new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ try
+ {
+ // Load installed flavormap.properties first.
+ String sep = File.separator;
+ File propsFile =
+ new File(System.getProperty("gnu.classpath.home.url")
+ + sep + "accessibility.properties");
+ InputStream in = new FileInputStream(propsFile);
+ Properties props = new Properties();
+ props.load(in);
+ in.close();
+
+ String augmented = Toolkit.getProperty("AWT.DnD.flavorMapFileURL",
+ null);
+ if (augmented != null)
+ {
+ URL url = new URL(augmented);
+ in = url.openStream();
+ props.load(in);
+ }
+ setupMapping(props);
+ }
+ catch (IOException ex)
+ {
+ // Can't do anything about it.
+ }
+ return null;
+ }
+ });
}
/**
+ * Sets up the mapping from native to mime types and vice versa as specified
+ * in the flavormap.properties file.
+ *
+ * This is package private to avoid an accessor method.
+ *
+ * @param props the properties file
+ */
+ void setupMapping(Properties props)
+ {
+ Enumeration propNames = props.propertyNames();
+ while (propNames.hasMoreElements())
+ {
+ try
+ {
+ String nat = (String) propNames.nextElement();
+ String mime = (String) props.getProperty(nat);
+ // Check valid mime type.
+ MimeType type = new MimeType(mime);
+ DataFlavor flav = new DataFlavor(mime);
+
+ List<DataFlavor> flavs = nativeToFlavorMap.get(nat);
+ if (flavs == null)
+ {
+ flavs = new ArrayList<DataFlavor>();
+ nativeToFlavorMap.put(nat, flavs);
+ }
+ List<String> nats = flavorToNativeMap.get(flav);
+ if (nats == null)
+ {
+ nats = new ArrayList<String>();
+ flavorToNativeMap.put(flav, nats);
+ }
+ flavs.add(flav);
+ nats.add(nat);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // Skip.
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Skip.
+ }
+ }
+ }
+
+ /**
* Maps the specified <code>DataFlavor</code> objects to the native
* data type name. The returned <code>Map</code> has keys that are
* the data flavors and values that are strings. The returned map
@@ -98,9 +190,9 @@
*
* @return A <code>Map</code> of native data types to data flavors.
*/
- public Map getNativesForFlavors (DataFlavor[] flavors)
+ public Map<DataFlavor, String> getNativesForFlavors (DataFlavor[] flavors)
{
- return new HashMap();
+ return new HashMap<DataFlavor, String>();
}
/**
@@ -114,9 +206,9 @@
*
* @return A <code>Map</code> of data flavors to native type names.
*/
- public Map getFlavorsForNatives (String[] natives)
+ public Map<String, DataFlavor> getFlavorsForNatives (String[] natives)
{
- return new HashMap();
+ return new HashMap<String, DataFlavor>();
}
/**
@@ -263,16 +355,52 @@
* specified native and a DataFlavor whose MIME type is a decoded
* version of the native.
*/
- public List getFlavorsForNative (String nat)
- throws NotImplementedException
+ public List<DataFlavor> getFlavorsForNative(String nat)
{
- throw new Error ("Not implemented");
+ List<DataFlavor> ret = new ArrayList<DataFlavor>();
+ if (nat == null)
+ {
+ Collection<List<DataFlavor>> all = nativeToFlavorMap.values();
+ for (List<DataFlavor> list : all)
+ {
+ for (DataFlavor flav : list)
+ {
+ if (! ret.contains(flav))
+ ret.add(flav);
+ }
+ }
+ }
+ else
+ {
+ List<DataFlavor> list = nativeToFlavorMap.get(nat);
+ if (list != null)
+ ret.addAll(list);
+ }
+ return ret;
}
- public List getNativesForFlavor (DataFlavor flav)
- throws NotImplementedException
+ public List<String> getNativesForFlavor (DataFlavor flav)
{
- throw new Error ("Not implemented");
+ List<String> ret = new ArrayList<String>();
+ if (flav == null)
+ {
+ Collection<List<String>> all = flavorToNativeMap.values();
+ for (List<String> list : all)
+ {
+ for (String nat : list)
+ {
+ if (! ret.contains(nat))
+ ret.add(nat);
+ }
+ }
+ }
+ else
+ {
+ List<String> list = flavorToNativeMap.get(flav);
+ if (list != null)
+ ret.addAll(list);
+ }
+ return ret;
}
/**
@@ -298,10 +426,10 @@
{
if ((nativeStr == null) || (flavor == null))
throw new NullPointerException();
- List flavors = (List) nativeToFlavorMap.get(nativeStr);
+ List<DataFlavor> flavors = nativeToFlavorMap.get(nativeStr);
if (flavors == null)
{
- flavors = new ArrayList();
+ flavors = new ArrayList<DataFlavor>();
nativeToFlavorMap.put(nativeStr, flavors);
}
else
@@ -336,10 +464,10 @@
{
if ((nativeStr == null) || (flavor == null))
throw new NullPointerException();
- List natives = (List) flavorToNativeMap.get(flavor);
+ List<String> natives = flavorToNativeMap.get(flavor);
if (natives == null)
{
- natives = new ArrayList();
+ natives = new ArrayList<String>();
flavorToNativeMap.put(flavor, natives);
}
else
Modified: trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* ComponentEvent.java -- notification of events for components
- Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -114,24 +114,27 @@
*/
public String paramString()
{
+ StringBuffer s = new StringBuffer();
+
// Unlike Sun, we don't throw NullPointerException or ClassCastException
// when source was illegally changed.
- switch (id)
- {
- case COMPONENT_MOVED:
- return "COMPONENT_MOVED "
- + (source instanceof Component
- ? ((Component) source).getBounds() : (Object) "");
- case COMPONENT_RESIZED:
- return "COMPONENT_RESIZED "
- + (source instanceof Component
- ? ((Component) source).getBounds() : (Object) "");
- case COMPONENT_SHOWN:
- return "COMPONENT_SHOWN";
- case COMPONENT_HIDDEN:
- return "COMPONENT_HIDDEN";
- default:
+ if (id == COMPONENT_MOVED)
+ s.append("COMPONENT_MOVED ");
+ else if (id == COMPONENT_RESIZED)
+ s.append("COMPONENT_RESIZED ");
+ else if (id == COMPONENT_SHOWN)
+ s.append("COMPONENT_SHOWN ");
+ else if (id == COMPONENT_HIDDEN)
+ s.append("COMPONENT_HIDDEN ");
+ else
return "unknown type";
+
+ s.append("(").append(getComponent().getX()).append(",")
+ .append(getComponent().getY()).append(" ")
+ .append(getComponent().getWidth()).append("x")
+ .append(getComponent().getHeight()).append(")");
+
+ return s.toString();
}
- }
+
} // class ComponentEvent
Modified: trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* LineBreakMeasurer.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,84 +38,114 @@
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
import java.text.BreakIterator;
+import java.awt.Shape;
public final class LineBreakMeasurer
{
- private AttributedCharacterIterator ci;
- private FontRenderContext frc;
- private BreakIterator bi;
+ private AttributedCharacterIterator text;
+ private int position;
+ private TextMeasurer tm;
+ private int numChars;
- /**
- * Constructs a <code>LineBreakMeasurer</code> object.
- */
- public LineBreakMeasurer (AttributedCharacterIterator text,
- FontRenderContext frc)
- {
- this (text, null, frc);
- }
-
- /**
- * Constructs a <code>LineBreakMeasurer</code> object.
- */
- public LineBreakMeasurer (AttributedCharacterIterator text,
+ public LineBreakMeasurer(AttributedCharacterIterator text,
BreakIterator breakIter, FontRenderContext frc)
{
- this.ci = text;
- this.bi = breakIter;
- this.frc = frc;
+ this( text, frc );
}
- public void deleteChar (AttributedCharacterIterator newParagraph,
- int deletePos)
- throws NotImplementedException
+ public LineBreakMeasurer(AttributedCharacterIterator text,
+ FontRenderContext frc)
{
- throw new Error ("not implemented");
+ this.text = text;
+ position = 0;
+ numChars = text.getEndIndex();
+ tm = new TextMeasurer( text, frc );
}
- public int getPosition ()
+ public void deleteChar(AttributedCharacterIterator newParagraph,
+ int deletePos)
{
- return ci.getIndex ();
+ tm.deleteChar( newParagraph, deletePos );
+ position = 0;
}
- public void insertChar (AttributedCharacterIterator newParagraph,
+ public void insertChar(AttributedCharacterIterator newParagraph,
int insertPos)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ tm.insertChar( newParagraph, insertPos );
+ position = 0;
}
- public TextLayout nextLayout (float wrappingWidth)
- throws NotImplementedException
+ public TextLayout nextLayout(float wrappingWidth)
{
- throw new Error ("not implemented");
+ return nextLayout( wrappingWidth, numChars, false );
}
- public TextLayout nextLayout (float wrappingWidth, int offsetLimit,
+ public TextLayout nextLayout(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
+ TextLayout tl = tm.getLayout( position, next );
+ position = next;
+ return tl;
}
- public int nextOffset (float wrappingWidth)
- throws NotImplementedException
+ public int nextOffset(float wrappingWidth)
{
- throw new Error ("not implemented");
+ return nextOffset( wrappingWidth, numChars, false );
}
- public int nextOffset (float wrappingWidth, int offsetLimit,
+ public int nextOffset(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ int guessOffset = tm.getLineBreakIndex(position, wrappingWidth);
+ if( offsetLimit > numChars )
+ offsetLimit = numChars;
+
+ if( guessOffset > offsetLimit )
+ {
+ text.setIndex( offsetLimit );
+ return offsetLimit;
+ }
+
+ text.setIndex( guessOffset );
+
+ // If we're on a breaking character, return directly
+ if( Character.isWhitespace( text.current() ) )
+ return guessOffset;
+
+ // Otherwise jump forward or backward to the last such char.
+ if( !requireNextWord )
+ while( !Character.isWhitespace( text.previous() ) &&
+ guessOffset > position )
+ guessOffset--;
+ else
+ while( !Character.isWhitespace( text.next() ) &&
+ guessOffset < offsetLimit )
+ guessOffset++;
+
+ if( guessOffset > offsetLimit )
+ {
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
- public void setPosition (int newPosition)
+ text.setIndex( guessOffset );
+
+ return guessOffset;
+ }
+
+ public void setPosition(int newPosition)
{
- ci.setIndex (newPosition);
+ position = newPosition;
}
+
+ public int getPosition()
+ {
+ return position;
+ }
}
+
Modified: trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -81,6 +81,9 @@
public boolean equals(TextHitInfo hitInfo)
{
+ if (hitInfo == null)
+ return false;
+
return (charIndex == hitInfo.getCharIndex ())
&& (leadingEdge == hitInfo.isLeadingEdge ());
}
@@ -97,7 +100,7 @@
public static TextHitInfo beforeOffset(int offset)
{
- return new TextHitInfo (offset, false);
+ return new TextHitInfo ((offset - 1), false);
}
public static TextHitInfo afterOffset(int offset)
Modified: trunk/core/src/classpath/java/java/awt/font/TextLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/TextLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/TextLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,19 +38,18 @@
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
-import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
import java.text.Bidi;
+import java.util.ArrayList;
import java.util.Map;
/**
@@ -58,21 +57,94 @@
*/
public final class TextLayout implements Cloneable
{
- private GlyphVector[] runs;
- private Font font;
+ /**
+ * Holds the layout data that belongs to one run of characters.
+ */
+ private class Run
+ {
+ /**
+ * The actual glyph vector.
+ */
+ GlyphVector glyphVector;
+
+ /**
+ * The font for this text run.
+ */
+ Font font;
+
+ /**
+ * The start of the run.
+ */
+ int runStart;
+
+ /**
+ * The end of the run.
+ */
+ int runEnd;
+
+ /**
+ * The layout location of the beginning of the run.
+ */
+ float location;
+
+ /**
+ * Initializes the Run instance.
+ *
+ * @param gv the glyph vector
+ * @param start the start index of the run
+ * @param end the end index of the run
+ */
+ Run(GlyphVector gv, Font f, int start, int end)
+ {
+ glyphVector = gv;
+ font = f;
+ runStart = start;
+ runEnd = end;
+ }
+
+ /**
+ * Returns <code>true</code> when this run is left to right,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when this run is left to right,
+ * <code>false</code> otherwise
+ */
+ boolean isLeftToRight()
+ {
+ return (glyphVector.getLayoutFlags() & GlyphVector.FLAG_RUN_RTL) == 0;
+ }
+ }
+
+ /**
+ * The laid out character runs.
+ */
+ private Run[] runs;
+
private FontRenderContext frc;
- private String string;
+ private char[] string;
+ private int offset;
+ private int length;
private Rectangle2D boundsCache;
private LineMetrics lm;
/**
- * Start and end character indices of the runs.
- * First index is the run number, second is 0 or 1 for the starting
- * and ending character index of the run, respectively.
+ * The total advance of this text layout. This is cache for maximum
+ * performance.
*/
- private int[][] runIndices;
+ private float totalAdvance = -1F;
+
+ /**
+ * The cached natural bounds.
+ */
+ private Rectangle2D naturalBounds;
/**
+ * Character indices.
+ * Fixt index is the glyphvector, second index is the (first) glyph.
+ */
+ private int[][] charIndices;
+
+ /**
* Base directionality, determined from the first char.
*/
private boolean leftToRight;
@@ -83,87 +155,249 @@
private boolean hasWhitespace = false;
/**
+ * The {@link Bidi} object that is used for reordering and by
+ * {@link #getCharacterLevel(int)}.
+ */
+ private Bidi bidi;
+
+ /**
+ * Mpas the logical position of each individual character in the original
+ * string to its visual position.
+ */
+ private int[] logicalToVisual;
+
+ /**
+ * Maps visual positions of a character to its logical position
+ * in the original string.
+ */
+ private int[] visualToLogical;
+
+ /**
+ * The cached hashCode.
+ */
+ private int hash;
+
+ /**
* The default caret policy.
*/
- static TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+ public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY =
+ new CaretPolicy();
/**
* Constructs a TextLayout.
*/
- public TextLayout (String string, Font font, FontRenderContext frc)
+ public TextLayout (String str, Font font, FontRenderContext frc)
{
- this.font = font;
this.frc = frc;
- this.string = string;
- lm = font.getLineMetrics(string, frc);
+ string = str.toCharArray();
+ offset = 0;
+ length = this.string.length;
+ lm = font.getLineMetrics(this.string, offset, length, frc);
// Get base direction and whitespace info
getStringProperties();
- if( Bidi.requiresBidi( string.toCharArray(), 0, string.length() ) )
+ if (Bidi.requiresBidi(string, offset, offset + length))
{
- Bidi bidi = new Bidi( string, leftToRight ?
- Bidi.DIRECTION_LEFT_TO_RIGHT :
- Bidi.DIRECTION_RIGHT_TO_LEFT );
+ bidi = new Bidi(str, leftToRight ? Bidi.DIRECTION_LEFT_TO_RIGHT
+ : Bidi.DIRECTION_RIGHT_TO_LEFT );
int rc = bidi.getRunCount();
byte[] table = new byte[ rc ];
for(int i = 0; i < table.length; i++)
table[i] = (byte)bidi.getRunLevel(i);
- runs = new GlyphVector[ rc ];
- runIndices = new int[rc][2];
- for(int i = 0; i < runs.length; i++)
+ runs = new Run[rc];
+ for(int i = 0; i < rc; i...
[truncated message content] |