From 648e8d6dd39f9bb1a61b7886007088e1064f7dae Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Wed, 14 Jun 2006 03:38:34 +0000 Subject: configure: Regenerate. 2006-06-13 Thomas Fitzsimmons * 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 --- libjava/classpath/java/awt/Component.java | 5 +- .../java/awt/datatransfer/DataFlavor.java | 7 +- .../classpath/java/awt/dnd/DropTargetContext.java | 61 +-- .../java/awt/dnd/DropTargetDropEvent.java | 53 ++- .../classpath/java/awt/font/LineBreakMeasurer.java | 165 +++++-- libjava/classpath/java/awt/font/TextLayout.java | 517 ++++++++++++++++----- .../classpath/java/awt/geom/AffineTransform.java | 4 +- .../classpath/java/awt/image/BufferedImage.java | 41 +- libjava/classpath/java/awt/image/PixelGrabber.java | 7 +- libjava/classpath/java/text/Bidi.java | 3 +- 10 files changed, 646 insertions(+), 217 deletions(-) (limited to 'libjava/classpath/java') diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java index cc42d04..3d3dcc3 100644 --- a/libjava/classpath/java/awt/Component.java +++ b/libjava/classpath/java/awt/Component.java @@ -1739,9 +1739,8 @@ public abstract class Component if (gfx == null && parent != null) { gfx = parent.getGraphics(); - Rectangle bounds = getBounds(); - gfx.setClip(bounds); - gfx.translate(bounds.x, bounds.y); + gfx.clipRect(getX(), getY(), getWidth(), getHeight()); + gfx.translate(getX(), getY()); return gfx; } gfx.setFont(font); diff --git a/libjava/classpath/java/awt/datatransfer/DataFlavor.java b/libjava/classpath/java/awt/datatransfer/DataFlavor.java index 788ae6d..5944c2e 100644 --- a/libjava/classpath/java/awt/datatransfer/DataFlavor.java +++ b/libjava/classpath/java/awt/datatransfer/DataFlavor.java @@ -38,6 +38,8 @@ exception statement from your version. */ package java.awt.datatransfer; +import gnu.classpath.NotImplementedException; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -785,7 +787,8 @@ public class DataFlavor implements java.io.Externalizable, Cloneable * * @exception IOException If an error occurs. */ - public void writeExternal(ObjectOutput stream) throws IOException + public void writeExternal(ObjectOutput stream) + throws IOException, NotImplementedException { // FIXME: Implement me } @@ -801,7 +804,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable * cannot be found. */ public void readExternal(ObjectInput stream) - throws IOException, ClassNotFoundException + throws IOException, ClassNotFoundException, NotImplementedException { // FIXME: Implement me } diff --git a/libjava/classpath/java/awt/dnd/DropTargetContext.java b/libjava/classpath/java/awt/dnd/DropTargetContext.java index 19e27a9..4a26d90 100644 --- a/libjava/classpath/java/awt/dnd/DropTargetContext.java +++ b/libjava/classpath/java/awt/dnd/DropTargetContext.java @@ -1,5 +1,5 @@ /* DropTargetContext.java -- - Copyright (C) 2002, 2003, 2004 Free Software Foundation + Copyright (C) 2002, 2003, 2004, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -37,6 +37,8 @@ exception statement from your version. */ package java.awt.dnd; +import gnu.classpath.NotImplementedException; + import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; @@ -59,23 +61,23 @@ public class DropTargetContext implements Serializable protected boolean isLocal; protected Transferable transferable; - TransferableProxy (Transferable t, boolean local) + TransferableProxy(Transferable t, boolean local) { this.transferable = t; this.isLocal = local; } - public DataFlavor[] getTransferDataFlavors () + public DataFlavor[] getTransferDataFlavors() { - return transferable.getTransferDataFlavors (); + return transferable.getTransferDataFlavors(); } - public boolean isDataFlavorSupported (DataFlavor flavor) + public boolean isDataFlavorSupported(DataFlavor flavor) { - return transferable.isDataFlavorSupported (flavor); + return transferable.isDataFlavorSupported(flavor); } - public Object getTransferData (DataFlavor flavor) + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { return transferable.getTransferData (flavor); @@ -87,32 +89,32 @@ public class DropTargetContext implements Serializable private java.awt.dnd.peer.DropTargetContextPeer dtcp; // package private - DropTargetContext (DropTarget dropTarget) + DropTargetContext(DropTarget dropTarget) { this.dropTarget = dropTarget; } - public DropTarget getDropTarget () + public DropTarget getDropTarget() { return dropTarget; } - public Component getComponent () + public Component getComponent() { - return dropTarget.getComponent (); + return dropTarget.getComponent(); } - public void addNotify (java.awt.dnd.peer.DropTargetContextPeer dtcp) + public void addNotify(java.awt.dnd.peer.DropTargetContextPeer dtcp) { this.dtcp = dtcp; } - public void removeNotify () + public void removeNotify() { this.dtcp = null; } - protected void setTargetActions (int actions) + protected void setTargetActions(int actions) { targetActions = actions; } @@ -127,45 +129,51 @@ public class DropTargetContext implements Serializable * * @exception InvalidDnDOperationException If a drop is not outstanding. */ - public void dropComplete (boolean success) + public void dropComplete(boolean success) + throws NotImplementedException { // FIXME: implement this } - protected void acceptDrag (int dragOperation) + protected void acceptDrag(int dragOperation) + throws NotImplementedException { // FIXME: implement this } - protected void rejectDrag () + protected void rejectDrag() + throws NotImplementedException { // FIXME: implement this } - protected void acceptDrop (int dropOperation) + protected void acceptDrop(int dropOperation) + throws NotImplementedException { // FIXME: implement this } - protected void rejectDrop () + protected void rejectDrop() + throws NotImplementedException { // FIXME: implement this } - protected DataFlavor[] getCurrentDataFlavors () + protected DataFlavor[] getCurrentDataFlavors() + throws NotImplementedException { // FIXME: implement this return null; } - protected List getCurrentDataFlavorsAsList () + protected List getCurrentDataFlavorsAsList() { - return Arrays.asList (getCurrentDataFlavors ()); + return Arrays.asList(getCurrentDataFlavors()); } - protected boolean isDataFlavorSupported (DataFlavor flavor) + protected boolean isDataFlavorSupported(DataFlavor flavor) { - return getCurrentDataFlavorsAsList ().contains (flavor); + return getCurrentDataFlavorsAsList().contains(flavor); } /** @@ -173,7 +181,8 @@ public class DropTargetContext implements Serializable * * @exception InvalidDnDOperationException If a drag is not outstanding. */ - protected Transferable getTransferable() throws InvalidDnDOperationException + protected Transferable getTransferable() + throws InvalidDnDOperationException, NotImplementedException { // FIXME: implement this return null; @@ -181,6 +190,6 @@ public class DropTargetContext implements Serializable protected Transferable createTransferableProxy(Transferable t, boolean local) { - return new TransferableProxy (t, local); + return new TransferableProxy(t, local); } } // class DropTargetContext diff --git a/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java index 0c0777f..a745bd2 100644 --- a/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java +++ b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java @@ -37,6 +37,8 @@ exception statement from your version. */ package java.awt.dnd; +import gnu.classpath.NotImplementedException; + import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; @@ -65,10 +67,10 @@ public class DropTargetDropEvent extends DropTargetEvent * actions is not a bitwise mask of DnDConstants, or dtc is null. * @exception NullPointerException If location is null. */ - public DropTargetDropEvent (DropTargetContext dtc, Point location, - int dropAction, int actions) + public DropTargetDropEvent(DropTargetContext dtc, Point location, + int dropAction, int actions) { - this (dtc, location, dropAction, actions, false); + this(dtc, location, dropAction, actions, false); } /** @@ -78,16 +80,16 @@ public class DropTargetDropEvent extends DropTargetEvent * actions is not a bitwise mask of DnDConstants, or dtc is null. * @exception NullPointerException If location is null. */ - public DropTargetDropEvent (DropTargetContext dtc, Point location, - int dropAction, int actions, boolean isLocalTx) + public DropTargetDropEvent(DropTargetContext dtc, Point location, + int dropAction, int actions, boolean isLocalTx) { - super (dtc); + super(dtc); if (location == null) - throw new NullPointerException (); + throw new NullPointerException(); if (dtc == null) - throw new IllegalArgumentException (); + throw new IllegalArgumentException(); if (dropAction != DnDConstants.ACTION_NONE && dropAction != DnDConstants.ACTION_COPY @@ -95,7 +97,7 @@ public class DropTargetDropEvent extends DropTargetEvent && dropAction != DnDConstants.ACTION_COPY_OR_MOVE && dropAction != DnDConstants.ACTION_LINK && dropAction != DnDConstants.ACTION_REFERENCE) - throw new IllegalArgumentException (); + throw new IllegalArgumentException(); int actionsMask = DnDConstants.ACTION_NONE | DnDConstants.ACTION_COPY @@ -105,7 +107,7 @@ public class DropTargetDropEvent extends DropTargetEvent | DnDConstants.ACTION_REFERENCE; if (~(actions ^ actionsMask) != 0) - throw new IllegalArgumentException (); + throw new IllegalArgumentException(); this.dropAction = dropAction; this.actions = actions; @@ -113,52 +115,53 @@ public class DropTargetDropEvent extends DropTargetEvent this.isLocalTx = isLocalTx; } - public Point getLocation () + public Point getLocation() { return location; } - public DataFlavor[] getCurrentDataFlavors () + public DataFlavor[] getCurrentDataFlavors() { - return context.getCurrentDataFlavors (); + return context.getCurrentDataFlavors(); } - public List getCurrentDataFlavorsAsList () + public List getCurrentDataFlavorsAsList() { - return context.getCurrentDataFlavorsAsList (); + return context.getCurrentDataFlavorsAsList(); } - public boolean isDataFlavorSupported (DataFlavor flavor) + public boolean isDataFlavorSupported(DataFlavor flavor) { - return context.isDataFlavorSupported (flavor); + return context.isDataFlavorSupported(flavor); } - public int getSourceActions () + public int getSourceActions() { return actions; } - public int getDropAction () + public int getDropAction() { return dropAction; } - public Transferable getTransferable () + public Transferable getTransferable() { return context.getTransferable (); } - public void acceptDrop (int dropAction) + public void acceptDrop(int dropAction) { - context.acceptDrop (dropAction); + context.acceptDrop(dropAction); } - public void rejectDrop () + public void rejectDrop() { - context.rejectDrop (); + context.rejectDrop(); } - public void dropComplete (boolean success) + public void dropComplete(boolean success) + throws NotImplementedException { // FIXME: implement this } diff --git a/libjava/classpath/java/awt/font/LineBreakMeasurer.java b/libjava/classpath/java/awt/font/LineBreakMeasurer.java index 14985b4..c2a6d45 100644 --- a/libjava/classpath/java/awt/font/LineBreakMeasurer.java +++ b/libjava/classpath/java/awt/font/LineBreakMeasurer.java @@ -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,161 @@ exception statement from your version. */ package java.awt.font; -import gnu.classpath.NotImplementedException; - import java.text.AttributedCharacterIterator; +import java.text.AttributedString; import java.text.BreakIterator; +import java.awt.font.TextLayout; +import java.awt.font.FontRenderContext; +import java.awt.Shape; public final class LineBreakMeasurer { - private AttributedCharacterIterator ci; + private AttributedCharacterIterator text; + private int position; private FontRenderContext frc; - private BreakIterator bi; + private TextLayout totalLayout; + private int numChars; - /** - * Constructs a LineBreakMeasurer object. - */ - public LineBreakMeasurer (AttributedCharacterIterator text, - FontRenderContext frc) + public LineBreakMeasurer(AttributedCharacterIterator text, + BreakIterator breakIter, FontRenderContext frc) { - this (text, null, frc); + this.text = text; + this.frc = frc; + position = 0; + totalLayout = new TextLayout(text, frc); + numChars = totalLayout.getCharacterCount(); } - /** - * Constructs a LineBreakMeasurer object. - */ - public LineBreakMeasurer (AttributedCharacterIterator text, - BreakIterator breakIter, FontRenderContext frc) + public LineBreakMeasurer(AttributedCharacterIterator text, + FontRenderContext frc) { - this.ci = text; - this.bi = breakIter; + this.text = text; this.frc = frc; + position = 0; + totalLayout = new TextLayout(text, frc); + numChars = totalLayout.getCharacterCount(); } - public void deleteChar (AttributedCharacterIterator newParagraph, - int deletePos) - throws NotImplementedException + public void deleteChar(AttributedCharacterIterator newParagraph, + int deletePos) { - throw new Error ("not implemented"); + totalLayout = new TextLayout(newParagraph, frc); + if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() ) + throw new NullPointerException("Invalid deletePos:"+deletePos); + numChars = totalLayout.getCharacterCount(); + text = newParagraph; + position = 0; } - public int getPosition () + public void insertChar(AttributedCharacterIterator newParagraph, + int insertPos) { - return ci.getIndex (); + totalLayout = new TextLayout(newParagraph, frc); + if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() ) + throw new NullPointerException("Invalid insertPos:"+insertPos); + numChars = totalLayout.getCharacterCount(); + text = newParagraph; + position = 0; } - public void insertChar (AttributedCharacterIterator newParagraph, - int insertPos) - throws NotImplementedException + public TextLayout nextLayout(float wrappingWidth) { - throw new Error ("not implemented"); + return nextLayout( wrappingWidth, numChars, false ); } - public TextLayout nextLayout (float wrappingWidth) - throws NotImplementedException + public TextLayout nextLayout(float wrappingWidth, int offsetLimit, + boolean requireNextWord) { - throw new Error ("not implemented"); + int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord ); + AttributedCharacterIterator aci = (new AttributedString( text, + position, next ) + ).getIterator(); + position = next; + return new TextLayout( aci, frc ); } - public TextLayout nextLayout (float wrappingWidth, int offsetLimit, - boolean requireNextWord) - throws NotImplementedException + public int nextOffset(float wrappingWidth) { - throw new Error ("not implemented"); + return nextOffset( wrappingWidth, numChars, false ); } - public int nextOffset (float wrappingWidth) - throws NotImplementedException + public int nextOffset(float wrappingWidth, int offsetLimit, + boolean requireNextWord) { - throw new Error ("not implemented"); + Shape s = totalLayout.getBlackBoxBounds( position, offsetLimit ); + double remainingLength = s.getBounds2D().getWidth(); + + int guessOffset = (int)( ( (double)wrappingWidth / (double)remainingLength) + * ( (double)numChars - (double)position ) ); + guessOffset += position; + if( guessOffset > offsetLimit ) + guessOffset = offsetLimit; + + s = totalLayout.getBlackBoxBounds( position, guessOffset ); + double guessLength = s.getBounds2D().getWidth(); + + boolean makeSmaller = ( guessLength > wrappingWidth ); + int inc = makeSmaller ? -1 : 1; + boolean keepGoing = true; + + do + { + guessOffset = guessOffset + inc; + if( guessOffset <= position || guessOffset > offsetLimit ) + { + keepGoing = false; + } + else + { + s = totalLayout.getBlackBoxBounds( position, guessOffset ); + guessLength = s.getBounds2D().getWidth(); + if( makeSmaller && ( guessLength <= wrappingWidth) ) + keepGoing = false; + if( !makeSmaller && ( guessLength >= wrappingWidth) ) + keepGoing = false; + } + } + while( keepGoing ); + + if( !makeSmaller ) + guessOffset--; + + if( guessOffset >= offsetLimit ) + return offsetLimit; + + text.setIndex( guessOffset ); + if( !requireNextWord ) + { + char c = text.previous(); + while( !Character.isWhitespace( c ) && c != '-' && + guessOffset > position ) + { + guessOffset--; + c = text.previous(); + } + } + else + { + char c = text.next(); + while( !Character.isWhitespace( c ) && c != '-' && + guessOffset < offsetLimit ) + { + guessOffset++; + c = text.next(); + } + } + + return guessOffset; } - public int nextOffset (float wrappingWidth, int offsetLimit, - boolean requireNextWord) - throws NotImplementedException + public void setPosition(int newPosition) { - throw new Error ("not implemented"); + position = newPosition; } - public void setPosition (int newPosition) + public int getPosition() { - ci.setIndex (newPosition); + return position; } } + diff --git a/libjava/classpath/java/awt/font/TextLayout.java b/libjava/classpath/java/awt/font/TextLayout.java index bb64161..4f8c1c6 100644 --- a/libjava/classpath/java/awt/font/TextLayout.java +++ b/libjava/classpath/java/awt/font/TextLayout.java @@ -1,5 +1,5 @@ /* TextLayout.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,7 @@ exception statement from your version. */ package java.awt.font; -import gnu.java.awt.ClasspathToolkit; -import gnu.java.awt.peer.ClasspathTextLayoutPeer; +import gnu.classpath.NotImplementedException; import java.awt.Font; import java.awt.Graphics2D; @@ -47,116 +46,269 @@ import java.awt.Shape; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; import java.text.AttributedCharacterIterator; import java.text.AttributedString; +import java.text.Bidi; import java.util.Map; /** - * @author Michael Koch + * @author Sven de Marothy */ public final class TextLayout implements Cloneable { - public static final CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy (); - ClasspathTextLayoutPeer peer; - - public static class CaretPolicy + private GlyphVector[] runs; + private Font font; + private FontRenderContext frc; + private String string; + 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. + */ + private int[][] runIndices; + + /** + * Base directionality, determined from the first char. + */ + private boolean leftToRight; + + /** + * Whether this layout contains whitespace or not. + */ + private boolean hasWhitespace = false; + + /** + * The default caret policy. + */ + static TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy(); + + /** + * Constructs a TextLayout. + */ + public TextLayout (String string, Font font, FontRenderContext frc) { - public CaretPolicy () - { - // Do nothing here. - } + this.font = font; + this.frc = frc; + this.string = string; + lm = font.getLineMetrics(string, frc); - public TextHitInfo getStrongCaret (TextHitInfo hit1, TextHitInfo hit2, - TextLayout layout) - { - return layout.peer.getStrongCaret(hit1, hit2); - } - } + // Get base direction and whitespace info + getStringProperties(); - public TextLayout (AttributedCharacterIterator text, FontRenderContext frc) - { - AttributedString as = new AttributedString (text); - ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); - peer = tk.getClasspathTextLayoutPeer(as, frc); + if( Bidi.requiresBidi( string.toCharArray(), 0, string.length() ) ) + { + Bidi bidi = new Bidi( string, 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++) + { + runIndices[i][0] = bidi.getRunStart( i ); + runIndices[i][1] = bidi.getRunLimit( i ); + if( runIndices[i][0] != runIndices[i][1] ) // no empty runs. + { + runs[i] = font.layoutGlyphVector + ( frc, string.toCharArray(), + runIndices[i][0], runIndices[i][1], + ((table[i] & 1) == 0) ? Font.LAYOUT_LEFT_TO_RIGHT : + Font.LAYOUT_RIGHT_TO_LEFT ); + } + } + Bidi.reorderVisually( table, 0, runs, 0, runs.length ); + } + else + { + runs = new GlyphVector[ 1 ]; + runIndices = new int[1][2]; + runIndices[0][0] = 0; + runIndices[0][1] = string.length(); + runs[ 0 ] = font.layoutGlyphVector( frc, string.toCharArray(), + 0, string.length(), + leftToRight ? + Font.LAYOUT_LEFT_TO_RIGHT : + Font.LAYOUT_RIGHT_TO_LEFT ); + } } - public TextLayout (String string, Font font, FontRenderContext frc) + public TextLayout (String string, Map attributes, FontRenderContext frc) { - AttributedString as = new AttributedString (string); - as.addAttribute (TextAttribute.FONT, font); - ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); - peer = tk.getClasspathTextLayoutPeer(as, frc); + this( string, new Font( attributes ), frc ); } - public TextLayout (String string, Map attributes, FontRenderContext frc) - { - AttributedString as = new AttributedString (string, attributes); - ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ()); - peer = tk.getClasspathTextLayoutPeer(as, frc); + public TextLayout (AttributedCharacterIterator text, FontRenderContext frc) + throws NotImplementedException + { + throw new Error ("not implemented"); + } + + /** + * Scan the character run for the first strongly directional character, + * which in turn defines the base directionality of the whole layout. + */ + private void getStringProperties() + { + boolean gotDirection = false; + int i = 0; + + leftToRight = true; + while( i < string.length() && !gotDirection ) + switch( Character.getDirectionality( string.charAt( i++ ) ) ) + { + case Character.DIRECTIONALITY_LEFT_TO_RIGHT: + case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING: + case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE: + gotDirection = true; + break; + + case Character.DIRECTIONALITY_RIGHT_TO_LEFT: + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING: + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE: + leftToRight = false; + gotDirection = true; + break; + } + + // Determine if there's whitespace in the thing. + // Ignore trailing chars. + i = string.length() - 1; + hasWhitespace = false; + while( i >= 0 && Character.isWhitespace( string.charAt(i) ) ) + i--; + // Check the remaining chars + while( i >= 0 ) + if( Character.isWhitespace( string.charAt(i--) ) ) + hasWhitespace = true; } protected Object clone () { - try - { - TextLayout tl = (TextLayout) super.clone (); - tl.peer = (ClasspathTextLayoutPeer) this.peer.clone(); - return tl; - } - catch (CloneNotSupportedException e) - { - // This should never occur - throw new InternalError (); - } + return new TextLayout( string, font, frc ); } - public void draw (Graphics2D g2, float x, float y) - { - peer.draw(g2, x, y); + { + for(int i = 0; i < runs.length; i++) + { + g2.drawGlyphVector(runs[i], x, y); + Rectangle2D r = runs[i].getLogicalBounds(); + x += r.getWidth(); + } } public boolean equals (Object obj) { - if (! (obj instanceof TextLayout)) + if( !( obj instanceof TextLayout) ) return false; - return equals ((TextLayout) obj); + return equals( (TextLayout) obj ); } public boolean equals (TextLayout tl) { - return this.peer.equals(tl.peer); + if( runs.length != tl.runs.length ) + return false; + // Compare all glyph vectors. + for( int i = 0; i < runs.length; i++ ) + if( !runs[i].equals( tl.runs[i] ) ) + return false; + return true; } public float getAdvance () { - return peer.getAdvance(); + float totalAdvance = 0f; + for(int i = 0; i < runs.length; i++) + totalAdvance += runs[i].getLogicalBounds().getWidth(); + return totalAdvance; } public float getAscent () { - return peer.getAscent(); + return lm.getAscent(); } public byte getBaseline () { - return peer.getBaseline(); + return (byte)lm.getBaselineIndex(); } public float[] getBaselineOffsets () { - return peer.getBaselineOffsets(); + return lm.getBaselineOffsets(); } public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint) { - return peer.getBlackBoxBounds(firstEndpoint, secondEndpoint); + if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() ) + return new Rectangle2D.Float(); + + GeneralPath gp = new GeneralPath(); + int i = 0; // run index + double advance = 0; + + // go to first run + while( runIndices[i + 1][1] < firstEndpoint ) + { + advance += runs[i].getLogicalBounds().getWidth(); + i++; + } + + int j = 0; // index into the run. + if( runIndices[i][1] - runIndices[i][0] > 1 ) + { + while( runs[i].getGlyphCharIndex( j + 1 ) < + (firstEndpoint - runIndices[i][0] ) )j++; + } + + gp.append(runs[i].getGlyphVisualBounds( j ), false); + boolean keepGoing = true;; + + do + { + while( j < runs[i].getNumGlyphs() && + runs[i].getGlyphCharIndex( j ) + runIndices[i][0] < + secondEndpoint ) + { + Rectangle2D r2 = (runs[i].getGlyphVisualBounds( j )). + getBounds2D(); + Point2D p = runs[i].getGlyphPosition( j ); + r2.setRect( advance + p.getX(), r2.getY(), + r2.getWidth(), r2.getHeight() ); + gp.append(r2, false); + j++; + } + + if( j >= runs[i].getNumGlyphs() ) + { + advance += runs[i].getLogicalBounds().getWidth(); + i++; + j = 0; + } + else + keepGoing = false; + } + while( keepGoing ); + + return gp; } public Rectangle2D getBounds() { - return peer.getBounds(); + if( boundsCache == null ) + boundsCache = getOutline(new AffineTransform()).getBounds(); + return boundsCache; } public float[] getCaretInfo (TextHitInfo hit) @@ -165,144 +317,274 @@ public final class TextLayout implements Cloneable } public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds) + throws NotImplementedException { - return peer.getCaretInfo(hit, bounds); + throw new Error ("not implemented"); } public Shape getCaretShape (TextHitInfo hit) { - return getCaretShape(hit, getBounds()); + return getCaretShape( hit, getBounds() ); } public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds) + throws NotImplementedException { - return peer.getCaretShape(hit, bounds); + throw new Error ("not implemented"); } public Shape[] getCaretShapes (int offset) { - return getCaretShapes(offset, getBounds()); + return getCaretShapes( offset, getBounds() ); } public Shape[] getCaretShapes (int offset, Rectangle2D bounds) + throws NotImplementedException { - return getCaretShapes(offset, getBounds(), DEFAULT_CARET_POLICY); - } - - public Shape[] getCaretShapes (int offset, Rectangle2D bounds, - TextLayout.CaretPolicy policy) - { - return peer.getCaretShapes(offset, bounds, policy); + throw new Error ("not implemented"); } public int getCharacterCount () { - return peer.getCharacterCount(); + return string.length(); } public byte getCharacterLevel (int index) + throws NotImplementedException { - return peer.getCharacterLevel(index); + throw new Error ("not implemented"); } public float getDescent () { - return peer.getDescent(); + return lm.getDescent(); } public TextLayout getJustifiedLayout (float justificationWidth) { - return peer.getJustifiedLayout(justificationWidth); + TextLayout newLayout = (TextLayout)clone(); + + if( hasWhitespace ) + newLayout.handleJustify( justificationWidth ); + + return newLayout; } public float getLeading () { - return peer.getLeading(); + return lm.getLeading(); } public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint) { - return getLogicalHighlightShape (firstEndpoint, secondEndpoint, getBounds()); + return getLogicalHighlightShape( firstEndpoint, secondEndpoint, + getBounds() ); } public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, Rectangle2D bounds) { - return peer.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds); + if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() ) + return new Rectangle2D.Float(); + + int i = 0; // run index + double advance = 0; + + // go to first run + if( i > 0 ) + while( runIndices[i + 1][1] < firstEndpoint ) + { + advance += runs[i].getLogicalBounds().getWidth(); + i++; + } + + int j = 0; // index into the run. + if( runIndices[i][1] - runIndices[i][0] > 1 ) + { + while( runs[i].getGlyphCharIndex( j + 1 ) < + (firstEndpoint - runIndices[i][0] ) )j++; + } + + Rectangle2D r = (runs[i].getGlyphLogicalBounds( j )).getBounds2D(); + boolean keepGoing = true;; + + do + { + while( j < runs[i].getNumGlyphs() && + runs[i].getGlyphCharIndex( j ) + runIndices[i][0] < + secondEndpoint ) + { + Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( j )). + getBounds2D(); + Point2D p = runs[i].getGlyphPosition( j ); + r2.setRect( advance + p.getX(), r2.getY(), + r2.getWidth(), r2.getHeight() ); + r = r.createUnion( r2 ); + j++; + } + + if( j >= runs[i].getNumGlyphs() ) + { + advance += runs[i].getLogicalBounds().getWidth(); + i++; + j = 0; + } + else + keepGoing = false; + } + while( keepGoing ); + + return r; } public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint) + throws NotImplementedException { - return peer.getLogicalRangesForVisualSelection(firstEndpoint, secondEndpoint); + throw new Error ("not implemented"); } public TextHitInfo getNextLeftHit (int offset) + throws NotImplementedException { - return getNextLeftHit(offset, DEFAULT_CARET_POLICY); - } - - public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy) - { - return peer.getNextLeftHit(offset, policy); + throw new Error ("not implemented"); } public TextHitInfo getNextLeftHit (TextHitInfo hit) + throws NotImplementedException { - return getNextLeftHit(hit.getCharIndex()); + throw new Error ("not implemented"); } public TextHitInfo getNextRightHit (int offset) + throws NotImplementedException { - return getNextRightHit(offset, DEFAULT_CARET_POLICY); - } - - public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy) - { - return peer.getNextRightHit(offset, policy); + throw new Error ("not implemented"); } public TextHitInfo getNextRightHit (TextHitInfo hit) + throws NotImplementedException { - return getNextRightHit(hit.getCharIndex()); + throw new Error ("not implemented"); } public Shape getOutline (AffineTransform tx) { - return peer.getOutline(tx); + float x = 0f; + GeneralPath gp = new GeneralPath(); + for(int i = 0; i < runs.length; i++) + { + gp.append( runs[i].getOutline( x, 0f ), false ); + Rectangle2D r = runs[i].getLogicalBounds(); + x += r.getWidth(); + } + if( tx != null ) + gp.transform( tx ); + return gp; } public float getVisibleAdvance () { - return peer.getVisibleAdvance(); + float totalAdvance = 0f; + + if( runs.length <= 0 ) + return 0f; + + // No trailing whitespace + if( !Character.isWhitespace( string.charAt( string.length() -1 ) ) ) + return getAdvance(); + + // Get length of all runs up to the last + for(int i = 0; i < runs.length - 1; i++) + totalAdvance += runs[i].getLogicalBounds().getWidth(); + + int lastRun = runIndices[ runs.length - 1 ][0]; + int j = string.length() - 1; + while( j >= lastRun && Character.isWhitespace( string.charAt( j ) ) ) j--; + + if( j < lastRun ) + return totalAdvance; // entire last run is whitespace + + int lastNonWSChar = j - lastRun; + j = 0; + while( runs[ runs.length - 1 ].getGlyphCharIndex( j ) + <= lastNonWSChar ) + { + totalAdvance += runs[ runs.length - 1 ].getGlyphLogicalBounds( j ). + getBounds2D().getWidth(); + j ++; + } + + return totalAdvance; } public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint) { - return getVisualHighlightShape(firstEndpoint, secondEndpoint, getBounds()); + return getVisualHighlightShape( firstEndpoint, secondEndpoint, + getBounds() ); } public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint, Rectangle2D bounds) + throws NotImplementedException { - return peer.getVisualHighlightShape(firstEndpoint, secondEndpoint, bounds); + throw new Error ("not implemented"); } public TextHitInfo getVisualOtherHit (TextHitInfo hit) + throws NotImplementedException { - return peer.getVisualOtherHit(hit); + throw new Error ("not implemented"); } + /** + * This is a protected method of a final class, meaning + * it exists only to taunt you. + */ protected void handleJustify (float justificationWidth) { - peer.handleJustify(justificationWidth); - } - - public int hashCode () - { - return peer.hashCode(); + // We assume that the text has non-trailing whitespace. + // First get the change in width to insert into the whitespaces. + double deltaW = justificationWidth - getVisibleAdvance(); + int nglyphs = 0; // # of whitespace chars + + // determine last non-whitespace char. + int lastNWS = string.length() - 1; + while( Character.isWhitespace( string.charAt( lastNWS ) ) ) lastNWS--; + + // locations of the glyphs. + int[] wsglyphs = new int[string.length() * 10]; + for(int run = 0; run < runs.length; run++ ) + for(int i = 0; i < runs[run].getNumGlyphs(); i++ ) + { + int cindex = runIndices[run][0] + runs[run].getGlyphCharIndex( i ); + if( Character.isWhitespace( string.charAt( cindex ) ) ) + // && cindex < lastNWS ) + { + wsglyphs[ nglyphs * 2 ] = run; + wsglyphs[ nglyphs * 2 + 1] = i; + nglyphs++; + } + } + + deltaW = deltaW / nglyphs; // Change in width per whitespace glyph + double w = 0; + int cws = 0; + // Shift all characters + for(int run = 0; run < runs.length; run++ ) + for(int i = 0; i < runs[ run ].getNumGlyphs(); i++ ) + { + if( wsglyphs[ cws * 2 ] == run && wsglyphs[ cws * 2 + 1 ] == i ) + { + cws++; // update 'current whitespace' + w += deltaW; // increment the shift + } + Point2D p = runs[ run ].getGlyphPosition( i ); + p.setLocation( p.getX() + w, p.getY() ); + runs[ run ].setGlyphPosition( i, p ); + } } public TextHitInfo hitTestChar (float x, float y) @@ -312,21 +594,48 @@ public final class TextLayout implements Cloneable public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds) { - return peer.hitTestChar(x, y, bounds); + return hitTestChar( x, y, getBounds() ); } public boolean isLeftToRight () { - return peer.isLeftToRight(); + return leftToRight; } public boolean isVertical () { - return peer.isVertical(); + return false; // FIXME: How do you create a vertical layout? + } + + public int hashCode () + throws NotImplementedException + { + throw new Error ("not implemented"); } public String toString () { - return peer.toString(); + return "TextLayout [string:"+string+", Font:"+font+" Rendercontext:"+ + frc+"]"; + } + + /** + * Inner class describing a caret policy + */ + public static class CaretPolicy + { + public CaretPolicy() + { + } + + public TextHitInfo getStrongCaret(TextHitInfo hit1, + TextHitInfo hit2, + TextLayout layout) + throws NotImplementedException + { + throw new Error ("not implemented"); + } } } + + diff --git a/libjava/classpath/java/awt/geom/AffineTransform.java b/libjava/classpath/java/awt/geom/AffineTransform.java index 4d1a4d6..55b6883 100644 --- a/libjava/classpath/java/awt/geom/AffineTransform.java +++ b/libjava/classpath/java/awt/geom/AffineTransform.java @@ -414,7 +414,9 @@ public class AffineTransform implements Cloneable, Serializable public static AffineTransform getTranslateInstance(double tx, double ty) { AffineTransform t = new AffineTransform(); - t.setToTranslation(tx, ty); + t.m02 = tx; + t.m12 = ty; + t.type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION; return t; } diff --git a/libjava/classpath/java/awt/image/BufferedImage.java b/libjava/classpath/java/awt/image/BufferedImage.java index 16b0143..77b8d6c 100644 --- a/libjava/classpath/java/awt/image/BufferedImage.java +++ b/libjava/classpath/java/awt/image/BufferedImage.java @@ -1,5 +1,5 @@ /* BufferedImage.java -- - Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation + Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -99,6 +99,13 @@ public class BufferedImage extends Image Vector observers; + /** + * Creates a new buffered image. + * + * @param w the width. + * @param h the height. + * @param type the image type (see the constants defined by this class). + */ public BufferedImage(int w, int h, int type) { ColorModel cm = null; @@ -363,11 +370,28 @@ public class BufferedImage extends Image return 1; } + /** + * Returns the value of the specified property, or + * {@link Image#UndefinedProperty} if the property is not defined. + * + * @param string the property key (null not permitted). + * + * @return The property value. + * + * @throws NullPointerException if string is null. + */ public Object getProperty(String string) { - if (properties == null) - return null; - return properties.get(string); + if (string == null) + throw new NullPointerException("The property name cannot be null."); + Object result = Image.UndefinedProperty; + if (properties != null) + { + Object v = properties.get(string); + if (v != null) + result = v; + } + return result; } public Object getProperty(String string, ImageObserver imageobserver) @@ -375,10 +399,15 @@ public class BufferedImage extends Image return getProperty(string); } - + /** + * Returns null always. + * + * @return null always. + */ public String[] getPropertyNames() { - // FIXME: implement + // This method should always return null, see: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4640609 return null; } diff --git a/libjava/classpath/java/awt/image/PixelGrabber.java b/libjava/classpath/java/awt/image/PixelGrabber.java index b8ca70c..70a80af 100644 --- a/libjava/classpath/java/awt/image/PixelGrabber.java +++ b/libjava/classpath/java/awt/image/PixelGrabber.java @@ -112,7 +112,8 @@ public class PixelGrabber implements ImageConsumer * in the grab rectangle will be stored at * pix[(n - y) * scansize + (m - x) + off]. * - * @param ip the ImageProducer from which to grab pixels + * @param ip the ImageProducer from which to grab pixels. This can + * be null. * @param x the x coordinate of the grab rectangle's top-left pixel, * specified relative to the top-left corner of the image produced * by ip @@ -131,9 +132,6 @@ public class PixelGrabber implements ImageConsumer public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int pix[], int off, int scansize) { - if (ip == null) - throw new NullPointerException("The ImageProducer must not be null."); - this.ip = ip; this.x = x; this.y = y; @@ -222,7 +220,6 @@ public class PixelGrabber implements ImageConsumer } catch (Exception ex) { - ex.printStackTrace(); imageComplete(ImageConsumer.IMAGEABORTED); } } diff --git a/libjava/classpath/java/text/Bidi.java b/libjava/classpath/java/text/Bidi.java index 4374360..05b10f5 100644 --- a/libjava/classpath/java/text/Bidi.java +++ b/libjava/classpath/java/text/Bidi.java @@ -644,6 +644,7 @@ public final class Bidi case Character.DIRECTIONALITY_OTHER_NEUTRALS: case Character.DIRECTIONALITY_SEGMENT_SEPARATOR: case Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR: + case Character.DIRECTIONALITY_WHITESPACE: if (neutralStart == -1) neutralStart = i; break; @@ -657,7 +658,7 @@ public final class Bidi ? prevStrong : embeddingDirection); for (int j = neutralStart; j < i; ++j) - types[i] = override; + types[j] = override; } prevStrong = newStrong; neutralStart = -1; -- cgit v1.1