summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu')
-rw-r--r--libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java6
-rw-r--r--libjava/classpath/gnu/CORBA/Poa/gnuPOA.java1
-rw-r--r--libjava/classpath/gnu/classpath/Pair.java126
-rw-r--r--libjava/classpath/gnu/classpath/ServiceFactory.java83
-rw-r--r--libjava/classpath/gnu/classpath/jdwp/util/Value.java0
-rw-r--r--libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java2
-rw-r--r--libjava/classpath/gnu/classpath/jdwp/value/ArrayValue.java2
-rw-r--r--libjava/classpath/gnu/java/awt/AWTUtilities.java203
-rw-r--r--libjava/classpath/gnu/java/awt/ClasspathGraphicsEnvironment.java67
-rw-r--r--libjava/classpath/gnu/java/awt/ClasspathToolkit.java45
-rw-r--r--libjava/classpath/gnu/java/awt/font/FontDelegate.java10
-rw-r--r--libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java49
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/AutoHinter.java83
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/AxisHints.java69
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Constants.java25
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Edge.java80
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java579
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/HintScaler.java (renamed from libjava/classpath/gnu/java/awt/font/autofit/Scaler.java)5
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Latin.java1214
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/LatinAxis.java11
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/LatinBlue.java59
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/LatinMetrics.java15
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Script.java6
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/ScriptMetrics.java6
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Segment.java50
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Utils.java255
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/Width.java16
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/Hinter.java63
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/OpenTypeFont.java38
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/Scaler.java3
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/Fixed.java20
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphLoader.java33
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/Point.java285
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java10
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/Zone.java146
-rw-r--r--libjava/classpath/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java24
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java494
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ActiveEdges.java195
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/PolyEdge.java71
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/Scanline.java91
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java404
-rw-r--r--libjava/classpath/gnu/java/awt/peer/ClasspathDesktopPeer.java301
-rw-r--r--libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java32
-rw-r--r--libjava/classpath/gnu/java/awt/peer/GnomeDesktopPeer.java153
-rw-r--r--libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java135
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/AsyncImage.java10
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java116
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java527
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java299
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java123
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java108
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java157
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java109
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java303
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java40
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java16
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java137
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java4
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java19
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java26
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java202
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java85
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java70
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java20
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java20
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java138
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java74
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java6
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java26
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java14
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java16
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java6
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java8
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java6
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java6
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java14
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java642
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java12
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java4
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java114
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java60
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java20
-rw-r--r--libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java49
-rw-r--r--libjava/classpath/gnu/java/awt/print/JavaPrinterGraphics.java3
-rw-r--r--libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java3
-rw-r--r--libjava/classpath/gnu/java/beans/encoder/ScanEngine.java2
-rw-r--r--libjava/classpath/gnu/java/io/Base64InputStream.java10
-rw-r--r--libjava/classpath/gnu/java/io/class-dependencies.conf75
-rw-r--r--libjava/classpath/gnu/java/lang/management/BeanImpl.java237
-rw-r--r--libjava/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java5
-rw-r--r--libjava/classpath/gnu/java/lang/management/ThreadMXBeanImpl.java62
-rw-r--r--libjava/classpath/gnu/java/locale/LocaleHelper.java127
-rw-r--r--libjava/classpath/gnu/java/math/Fixed.java207
-rw-r--r--libjava/classpath/gnu/java/net/BASE64.java190
-rw-r--r--libjava/classpath/gnu/java/net/DefaultContentHandlerFactory.java4
-rw-r--r--libjava/classpath/gnu/java/net/GetLocalHostAction.java4
-rw-r--r--libjava/classpath/gnu/java/net/HeaderFieldHelper.java19
-rw-r--r--libjava/classpath/gnu/java/net/IndexListParser.java8
-rw-r--r--libjava/classpath/gnu/java/net/loader/JarURLLoader.java20
-rw-r--r--libjava/classpath/gnu/java/net/loader/URLLoader.java2
-rw-r--r--libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java9
-rw-r--r--libjava/classpath/gnu/java/net/local/LocalServerSocket.java1
-rw-r--r--libjava/classpath/gnu/java/net/local/LocalSocket.java1
-rw-r--r--libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java4
-rw-r--r--libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java15
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java4
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java14
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java13
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/Headers.java45
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/Request.java17
-rw-r--r--libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java28
-rw-r--r--libjava/classpath/gnu/java/net/protocol/jar/Connection.java5
-rw-r--r--libjava/classpath/gnu/java/net/protocol/jar/Handler.java4
-rw-r--r--libjava/classpath/gnu/java/nio/ChannelInputStream.java12
-rw-r--r--libjava/classpath/gnu/java/nio/SelectorProviderImpl.java1
-rw-r--r--libjava/classpath/gnu/java/nio/charset/ByteCharset.java7
-rw-r--r--libjava/classpath/gnu/java/nio/charset/EncodingHelper.java11
-rw-r--r--libjava/classpath/gnu/java/security/util/Base64.java349
-rw-r--r--libjava/classpath/gnu/java/security/x509/X509Certificate.java64
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java68
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java10
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/Extension.java16
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/GeneralName.java232
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java92
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/GeneralSubtree.java156
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java4
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/NameConstraints.java161
-rw-r--r--libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java4
-rw-r--r--libjava/classpath/gnu/java/util/Base64.java (renamed from libjava/classpath/gnu/javax/net/ssl/Base64.java)39
-rw-r--r--libjava/classpath/gnu/java/util/prefs/EventDispatcher.java4
-rw-r--r--libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java20
-rw-r--r--libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java6
-rw-r--r--libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java8
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenChar.java5
-rw-r--r--libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java4
-rw-r--r--libjava/classpath/gnu/javax/management/Translator.java544
-rw-r--r--libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java5
-rw-r--r--libjava/classpath/gnu/javax/net/ssl/provider/SSLEngineImpl.java2
-rw-r--r--libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java3
-rw-r--r--libjava/classpath/gnu/javax/security/auth/login/ConfigFileParser.java8
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java6
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java5
-rw-r--r--libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java5
-rw-r--r--libjava/classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java2
-rw-r--r--libjava/classpath/gnu/javax/swing/text/html/css/CSSParser.java7
-rw-r--r--libjava/classpath/gnu/javax/swing/text/html/parser/gnuDTD.java1
-rw-r--r--libjava/classpath/gnu/javax/swing/text/html/parser/support/Parser.java2
-rw-r--r--libjava/classpath/gnu/xml/dom/DomDocumentBuilder.java55
-rw-r--r--libjava/classpath/gnu/xml/dom/ls/DomLSParser.java11
-rw-r--r--libjava/classpath/gnu/xml/pipeline/DomConsumer.java2
-rw-r--r--libjava/classpath/gnu/xml/stream/SAXParser.java4
-rw-r--r--libjava/classpath/gnu/xml/stream/XMLParser.java18
-rw-r--r--libjava/classpath/gnu/xml/util/XCat.java2
153 files changed, 8609 insertions, 3655 deletions
diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java
index 0c31d4093e2..57150f74695 100644
--- a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java
+++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java
@@ -172,7 +172,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
else
return super.current_member_kind();
}
- ;
/** @inheritDoc */
public String current_member_name() throws TypeMismatch, InvalidValue
@@ -182,7 +181,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
else
return super.current_member_name();
}
- ;
/** @inheritDoc */
public NameDynAnyPair[] get_members_as_dyn_any() throws InvalidValue
@@ -191,7 +189,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
throw new InvalidValue(ISNULL);
return super.gnu_get_members_as_dyn_any();
}
- ;
/** @inheritDoc */
public NameValuePair[] get_members() throws InvalidValue
@@ -201,7 +198,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
else
return super.gnu_get_members();
}
- ;
/** @inheritDoc */
public void set_members_as_dyn_any(NameDynAnyPair[] value)
@@ -210,7 +206,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
super.set_members_as_dyn_any(value);
isNull = false;
}
- ;
/** @inheritDoc */
public void set_members(NameValuePair[] value)
@@ -219,7 +214,6 @@ public class gnuDynValue extends RecordAny implements DynValue,
super.set_members(value);
isNull = false;
}
- ;
/** @inheritDoc */
public boolean is_null()
diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java
index 8ceec23d781..0dbca7cfbde 100644
--- a/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java
+++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java
@@ -1348,7 +1348,6 @@ public class gnuPOA
{
return name;
}
- ;
/**
* Return the parent of this POA.
diff --git a/libjava/classpath/gnu/classpath/Pair.java b/libjava/classpath/gnu/classpath/Pair.java
new file mode 100644
index 00000000000..57af37a7464
--- /dev/null
+++ b/libjava/classpath/gnu/classpath/Pair.java
@@ -0,0 +1,126 @@
+/* Pair.java -- A heterogenous pair of objects.
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath;
+
+/**
+ * A container for a pair of heterogenous objects.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public class Pair<A,B>
+{
+
+ /**
+ * The left-hand side of the pair.
+ */
+ private A left;
+
+ /**
+ * The right-hand side of the pair.
+ */
+ private B right;
+
+ /**
+ * Constructs a new pair using the given left and
+ * right values.
+ *
+ * @param left the left-hand side of the pair.
+ * @param right the right-hand side of the pair.
+ */
+ public Pair(A left, B right)
+ {
+ this.left = left;
+ this.right = right;
+ }
+
+ /**
+ * Returns the left-hand side of the pair.
+ *
+ * @return the left-hand value.
+ */
+ public A getLeft()
+ {
+ return left;
+ }
+
+ /**
+ * Returns the right-hand side of the pair.
+ *
+ * @return the right-hand value.
+ */
+ public B getRight()
+ {
+ return right;
+ }
+
+ /**
+ * Returns true if the specified object is also a
+ * pair with equivalent left and right values.
+ *
+ * @param obj the object to compare.
+ * @return true if the two are equal.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof Pair)
+ {
+ Pair<A,B> p = (Pair<A,B>) obj;
+ A lp = p.getLeft();
+ B rp = p.getRight();
+ return (lp == null ? left == null : lp.equals(left)) &&
+ (rp == null ? right == null : rp.equals(right));
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hashcode for the pair, created by the
+ * summation of the hashcodes of the left and right
+ * hand values.
+ *
+ * @return a hashcode for the pair.
+ */
+ public int hashCode()
+ {
+ return (left == null ? 0 : left.hashCode())
+ + (right == null ? 0 : right.hashCode());
+ }
+
+}
diff --git a/libjava/classpath/gnu/classpath/ServiceFactory.java b/libjava/classpath/gnu/classpath/ServiceFactory.java
index 122a79c96ed..daf996c23ca 100644
--- a/libjava/classpath/gnu/classpath/ServiceFactory.java
+++ b/libjava/classpath/gnu/classpath/ServiceFactory.java
@@ -49,6 +49,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.ServiceConfigurationError;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
@@ -176,7 +177,6 @@ public final class ServiceFactory
*/
private static final Logger LOGGER = Logger.getLogger("gnu.classpath");
-
/**
* Declared private in order to prevent constructing instances of
* this utility class.
@@ -225,6 +225,51 @@ public final class ServiceFactory
public static Iterator lookupProviders(Class spi,
ClassLoader loader)
{
+ return lookupProviders(spi, loader, false);
+ }
+
+ /**
+ * Finds service providers that are implementing the specified
+ * Service Provider Interface.
+ *
+ * <p><b>On-demand loading:</b> Loading and initializing service
+ * providers is delayed as much as possible. The rationale is that
+ * typical clients will iterate through the set of installed service
+ * providers until one is found that matches some criteria (like
+ * supported formats, or quality of service). In such scenarios, it
+ * might make sense to install only the frequently needed service
+ * providers on the local machine. More exotic providers can be put
+ * onto a server; the server will only be contacted when no suitable
+ * service could be found locally.
+ *
+ * <p><b>Security considerations:</b> Any loaded service providers
+ * are loaded through the specified ClassLoader, or the system
+ * ClassLoader if <code>classLoader</code> is
+ * <code>null</code>. When <code>lookupProviders</code> is called,
+ * the current {@link AccessControlContext} gets recorded. This
+ * captured security context will determine the permissions when
+ * services get loaded via the <code>next()</code> method of the
+ * returned <code>Iterator</code>.
+ *
+ * @param spi the service provider interface which must be
+ * implemented by any loaded service providers.
+ *
+ * @param loader the class loader that will be used to load the
+ * service providers, or <code>null</code> for the system class
+ * loader. For using the context class loader, see {@link
+ * #lookupProviders(Class)}.
+ * @param error true if a {@link ServiceConfigurationError}
+ * should be thrown when an error occurs, rather
+ * than it merely being logged.
+ * @return an iterator over instances of <code>spi</code>.
+ *
+ * @throws IllegalArgumentException if <code>spi</code> is
+ * <code>null</code>.
+ */
+ public static Iterator lookupProviders(Class spi,
+ ClassLoader loader,
+ boolean error)
+ {
String resourceName;
Enumeration urls;
@@ -246,10 +291,14 @@ public final class ServiceFactory
* does not return anything (no providers installed).
*/
log(Level.WARNING, "cannot access {0}", resourceName, ioex);
- return Collections.EMPTY_LIST.iterator();
+ if (error)
+ throw new ServiceConfigurationError("Failed to access + " +
+ resourceName, ioex);
+ else
+ return Collections.EMPTY_LIST.iterator();
}
- return new ServiceIterator(spi, urls, loader,
+ return new ServiceIterator(spi, urls, loader, error,
AccessController.getContext());
}
@@ -342,6 +391,11 @@ public final class ServiceFactory
*/
private Object nextProvider;
+ /**
+ * True if a {@link ServiceConfigurationError} should be thrown
+ * when an error occurs, instead of it merely being logged.
+ */
+ private boolean error;
/**
* Constructs an Iterator that loads and initializes services on
@@ -359,16 +413,21 @@ public final class ServiceFactory
* @param loader the ClassLoader that gets used for loading
* service providers.
*
+ * @param error true if a {@link ServiceConfigurationError}
+ * should be thrown when an error occurs, rather
+ * than it merely being logged.
+ *
* @param securityContext the security context to use when loading
* and initializing service providers.
*/
ServiceIterator(Class spi, Enumeration urls, ClassLoader loader,
- AccessControlContext securityContext)
+ boolean error, AccessControlContext securityContext)
{
this.spi = spi;
this.urls = urls;
this.loader = loader;
this.securityContext = securityContext;
+ this.error = error;
this.nextProvider = loadNextServiceProvider();
}
@@ -426,6 +485,9 @@ public final class ServiceFactory
log(Level.WARNING, "IOException upon reading {0}", currentURL,
readProblem);
line = null;
+ if (error)
+ throw new ServiceConfigurationError("Error reading " +
+ currentURL, readProblem);
}
/* When we are at the end of one list of services,
@@ -477,6 +539,13 @@ public final class ServiceFactory
log(Level.WARNING, msg,
new Object[] { line, spi.getName(), currentURL },
ex);
+ if (error)
+ throw new ServiceConfigurationError("Cannot load service "+
+ "provider class " +
+ line + " specified by "+
+ "\"META-INF/services/"+
+ spi.getName() + "\" in "+
+ currentURL, ex);
continue;
}
}
@@ -497,6 +566,9 @@ public final class ServiceFactory
catch (Exception ex)
{
log(Level.WARNING, "cannot close {0}", currentURL, ex);
+ if (error)
+ throw new ServiceConfigurationError("Cannot close " +
+ currentURL, ex);
}
reader = null;
currentURL = null;
@@ -515,6 +587,9 @@ public final class ServiceFactory
catch (Exception ex)
{
log(Level.WARNING, "cannot open {0}", currentURL, ex);
+ if (error)
+ throw new ServiceConfigurationError("Cannot open " +
+ currentURL, ex);
}
}
while (reader == null);
diff --git a/libjava/classpath/gnu/classpath/jdwp/util/Value.java b/libjava/classpath/gnu/classpath/jdwp/util/Value.java
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/libjava/classpath/gnu/classpath/jdwp/util/Value.java
+++ /dev/null
diff --git a/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java b/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java
index f30c2158100..9732422f57e 100644
--- a/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java
+++ b/libjava/classpath/gnu/classpath/jdwp/util/VariableTable.java
@@ -1,5 +1,5 @@
/* VariableTable.java -- A class representing a Variable Table for a method
- Copyright (C) 2005 Free Software Foundation
+ Copyright (C) 2005, 2007 Free Software Foundation
This file is part of GNU Classpath.
diff --git a/libjava/classpath/gnu/classpath/jdwp/value/ArrayValue.java b/libjava/classpath/gnu/classpath/jdwp/value/ArrayValue.java
index c5e00a019d9..66e7c4e32b4 100644
--- a/libjava/classpath/gnu/classpath/jdwp/value/ArrayValue.java
+++ b/libjava/classpath/gnu/classpath/jdwp/value/ArrayValue.java
@@ -1,4 +1,4 @@
-/* ArrayValue.java -- JDWP wrapper class for an Object value
+/* ObjectValue.java -- JDWP wrapper class for an Object value
Copyright (C) 2007 Free Software Foundation
This file is part of GNU Classpath.
diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java
index ca7b5511853..1b68703697f 100644
--- a/libjava/classpath/gnu/java/awt/AWTUtilities.java
+++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java
@@ -1,5 +1,5 @@
/* AWTUtilities.java -- Common utility methods for AWT and Swing.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,6 +47,7 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.AbstractSequentialList;
import java.util.List;
@@ -694,4 +695,204 @@ public class AWTUtilities
{
return java.awt.EventQueue.isDispatchThread();
}
+
+ /**
+ * Returns whether the specified key code is valid.
+ */
+ public static boolean isValidKey(int keyCode)
+ {
+ switch (keyCode)
+ {
+ case KeyEvent.VK_ENTER:
+ case KeyEvent.VK_BACK_SPACE:
+ case KeyEvent.VK_TAB:
+ case KeyEvent.VK_CANCEL:
+ case KeyEvent.VK_CLEAR:
+ case KeyEvent.VK_SHIFT:
+ case KeyEvent.VK_CONTROL:
+ case KeyEvent.VK_ALT:
+ case KeyEvent.VK_PAUSE:
+ case KeyEvent.VK_CAPS_LOCK:
+ case KeyEvent.VK_ESCAPE:
+ case KeyEvent.VK_SPACE:
+ case KeyEvent.VK_PAGE_UP:
+ case KeyEvent.VK_PAGE_DOWN:
+ case KeyEvent.VK_END:
+ case KeyEvent.VK_HOME:
+ case KeyEvent.VK_LEFT:
+ case KeyEvent.VK_UP:
+ case KeyEvent.VK_RIGHT:
+ case KeyEvent.VK_DOWN:
+ case KeyEvent.VK_COMMA:
+ case KeyEvent.VK_MINUS:
+ case KeyEvent.VK_PERIOD:
+ case KeyEvent.VK_SLASH:
+ case KeyEvent.VK_0:
+ case KeyEvent.VK_1:
+ case KeyEvent.VK_2:
+ case KeyEvent.VK_3:
+ case KeyEvent.VK_4:
+ case KeyEvent.VK_5:
+ case KeyEvent.VK_6:
+ case KeyEvent.VK_7:
+ case KeyEvent.VK_8:
+ case KeyEvent.VK_9:
+ case KeyEvent.VK_SEMICOLON:
+ case KeyEvent.VK_EQUALS:
+ case KeyEvent.VK_A:
+ case KeyEvent.VK_B:
+ case KeyEvent.VK_C:
+ case KeyEvent.VK_D:
+ case KeyEvent.VK_E:
+ case KeyEvent.VK_F:
+ case KeyEvent.VK_G:
+ case KeyEvent.VK_H:
+ case KeyEvent.VK_I:
+ case KeyEvent.VK_J:
+ case KeyEvent.VK_K:
+ case KeyEvent.VK_L:
+ case KeyEvent.VK_M:
+ case KeyEvent.VK_N:
+ case KeyEvent.VK_O:
+ case KeyEvent.VK_P:
+ case KeyEvent.VK_Q:
+ case KeyEvent.VK_R:
+ case KeyEvent.VK_S:
+ case KeyEvent.VK_T:
+ case KeyEvent.VK_U:
+ case KeyEvent.VK_V:
+ case KeyEvent.VK_W:
+ case KeyEvent.VK_X:
+ case KeyEvent.VK_Y:
+ case KeyEvent.VK_Z:
+ case KeyEvent.VK_OPEN_BRACKET:
+ case KeyEvent.VK_BACK_SLASH:
+ case KeyEvent.VK_CLOSE_BRACKET:
+ case KeyEvent.VK_NUMPAD0:
+ case KeyEvent.VK_NUMPAD1:
+ case KeyEvent.VK_NUMPAD2:
+ case KeyEvent.VK_NUMPAD3:
+ case KeyEvent.VK_NUMPAD4:
+ case KeyEvent.VK_NUMPAD5:
+ case KeyEvent.VK_NUMPAD6:
+ case KeyEvent.VK_NUMPAD7:
+ case KeyEvent.VK_NUMPAD8:
+ case KeyEvent.VK_NUMPAD9:
+ case KeyEvent.VK_MULTIPLY:
+ case KeyEvent.VK_ADD:
+ case KeyEvent.VK_SEPARATOR:
+ case KeyEvent.VK_SUBTRACT:
+ case KeyEvent.VK_DECIMAL:
+ case KeyEvent.VK_DIVIDE:
+ case KeyEvent.VK_DELETE:
+ case KeyEvent.VK_NUM_LOCK:
+ case KeyEvent.VK_SCROLL_LOCK:
+ case KeyEvent.VK_F1:
+ case KeyEvent.VK_F2:
+ case KeyEvent.VK_F3:
+ case KeyEvent.VK_F4:
+ case KeyEvent.VK_F5:
+ case KeyEvent.VK_F6:
+ case KeyEvent.VK_F7:
+ case KeyEvent.VK_F8:
+ case KeyEvent.VK_F9:
+ case KeyEvent.VK_F10:
+ case KeyEvent.VK_F11:
+ case KeyEvent.VK_F12:
+ case KeyEvent.VK_F13:
+ case KeyEvent.VK_F14:
+ case KeyEvent.VK_F15:
+ case KeyEvent.VK_F16:
+ case KeyEvent.VK_F17:
+ case KeyEvent.VK_F18:
+ case KeyEvent.VK_F19:
+ case KeyEvent.VK_F20:
+ case KeyEvent.VK_F21:
+ case KeyEvent.VK_F22:
+ case KeyEvent.VK_F23:
+ case KeyEvent.VK_F24:
+ case KeyEvent.VK_PRINTSCREEN:
+ case KeyEvent.VK_INSERT:
+ case KeyEvent.VK_HELP:
+ case KeyEvent.VK_META:
+ case KeyEvent.VK_BACK_QUOTE:
+ case KeyEvent.VK_QUOTE:
+ case KeyEvent.VK_KP_UP:
+ case KeyEvent.VK_KP_DOWN:
+ case KeyEvent.VK_KP_LEFT:
+ case KeyEvent.VK_KP_RIGHT:
+ case KeyEvent.VK_DEAD_GRAVE:
+ case KeyEvent.VK_DEAD_ACUTE:
+ case KeyEvent.VK_DEAD_CIRCUMFLEX:
+ case KeyEvent.VK_DEAD_TILDE:
+ case KeyEvent.VK_DEAD_MACRON:
+ case KeyEvent.VK_DEAD_BREVE:
+ case KeyEvent.VK_DEAD_ABOVEDOT:
+ case KeyEvent.VK_DEAD_DIAERESIS:
+ case KeyEvent.VK_DEAD_ABOVERING:
+ case KeyEvent.VK_DEAD_DOUBLEACUTE:
+ case KeyEvent.VK_DEAD_CARON:
+ case KeyEvent.VK_DEAD_CEDILLA:
+ case KeyEvent.VK_DEAD_OGONEK:
+ case KeyEvent.VK_DEAD_IOTA:
+ case KeyEvent.VK_DEAD_VOICED_SOUND:
+ case KeyEvent.VK_DEAD_SEMIVOICED_SOUND:
+ case KeyEvent.VK_AMPERSAND:
+ case KeyEvent.VK_ASTERISK:
+ case KeyEvent.VK_QUOTEDBL:
+ case KeyEvent.VK_LESS:
+ case KeyEvent.VK_GREATER:
+ case KeyEvent.VK_BRACELEFT:
+ case KeyEvent.VK_BRACERIGHT:
+ case KeyEvent.VK_AT:
+ case KeyEvent.VK_COLON:
+ case KeyEvent.VK_CIRCUMFLEX:
+ case KeyEvent.VK_DOLLAR:
+ case KeyEvent.VK_EURO_SIGN:
+ case KeyEvent.VK_EXCLAMATION_MARK:
+ case KeyEvent.VK_INVERTED_EXCLAMATION_MARK:
+ case KeyEvent.VK_LEFT_PARENTHESIS:
+ case KeyEvent.VK_NUMBER_SIGN:
+ case KeyEvent.VK_PLUS:
+ case KeyEvent.VK_RIGHT_PARENTHESIS:
+ case KeyEvent.VK_UNDERSCORE:
+ case KeyEvent.VK_FINAL:
+ case KeyEvent.VK_CONVERT:
+ case KeyEvent.VK_NONCONVERT:
+ case KeyEvent.VK_ACCEPT:
+ case KeyEvent.VK_MODECHANGE:
+ case KeyEvent.VK_KANA:
+ case KeyEvent.VK_KANJI:
+ case KeyEvent.VK_ALPHANUMERIC:
+ case KeyEvent.VK_KATAKANA:
+ case KeyEvent.VK_HIRAGANA:
+ case KeyEvent.VK_FULL_WIDTH:
+ case KeyEvent.VK_HALF_WIDTH:
+ case KeyEvent.VK_ROMAN_CHARACTERS:
+ case KeyEvent.VK_ALL_CANDIDATES:
+ case KeyEvent.VK_PREVIOUS_CANDIDATE:
+ case KeyEvent.VK_CODE_INPUT:
+ case KeyEvent.VK_JAPANESE_KATAKANA:
+ case KeyEvent.VK_JAPANESE_HIRAGANA:
+ case KeyEvent.VK_JAPANESE_ROMAN:
+ case KeyEvent.VK_KANA_LOCK:
+ case KeyEvent.VK_INPUT_METHOD_ON_OFF:
+ case KeyEvent.VK_CUT:
+ case KeyEvent.VK_COPY:
+ case KeyEvent.VK_PASTE:
+ case KeyEvent.VK_UNDO:
+ case KeyEvent.VK_AGAIN:
+ case KeyEvent.VK_FIND:
+ case KeyEvent.VK_PROPS:
+ case KeyEvent.VK_STOP:
+ case KeyEvent.VK_COMPOSE:
+ case KeyEvent.VK_ALT_GRAPH:
+ case KeyEvent.VK_BEGIN:
+ case KeyEvent.VK_CONTEXT_MENU:
+ case KeyEvent.VK_WINDOWS:
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/ClasspathGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/ClasspathGraphicsEnvironment.java
new file mode 100644
index 00000000000..865da1d9594
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/ClasspathGraphicsEnvironment.java
@@ -0,0 +1,67 @@
+/* ClasspathGraphicsEnvironment.java
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt;
+
+import java.awt.GraphicsEnvironment;
+import java.awt.image.ColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class extends the GraphicsEnvironment API with some Classpath-specific
+ * methods, in order to provide optimized graphics handling.
+ *
+ * @author Francis Kung <fkung@redhat.com>
+ */
+public abstract class ClasspathGraphicsEnvironment
+ extends GraphicsEnvironment
+{
+ /**
+ * Returns an appropriate Raster that can efficiently back a
+ * BufferedImage with the given ColorModel and SampleModel.
+ *
+ * @param cm The color model.
+ * @param sm The samepl model.
+ * @return An appropriate WritableRaster, or null if acceleration/optimization
+ * is not available for the given colour model / sample model.
+ */
+ public WritableRaster createRaster(ColorModel cm, SampleModel sm)
+ {
+ return null;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java
index 968cc3b1643..d78fbab4e1e 100644
--- a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java
+++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java
@@ -38,36 +38,28 @@ exception statement from your version. */
package gnu.java.awt;
-import gnu.java.awt.EmbeddedWindow;
+import gnu.java.awt.peer.ClasspathDesktopPeer;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.peer.EmbeddedWindowPeer;
import gnu.java.security.action.SetAccessibleAction;
import java.awt.AWTException;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.DisplayMode;
+import java.awt.Desktop;
import java.awt.Font;
-import java.awt.FontMetrics;
+import java.awt.FontFormatException;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Point;
+import java.awt.HeadlessException;
import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.image.ColorModel;
-import java.awt.image.ImageProducer;
+import java.awt.font.TextAttribute;
+import java.awt.peer.DesktopPeer;
import java.awt.peer.RobotPeer;
-import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.AttributedString;
-import java.util.HashMap;
-import java.util.Map;
import java.security.AccessController;
+import java.util.Map;
import javax.imageio.spi.IIORegistry;
@@ -118,7 +110,8 @@ public abstract class ClasspathToolkit
* this font peer should have, such as size, weight, family name, or
* transformation.
*/
- public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs);
+ public abstract ClasspathFontPeer getClasspathFontPeer (String name,
+ Map<?,?> attrs);
/**
* Creates a {@link Font}, in a platform-specific manner.
@@ -137,9 +130,8 @@ public abstract class ClasspathToolkit
try
{
Constructor fontConstructor = Font.class.getDeclaredConstructor
- (new Class[] { String.class, Map.class });
- AccessController.doPrivileged
- (new SetAccessibleAction(fontConstructor));
+ (new Class[] { String.class, Map.class });
+ AccessController.doPrivileged(new SetAccessibleAction(fontConstructor));
f = (Font) fontConstructor.newInstance(new Object[] { name, attrs });
}
catch (IllegalAccessException e)
@@ -224,5 +216,18 @@ public abstract class ClasspathToolkit
{
return -1;
}
+
+ /* (non-Javadoc)
+ * @see java.awt.Toolkit#createDesktopPeer(java.awt.Desktop)
+ */
+ protected DesktopPeer createDesktopPeer(Desktop target)
+ throws HeadlessException
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException();
+
+ return ClasspathDesktopPeer.getDesktop();
+ }
+
}
diff --git a/libjava/classpath/gnu/java/awt/font/FontDelegate.java b/libjava/classpath/gnu/java/awt/font/FontDelegate.java
index a26510ee2de..030f9d3bca5 100644
--- a/libjava/classpath/gnu/java/awt/font/FontDelegate.java
+++ b/libjava/classpath/gnu/java/awt/font/FontDelegate.java
@@ -61,6 +61,13 @@ import java.util.Locale;
*/
public interface FontDelegate
{
+ public static final int FLAG_FITTED = 1 << 0;
+ public static final int FLAG_NO_HINT_HORIZONTAL = 1 << 1;
+ public static final int FLAG_NO_HINT_VERTICAL = 1 << 2;
+ public static final int FLAG_NO_HINT_EDGE_POINTS = 1 << 3;
+ public static final int FLAG_NO_HINT_STRONG_POINTS = 1 << 4;
+ public static final int FLAG_NO_HINT_WEAK_POINTS = 1 << 5;
+
/**
* Returns the full name of this font face in the specified
* locale, for example <i>&#x201c;Univers Light&#x201d;</i>.
@@ -221,7 +228,8 @@ public interface FontDelegate
float pointSize,
AffineTransform transform,
boolean antialias,
- boolean fractionalMetrics);
+ boolean fractionalMetrics,
+ int type);
/**
diff --git a/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java b/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java
index f17a4511375..2f73dce77b0 100644
--- a/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java
+++ b/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java
@@ -164,7 +164,9 @@ public class GNUGlyphVector
renderContext.usesFractionalMetrics(),
/* horizontal */ true,
advance);
- pos[p] = x += advance.x;
+ // FIXME: We shouldn't round here, but instead hint the metrics
+ // correctly.
+ pos[p] = x += Math.round(advance.x);
pos[p + 1] = y += advance.y;
}
valid = true;
@@ -284,6 +286,22 @@ public class GNUGlyphVector
return outline;
}
+ public Shape getOutline(float x, float y, int type)
+ {
+ validate();
+
+ GeneralPath outline = new GeneralPath();
+ int len = glyphs.length;
+ for (int i = 0; i < len; i++)
+ {
+ GeneralPath p = new GeneralPath(getGlyphOutline(i, type));
+ outline.append(p, false);
+ }
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ outline.transform(t);
+ return outline;
+ }
/**
* Determines the shape of the specified glyph.
@@ -309,7 +327,8 @@ public class GNUGlyphVector
path = fontDelegate.getGlyphOutline(glyphs[glyphIndex], fontSize, tx,
renderContext.isAntiAliased(),
- renderContext.usesFractionalMetrics());
+ renderContext.usesFractionalMetrics(),
+ FontDelegate.FLAG_FITTED);
tx = new AffineTransform();
tx.translate(pos[glyphIndex * 2], pos[glyphIndex * 2 + 1]);
@@ -317,6 +336,32 @@ public class GNUGlyphVector
return path;
}
+ public Shape getGlyphOutline(int glyphIndex, int type)
+ {
+ AffineTransform tx, glyphTx;
+ GeneralPath path;
+
+ validate();
+
+ if ((transforms != null)
+ && ((glyphTx = transforms[glyphIndex]) != null))
+ {
+ tx = new AffineTransform(transform);
+ tx.concatenate(glyphTx);
+ }
+ else
+ tx = transform;
+
+ path = fontDelegate.getGlyphOutline(glyphs[glyphIndex], fontSize, tx,
+ renderContext.isAntiAliased(),
+ renderContext.usesFractionalMetrics(),
+ type);
+
+ tx = new AffineTransform();
+ tx.translate(pos[glyphIndex * 2], pos[glyphIndex * 2 + 1]);
+ path.transform(tx);
+ return path;
+ }
/**
* Determines the position of the specified glyph, or the
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/AutoHinter.java b/libjava/classpath/gnu/java/awt/font/autofit/AutoHinter.java
new file mode 100644
index 00000000000..b0420ab7a2d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/autofit/AutoHinter.java
@@ -0,0 +1,83 @@
+/* AutoHinter.java -- The entry point into the hinter implementation.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.autofit;
+
+import gnu.java.awt.font.opentype.Hinter;
+import gnu.java.awt.font.opentype.OpenTypeFont;
+import gnu.java.awt.font.opentype.truetype.Fixed;
+import gnu.java.awt.font.opentype.truetype.Zone;
+
+/**
+ * The public interface to the automatic gridfitter.
+ */
+public class AutoHinter
+ implements Hinter
+{
+ Latin latinScript;
+ LatinMetrics metrics;
+ GlyphHints hints;
+
+ HintScaler scaler = new HintScaler();
+ public void init(OpenTypeFont font)
+ {
+ // TODO: Should support other scripts too.
+ latinScript = new Latin();
+ metrics = new LatinMetrics(font);
+ latinScript.initMetrics(metrics, font);
+ scaler.face = font;
+ }
+
+ public void applyHints(Zone outline)
+ {
+ if (hints == null)
+ hints = new GlyphHints();
+ scaler.xScale = Fixed.valueOf16(outline.scaleX * 64);
+ scaler.yScale = Fixed.valueOf16(outline.scaleY * 64);
+ latinScript.scaleMetrics(metrics, scaler);
+ latinScript.applyHints(hints, outline, metrics);
+ }
+
+ public void setFlags(int flags)
+ {
+ if (hints == null)
+ hints = new GlyphHints();
+ hints.flags = flags;
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/AxisHints.java b/libjava/classpath/gnu/java/awt/font/autofit/AxisHints.java
index b2c9912342b..87f2abcc3df 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/AxisHints.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/AxisHints.java
@@ -1,4 +1,4 @@
-/* AxisHints.java -- FIXME: briefly describe file purpose
+/* AxisHints.java -- Hints specific to an axis
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,4 +42,71 @@ class AxisHints
{
Segment[] segments;
+ int majorDir;
+ int numSegments;
+ int numEdges;
+ Edge[] edges;
+
+ AxisHints()
+ {
+ segments = new Segment[4];
+ edges = new Edge[4];
+ }
+
+ Segment newSegment()
+ {
+ if (numSegments >= segments.length)
+ {
+ // Grow array.
+ int newMax = segments.length;
+ newMax += (newMax >> 2) + 4; // From FreeType.
+ Segment[] newSegs = new Segment[newMax];
+ System.arraycopy(segments, 0, newSegs, 0, numSegments);
+ segments = newSegs;
+ }
+ Segment seg = new Segment();
+ segments[numSegments] = seg;
+ numSegments++;
+ return seg;
+ }
+
+ public Edge newEdge(int pos)
+ {
+ if (numEdges >= edges.length)
+ {
+ // Grow array.
+ int newMax = edges.length;
+ newMax += (newMax >> 2) + 4; // From FreeType.
+ Edge[] newEdges = new Edge[newMax];
+ System.arraycopy(edges, 0, newEdges, 0, numEdges);
+ edges = newEdges;
+ }
+ int edgeIndex = numEdges;
+ Edge edge = edges[edgeIndex] = new Edge();
+ while (edgeIndex > 0 && edges[edgeIndex - 1].fpos > pos)
+ {
+ edges[edgeIndex] = edges[edgeIndex - 1];
+ edgeIndex--;
+ }
+ edges[edgeIndex] = edge;
+ numEdges++;
+ edge.fpos = pos;
+
+ return edge;
+
+ }
+
+ int getEdgeIndex(Edge edge2)
+ {
+ int idx = -1;
+ for (int i = 0; i < numEdges; i++)
+ {
+ if (edges[i] == edge2)
+ {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Constants.java b/libjava/classpath/gnu/java/awt/font/autofit/Constants.java
index cb3992825ab..c5b90fa5485 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Constants.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Constants.java
@@ -58,4 +58,29 @@ interface Constants
* The number of dimensions.
*/
static final int DIMENSION_MAX = 2;
+
+ /**
+ * Indicates a vector with no specific direction.
+ */
+ static final int DIR_NONE = 0;
+
+ /**
+ * Right direction.
+ */
+ static final int DIR_RIGHT = 1;
+
+ /**
+ * Left direction.
+ */
+ static final int DIR_LEFT = -1;
+
+ /**
+ * Up direction.
+ */
+ static final int DIR_UP = 2;
+
+ /**
+ * Down direction.
+ */
+ static final int DIR_DOWN = -2;
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Edge.java b/libjava/classpath/gnu/java/awt/font/autofit/Edge.java
new file mode 100644
index 00000000000..d9736650b5f
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Edge.java
@@ -0,0 +1,80 @@
+/* Edge.java -- An edge of segments
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.autofit;
+
+class Edge
+{
+ int fpos;
+ Segment first;
+ Segment last;
+ int opos;
+ Edge link;
+ Edge serif;
+ int flags;
+ int dir;
+ Width blueEdge;
+ int pos;
+ int scale;
+
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[Edge] id");
+ s.append(hashCode());
+ s.append(", fpos: ");
+ s.append(fpos);
+ s.append(", opos: ");
+ s.append(opos);
+ s.append(", pos: ");
+ s.append(pos);
+ s.append(", dir: ");
+ s.append(dir);
+ s.append(", serif: ");
+ s.append(serif != null ? serif.hashCode() : "null");
+ s.append(", link: ");
+ s.append(link != null ? link.hashCode() : "null");
+ s.append(", flags: " + flags);
+ s.append(", blue: " + blueEdge);
+ s.append(", first: ");
+ s.append(first == null ? "null" : first.hashCode());
+ s.append(", last: ");
+ s.append(last == null ? "null" : last.hashCode());
+ return s.toString();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java b/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java
index ad73a04a69b..72f07ed81fc 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java
@@ -38,12 +38,16 @@ exception statement from your version. */
package gnu.java.awt.font.autofit;
+import gnu.java.awt.font.FontDelegate;
+import gnu.java.awt.font.opentype.truetype.Fixed;
+import gnu.java.awt.font.opentype.truetype.Point;
import gnu.java.awt.font.opentype.truetype.Zone;
/**
* The data and methods used for the actual hinting process.
*/
class GlyphHints
+ implements Constants
{
int xScale;
@@ -53,23 +57,584 @@ class GlyphHints
AxisHints[] axis;
- void rescale(ScriptMetrics metrics)
+ Point[] points;
+ int numPoints;
+ int maxPoints;
+
+ Point[] contours;
+ int numContours;
+ int maxContours;
+
+ ScriptMetrics metrics;
+
+ int flags;
+
+ GlyphHints()
+ {
+ axis = new AxisHints[Constants.DIMENSION_MAX];
+ axis[Constants.DIMENSION_VERT] = new AxisHints();
+ axis[Constants.DIMENSION_HORZ] = new AxisHints();
+
+ xScale = Fixed.ONE;
+ yScale = Fixed.ONE;
+ }
+
+ void rescale(ScriptMetrics m)
{
- // TODO: Implement.
+ metrics = m;
+ // TODO: Copy scalerFlags.
}
void reload(Zone outline)
{
- // TODO: Implement.
+ numPoints = 0;
+ numContours = 0;
+ axis[0].numSegments = 0;
+ axis[0].numEdges = 0;
+ axis[1].numSegments = 0;
+ axis[1].numEdges = 0;
+
+ // Create/reallocate the contours array.
+ int newMax = outline.getNumContours();
+ if (newMax > maxContours || contours == null)
+ {
+ newMax = (newMax + 3) & ~3; // Taken from afhints.c .
+ Point[] newContours = new Point[newMax];
+ if (contours != null)
+ {
+ System.arraycopy(contours, 0, newContours, 0, maxContours);
+ }
+ contours = newContours;
+ maxContours = newMax;
+ }
+
+ // Create/reallocate the points array.
+ newMax = outline.getSize() + 2;
+ if (newMax > maxPoints || points == null)
+ {
+ newMax = (newMax + 2 + 7) & ~7; // Taken from afhints.c .
+ Point[] newPoints = new Point[newMax];
+ if (points != null)
+ {
+ System.arraycopy(points, 0, newPoints, 0, maxPoints);
+ }
+ points = newPoints;
+ maxPoints = newMax;
+ }
+
+ numPoints = outline.getSize() - 4; // 4 phantom points.
+ numContours = outline.getNumContours();
+
+ // Set major direction. We don't handle Type 1 fonts yet.
+ axis[DIMENSION_HORZ].majorDir = DIR_UP;
+ axis[DIMENSION_VERT].majorDir = DIR_LEFT;
+
+ // TODO: Freetype seems to scale and translate the glyph at that point.
+ // I suppose that this is not really needed.
+ // The scales are scaling from font units to 1/64 device pixels.
+ xScale = Fixed.valueOf16(outline.scaleX * 64);
+ yScale = Fixed.valueOf16(outline.scaleY * 64);
+
+ // FIXME: What is that xDelta and yDelta used for?
+ System.arraycopy(outline.getPoints(), 0, points, 0, numPoints);
+
+ // Setup prev and next and contours array.
+ // TODO: Probably cache this.
+ contours = new Point[numContours];
+ Point currentContour = points[0];
+ for (int i = 0, cIndex = 0; i < numPoints; i++)
+ {
+ // Start new contour when the last point has been a contour end.
+ if (outline.isContourEnd(i))
+ {
+ // Connect the contour end point to the start point.
+ points[i].setNext(currentContour);
+ currentContour.setPrev(points[i]);
+ contours[cIndex] = currentContour;
+ cIndex++;
+ currentContour = i < numPoints - 1 ? points[i + 1] : null;
+ }
+ else
+ {
+ // Connect the current and the previous point.
+ points[i].setNext(points[i + 1]);
+ points[i + 1].setPrev(points[i]);
+ }
+ }
+ // Compute directions of in and out vectors of all points as well
+ // as the weak point flag.
+ for (int i = 0; i < numPoints; i++)
+ {
+ // Compute in and out dir.
+ Point p = points[i];
+ Point prev = p.getPrev();
+ int inX = p.getOrigX() - prev.getOrigX();
+ int inY = p.getOrigY() - prev.getOrigY();
+ p.setInDir(Utils.computeDirection(inX, inY));
+ Point next = p.getNext();
+ int outX = next.getOrigX() - p.getOrigX();
+ int outY = next.getOrigY() - p.getOrigY();
+ p.setOutDir(Utils.computeDirection(outX, outY));
+
+ if (p.isControlPoint())
+ {
+ setWeakPoint(p);
+ }
+ else if (p.getOutDir() == p.getInDir())
+ {
+ if (p.getOutDir() != DIR_NONE)
+ setWeakPoint(p);
+ else
+ {
+ int angleIn = Utils.atan(inY, inX);
+ int angleOut = Utils.atan(outY, outX);
+ int delta = Utils.angleDiff(angleIn, angleOut);
+ if (delta < 2 && delta > -2)
+ setWeakPoint(p);
+ }
+ }
+ else if (p.getInDir() == - p.getOutDir())
+ {
+ setWeakPoint(p);
+ }
+ }
+ computeInflectionPoints();
+ }
+
+ private void setWeakPoint(Point p)
+ {
+ p.setFlags((byte) (p.getFlags() | Point.FLAG_WEAK_INTERPOLATION));
+ }
+
+ /**
+ * Computes the inflection points for a glyph.
+ */
+ private void computeInflectionPoints()
+ {
+ // Do each contour separately.
+ contours : for (int c = 0; c < contours.length; c++)
+ {
+ Point point = contours[c];
+ Point first = point;
+ Point start = point;
+ Point end = point;
+ do
+ {
+ end = end.getNext();
+ if (end == first)
+ continue contours;
+ } while (end.getOrigX() == first.getOrigX()
+ && end.getOrigY() == first.getOrigY());
+
+ // Extend segment start whenever possible.
+ Point before = start;
+ int angleIn;
+ int angleSeg = Utils.atan(end.getOrigX() - start.getOrigX(),
+ end.getOrigY() - start.getOrigY());
+ do
+ {
+ do
+ {
+ start = before;
+ before = before.getPrev();
+ if (before == first)
+ continue contours;
+ } while (before.getOrigX() == start.getOrigX()
+ && before.getOrigY() == start.getOrigY());
+ angleIn = Utils.atan(start.getOrigX() - before.getOrigX(),
+ start.getOrigY() - before.getOrigY());
+ } while (angleIn == angleSeg);
+
+ first = start;
+ int diffIn = Utils.angleDiff(angleIn, angleSeg);
+ // Now, process all segments in the contour.
+ Point after;
+ boolean finished = false;
+ int angleOut, diffOut;
+ do
+ {
+ // First, extend the current segment's end whenever possible.
+ after = end;
+ do
+ {
+ do
+ {
+ end = after;
+ after = after.getNext();
+ if (after == first)
+ finished = true;
+ } while (end.getOrigX() == after.getOrigX()
+ && end.getOrigY() == after.getOrigY());
+ angleOut = Utils.atan(after.getOrigX() - end.getOrigX(),
+ after.getOrigY() - end.getOrigY());
+ } while (angleOut == angleSeg);
+ diffOut = Utils.angleDiff(angleSeg, angleOut);
+ if ((diffIn ^ diffOut) < 0)
+ {
+ // diffIn and diffOut have different signs, we have
+ // inflection points here.
+ do
+ {
+ start.addFlags(Point.FLAG_INFLECTION);
+ start = start.getNext();
+ } while (start != end);
+ start.addFlags(Point.FLAG_INFLECTION);
+ }
+ start = end;
+ end = after;
+ angleSeg = angleOut;
+ diffIn = diffOut;
+ } while (! finished);
+ }
+ }
+
+ boolean doHorizontal()
+ {
+ return (flags & FontDelegate.FLAG_NO_HINT_HORIZONTAL) == 0;
+ }
+
+ boolean doVertical()
+ {
+ return (flags & FontDelegate.FLAG_NO_HINT_VERTICAL) == 0;
+ }
+
+ void alignWeakPoints(int dim)
+ {
+ short touchFlag;
+ Point point;
+ // PASS 1 : Move segments to edge positions.
+ if (dim == DIMENSION_HORZ)
+ {
+ touchFlag = Point.FLAG_DONE_X;
+ for (int p = 0; p < numPoints; p++)
+ {
+ point = points[p];
+ point.setU(point.getX());
+ point.setV(point.getScaledX());
+ }
+ }
+ else
+ {
+ touchFlag = Point.FLAG_DONE_Y;
+ for (int p = 0; p < numPoints; p++)
+ {
+ point = points[p];
+ point.setU(point.getY());
+ point.setV(point.getScaledY());
+ }
+ }
+ point = points[0];
+ for (int c = 0; c < numContours; c++)
+ {
+ point = contours[c];
+ int idx = getPointIndex(point);
+ Point endPoint = point.getPrev();
+ int endIdx = getPointIndex(endPoint);
+ int firstIdx = idx;
+ while (idx <= endIdx
+ && (point.getFlags() & touchFlag) == 0)
+ {
+ idx++;
+ point = points[idx];
+ }
+ if (idx <= endIdx)
+ {
+ int firstTouched = idx;
+ int curTouched = idx;
+ idx++;
+ point = points[idx];
+ while (idx <= endIdx)
+ {
+ if ((point.getFlags() & touchFlag) != 0)
+ {
+ // We found two successive touch points. We interpolate
+ // all contour points between them.
+ iupInterp(curTouched + 1, idx - 1, curTouched, idx);
+ curTouched = idx;
+ }
+ idx++;
+ point = points[idx];
+ }
+ if (curTouched == firstTouched)
+ {
+ // This is a special case: Only one point was touched in the
+ // contour. We thus simply shift the whole contour.
+ iupShift(firstIdx, endIdx, curTouched);
+ }
+ else
+ {
+ // Now interpolate after the last touched point to the end
+ // of the contour.
+ iupInterp(curTouched + 1, endIdx, curTouched, firstTouched);
+ // If the first contour point isn't touched, interpolate
+ // from the contour start to the first touched point.
+ if (firstTouched > 0)
+ {
+ iupInterp(firstIdx, firstTouched - 1, curTouched,
+ firstTouched);
+ }
+ }
+ }
+ }
+ // Now store the values back.
+ if (dim == DIMENSION_HORZ)
+ {
+ for (int p = 0; p < numPoints; p++)
+ {
+ point = points[p];
+ point.setX(point.getU());
+ }
+ }
+ else
+ {
+ for (int p = 0; p < numPoints; p++)
+ {
+ point = points[p];
+ point.setY(point.getU());
+ }
+ }
+ }
+
+ private void iupShift(int p1, int p2, int ref)
+ {
+ int delta = points[ref].getU() - points[ref].getV();
+ for (int p = p1; p < ref; p++)
+ {
+ points[p].setU(points[p].getV() + delta);
+ }
+ for (int p = ref + 1; p <= p2; p++)
+ {
+ points[p].setU(points[p].getV() + delta);
+ }
+ }
+
+ private void iupInterp(int p1, int p2, int ref1, int ref2)
+ {
+ int v1 = points[ref1].getV();
+ int v2 = points[ref2].getV();
+ int d1 = points[ref1].getU() - v1;
+ int d2 = points[ref2].getU() - v2;
+ if (p1 > p2)
+ return;
+ if (v1 == v2)
+ {
+ for (int p = p1; p <= p2; p++)
+ {
+ int u = points[p].getV();
+ if (u <= v1)
+ u += d1;
+ else
+ u += d2;
+ points[p].setU(u);
+ }
+ }
+ else if (v1 < v2)
+ {
+ for (int p = p1; p <= p2; p++)
+ {
+ int u = points[p].getV();
+ if (u <= v1)
+ u += d1;
+ else if (u >= v2)
+ u += d2;
+ else
+ {
+ u = points[ref1].getU() + Utils.mulDiv(u - v1,
+ points[ref2].getU()
+ - points[ref1].getU(),
+ v2 - v1);
+ }
+ points[p].setU(u);
+ }
+ }
+ else
+ {
+ for (int p = p1; p <= p2; p++)
+ {
+ int u = points[p].getV();
+ if (u <= v2)
+ u += d2;
+ else if (u >= v1)
+ u += d1;
+ else
+ {
+ u = points[ref1].getU() + Utils.mulDiv(u - v1,
+ points[ref2].getU()
+ - points[ref1].getU(),
+ v2 - v1);
+ }
+ points[p].setU(u);
+ }
+ }
+ }
+
+ void alignStrongPoints(int dim)
+ {
+ AxisHints ax = axis[dim];
+ Edge[] edges = ax.edges;
+ int numEdges = ax.numEdges;
+ short touchFlag;
+ if (dim == DIMENSION_HORZ)
+ touchFlag = Point.FLAG_DONE_X;
+ else
+ touchFlag = Point.FLAG_DONE_Y;
+
+ if (numEdges > 0)
+ {
+ for (int p = 0; p < numPoints; p++)
+ {
+ Point point = points[p];
+ if ((point.getFlags() & touchFlag) != 0)
+ continue;
+ // If this point is a candidate for weak interpolation, we
+ // interpolate it after all strong points have been processed.
+ if ((point.getFlags() & Point.FLAG_WEAK_INTERPOLATION) != 0
+ && (point.getFlags() & Point.FLAG_INFLECTION) == 0)
+ continue;
+
+ int u, ou, fu, delta;
+ if (dim == DIMENSION_VERT)
+ {
+ u = point.getOrigY();
+ ou = point.getScaledY();
+ }
+ else
+ {
+ u = point.getOrigX();
+ ou = point.getScaledX();
+ }
+ fu = u;
+ // Is the point before the first edge?
+ Edge edge = edges[0];
+ // Inversed vertical dimension.
+ delta = edge.fpos - u;
+ if (delta >= 0)
+ {
+ u = edge.pos - (edge.opos - ou);
+ storePoint(point, u, dim, touchFlag);
+ }
+ else
+ {
+ // Is the point after the last edge?
+ edge = edges[numEdges - 1];
+ delta = u - edge.fpos;
+ if (delta >= 0)
+ {
+ u = edge.pos + (ou - edge.opos);
+ storePoint(point, u, dim, touchFlag);
+ }
+ else
+ {
+ // Find enclosing edges.
+ int min = 0;
+ int max = numEdges;
+ int mid, fpos;
+ boolean found = false;
+ while (min < max)
+ {
+ mid = (max + min) / 2;
+ edge = edges[mid];
+ fpos = edge.fpos;
+ if (u < fpos)
+ max = mid;
+ else if (u > fpos)
+ min = mid + 1;
+ else
+ {
+ // Directly on the edge.
+ u = edge.pos;
+ storePoint(point, u, dim, touchFlag);
+ found = true;
+ break;
+ }
+ }
+ if (! found)
+ {
+ Edge before = edges[min - 1];
+ Edge after = edges[min];
+ if (before.scale == 0)
+ {
+ before.scale = Fixed.div16(after.pos - before.pos,
+ after.fpos - before.fpos);
+ }
+ u = before.pos + Fixed.mul16(fu - before.fpos,
+ before.scale);
+ }
+ storePoint(point, u, dim, touchFlag);
+ }
+ }
+ }
+ }
+ }
+
+ private void storePoint(Point p, int u, int dim, short touchFlag)
+ {
+ if (dim == DIMENSION_HORZ)
+ p.setX(u);
+ else
+ p.setY(u);
+ p.addFlags(touchFlag);
+ }
+
+ void alignEdgePoints(int dim)
+ {
+ AxisHints ax = axis[dim];
+ Edge[] edges = ax.edges;
+ int numEdges = ax.numEdges;
+ for (int e = 0; e < numEdges; e++)
+ {
+ Edge edge = edges[e];
+ Segment seg = edge.first;
+ do
+ {
+ Point point = seg.first;
+ while (true)
+ {
+ if (dim == DIMENSION_HORZ)
+ {
+ point.setX(edge.pos);
+ point.addFlags(Point.FLAG_DONE_X);
+ }
+ else
+ {
+ point.setY(edge.pos);
+ point.addFlags(Point.FLAG_DONE_Y);
+ }
+ if (point == seg.last)
+ break;
+ point = point.getNext();
+ }
+ seg = seg.edgeNext;
+ } while (seg != edge.first);
+ }
+ }
+
+ private int getPointIndex(Point p)
+ {
+ int idx = -1;
+ for (int i = 0; i < numPoints; i++)
+ {
+ if (p == points[i])
+ {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ }
+
+ public boolean doAlignEdgePoints()
+ {
+ return (flags & FontDelegate.FLAG_NO_HINT_EDGE_POINTS) == 0;
}
- void computeSegments(int dim)
+ public boolean doAlignStrongPoints()
{
- // TODO: Implement.
+ return (flags & FontDelegate.FLAG_NO_HINT_STRONG_POINTS) == 0;
}
- void linkSegments(int dim)
+ public boolean doAlignWeakPoints()
{
- // TODO: Implement.
+ return (flags & FontDelegate.FLAG_NO_HINT_WEAK_POINTS) == 0;
}
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Scaler.java b/libjava/classpath/gnu/java/awt/font/autofit/HintScaler.java
index 10518512578..01276b4db01 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Scaler.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/HintScaler.java
@@ -40,7 +40,7 @@ package gnu.java.awt.font.autofit;
import gnu.java.awt.font.opentype.OpenTypeFont;
-class Scaler
+class HintScaler
{
int xScale;
@@ -48,5 +48,6 @@ class Scaler
int yScale;
int yDelta;
OpenTypeFont face;
-
+ int renderMode;
+
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Latin.java b/libjava/classpath/gnu/java/awt/font/autofit/Latin.java
index 0352b41a45a..8951e8b19db 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Latin.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Latin.java
@@ -39,8 +39,11 @@ exception statement from your version. */
package gnu.java.awt.font.autofit;
import java.awt.geom.AffineTransform;
+import java.util.HashSet;
import gnu.java.awt.font.opentype.OpenTypeFont;
+import gnu.java.awt.font.opentype.truetype.Fixed;
+import gnu.java.awt.font.opentype.truetype.Point;
import gnu.java.awt.font.opentype.truetype.Zone;
/**
@@ -50,12 +53,476 @@ class Latin
implements Script, Constants
{
- private static final int MAX_WIDTHS = 16;
+ static final int MAX_WIDTHS = 16;
- public void applyHints(GlyphHints hints, ScriptMetrics metrics)
+ private final static int MAX_TEST_CHARS = 12;
+
+ /**
+ * The types of the 6 blue zones.
+ */
+ private static final int CAPITAL_TOP = 0;
+ private static final int CAPITAL_BOTTOM = 1;
+ private static final int SMALL_F_TOP = 2;
+ private static final int SMALL_TOP = 3;
+ private static final int SMALL_BOTTOM = 4;
+ private static final int SMALL_MINOR = 5;
+ static final int BLUE_MAX = 6;
+
+ /**
+ * The test chars for the blue zones.
+ *
+ * @see #initBlues(LatinMetrics, OpenTypeFont)
+ */
+ private static final String[] TEST_CHARS =
+ new String[]{"THEZOCQS", "HEZLOCUS", "fijkdbh",
+ "xzroesc", "xzroesc", "pqgjy"};
+
+ public void applyHints(GlyphHints hints, Zone outline, ScriptMetrics metrics)
+ {
+ hints.reload(outline);
+ hints.rescale(metrics);
+ if (hints.doHorizontal())
+ {
+ detectFeatures(hints, DIMENSION_HORZ);
+ }
+ if (hints.doVertical())
+ {
+ detectFeatures(hints, DIMENSION_VERT);
+ computeBlueEdges(hints, (LatinMetrics) metrics);
+ }
+ // Grid-fit the outline.
+ for (int dim = 0; dim < DIMENSION_MAX; dim++)
+ {
+ if (dim == DIMENSION_HORZ && hints.doHorizontal()
+ || dim == DIMENSION_VERT && hints.doVertical())
+ {
+ hintEdges(hints, dim);
+ if (hints.doAlignEdgePoints())
+ hints.alignEdgePoints(dim);
+ if (hints.doAlignStrongPoints())
+ hints.alignStrongPoints(dim);
+ if (hints.doAlignWeakPoints())
+ hints.alignWeakPoints(dim);
+
+ }
+ }
+ // FreeType does a save call here. I guess that's not needed as we operate
+ // on the live glyph data anyway.
+ }
+
+ private void hintEdges(GlyphHints hints, int dim)
+ {
+ AxisHints axis = hints.axis[dim];
+ Edge[] edges = axis.edges;
+ int numEdges = axis.numEdges;
+ Edge anchor = null;
+ int hasSerifs = 0;
+
+ // We begin by aligning all stems relative to the blue zone if
+ // needed -- that's only for horizontal edges.
+ if (dim == DIMENSION_VERT)
+ {
+ for (int e = 0; e < numEdges; e++)
+ {
+ Edge edge = edges[e];
+ if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0)
+ continue;
+
+ Width blue = edge.blueEdge;
+ Edge edge1 = null;
+ Edge edge2 = edge.link;
+ if (blue != null)
+ {
+ edge1 = edge;
+ }
+ else if (edge2 != null && edge2.blueEdge != null)
+ {
+ blue = edge2.blueEdge;
+ edge1 = edge2;
+ edge2 = edge;
+ }
+ if (edge1 == null)
+ continue;
+
+ edge1.pos = blue.fit;
+ edge1.flags |= Segment.FLAG_EDGE_DONE;
+
+ if (edge2 != null && edge2.blueEdge == null)
+ {
+ alignLinkedEdge(hints, dim, edge1, edge2);
+ edge2.flags |= Segment.FLAG_EDGE_DONE;
+ }
+ if (anchor == null)
+ anchor = edge;
+ }
+ }
+
+ // Now we will align all stem edges, trying to maintain the
+ // relative order of stems in the glyph.
+ for (int e = 0; e < numEdges; e++)
+ {
+ Edge edge = edges[e];
+ if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0)
+ continue;
+ Edge edge2 = edge.link;
+ if (edge2 == null)
+ {
+ hasSerifs++;
+ continue;
+ }
+ // Now align the stem.
+ // This should not happen, but it's better to be safe.
+ if (edge2.blueEdge != null || axis.getEdgeIndex(edge2) < e)
+ {
+ alignLinkedEdge(hints, dim, edge2, edge);
+ edge.flags |= Segment.FLAG_EDGE_DONE;
+ continue;
+ }
+
+ if (anchor == null)
+ {
+ int orgLen = edge2.opos - edge.opos;
+ int curLen = computeStemWidth(hints, dim, orgLen, edge.flags,
+ edge2.flags);
+ int uOff, dOff, orgCenter, curPos1, error1, error2;
+ if (curLen <= 64) // < 1 Pixel.
+ {
+ uOff = 32;
+ dOff = 32;
+ }
+ else
+ {
+ uOff = 38;
+ dOff = 26;
+ }
+ if (curLen < 96)
+ {
+ orgCenter = edge.opos + (orgLen >> 1);
+ curPos1 = Utils.pixRound(orgCenter);
+ error1 = orgCenter - (curPos1 - uOff);
+ if (error1 < 0)
+ error1 = -error1;
+ error2 = orgCenter - (curPos1 + dOff);
+ if (error2 < 0)
+ error2 = -error2;
+ if (error1 < error2)
+ {
+ curPos1 -= uOff;
+ }
+ else
+ {
+ curPos1 += dOff;
+ }
+ edge.pos = curPos1 - curLen / 2;
+ edge2.pos = curPos1 + curLen / 2;
+ }
+ else
+ {
+ edge.pos = Utils.pixRound(edge.opos);
+ }
+ anchor = edge;
+ edge.flags |= Segment.FLAG_EDGE_DONE;
+ alignLinkedEdge(hints, dim, edge, edge2);
+ }
+ else
+ {
+ int aDiff = edge.opos - anchor.opos;
+ int orgPos = anchor.pos + aDiff;
+ int orgLen = edge2.opos - edge.opos;
+ int orgCenter = orgPos + (orgLen >> 1);
+ int curLen = computeStemWidth(hints, dim, orgLen, edge.flags,
+ edge2.flags);
+ //System.err.println("stem width: " + curLen);
+ if (curLen < 96)
+ {
+ int uOff, dOff;
+ int curPos1 = Utils.pixRound(orgCenter);
+ if (curLen <= 64)
+ {
+ uOff = 32;
+ dOff = 32;
+ }
+ else
+ {
+ uOff = 38;
+ dOff = 26;
+ }
+ int delta1 = orgCenter - (curPos1 - uOff);
+ if (delta1 < 0)
+ delta1 = -delta1;
+ int delta2 = orgCenter - (curPos1 + dOff);
+ if (delta2 < 0)
+ delta2 = -delta2;
+ if (delta1 < delta2)
+ {
+ curPos1 -= uOff;
+ }
+ else
+ {
+ curPos1 += dOff;
+ }
+ edge.pos = curPos1 - curLen / 2;
+ edge2.pos = curPos1 + curLen / 2;
+ }
+ else
+ {
+ orgPos = anchor.pos + (edge.opos - anchor.opos);
+ orgLen = edge2.opos - edge.opos;
+ orgCenter = orgPos + (orgLen >> 1);
+ curLen = computeStemWidth(hints, dim, orgLen, edge.flags,
+ edge2.flags);
+ int curPos1 = Utils.pixRound(orgPos);
+ int delta1 = curPos1 + (curLen >> 1) - orgCenter;
+ if (delta1 < 0)
+ delta1 = -delta1;
+ int curPos2 = Utils.pixRound(orgPos + orgLen) - curLen;
+ int delta2 = curPos2 + (curLen >> 1) - orgCenter;
+ if (delta2 < 0)
+ delta2 = -delta2;
+ edge.pos = (delta1 < delta2) ? curPos1 : curPos2;
+ edge2.pos = edge.pos + curLen;
+ }
+ edge.flags |= Segment.FLAG_EDGE_DONE;
+ edge2.flags |= Segment.FLAG_EDGE_DONE;
+
+ if (e > 0 && edge.pos < edges[e - 1].pos)
+ {
+ edge.pos = edges[e - 1].pos;
+ }
+ }
+ }
+ // TODO: Implement the lowercase m symmetry thing.
+
+ // Now we hint the remaining edges (serifs and singles) in order
+ // to complete our processing.
+ if (hasSerifs > 0 || anchor == null)
+ {
+ for (int e = 0; e < numEdges; e++)
+ {
+ Edge edge = edges[e];
+ if ((edge.flags & Segment.FLAG_EDGE_DONE) != 0)
+ continue;
+ if (edge.serif != null)
+ {
+ alignSerifEdge(hints, edge.serif, edge);
+ }
+ else if (anchor == null)
+ {
+ edge.pos = Utils.pixRound(edge.opos);
+ anchor = edge;
+ }
+ else
+ {
+ edge.pos = anchor.pos
+ + Utils.pixRound(edge.opos - anchor.opos);
+ }
+ edge.flags |= Segment.FLAG_EDGE_DONE;
+
+ if (e > 0 && edge.pos < edges[e - 1].pos)
+ {
+ edge.pos = edges[e - 1].pos;
+ }
+ if (e + 1 < numEdges
+ && (edges[e + 1].flags & Segment.FLAG_EDGE_DONE) != 0
+ && edge.pos > edges[e + 1].pos)
+ {
+ edge.pos = edges[e + 1].pos;
+ }
+ }
+ }
+
+ // Debug: print all hinted edges.
+ // System.err.println("hinted edges: " );
+ // for (int i = 0; i < numEdges; i++)
+ // {
+ // System.err.println("edge#" + i + ": " + edges[i]);
+ // }
+ }
+
+ private void alignSerifEdge(GlyphHints hints, Edge base, Edge serif)
+ {
+ serif.pos = base.pos + (serif.opos - base.opos);
+ }
+
+ private int computeStemWidth(GlyphHints hints, int dim, int width,
+ int baseFlags, int stemFlags)
+ {
+ LatinMetrics metrics = (LatinMetrics) hints.metrics;
+ LatinAxis axis = metrics.axis[dim];
+ int dist = width;
+ int sign = 0;
+ boolean vertical = dim == DIMENSION_VERT;
+ if (! doStemAdjust(hints))
+ return width;
+ if (dist < 0)
+ {
+ dist = -width;
+ sign = 1;
+ }
+ if ((vertical && ! doVertSnap(hints)) || ! vertical && ! doHorzSnap(hints))
+ {
+ // Smooth hinting process. Very lightly quantize the stem width.
+ // Leave the widths of serifs alone.
+ if ((stemFlags & Segment.FLAG_EDGE_SERIF) != 0 && vertical
+ && dist < 3 * 64)
+ {
+ return doneWidth(dist, sign);
+ }
+ else if ((baseFlags & Segment.FLAG_EDGE_ROUND) != 0)
+ {
+ if (dist < 80)
+ dist = 64;
+ }
+ else if (dist < 56)
+ {
+ dist = 56;
+ }
+ if (axis.widthCount > 0)
+ {
+ int delta;
+ if (axis.widthCount > 0)
+ {
+ delta = dist - axis.widths[0].cur;
+ if (delta < 0)
+ {
+ delta = -delta;
+ }
+ if (delta < 40)
+ {
+ dist = axis.widths[0].cur;
+ if (dist < 48)
+ dist = 48;
+ return doneWidth(dist, sign);
+ }
+ }
+ if (dist < 3 * 64) // < 3 pixels.
+ {
+ delta = dist & 63;
+ dist &= -64;
+ if (delta < 10)
+ dist += delta;
+ else if (delta < 32)
+ dist += 10;
+ else if (delta < 54)
+ dist += 54;
+ else
+ dist += delta;
+
+ }
+ else
+ {
+ dist = (dist + 32) & ~63;
+ }
+ }
+ }
+ else
+ {
+ // Strong hinting process: Snap the stem width to integer pixels.
+ dist = snapWidth(axis.widths, axis.widthCount, dist);
+ if (vertical)
+ {
+ // In the case of vertical hinting, always round
+ // the stem heights to integer pixels.
+ if (dist >= 64)
+ dist = (dist + 16) & ~63;
+ else
+ dist = 64;
+ }
+ else
+ {
+ if (doMono(hints))
+ {
+ // Monochrome horizontal hinting: Snap widths to integer pixels
+ // with a different threshold.
+ if (dist < 64)
+ dist = 64;
+ else
+ dist = (dist + 32) & ~63;
+ }
+ else
+ {
+ // For anti-aliased hinting, we adopt a more subtle
+ // approach: We strengthen small stems, round those stems
+ // whose size is between 1 and 2 pixels to an integer,
+ // otherwise nothing.
+ if (dist < 48)
+ dist = (dist + 64) >> 1;
+ else if (dist < 128)
+ dist = (dist + 22) & ~63;
+ else
+ // Round otherwise to prevent color fringes in LCD mode.
+ dist = (dist + 32) & ~63;
+ }
+ }
+ }
+ return doneWidth(dist, sign);
+ }
+
+ private boolean doMono(GlyphHints hints)
+ {
+ return true;
+ }
+
+ private int snapWidth(Width[] widths, int count, int width)
+ {
+ int best = 64 + 32 + 2;
+ int reference = width;
+ for (int n = 0; n < count; n++)
+ {
+ int w = widths[n].cur;
+ int dist = width - w;
+ if (dist < 0)
+ dist = -dist;
+ if (dist < best)
+ {
+ best = dist;
+ reference = w;
+ }
+ }
+ int scaled = Utils.pixRound(reference);
+ if (width >= reference)
+ {
+ if (width < scaled + 48)
+ width = reference;
+ }
+ else
+ {
+ if (width > scaled + 48)
+ width = reference;
+ }
+ return width;
+ }
+
+ private int doneWidth(int w, int s)
+ {
+ if (s == 1)
+ w = -w;
+ return w;
+ }
+
+ private boolean doVertSnap(GlyphHints hints)
+ {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ private boolean doHorzSnap(GlyphHints hints)
{
// TODO Auto-generated method stub
+ return true;
+ }
+ private boolean doStemAdjust(GlyphHints hints)
+ {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ private void alignLinkedEdge(GlyphHints hints, int dim, Edge base, Edge stem)
+ {
+ int dist = stem.opos - base.opos;
+ int fitted = computeStemWidth(hints, dim, dist, base.flags, stem.flags);
+ stem.pos = base.pos + fitted;
}
public void doneMetrics(ScriptMetrics metrics)
@@ -99,10 +566,119 @@ class Latin
initBlues(lm, face);
}
- public void scaleMetrics(ScriptMetrics metrics)
+ public void scaleMetrics(ScriptMetrics metrics, HintScaler scaler)
{
- // TODO Auto-generated method stub
+ LatinMetrics lm = (LatinMetrics) metrics;
+ lm.scaler.renderMode = scaler.renderMode;
+ lm.scaler.face = scaler.face;
+ scaleMetricsDim(lm, scaler, DIMENSION_HORZ);
+ scaleMetricsDim(lm, scaler, DIMENSION_VERT);
+ }
+ private void scaleMetricsDim(LatinMetrics lm, HintScaler scaler, int dim)
+ {
+ int scale;
+ int delta;
+ if (dim == DIMENSION_HORZ)
+ {
+ scale = scaler.xScale;
+ delta = scaler.xDelta;
+ }
+ else
+ {
+ scale = scaler.yScale;
+ delta = scaler.yDelta;
+ }
+ LatinAxis axis = lm.axis[dim];
+ if (axis.orgScale == scale && axis.orgDelta == delta)
+ // No change, no need to adjust.
+ return;
+ axis.orgScale = scale;
+ axis.orgDelta = delta;
+
+ // Correct X and Y scale to optimize the alignment of the top small
+ // letters to the pixel grid.
+ LatinAxis axis2 = lm.axis[DIMENSION_VERT];
+ LatinBlue blue = null;
+// for (int nn = 0; nn < axis2.blueCount; nn++)
+// {
+// if ((axis2.blues[nn].flags & LatinBlue.FLAG_ADJUSTMENT) != 0)
+// {
+// blue = axis2.blues[nn];
+// break;
+// }
+// }
+// if (blue != null)
+// {
+// int scaled = Fixed.mul16(blue.shoot.org, scaler.yScale);
+// int fitted = Utils.pixRound(scaled);
+// if (scaled != fitted)
+// {
+// if (dim == DIMENSION_HORZ)
+// {
+// if (fitted < scaled)
+// {
+// scale -= scale / 50;
+// }
+// }
+// else
+// {
+// scale = Utils.mulDiv(scale, fitted, scaled);
+// }
+// }
+// }
+ axis.scale = scale;
+ axis.delta = delta;
+ if (dim == DIMENSION_HORZ)
+ {
+ lm.scaler.xScale = scale;
+ lm.scaler.xDelta = delta;
+ }
+ else
+ {
+ lm.scaler.yScale = scale;
+ lm.scaler.yDelta = delta;
+ }
+ // Scale the standard widths.
+ for (int nn = 0; nn < axis.widthCount; nn++)
+ {
+ Width w = axis.widths[nn];
+ w.cur = Fixed.mul16(w.org, scale);
+ w.fit = w.cur;
+ }
+ // Scale blue zones.
+ if (dim == DIMENSION_VERT)
+ {
+ for (int nn = 0; nn < axis.blueCount; nn++)
+ {
+ blue = axis.blues[nn];
+ blue.ref.cur = Fixed.mul16(blue.ref.org, scale) + delta;
+ blue.ref.fit = blue.ref.cur;
+ blue.shoot.cur = Fixed.mul16(blue.ref.org, scale) + delta;
+ blue.flags &= ~LatinBlue.FLAG_BLUE_ACTIVE;
+ // A blue zone is only active if it is less than 3/4 pixels tall.
+ int dist = Fixed.mul16(blue.ref.org - blue.shoot.org, scale);
+ if (dist <= 48 && dist >= -48)
+ {
+ int delta1 = blue.shoot.org - blue.ref.org;
+ int delta2 = delta1;
+ if (delta1 < 0)
+ delta2 = -delta2;
+ delta2 = Fixed.mul16(delta2, scale);
+ if (delta2 < 32)
+ delta2 = 0;
+ else if (delta2 < 64)
+ delta2 = 32 + (((delta2 - 32) + 16) & ~31);
+ else
+ delta2 = Utils.pixRound(delta2);
+ if (delta1 < 0)
+ delta2 = -delta2;
+ blue.ref.fit = Utils.pixRound(blue.ref.cur);
+ blue.shoot.fit = blue.ref.fit + delta2;
+ blue.flags |= LatinBlue.FLAG_BLUE_ACTIVE;
+ }
+ }
+ }
}
/**
@@ -118,12 +694,9 @@ class Latin
metrics.axis[DIMENSION_HORZ].widthCount = 0;
metrics.axis[DIMENSION_VERT].widthCount = 0;
int glyphIndex = face.getGlyph(ch);
- // TODO: Avoid that AffineTransform constructor and change
- // getRawGlyphOutline() to accept null or remove that parameter altogether.
- // Consider this when the thing is done and we know what we need that for.
- Zone outline = face.getRawGlyphOutline(glyphIndex, new AffineTransform());
+ Zone outline = face.getRawGlyphOutline(glyphIndex, IDENTITY);
LatinMetrics dummy = new LatinMetrics();
- Scaler scaler = dummy.scaler;
+ HintScaler scaler = dummy.scaler;
dummy.unitsPerEm = metrics.unitsPerEm;
scaler.xScale = scaler.yScale = 10000;
scaler.xDelta = scaler.yDelta = 0;
@@ -135,20 +708,24 @@ class Latin
LatinAxis axis = metrics.axis[dim];
AxisHints axHints = hints.axis[dim];
int numWidths = 0;
- hints.computeSegments(dim);
- hints.linkSegments(dim);
+ computeSegments(hints, dim);
+ linkSegments(hints, dim);
Segment[] segs = axHints.segments;
+ HashSet<Segment> touched = new HashSet<Segment>();
for (int i = 0; i < segs.length; i++)
{
Segment seg = segs[i];
Segment link = seg.link;
- if (link != null && link.link == seg && link.index > i)
+ if (link != null && link.link == seg && ! touched.contains(link))
{
int dist = Math.abs(seg.pos - link.pos);
if (numWidths < MAX_WIDTHS)
- axis.widths[numWidths++].org = dist;
+ axis.widths[numWidths++] = new Width(dist);
}
+ touched.add(seg);
}
+ Utils.sort(numWidths, axis.widths);
+ axis.widthCount = numWidths;
}
for (int dim = 0; dim < DIMENSION_MAX; dim++)
{
@@ -159,6 +736,78 @@ class Latin
}
}
+ void linkSegments(GlyphHints hints, int dim)
+ {
+ AxisHints axis = hints.axis[dim];
+ Segment[] segments = axis.segments;
+ int numSegs = axis.numSegments;
+ int majorDir = axis.majorDir;
+ int lenThreshold = constant((LatinMetrics) hints.metrics, 8);
+ lenThreshold = Math.min(1, lenThreshold);
+ int lenScore = constant((LatinMetrics) hints.metrics, 3000);
+ for (int i1 = 0; i1 < numSegs; i1++)
+ {
+ Segment seg1 = segments[i1];
+ // The fake segments are introduced to hint the metrics.
+ // Never link them to anything.
+ if (seg1.first == seg1.last || seg1.dir != majorDir)
+ continue;
+ for (int i2 = 0; i2 < numSegs; i2++)
+ {
+ Segment seg2 = segments[i2];
+ if (seg2 != seg1 && seg1.dir + seg2.dir == 0)
+ {
+ int pos1 = seg1.pos;
+ int pos2 = seg2.pos;
+ // The vertical coords are swapped compared to how FT handles
+ // this.
+ int dist = dim == DIMENSION_VERT ? pos1 - pos2 : pos2 - pos1;
+ if (dist >= 0)
+ {
+ int min = seg1.minPos;
+ int max = seg1.maxPos;
+ int len, score;
+ if (min < seg2.minPos)
+ min = seg2.minPos;
+ if (max > seg2.maxPos)
+ max = seg2.maxPos;
+ len = max - min;
+ if (len > lenThreshold)
+ {
+ score = dist + lenScore / len;
+ if (score < seg1.score)
+ {
+ seg1.score = score;
+ seg1.link = seg2;
+ }
+ if (score < seg2.score)
+ {
+ seg2.score = score;
+ seg2.link = seg1;
+ }
+ }
+ }
+ }
+ }
+ }
+ for (int i1 = 0; i1 < numSegs; i1++)
+ {
+ Segment seg1 = segments[i1];
+ Segment seg2 = seg1.link;
+ if (seg2 != null)
+ {
+ seg2.numLinked++;
+ if (seg2.link != seg1)
+ {
+ seg1.link = null;
+ seg1.serif = seg2.link;
+ }
+ }
+ // Uncomment to show all segments.
+ // System.err.println("segment#" + i1 + ": " + seg1);
+ }
+ }
+
/**
* Initializes the blue zones of the font.
*
@@ -167,11 +816,548 @@ class Latin
*/
private void initBlues(LatinMetrics metrics, OpenTypeFont face)
{
- // TODO: Implement.
+ int[] flats = new int[MAX_TEST_CHARS];
+ int[] rounds = new int[MAX_TEST_CHARS];
+ int numFlats;
+ int numRounds;
+ LatinBlue blue;
+ LatinAxis axis = metrics.axis[DIMENSION_VERT];
+ // We compute the blues simply by loading each character in the test
+ // strings, then compute its topmost or bottommost points.
+ for (int bb = 0; bb < BLUE_MAX; bb++)
+ {
+ String p = TEST_CHARS[bb];
+ int blueRef;
+ int blueShoot;
+ numFlats = 0;
+ numRounds = 0;
+ for (int i = 0; i < p.length(); i++)
+ {
+ // Load the character.
+ int glyphIndex = face.getGlyph(p.charAt(i));
+ Zone glyph =
+ face.getRawGlyphOutline(glyphIndex, IDENTITY);
+
+ // Now compute the min and max points.
+ int numPoints = glyph.getSize() - 4; // 4 phantom points.
+ Point[] points = glyph.getPoints();
+ Point point = points[0];
+ int extremum = 0;
+ int index = 1;
+ if (isTopBlue(bb))
+ {
+ for (; index < numPoints; index++)
+ {
+ point = points[index];
+ // We have the vertical direction swapped. The higher
+ // points have smaller (negative) Y.
+ if (point.getOrigY() < points[extremum].getOrigY())
+ extremum = index;
+ }
+ }
+ else
+ {
+ for (; index < numPoints; index++)
+ {
+ point = points[index];
+ // We have the vertical direction swapped. The higher
+ // points have smaller (negative) Y.
+ if (point.getOrigY() > points[extremum].getOrigY())
+ extremum = index;
+ }
+ }
+ // Debug, prints out the maxima.
+ // System.err.println("extremum for " + bb + " / "+ p.charAt(i)
+ // + ": " + points[extremum]);
+
+ // Now determine if the point is part of a straight or round
+ // segment.
+ boolean round;
+ int idx = extremum;
+ int first, last, prev, next, end;
+ int dist;
+ last = -1;
+ first = 0;
+ for (int n = 0; n < glyph.getNumContours(); n++)
+ {
+ end = glyph.getContourEnd(n);
+ // System.err.println("contour end for " + n + ": " + end);
+ if (end >= idx)
+ {
+ last = end;
+ break;
+ }
+ first = end + 1;
+ }
+ // Should never happen.
+ assert last >= 0;
+
+ // Now look for the previous and next points that are not on the
+ // same Y coordinate. Threshold the 'closeness'.
+ prev = idx;
+ next = prev;
+ do
+ {
+ if (prev > first)
+ prev--;
+ else
+ prev = last;
+ dist = points[prev].getOrigY() - points[extremum].getOrigY();
+ if (dist < -5 || dist > 5)
+ break;
+ } while (prev != idx);
+ do
+ {
+ if (next < last)
+ next++;
+ else
+ next = first;
+ dist = points[next].getOrigY() - points[extremum].getOrigY();
+ if (dist < -5 || dist > 5)
+ break;
+ } while (next != idx);
+ round = points[prev].isControlPoint()
+ || points[next].isControlPoint();
+
+ if (round)
+ {
+ rounds[numRounds++] = points[extremum].getOrigY();
+ // System.err.println("new round extremum: " + bb + ": "
+ // + points[extremum].getOrigY());
+ }
+ else
+ {
+ flats[numFlats++] = points[extremum].getOrigY();
+ // System.err.println("new flat extremum: " + bb + ": "
+ // + points[extremum].getOrigY());
+ }
+ }
+ // We have computed the contents of the rounds and flats tables.
+ // Now determine the reference and overshoot position of the blues --
+ // we simply take the median after a simple sort.
+ Utils.sort(numRounds, rounds);
+ Utils.sort(numFlats, flats);
+ blue = axis.blues[axis.blueCount] = new LatinBlue();
+ axis.blueCount++;
+ if (numFlats == 0)
+ {
+ blue.ref = blue.shoot = new Width(rounds[numRounds / 2]);
+ }
+ else if (numRounds == 0)
+ {
+ blue.ref = blue.shoot = new Width(flats[numFlats / 2]);
+ }
+ else
+ {
+ blue.ref = new Width(flats[numFlats / 2]);
+ blue.shoot = new Width(rounds[numRounds / 2]);
+ }
+ // There are sometimes problems: if the overshoot position of top
+ // zones is under its reference position, or the opposite for bottom
+ // zones. We must check everything there and correct problems.
+ if (blue.shoot != blue.ref)
+ {
+ int ref = blue.ref.org;
+ int shoot = blue.shoot.org;
+ // Inversed vertical coordinates!
+ boolean overRef = shoot < ref;
+ if (isTopBlue(bb) ^ overRef)
+ {
+ blue.shoot = blue.ref = new Width((shoot + ref) / 2);
+ }
+ }
+ blue.flags = 0;
+ if (isTopBlue(bb))
+ blue.flags |= LatinBlue.FLAG_TOP;
+ // The following flag is used later to adjust y and x scales in
+ // order to optimize the pixel grid alignment of the top small
+ // letters.
+ if (bb == SMALL_TOP)
+ {
+ blue.flags |= LatinBlue.FLAG_ADJUSTMENT;
+ }
+ // Debug: print out the blue zones.
+ // System.err.println("blue zone #" + bb + ": " + blue);
+ }
}
+ private static final AffineTransform IDENTITY = new AffineTransform();
+
private int constant(LatinMetrics metrics, int c)
{
return c * (metrics.unitsPerEm / 2048);
}
+
+ private void computeSegments(GlyphHints hints, int dim)
+ {
+ Point[] points = hints.points;
+ if (dim == DIMENSION_HORZ)
+ {
+ for (int i = 0; i < hints.numPoints; i++)
+ {
+ points[i].setU(points[i].getOrigX());
+ points[i].setV(points[i].getOrigY());
+ }
+ }
+ else
+ {
+ for (int i = 0; i < hints.numPoints; i++)
+ {
+ points[i].setU(points[i].getOrigY());
+ points[i].setV(points[i].getOrigX());
+ }
+ }
+ // Now look at each contour.
+ AxisHints axis = hints.axis[dim];
+ int majorDir = Math.abs(axis.majorDir);
+ int segmentDir = majorDir;
+ Point[] contours = hints.contours;
+ int numContours = hints.numContours;
+ Segment segment = null;
+ for (int i = 0; i < numContours; i++)
+ {
+ int minPos = 32000;
+ int maxPos = -32000;
+
+ Point point = contours[i];
+ Point last = point.getPrev();
+ if (point == last) // Skip singletons.
+ continue;
+ if (Math.abs(last.getOutDir()) == majorDir
+ && Math.abs(point.getOutDir()) == majorDir)
+ {
+ // We are already on an edge. Locate its start.
+ last = point;
+ while (true)
+ {
+ point = point.getPrev();
+ if (Math.abs(point.getOutDir()) != majorDir)
+ {
+ point = point.getNext();
+ break;
+ }
+ if (point == last)
+ break;
+ }
+ }
+ last = point;
+ boolean passed = false;
+ boolean onEdge = false;
+ while (true)
+ {
+ int u, v;
+ if (onEdge)
+ {
+ u = point.getU();
+ if (u < minPos)
+ minPos = u;
+ if (u > maxPos)
+ maxPos = u;
+ if (point.getOutDir() != segmentDir || point == last)
+ {
+ // Leaving an edge. Record new segment.
+ segment.last = point;
+ // (minPos + maxPos) / 2.
+ segment.pos = (minPos + maxPos) >> 1;
+ if (segment.first.isControlPoint()
+ || point.isControlPoint())
+ segment.flags |= Segment.FLAG_EDGE_ROUND;
+ minPos = maxPos = point.getV();
+ v = segment.first.getV();
+ if (v < minPos)
+ minPos = v;
+ if (v > maxPos)
+ maxPos = v;
+ segment.minPos = minPos;
+ segment.maxPos = maxPos;
+ onEdge = false;
+ segment = null;
+ }
+ }
+ if (point == last)
+ {
+ if (passed)
+ break;
+ passed = true;
+ }
+ if (! onEdge && Math.abs(point.getOutDir()) == majorDir)
+ {
+ // This is the start of a new segment.
+ segmentDir = point.getOutDir();
+ segment = axis.newSegment();
+ segment.dir = segmentDir;
+ segment.flags = Segment.FLAG_EDGE_NORMAL;
+ minPos = maxPos = point.getU();
+ segment.first = point;
+ segment.last = point;
+ segment.contour = contours[i];
+ segment.score = 32000;
+ segment.len = 0;
+ segment.link = null;
+ onEdge = true;
+ }
+ point = point.getNext();
+ }
+ }
+
+ }
+
+ private boolean isTopBlue(int b)
+ {
+ return b == CAPITAL_TOP || b == SMALL_F_TOP || b == SMALL_TOP;
+ }
+
+ private void detectFeatures(GlyphHints hints, int dim)
+ {
+ computeSegments(hints, dim);
+ linkSegments(hints, dim);
+ computeEdges(hints, dim);
+ }
+
+ private void computeEdges(GlyphHints hints, int dim)
+ {
+ AxisHints axis = hints.axis[dim];
+ LatinAxis laxis = ((LatinMetrics) hints.metrics).axis[dim];
+ Segment[] segments = axis.segments;
+ int numSegments = axis.numSegments;
+ Segment seg;
+ int upDir;
+ int scale;
+ int edgeDistanceThreshold;
+ axis.numEdges = 0;
+ scale = dim == DIMENSION_HORZ ? hints.xScale : hints.yScale;
+ upDir = dim == DIMENSION_HORZ ? DIR_UP : DIR_RIGHT;
+
+ // We will begin by generating a sorted table of edges for the
+ // current direction. To do so, we simply scan each segment and try
+ // to find an edge in our table that corresponds to its position.
+ //
+ // If no edge is found, we create one and insert a new edge in the
+ // sorted table. Otherwise, we simply add the segment to the egde's
+ // list which will be processed in the second step to compute the
+ // edge's properties.
+ //
+ // Note that the edge table is sorted along the segment/edge
+ // position.
+
+ edgeDistanceThreshold = Fixed.mul16(laxis.edgeDistanceTreshold, scale);
+ if (edgeDistanceThreshold > 64 / 4)
+ edgeDistanceThreshold = 64 / 4;
+ edgeDistanceThreshold = Fixed.div16(edgeDistanceThreshold, scale);
+ for (int i = 0; i < numSegments; i++)
+ {
+ seg = segments[i];
+ Edge found = null;
+ for (int ee = 0; ee < axis.numEdges; ee++)
+ {
+ Edge edge = axis.edges[ee];
+ int dist = seg.pos - edge.fpos;
+ if (dist < 0)
+ dist = -dist;
+ if (dist < edgeDistanceThreshold)
+ {
+ found = edge;
+ break;
+ }
+ }
+ if (found == null)
+ {
+ // Insert new edge in the list and sort according to
+ // the position.
+ Edge edge = axis.newEdge(seg.pos);
+ edge.first = seg;
+ edge.last = seg;
+ edge.fpos = seg.pos;
+ edge.opos = edge.pos = Fixed.mul16(seg.pos, scale);
+ seg.edgeNext = seg;
+ seg.edge = edge;
+ }
+ else
+ {
+ seg.edgeNext = found.first;
+ found.last.edgeNext = seg;
+ found.last = seg;
+ seg.edge = found;
+ }
+ }
+ // Good. We will now compute each edge's properties according to
+ // segments found on its position. Basically these are:
+ // - Edge's main direction.
+ // - Stem edge, serif edge, or both (which defaults to stem edge).
+ // - Rounded edge, straight or both (which defaults to straight).
+ // - Link for edge.
+
+ // Now, compute each edge properties.
+ for (int e = 0; e < axis.numEdges; e++)
+ {
+ Edge edge = axis.edges[e];
+ // Does it contain round segments?
+ int isRound = 0;
+ // Does it contain straight segments?
+ int isStraight = 0;
+ // Number of upward segments.
+ int ups = 0;
+ // Number of downward segments.
+ int downs = 0;
+
+ seg = edge.first;
+ do
+ {
+ // Check for roundness of segment.
+ if ((seg.flags & Segment.FLAG_EDGE_ROUND) != 0)
+ isRound++;
+ else
+ isStraight++;
+
+ // Check for segment direction.
+ if (seg.dir == upDir)
+ ups += seg.maxPos - seg.minPos;
+ else
+ downs += seg.maxPos - seg.minPos;
+
+ // Check for links. If seg.serif is set, then seg.link must
+ // be ignored.
+ boolean isSerif = seg.serif != null && seg.serif.edge != edge;
+ if (seg.link != null || isSerif)
+ {
+ Edge edge2 = edge.link;
+ Segment seg2 = seg.link;
+ if (isSerif)
+ {
+ seg2 = seg.serif;
+ edge2 = edge.serif;
+ }
+ if (edge2 != null)
+ {
+ int edgeDelta = edge.fpos - edge2.fpos;
+ if (edgeDelta < 0)
+ edgeDelta = -edgeDelta;
+ int segDelta = seg.pos - seg2.pos;
+ if (segDelta < 0)
+ segDelta = -segDelta;
+ if (segDelta < edgeDelta)
+ edge2 = seg2.edge;
+ }
+ else
+ {
+ edge2 = seg2.edge;
+ }
+ if (isSerif)
+ {
+ edge.serif = edge2;
+ edge2.flags |= Segment.FLAG_EDGE_SERIF;
+ }
+ else
+ {
+ edge.link = edge2;
+ }
+ }
+ seg = seg.edgeNext;
+ } while (seg != edge.first);
+ edge.flags = Segment.FLAG_EDGE_NORMAL;
+ if (isRound > 0 && isRound > isStraight)
+ edge.flags |= Segment.FLAG_EDGE_ROUND;
+
+ // Set the edge's main direction.
+ edge.dir = DIR_NONE;
+ if (ups > downs)
+ edge.dir = upDir;
+ else if (ups < downs)
+ edge.dir = -upDir;
+ else if (ups == downs)
+ edge.dir = 0;
+
+ // Gets rid of serif if link is set. This gets rid of many
+ // unpleasant artifacts.
+ if (edge.serif != null && edge.link != null)
+ {
+ edge.serif = null;
+ }
+
+ // Debug: Print out all edges.
+ // System.err.println("edge# " + e + ": " + edge);
+ }
+ }
+
+ private void computeBlueEdges(GlyphHints hints, LatinMetrics metrics)
+ {
+ AxisHints axis = hints.axis[DIMENSION_VERT];
+ Edge[] edges = axis.edges;
+ int numEdges = axis.numEdges;
+ LatinAxis latin = metrics.axis[DIMENSION_VERT];
+ int scale = latin.scale;
+
+ // Compute which blue zones are active. I.e. have their scaled
+ // size < 3/4 pixels.
+
+ // For each horizontal edge search the blue zone that is closest.
+ for (int e = 0; e < numEdges; e++)
+ {
+ Edge edge = edges[e];
+ // System.err.println("checking edge: " + edge);
+ Width bestBlue = null;
+ int bestDist = Fixed.mul16(metrics.unitsPerEm / 40, scale);
+
+ if (bestDist > 64 / 2)
+ bestDist = 64 / 2;
+ for (int bb = 0; bb < BLUE_MAX; bb++)
+ {
+ LatinBlue blue = latin.blues[bb];
+ // System.err.println("checking blue: " + blue);
+ // Skip inactive blue zones, i.e. those that are too small.
+ if ((blue.flags & LatinBlue.FLAG_BLUE_ACTIVE) == 0)
+ continue;
+ // If it is a top zone, check for right edges. If it is a bottom
+ // zone, check for left edges.
+ boolean isTopBlue = (blue.flags & LatinBlue.FLAG_TOP) != 0;
+ boolean isMajorDir = edge.dir == axis.majorDir;
+
+ // If it is a top zone, the edge must be against the major
+ // direction. If it is a bottom zone it must be in the major
+ // direction.
+ if (isTopBlue ^ isMajorDir)
+ {
+ int dist = edge.fpos - blue.ref.org;
+ if (dist < 0)
+ dist = -dist;
+ dist = Fixed.mul16(dist, scale);
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ bestBlue = blue.ref;
+ }
+
+ // Now, compare it to the overshoot position if the edge is
+ // rounded, and if the edge is over the reference position of
+ // a top zone, or under the reference position of a bottom
+ // zone.
+ if ((edge.flags & Segment.FLAG_EDGE_ROUND) != 0 && dist != 0)
+ {
+ // Inversed vertical coordinates!
+ boolean isUnderRef = edge.fpos > blue.ref.org;
+ if (isTopBlue ^ isUnderRef)
+ {
+ blue = latin.blues[bb]; // Needed?
+ dist = edge.fpos - blue.shoot.org;
+ if (dist < 0)
+ dist = -dist;
+ dist = Fixed.mul16(dist, scale);
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ bestBlue = blue.shoot;
+ }
+ }
+ }
+
+ }
+ }
+ if (bestBlue != null)
+ {
+ edge.blueEdge = bestBlue;
+ // Debug: Print out the blue edges.
+ // System.err.println("blue edge for: " + edge + ": " + bestBlue);
+ }
+ }
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/LatinAxis.java b/libjava/classpath/gnu/java/awt/font/autofit/LatinAxis.java
index 8ca1e6d9ed2..9237d0ee5b1 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/LatinAxis.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/LatinAxis.java
@@ -49,5 +49,14 @@ class LatinAxis
int widthCount;
Width[] widths;
- float edgeDistanceTreshold;
+ int edgeDistanceTreshold;
+ LatinBlue[] blues;
+ int blueCount;
+ int orgDelta;
+ int orgScale;
+ LatinAxis()
+ {
+ widths = new Width[Latin.MAX_WIDTHS];
+ blues = new LatinBlue[Latin.BLUE_MAX];
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/LatinBlue.java b/libjava/classpath/gnu/java/awt/font/autofit/LatinBlue.java
new file mode 100644
index 00000000000..694fb24fe07
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/autofit/LatinBlue.java
@@ -0,0 +1,59 @@
+/* LatinBlue.java -- FIXME: briefly describe file purpose
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.autofit;
+
+public class LatinBlue
+{
+ static final int FLAG_BLUE_ACTIVE = 1 << 0;
+ static final int FLAG_TOP = 1 << 1;
+ static final int FLAG_ADJUSTMENT = 1 << 2;
+ Width ref;
+ Width shoot;
+ int flags;
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[BlueZone]");
+ s.append(" ref: ");
+ s.append(ref.org);
+ s.append(", shoot: ");
+ s.append(shoot.org);
+ return s.toString();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/LatinMetrics.java b/libjava/classpath/gnu/java/awt/font/autofit/LatinMetrics.java
index cd955348b37..33fc63ad4ba 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/LatinMetrics.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/LatinMetrics.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package gnu.java.awt.font.autofit;
+import gnu.java.awt.font.opentype.OpenTypeFont;
+
/**
* Latin specific metrics data.
*/
@@ -48,4 +50,17 @@ class LatinMetrics
LatinAxis[] axis;
int unitsPerEm;
+
+ LatinMetrics()
+ {
+ super();
+ axis = new LatinAxis[Constants.DIMENSION_MAX];
+ axis[Constants.DIMENSION_HORZ] = new LatinAxis();
+ axis[Constants.DIMENSION_VERT] = new LatinAxis();
+ }
+ LatinMetrics(OpenTypeFont face)
+ {
+ this();
+ unitsPerEm = face.unitsPerEm;
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Script.java b/libjava/classpath/gnu/java/awt/font/autofit/Script.java
index 3b353010f2d..c223f0a26af 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Script.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Script.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package gnu.java.awt.font.autofit;
import gnu.java.awt.font.opentype.OpenTypeFont;
+import gnu.java.awt.font.opentype.truetype.Zone;
/**
* Defines script specific methods for the auto fitter.
@@ -51,12 +52,11 @@ interface Script
*/
void initMetrics(ScriptMetrics metrics, OpenTypeFont face);
- void scaleMetrics(ScriptMetrics metrics/* , scaler, map this */);
+ void scaleMetrics(ScriptMetrics metrics , HintScaler scaler);
void doneMetrics(ScriptMetrics metrics);
void initHints(GlyphHints hints, ScriptMetrics metrics);
- void applyHints(GlyphHints hints, /* some outline object, */
- ScriptMetrics metrics);
+ void applyHints(GlyphHints hints, Zone outline, ScriptMetrics metrics);
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/ScriptMetrics.java b/libjava/classpath/gnu/java/awt/font/autofit/ScriptMetrics.java
index 77c815ae59d..984a06daee4 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/ScriptMetrics.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/ScriptMetrics.java
@@ -45,5 +45,9 @@ class ScriptMetrics
{
Script script;
- Scaler scaler;
+ HintScaler scaler;
+ ScriptMetrics()
+ {
+ scaler = new HintScaler();
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Segment.java b/libjava/classpath/gnu/java/awt/font/autofit/Segment.java
index 32032a48fcc..640e82ce2e9 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Segment.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Segment.java
@@ -38,10 +38,58 @@ exception statement from your version. */
package gnu.java.awt.font.autofit;
+import gnu.java.awt.font.opentype.truetype.Point;
+
class Segment
{
+ static final int FLAG_EDGE_NORMAL = 0;
+ static final int FLAG_EDGE_ROUND = 1;
+ static final int FLAG_EDGE_SERIF = 2;
+ static final int FLAG_EDGE_DONE = 4;
+ int dir;
+ int flags;
Segment link;
- int index;
+ Segment serif;
+ int numLinked;
int pos;
+ Point first;
+ Point last;
+ Point contour;
+ int minPos;
+ int maxPos;
+ int score;
+ int len;
+ Segment edgeNext;
+ Edge edge;
+
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[Segment] id: ");
+ s.append(hashCode());
+ s.append(", len:");
+ s.append(len);
+ s.append(", round: ");
+ s.append(((flags & FLAG_EDGE_ROUND) != 0));
+ s.append(", dir: ");
+ s.append(dir);
+ s.append(", pos: ");
+ s.append(pos);
+ s.append(", minPos: ");
+ s.append(minPos);
+ s.append(", maxPos: ");
+ s.append(maxPos);
+ s.append(", first: ");
+ s.append(first);
+ s.append(", last: ");
+ s.append(last);
+ s.append(", contour: ");
+ s.append(contour);
+ s.append(", link: ");
+ s.append(link == null ? "null" : link.hashCode());
+ s.append(", serif: ");
+ s.append(serif == null ? "null" : serif.hashCode());
+ return s.toString();
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Utils.java b/libjava/classpath/gnu/java/awt/font/autofit/Utils.java
new file mode 100644
index 00000000000..4df4705a8d1
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Utils.java
@@ -0,0 +1,255 @@
+/* Utils.java -- A collection of utility functions for the autofitter
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.autofit;
+
+import gnu.java.awt.font.opentype.truetype.Fixed;
+
+/**
+ * A collection of utility methods used all around the auto fitter.
+ */
+class Utils
+ implements Constants
+{
+
+ private static final int ATAN_BITS = 8;
+ private static final byte[] ATAN = new byte[]
+ {
+ 0, 0, 1, 1, 1, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 5,
+ 5, 5, 6, 6, 6, 7, 7, 7,
+ 8, 8, 8, 9, 9, 9, 10, 10,
+ 10, 10, 11, 11, 11, 12, 12, 12,
+ 13, 13, 13, 14, 14, 14, 14, 15,
+ 15, 15, 16, 16, 16, 17, 17, 17,
+ 18, 18, 18, 18, 19, 19, 19, 20,
+ 20, 20, 21, 21, 21, 21, 22, 22,
+ 22, 23, 23, 23, 24, 24, 24, 24,
+ 25, 25, 25, 26, 26, 26, 26, 27,
+ 27, 27, 28, 28, 28, 28, 29, 29,
+ 29, 30, 30, 30, 30, 31, 31, 31,
+ 31, 32, 32, 32, 33, 33, 33, 33,
+ 34, 34, 34, 34, 35, 35, 35, 35,
+ 36, 36, 36, 36, 37, 37, 37, 38,
+ 38, 38, 38, 39, 39, 39, 39, 40,
+ 40, 40, 40, 41, 41, 41, 41, 42,
+ 42, 42, 42, 42, 43, 43, 43, 43,
+ 44, 44, 44, 44, 45, 45, 45, 45,
+ 46, 46, 46, 46, 46, 47, 47, 47,
+ 47, 48, 48, 48, 48, 48, 49, 49,
+ 49, 49, 50, 50, 50, 50, 50, 51,
+ 51, 51, 51, 51, 52, 52, 52, 52,
+ 52, 53, 53, 53, 53, 53, 54, 54,
+ 54, 54, 54, 55, 55, 55, 55, 55,
+ 56, 56, 56, 56, 56, 57, 57, 57,
+ 57, 57, 57, 58, 58, 58, 58, 58,
+ 59, 59, 59, 59, 59, 59, 60, 60,
+ 60, 60, 60, 61, 61, 61, 61, 61,
+ 61, 62, 62, 62, 62, 62, 62, 63,
+ 63, 63, 63, 63, 63, 64, 64, 64
+ };
+
+ private static final int ANGLE_PI = 256;
+ private static final int ANGLE_PI2 = ANGLE_PI / 2;
+ private static final int ANGLE_PI4 = ANGLE_PI / 4;
+ private static final int ANGLE_2PI = ANGLE_PI * 2;
+
+ /**
+ * Computes the direction constant for the specified vector. The vector is
+ * given as differential value already.
+ *
+ * @param dx the x vector
+ * @param dy the y vector
+ *
+ * @return the direction of that vector, or DIR_NONE, if that vector is not
+ * approximating against one of the major axises
+ */
+ static int computeDirection(int dx, int dy)
+ {
+ int dir = DIR_NONE;
+ if (dx < 0)
+ {
+ if (dy < 0)
+ {
+ if (-dx * 12 < -dy)
+ dir = DIR_UP;
+ else if (-dy * 12 < -dx)
+ dir = DIR_LEFT;
+ }
+ else // dy >= 0 .
+ {
+ if (-dx * 12 < dy)
+ dir = DIR_DOWN;
+ else if (dy * 12 < -dx)
+ dir = DIR_LEFT;
+ }
+ }
+ else // dx >= 0 .
+ {
+ if (dy < 0)
+ {
+ if (dx * 12 < -dy)
+ dir = DIR_UP;
+ else if (-dy * 12 < dx)
+ dir = DIR_RIGHT;
+ }
+ else // dy >= 0 .
+ {
+ if (dx * 12 < dy)
+ dir = DIR_DOWN;
+ else if (dy * 12 < dx)
+ dir = DIR_RIGHT;
+ }
+ }
+ return dir;
+ }
+
+ public static int atan(int dx, int dy)
+ {
+ int angle;
+ // Trivial cases.
+ if (dy == 0)
+ {
+ angle = 0;
+ if (dx < 0)
+ angle = ANGLE_PI;
+ return angle;
+ }
+ else if (dx == 0)
+ {
+ angle = ANGLE_PI2;
+ if (dy < 0)
+ angle = - ANGLE_PI2;
+ return angle;
+ }
+
+
+ angle = 0;
+ if (dx < 0)
+ {
+ dx = -dx;
+ dy = -dy;
+ angle = ANGLE_PI;
+ }
+ if (dy < 0)
+ {
+ int tmp = dx;
+ dx = -dy;
+ dy = tmp;
+ angle -= ANGLE_PI2;
+ }
+ if (dx == 0 && dy == 0)
+ return 0;
+
+ if (dx == dy)
+ angle += ANGLE_PI4;
+ else if (dx > dy)
+ {
+ angle += ATAN[Fixed.div(dy, dx) << (ATAN_BITS - 6)];
+ }
+ else
+ {
+ angle += ANGLE_PI2 - ATAN[Fixed.div(dx, dy) << (ATAN_BITS - 6)];
+ }
+
+ if (angle > ANGLE_PI)
+ angle -= ANGLE_2PI;
+ return angle;
+ }
+
+ public static int angleDiff(int ang1, int ang2)
+ {
+ int delta = ang2 - ang1;
+ delta %= ANGLE_2PI;
+ if (delta < 0)
+ delta += ANGLE_2PI;
+ if (delta > ANGLE_PI)
+ delta -= ANGLE_2PI;
+ return delta;
+ }
+
+ static void sort(int num, int[] array)
+ {
+ int swap;
+ for (int i = 1; i < num; i++)
+ {
+ for (int j = i; j > 0; j--)
+ {
+ if (array[j] > array[j - 1])
+ break;
+ swap = array[j];
+ array[j] = array[j - 1];
+ array[j - 1] = swap;
+ }
+ }
+ }
+
+ static void sort(int num, Width[] array)
+ {
+ Width swap;
+ for (int i = 1; i < num; i++)
+ {
+ for (int j = 1; j > 0; j--)
+ {
+ if (array[j].org > array[j - 1].org)
+ break;
+ swap = array[j];
+ array[j] = array[j - 1];
+ array[j - 1] = swap;
+ }
+ }
+ }
+
+ static int pixRound(int val)
+ {
+ return pixFloor(val + 32);
+ }
+
+ static int pixFloor(int val)
+ {
+ return val & ~63;
+ }
+
+ public static int mulDiv(int a, int b, int c)
+ {
+ long prod = a * b;
+ long div = (prod / c);
+ return (int) div;
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/Width.java b/libjava/classpath/gnu/java/awt/font/autofit/Width.java
index d4d540069ee..c890cf3de3d 100644
--- a/libjava/classpath/gnu/java/awt/font/autofit/Width.java
+++ b/libjava/classpath/gnu/java/awt/font/autofit/Width.java
@@ -43,4 +43,20 @@ public class Width
int org;
int cur;
int fit;
+ Width(int dist)
+ {
+ org = dist;
+ }
+
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[Width] org: ");
+ s.append(org);
+ s.append(", cur: ");
+ s.append(cur);
+ s.append(", fit: ");
+ s.append(fit);
+ return s.toString();
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/Hinter.java b/libjava/classpath/gnu/java/awt/font/opentype/Hinter.java
new file mode 100644
index 00000000000..9758a2896b7
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/opentype/Hinter.java
@@ -0,0 +1,63 @@
+/* Hinter.java -- The interface to a hinting implementation
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.opentype;
+
+import gnu.java.awt.font.opentype.truetype.Zone;
+
+/**
+ * The interface to a hinting implementation.
+ */
+public interface Hinter
+{
+ /**
+ * Initializes the hinter.
+ *
+ * @param face the font for which the hinter should be used
+ */
+ void init(OpenTypeFont face);
+
+ /**
+ * Hints the specified outline.
+ *
+ * @param outline the outline to hint
+ */
+ void applyHints(Zone outline);
+
+ void setFlags(int flags);
+}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/OpenTypeFont.java b/libjava/classpath/gnu/java/awt/font/opentype/OpenTypeFont.java
index efc30811f7b..a270ce7d96d 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/OpenTypeFont.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/OpenTypeFont.java
@@ -51,6 +51,7 @@ import java.util.Locale;
import gnu.java.awt.font.FontDelegate;
import gnu.java.awt.font.GNUGlyphVector;
+import gnu.java.awt.font.autofit.AutoHinter;
import gnu.java.awt.font.opentype.truetype.TrueTypeScaler;
import gnu.java.awt.font.opentype.truetype.Zone;
@@ -146,7 +147,8 @@ public final class OpenTypeFont
*/
private GlyphNamer glyphNamer;
-
+ private Hinter hinter;
+
/**
* Constructs an OpenType or TrueType font.
*
@@ -579,6 +581,9 @@ public final class OpenTypeFont
FontRenderContext frc,
CharacterIterator ci)
{
+ // Initialize hinter if necessary.
+ checkHinter(FontDelegate.FLAG_FITTED);
+
CharGlyphMap cmap;
int numGlyphs;
int[] glyphs;
@@ -689,13 +694,15 @@ public final class OpenTypeFont
float pointSize,
AffineTransform transform,
boolean antialias,
- boolean fractionalMetrics)
+ boolean fractionalMetrics,
+ int flags)
{
/* The synchronization is needed because the scaler is not
* synchronized.
*/
+ checkHinter(flags);
return scaler.getOutline(glyph, pointSize, transform,
- antialias, fractionalMetrics);
+ antialias, fractionalMetrics, hinter, flags);
}
/**
@@ -837,4 +844,29 @@ public final class OpenTypeFont
c[3] = (char) (tag & 0xff);
return new String(c);
}
+
+ /**
+ * Checks if a hinter is installed and installs one when not.
+ */
+ private void checkHinter(int flags)
+ {
+ // When another hinting impl gets added (maybe a true TrueType hinter)
+ // then add some options here. The Hinter interface might need to be
+ // tweaked.
+ if (hinter == null)
+ {
+ try
+ {
+ hinter = new AutoHinter();
+ hinter.init(this);
+ }
+ catch (Exception ex)
+ {
+ // Protect from problems inside hinter.
+ hinter = null;
+ ex.printStackTrace();
+ }
+ }
+ hinter.setFlags(flags);
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/Scaler.java b/libjava/classpath/gnu/java/awt/font/opentype/Scaler.java
index 83a31c576c7..c7582b66657 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/Scaler.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/Scaler.java
@@ -90,7 +90,8 @@ public abstract class Scaler
float pointSize,
AffineTransform transform,
boolean antialias,
- boolean fractionalMetrics);
+ boolean fractionalMetrics,
+ Hinter hinter, int type);
/**
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/Fixed.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Fixed.java
index 5d81c5d2e6a..287593e439c 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/truetype/Fixed.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Fixed.java
@@ -48,7 +48,7 @@ package gnu.java.awt.font.opentype.truetype;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-final class Fixed
+public final class Fixed
{
public static final int ONE = 1<<6;
@@ -69,14 +69,21 @@ final class Fixed
return (int) ((((long) a) * b) >> 6);
}
+ public static int mul16(int a, int b)
+ {
+ return (int) ((((long) a) * b) >> 16);
+ }
public static int div(int a, int b)
{
return (int) ((((long) a) << 6) / b);
}
+ public static int div16(int a, int b)
+ {
+ return (int) ((((long) a) << 16) / b);
+ }
-
public static int ceil(int a)
{
return (a + 63) & -64;
@@ -119,7 +126,10 @@ final class Fixed
{
return ((float) f) / 64;
}
-
+ public static float floatValue16(int f)
+ {
+ return ((float) f) / 65536;
+ }
public static double doubleValue(int f)
{
@@ -138,6 +148,10 @@ final class Fixed
return (int) (d * 64);
}
+ public static int valueOf16(double d)
+ {
+ return (int) (d * (1 << 16));
+ }
/**
* Makes a string representation of a fixed-point number.
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphLoader.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphLoader.java
index 3733afe92d8..249a87dd403 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphLoader.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/GlyphLoader.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package gnu.java.awt.font.opentype.truetype;
+import gnu.java.awt.font.opentype.Hinter;
+
import java.awt.geom.AffineTransform;
import java.nio.ByteBuffer;
@@ -112,17 +114,17 @@ final class GlyphLoader
double pointSize,
AffineTransform transform,
boolean antialias,
- Zone glyphZone)
+ Zone glyphZone, Hinter hinter)
{
glyphZone.setNumPoints(4);
loadSubGlyph(glyphIndex, pointSize, transform, antialias, glyphZone,
- 0, 0);
+ 0, 0, hinter);
}
public void loadGlyph(int glyphIndex, AffineTransform transform,
- Zone glyphZone)
+ Zone glyphZone, Hinter hinter)
{
- loadGlyph(glyphIndex, unitsPerEm, transform, false, glyphZone);
+ loadGlyph(glyphIndex, unitsPerEm, transform, false, glyphZone, hinter);
}
private void loadSubGlyph(int glyphIndex,
@@ -131,7 +133,8 @@ final class GlyphLoader
boolean antialias,
Zone glyphZone,
int preTranslateX,
- int preTranslateY)
+ int preTranslateY,
+ Hinter hinter)
{
ByteBuffer glyph;
int numContours;
@@ -159,11 +162,11 @@ final class GlyphLoader
if (numContours >= 0)
loadSimpleGlyph(glyphIndex, pointSize, transform, antialias,
numContours, glyph, glyphZone,
- preTranslateX, preTranslateY);
+ preTranslateX, preTranslateY, hinter);
else
loadCompoundGlyph(glyphIndex, pointSize, transform, antialias,
glyph, glyphZone,
- preTranslateX, preTranslateY);
+ preTranslateX, preTranslateY, hinter);
}
@@ -172,7 +175,8 @@ final class GlyphLoader
boolean antialias,
int numContours, ByteBuffer glyph,
Zone glyphZone,
- int preTranslateX, int preTranslateY)
+ int preTranslateX, int preTranslateY,
+ Hinter hinter)
{
int numPoints;
int posInstructions, numInstructions;
@@ -203,10 +207,10 @@ final class GlyphLoader
glyphZone.transform(pointSize, transform, unitsPerEm,
preTranslateX, preTranslateY);
- if (execInstructions)
- {
- // FIXME: Hint the glyph.
- }
+ if (execInstructions && hinter != null)
+ {
+ hinter.applyHints(glyphZone);
+ }
}
@@ -229,7 +233,8 @@ final class GlyphLoader
boolean antialias,
ByteBuffer glyph,
Zone glyphZone,
- int preTranslateX, int preTranslateY)
+ int preTranslateX, int preTranslateY,
+ Hinter hinter)
{
short flags;
int subGlyphIndex;
@@ -326,7 +331,7 @@ final class GlyphLoader
loadSubGlyph(subGlyphIndex, pointSize, componentTransform,
antialias, subGlyphZone,
Math.round((float) e + preTranslateX),
- Math.round(-((float) f + preTranslateY)));
+ Math.round(-((float) f + preTranslateY)), hinter);
glyphZone.combineWithSubGlyph(subGlyphZone, 4);
glyph.limit(lim).position(pos);
}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/Point.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Point.java
new file mode 100644
index 00000000000..c9664d2dc07
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Point.java
@@ -0,0 +1,285 @@
+/* Point.java -- Holds information for one point on a glyph outline
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.font.opentype.truetype;
+
+/**
+ * Encapsulates information regarding one point on a glyph outline.
+ */
+public class Point
+{
+ public static final short FLAG_TOUCHED_X = 1;
+ public static final short FLAG_TOUCHED_Y = 2;
+ public static final short FLAG_ON_CURVE = 4;
+ public static final short FLAG_CONTOUR_END = 8;
+ public static final short FLAG_WEAK_INTERPOLATION = 16;
+ public static final short FLAG_INFLECTION = 32;
+ public static final short FLAG_DONE_X = 64;
+ public static final short FLAG_DONE_Y = 128;
+
+ /**
+ * Right direction.
+ */
+ public static final int DIR_RIGHT = 1;
+
+ /**
+ * Left direction.
+ */
+ public static final int DIR_LEFT = -1;
+
+ /**
+ * Up direction.
+ */
+ public static final int DIR_UP = 2;
+
+ /**
+ * Down direction.
+ */
+ public static final int DIR_DOWN = -2;
+
+ /**
+ * The original x coordinate in font units.
+ */
+ int origX;
+
+ /**
+ * The original y coordinate in font units.
+ */
+ int origY;
+
+ /**
+ * The x coordinate scaled to the target.
+ */
+ int scaledX;
+
+ /**
+ * The y coordinate scaled to the target.
+ */
+ int scaledY;
+
+ /**
+ * The final hinted and scaled x coordinate.
+ */
+ int x;
+
+ /**
+ * The final hinted and scaled y coordinate.
+ */
+ int y;
+
+ int u;
+ int v;
+
+ /**
+ * The glyph flags.
+ */
+ short flags;
+
+ /**
+ * The previous point in the contour.
+ */
+ private Point prev;
+
+ /**
+ * The next point in the contour.
+ */
+ private Point next;
+
+ /**
+ * The in-direction of the point, according to the DIR_* constants of this
+ * class.
+ */
+ int inDir;
+
+ /**
+ * The out-direction of the point, according to the DIR_* constants of this
+ * class.
+ */
+ int outDir;
+
+ public Point getNext()
+ {
+ return next;
+ }
+
+ public void setNext(Point next)
+ {
+ this.next = next;
+ }
+
+ public Point getPrev()
+ {
+ return prev;
+ }
+
+ public void setPrev(Point prev)
+ {
+ this.prev = prev;
+ }
+
+ public int getOrigX()
+ {
+ return origX;
+ }
+
+ public void setOrigX(int origX)
+ {
+ this.origX = origX;
+ }
+
+ public int getOrigY()
+ {
+ return origY;
+ }
+
+ public void setOrigY(int origY)
+ {
+ this.origY = origY;
+ }
+
+ public int getInDir()
+ {
+ return inDir;
+ }
+
+ public void setInDir(int inDir)
+ {
+ this.inDir = inDir;
+ }
+
+ public int getOutDir()
+ {
+ return outDir;
+ }
+
+ public void setOutDir(int outDir)
+ {
+ this.outDir = outDir;
+ }
+
+ public short getFlags()
+ {
+ return flags;
+ }
+
+ public void setFlags(short flags)
+ {
+ this.flags = flags;
+ }
+
+ public void addFlags(short flags)
+ {
+ this.flags |= flags;
+ }
+
+ public boolean isControlPoint()
+ {
+ return (flags & FLAG_ON_CURVE) == 0;
+ }
+
+ public int getU()
+ {
+ return u;
+ }
+
+ public void setU(int u)
+ {
+ this.u = u;
+ }
+
+ public int getV()
+ {
+ return v;
+ }
+
+ public void setV(int v)
+ {
+ this.v = v;
+ }
+
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[Point] origX: ");
+ s.append(origX);
+ s.append(", origY: ");
+ s.append(origY);
+ // TODO: Add more info when needed.
+ return s.toString();
+ }
+
+ public int getX()
+ {
+ return x;
+ }
+
+ public void setX(int x)
+ {
+ this.x = x;
+ }
+
+ public int getY()
+ {
+ return y;
+ }
+
+ public void setY(int y)
+ {
+ this.y = y;
+ }
+
+ public int getScaledX()
+ {
+ return scaledX;
+ }
+
+ public void setScaledX(int scaledX)
+ {
+ this.scaledX = scaledX;
+ }
+
+ public int getScaledY()
+ {
+ return scaledY;
+ }
+
+ public void setScaledY(int scaledY)
+ {
+ this.scaledY = scaledY;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
index 8dfdeff0790..5f5cc0001d9 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.java.awt.font.opentype.truetype;
+import gnu.java.awt.font.opentype.Hinter;
import gnu.java.awt.font.opentype.Scaler;
import java.awt.FontFormatException;
@@ -191,17 +192,18 @@ public final class TrueTypeScaler
float pointSize,
AffineTransform deviceTransform,
boolean antialias,
- boolean fractionalMetrics)
+ boolean fractionalMetrics, Hinter hinter,
+ int type)
{
glyphLoader.loadGlyph(glyphIndex, pointSize, deviceTransform,
- antialias, glyphZone);
- return glyphZone.getPath();
+ antialias, glyphZone, hinter);
+ return glyphZone.getPath(type);
}
public Zone getRawOutline(int glyphIndex, AffineTransform transform)
{
Zone zone = new Zone(glyphZone.getCapacity());
- glyphLoader.loadGlyph(glyphIndex, transform, zone);
+ glyphLoader.loadGlyph(glyphIndex, transform, zone, null);
return zone;
}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/Zone.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Zone.java
index ff5bb631619..7c25a0a6a49 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/truetype/Zone.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/Zone.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package gnu.java.awt.font.opentype.truetype;
+import gnu.java.awt.font.FontDelegate;
+
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
@@ -47,27 +49,19 @@ import java.awt.geom.PathIterator;
*/
public final class Zone
{
- private final int[] pos;
- private final int[] origPos;
- private final byte[] flags;
+ private Point[] points;
private int numPoints;
- private static final int FLAG_TOUCHED_X = 1;
- private static final int FLAG_TOUCHED_Y = 2;
- private static final int FLAG_ON_CURVE = 4;
- private static final int FLAG_CONTOUR_END = 8;
+ public double scaleX, scaleY, shearX, shearY;
public Zone(int maxNumPoints)
{
- origPos = new int[maxNumPoints * 2];
- pos = new int[maxNumPoints * 2];
- flags = new byte[maxNumPoints];
+ points = new Point[maxNumPoints];
}
-
public int getCapacity()
{
- return flags.length;
+ return points.length;
}
@@ -79,91 +73,110 @@ public final class Zone
public int getX(int point)
{
- return pos[2 * point];
+ return getX(point, FontDelegate.FLAG_FITTED);
+ }
+
+ public int getX(int point, int flags)
+ {
+ int x;
+ if ((flags & FontDelegate.FLAG_FITTED) != 0)
+ x = points[point].x;
+ else
+ x = points[point].scaledX;
+ return x;
}
public void setX(int point, int value, boolean touch)
{
- pos[2 * point] = value;
+ points[point].scaledX = value;
+ points[point].x = value;
if (touch)
- flags[point] |= FLAG_TOUCHED_X;
+ points[point].flags |= Point.FLAG_TOUCHED_X;
}
public void setY(int point, int value, boolean touch)
{
- pos[2 * point + 1] = value;
+ points[point].scaledY = value;
+ points[point].y = value;
if (touch)
- flags[point] |= FLAG_TOUCHED_Y;
+ points[point].flags |= Point.FLAG_TOUCHED_Y;
}
-
public int getY(int point)
{
- return pos[2 * point + 1];
+ return getY(point, FontDelegate.FLAG_FITTED);
+ }
+
+ public int getY(int point, int flags)
+ {
+ int y;
+ if ((flags & FontDelegate.FLAG_FITTED) != 0)
+ y = points[point].y;
+ else
+ y = points[point].scaledY;
+ return y;
}
public int getOriginalX(int point)
{
- return origPos[2 * point];
+ return points[point].origX;
}
public int getOriginalY(int point)
{
- return origPos[2 * point + 1];
+ return points[point].origY;
}
public void setOriginalX(int point, int x)
{
- origPos[2 * point] = x;
+ points[point].origX = x;
}
public void setOriginalY(int point, int y)
{
- origPos[2 * point + 1] = y;
+ points[point].origY = y;
}
public void setNumPoints(int numPoints)
{
- this.numPoints = numPoints;
for (int i = 0; i < numPoints; i++)
- flags[i] = 0;
- for (int i = 0; i < 2 * numPoints; i++)
- origPos[i] = pos[i] = 0;
+ points[i] = new Point();
+ this.numPoints = numPoints;
}
public boolean isOnCurve(int point)
{
- return (flags[point] & FLAG_ON_CURVE) != 0;
+ return (points[point].flags & Point.FLAG_ON_CURVE) != 0;
}
public void setOnCurve(int point, boolean onCurve)
{
if (onCurve)
- flags[point] |= FLAG_ON_CURVE;
+ points[point].flags |= Point.FLAG_ON_CURVE;
else
- flags[point] &= ~FLAG_ON_CURVE;
+ points[point].flags &= ~Point.FLAG_ON_CURVE;
}
public boolean isContourEnd(int point)
{
- return (flags[point] & FLAG_CONTOUR_END) != 0;
+ return (points[point].flags & Point.FLAG_CONTOUR_END) != 0;
}
public void setContourEnd(int point, boolean segEnd)
{
if (segEnd)
- flags[point] |= FLAG_CONTOUR_END;
+ points[point].flags |= Point.FLAG_CONTOUR_END;
else
- flags[point] &= ~FLAG_CONTOUR_END;
+ points[point].flags &= ~Point.FLAG_CONTOUR_END;
}
@@ -172,7 +185,6 @@ public final class Zone
void transform(double pointSize, AffineTransform deviceTransform,
int unitsPerEm, int preTranslateX, int preTranslateY)
{
- double scaleX, scaleY, shearX, shearY;
double factor;
factor = pointSize / (double) unitsPerEm;
@@ -183,11 +195,13 @@ public final class Zone
for (int i = 0; i < numPoints; i++)
{
- int x = origPos[2 * i] + preTranslateX;
- int y = origPos[2 * i + 1] + preTranslateY;
+ int x = points[i].origX + preTranslateX;
+ int y = points[i].origY + preTranslateY;
- origPos[2*i] = pos[2 * i] = Fixed.valueOf(scaleX * x + shearX * y);
- origPos[2*i+1] = pos[2 * i + 1] = Fixed.valueOf(shearY * x + scaleY * y);
+ points[i].scaledX = points[i].x = Fixed.valueOf(scaleX * x
+ + shearX * y);
+ points[i].scaledY = points[i].y = Fixed.valueOf(shearY * x
+ + scaleY * y);
}
}
@@ -197,11 +211,7 @@ public final class Zone
{
int offset = this.numPoints - numPhantomPoints;
int count = zone.numPoints;
- System.arraycopy(zone.origPos, 0, this.origPos, 2 * offset,
- count * 2);
- System.arraycopy(zone.pos, 0, this.pos, 2 * offset,
- count * 2);
- System.arraycopy(zone.flags, 0, this.flags, offset, count);
+ System.arraycopy(zone.points, 0, this.points, offset, count);
this.numPoints += count - numPhantomPoints;
}
@@ -211,9 +221,9 @@ public final class Zone
for (int i = 0; i < numPoints; i++)
{
System.out.print(" " + i + ": ");
- System.out.print(Fixed.toString(pos[i*2], pos[i*2+1]));
+ System.out.print(Fixed.toString(points[i].scaledX, points[i].scaledY));
System.out.print(' ');
- System.out.print(Fixed.toString(origPos[i*2], origPos[i*2+1]));
+ System.out.print(Fixed.toString(points[i].origX, points[i].origY));
System.out.print(' ');
if (isOnCurve(i))
System.out.print('.');
@@ -228,16 +238,54 @@ public final class Zone
}
- public PathIterator getPathIterator()
+ public PathIterator getPathIterator(int type)
{
- return new ZonePathIterator(this);
+ return new ZonePathIterator(this, type);
}
- public GeneralPath getPath()
+ public GeneralPath getPath(int type)
{
GeneralPath p = new GeneralPath(GeneralPath.WIND_NON_ZERO, numPoints);
- p.append(getPathIterator(), /* connect */ false);
+ p.append(getPathIterator(type), /* connect */ false);
return p;
}
+
+ /**
+ * Returns the number of contours in this outline.
+ *
+ * @return the number of contours in this outline
+ */
+ public int getNumContours()
+ {
+ int num = 0;
+ for (int i = 0; i < numPoints; i++)
+ {
+ if (isContourEnd(i))
+ num++;
+ }
+ return num;
+ }
+
+ public int getContourEnd(int n)
+ {
+ int idx = -1;
+ int num = 0;
+ for (int i = 0; i < numPoints; i++)
+ {
+ if (isContourEnd(i))
+ {
+ idx = i;
+ if (num == n)
+ break;
+ num++;
+ }
+ }
+ return idx;
+ }
+
+ public Point[] getPoints()
+ {
+ return points;
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java b/libjava/classpath/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java
index d000b9c3e42..0f60828b892 100644
--- a/libjava/classpath/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java
+++ b/libjava/classpath/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java
@@ -116,6 +116,7 @@ final class ZonePathIterator
private int contourStart;
+ private int type;
/**
* Constructs a ZonePathIterator for the specified zone.
@@ -123,9 +124,10 @@ final class ZonePathIterator
* @param zone the zone whose segments will be enumerated
* by this iterator.
*/
- ZonePathIterator(Zone zone)
+ ZonePathIterator(Zone zone, int t)
{
this.zone = zone;
+ type = t;
numPoints = zone.getSize() - /* four phantom points */ 4;
// The first segment that needs to be emitted is a SEG_MOVETO.
@@ -309,8 +311,8 @@ final class ZonePathIterator
int curX, curY;
int succ, succX, succY;
- curX = zone.getX(cur);
- curY = zone.getY(cur);
+ curX = zone.getX(cur, type);
+ curY = zone.getY(cur, type);
coords[0] = Fixed.floatValue(curX);
coords[1] = Fixed.floatValue(curY);
@@ -318,8 +320,8 @@ final class ZonePathIterator
return PathIterator.SEG_LINETO;
succ = getSuccessor(cur);
- succX = zone.getX(succ);
- succY = zone.getY(succ);
+ succX = zone.getX(succ, type);
+ succY = zone.getY(succ, type);
if (zone.isOnCurve(succ))
{
@@ -359,8 +361,8 @@ final class ZonePathIterator
if (zone.isOnCurve(contourStart))
{
- x = zone.getX(contourStart);
- y = zone.getY(contourStart);
+ x = zone.getX(contourStart, type);
+ y = zone.getY(contourStart, type);
}
else
{
@@ -374,13 +376,13 @@ final class ZonePathIterator
/* An example is the 'o' glyph of the Helvetica which comes
* with Apple MacOS X 10.1.5.
*/
- x = zone.getX(contourEnd);
- y = zone.getY(contourEnd);
+ x = zone.getX(contourEnd, type);
+ y = zone.getY(contourEnd, type);
}
else
{
- x = (zone.getX(contourStart) + zone.getX(contourEnd)) / 2;
- y = (zone.getY(contourStart) + zone.getY(contourEnd)) / 2;
+ x = (zone.getX(contourStart, type) + zone.getX(contourEnd, type)) / 2;
+ y = (zone.getY(contourStart, type) + zone.getY(contourEnd, type)) / 2;
}
}
diff --git a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
index da21253980f..f6c5ff0cb3b 100644
--- a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
+++ b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
@@ -67,8 +67,6 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
@@ -82,7 +80,6 @@ import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
/**
@@ -154,6 +151,11 @@ public abstract class AbstractGraphics2D
{
/**
+ * The default font to use on the graphics object.
+ */
+ private static final Font FONT = new Font("SansSerif", Font.PLAIN, 12);
+
+ /**
* Accuracy of the sampling in the anti-aliasing shape filler.
* Lower values give more speed, while higher values give more quality.
* It is advisable to choose powers of two.
@@ -164,7 +166,14 @@ public abstract class AbstractGraphics2D
* Caches certain shapes to avoid massive creation of such Shapes in
* the various draw* and fill* methods.
*/
- private static final ThreadLocal shapeCache = new ThreadLocal();
+ private static final ThreadLocal<ShapeCache> shapeCache =
+ new ThreadLocal<ShapeCache>();
+
+ /**
+ * The scanline converters by thread.
+ */
+ private static final ThreadLocal<ScanlineConverter> scanlineConverters =
+ new ThreadLocal<ScanlineConverter>();
/**
* The transformation for this Graphics2D instance
@@ -177,6 +186,11 @@ public abstract class AbstractGraphics2D
private Paint paint;
/**
+ * The paint context during rendering.
+ */
+ private PaintContext paintContext;
+
+ /**
* The background.
*/
private Color background;
@@ -239,6 +253,17 @@ public abstract class AbstractGraphics2D
*/
private boolean isOptimized = true;
+ private static final BasicStroke STANDARD_STROKE = new BasicStroke();
+
+ private static final HashMap STANDARD_HINTS;
+ static {
+ HashMap hints = new HashMap();
+ hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+ hints.put(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_DEFAULT);
+ STANDARD_HINTS = hints;
+ }
/**
* Creates a new AbstractGraphics2D instance.
*/
@@ -247,13 +272,8 @@ public abstract class AbstractGraphics2D
transform = new AffineTransform();
background = Color.WHITE;
composite = AlphaComposite.SrcOver;
- stroke = new BasicStroke();
- HashMap hints = new HashMap();
- hints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
- RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
- hints.put(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_DEFAULT);
- renderingHints = new RenderingHints(hints);
+ stroke = STANDARD_STROKE;
+ renderingHints = new RenderingHints(STANDARD_HINTS);
}
/**
@@ -958,15 +978,8 @@ public abstract class AbstractGraphics2D
*/
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
- int numGlyphs = gv.getNumGlyphs();
translate(x, y);
- // TODO: We could use fill(gv.getOutline()), but that seems to be
- // slightly more inefficient.
- for (int i = 0; i < numGlyphs; i++)
- {
- Shape o = gv.getGlyphOutline(i);
- fillShape(o, true);
- }
+ fillShape(gv.getOutline(), true);
translate(-x, -y);
}
@@ -1557,21 +1570,14 @@ public abstract class AbstractGraphics2D
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
}
- Rectangle2D userBounds = s.getBounds2D();
- Rectangle2D deviceBounds = new Rectangle2D.Double();
- ArrayList segs = getSegments(s, transform, deviceBounds, false);
- Rectangle2D clipBounds = new Rectangle2D.Double();
- ArrayList clipSegs = getSegments(clip, transform, clipBounds, true);
- segs.addAll(clipSegs);
- Rectangle2D inclClipBounds = new Rectangle2D.Double();
- Rectangle2D.union(clipBounds, deviceBounds, inclClipBounds);
- if (segs.size() > 0)
+ ScanlineConverter sc = getScanlineConverter();
+ int resolution = 0;
+ if (antialias)
{
- if (antialias)
- fillShapeAntialias(segs, deviceBounds, userBounds, inclClipBounds);
- else
- fillShapeImpl(segs, deviceBounds, userBounds, inclClipBounds);
+ // Adjust resolution according to rendering hints.
+ resolution = 2;
}
+ sc.renderShape(this, s, clip, transform, resolution);
}
/**
@@ -1705,141 +1711,6 @@ public abstract class AbstractGraphics2D
}
/**
- * Fills the specified polygon without anti-aliasing.
- */
- private void fillShapeImpl(ArrayList segs, Rectangle2D deviceBounds2D,
- Rectangle2D userBounds,
- Rectangle2D inclClipBounds)
- {
- // This is an implementation of a polygon scanline conversion algorithm
- // described here:
- // http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/
-
- // Create table of all edges.
- // The edge buckets, sorted and indexed by their Y values.
-
- double minX = deviceBounds2D.getMinX();
- double minY = deviceBounds2D.getMinY();
- double maxX = deviceBounds2D.getMaxX();
- double maxY = deviceBounds2D.getMaxY();
- double icMinY = inclClipBounds.getMinY();
- double icMaxY = inclClipBounds.getMaxY();
- Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,
- (int) Math.ceil(maxX) - (int) minX,
- (int) Math.ceil(maxY) - (int) minY);
- PaintContext pCtx = paint.createContext(getColorModel(), deviceBounds,
- userBounds, transform, renderingHints);
-
- ArrayList[] edgeTable = new ArrayList[(int) Math.ceil(icMaxY)
- - (int) Math.ceil(icMinY) + 1];
-
- for (Iterator i = segs.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- int yindex = (int) Math.ceil(edge.y0) - (int) Math.ceil(icMinY);
- if (edgeTable[yindex] == null) // Create bucket when needed.
- edgeTable[yindex] = new ArrayList();
- edgeTable[yindex].add(edge); // Add edge to the bucket of its line.
- }
-
- // TODO: The following could be useful for a future optimization.
-// // Sort all the edges in the edge table within their buckets.
-// for (int y = 0; y < edgeTable.length; y++)
-// {
-// if (edgeTable[y] != null)
-// Collections.sort(edgeTable[y]);
-// }
-
- // The activeEdges list contains all the edges of the current scanline
- // ordered by their intersection points with this scanline.
- ArrayList activeEdges = new ArrayList();
- PolyEdgeComparator comparator = new PolyEdgeComparator();
-
- // Scan all relevant lines.
- int minYInt = (int) Math.ceil(icMinY);
-
- Rectangle devClip = getDeviceBounds();
- int scanlineMax = (int) Math.min(maxY, devClip.getMaxY());
- for (int y = minYInt; y < scanlineMax; y++)
- {
- ArrayList bucket = edgeTable[y - minYInt];
- // Update all the x intersections in the current activeEdges table
- // and remove entries that are no longer in the scanline.
- for (Iterator i = activeEdges.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- if (y > edge.y1)
- i.remove();
- else
- {
- edge.xIntersection += edge.slope;
- //edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);
- //System.err.println("edge.xIntersection: " + edge.xIntersection);
- }
- }
-
- if (bucket != null)
- activeEdges.addAll(bucket);
-
- // Sort current edges. We are using a bubble sort, because the order
- // of the intersections will not change in most situations. They
- // will only change, when edges intersect each other.
- int size = activeEdges.size();
- if (size > 1)
- {
- for (int i = 1; i < size; i++)
- {
- PolyEdge e1 = (PolyEdge) activeEdges.get(i - 1);
- PolyEdge e2 = (PolyEdge) activeEdges.get(i);
- if (comparator.compare(e1, e2) > 0)
- {
- // Swap e2 with its left neighbor until it 'fits'.
- int j = i;
- do
- {
- activeEdges.set(j, e1);
- activeEdges.set(j - 1, e2);
- j--;
- if (j >= 1)
- e1 = (PolyEdge) activeEdges.get(j - 1);
- } while (j >= 1 && comparator.compare(e1, e2) > 0);
- }
- }
- }
-
- // Now draw all pixels inside the polygon.
- // This is the last edge that intersected the scanline.
- PolyEdge previous = null; // Gets initialized below.
- boolean insideShape = false;
- boolean insideClip = false;
- //System.err.println("scanline: " + y);
- for (Iterator i = activeEdges.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- if (edge.y1 <= y)
- continue;
-
- // Draw scanline when we are inside the shape AND inside the
- // clip.
- if (insideClip && insideShape)
- {
- int x0 = (int) previous.xIntersection;
- int x1 = (int) edge.xIntersection;
- if (x0 < x1)
- fillScanline(pCtx, x0, x1, y);
- }
- // Update state.
- previous = edge;
- if (edge.isClip)
- insideClip = ! insideClip;
- else
- insideShape = ! insideShape;
- }
- }
- pCtx.dispose();
- }
-
- /**
* Paints a scanline between x0 and x1. Override this when your backend
* can efficiently draw/fill horizontal lines.
*
@@ -1847,8 +1718,9 @@ public abstract class AbstractGraphics2D
* @param x1 the right offset
* @param y the scanline
*/
- protected void fillScanline(PaintContext pCtx, int x0, int x1, int y)
+ protected void fillScanline(int x0, int x1, int y)
{
+ PaintContext pCtx = paintContext;
Raster paintRaster = pCtx.getRaster(x0, y, x1 - x0, 1);
ColorModel paintColorModel = pCtx.getColorModel();
CompositeContext cCtx = composite.createContext(paintColorModel,
@@ -1860,198 +1732,6 @@ public abstract class AbstractGraphics2D
cCtx.dispose();
}
- /**
- * Fills arbitrary shapes in an anti-aliased fashion.
- *
- * @param segs the line segments which define the shape which is to be filled
- */
- private void fillShapeAntialias(ArrayList segs, Rectangle2D deviceBounds2D,
- Rectangle2D userBounds,
- Rectangle2D inclClipBounds)
- {
- // This is an implementation of a polygon scanline conversion algorithm
- // described here:
- // http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/scan/
- // The antialiasing is implemented using a sampling technique, we do
- // not scan whole lines but fractions of the line.
-
- double minX = deviceBounds2D.getMinX();
- double minY = deviceBounds2D.getMinY();
- double maxX = deviceBounds2D.getMaxX();
- double maxY = deviceBounds2D.getMaxY();
- double icMinY = inclClipBounds.getMinY();
- double icMaxY = inclClipBounds.getMaxY();
- double icMinX = inclClipBounds.getMinX();
- double icMaxX = inclClipBounds.getMaxX();
- Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,
- (int) Math.ceil(maxX) - (int) minX,
- (int) Math.ceil(maxY) - (int) minY);
- PaintContext pCtx = paint.createContext(ColorModel.getRGBdefault(),
- deviceBounds,
- userBounds, transform,
- renderingHints);
-
- // This array will contain the oversampled transparency values for
- // each pixel in the scanline.
- int numScanlines = (int) Math.ceil(icMaxY) - (int) icMinY;
- int numScanlinePixels = (int) Math.ceil(icMaxX) - (int) icMinX + 1;
- if (alpha == null || alpha.length < (numScanlinePixels + 1))
- alpha = new int[numScanlinePixels + 1];
-
- int firstLine = (int) icMinY;
- //System.err.println("minY: " + minY);
- int firstSubline = (int) (Math.ceil((icMinY - Math.floor(icMinY)) * AA_SAMPLING));
- double firstLineDouble = firstLine + firstSubline / (double) AA_SAMPLING;
- //System.err.println("firstSubline: " + firstSubline);
-
- // Create table of all edges.
- // The edge buckets, sorted and indexed by their Y values.
- //System.err.println("numScanlines: " + numScanlines);
- if (edgeTable == null
- || edgeTable.length < numScanlines * AA_SAMPLING + AA_SAMPLING)
- edgeTable = new ArrayList[numScanlines * AA_SAMPLING + AA_SAMPLING];
-
- //System.err.println("firstLineDouble: " + firstLineDouble);
-
- for (Iterator i = segs.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- int yindex = (int) (Math.ceil((edge.y0 - firstLineDouble) * AA_SAMPLING));
- //System.err.println("yindex: " + yindex + " for y0: " + edge.y0);
- // Initialize edge's slope and initial xIntersection.
- edge.slope = ((edge.x1 - edge.x0) / (edge.y1 - edge.y0)) / AA_SAMPLING;
- if (edge.y0 == edge.y1) // Horizontal edge.
- edge.xIntersection = Math.min(edge.x0, edge.x1);
- else
- {
- double alignedFirst = Math.ceil(edge.y0 * AA_SAMPLING) / AA_SAMPLING;
- edge.xIntersection = edge.x0 + (edge.slope * AA_SAMPLING) * (alignedFirst - edge.y0);
- }
- //System.err.println(edge);
- // FIXME: Sanity check should not be needed when clipping works.
- if (yindex >= 0 && yindex < edgeTable.length)
- {
- if (edgeTable[yindex] == null) // Create bucket when needed.
- edgeTable[yindex] = new ArrayList();
- edgeTable[yindex].add(edge); // Add edge to the bucket of its line.
- }
- }
-
- // The activeEdges list contains all the edges of the current scanline
- // ordered by their intersection points with this scanline.
- ArrayList activeEdges = new ArrayList();
- PolyEdgeComparator comparator = new PolyEdgeComparator();
-
- // Scan all lines.
- int yindex = 0;
- //System.err.println("firstLine: " + firstLine + ", maxY: " + maxY + ", firstSubline: " + firstSubline);
- for (int y = firstLine; y <= icMaxY; y++)
- {
- int leftX = (int) icMaxX;
- int rightX = (int) icMinX;
- boolean emptyScanline = true;
- for (int subY = firstSubline; subY < AA_SAMPLING; subY++)
- {
- //System.err.println("scanline: " + y + ", subScanline: " + subY);
- ArrayList bucket = edgeTable[yindex];
- // Update all the x intersections in the current activeEdges table
- // and remove entries that are no longer in the scanline.
- for (Iterator i = activeEdges.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- // TODO: Do the following using integer arithmetics.
- if ((y + ((double) subY / (double) AA_SAMPLING)) > edge.y1)
- i.remove();
- else
- {
- edge.xIntersection += edge.slope;
- //System.err.println("edge: " + edge);
- //edge.xIntersection = edge.x0 + edge.slope * (y - edge.y0);
- //System.err.println("edge.xIntersection: " + edge.xIntersection);
- }
- }
-
- if (bucket != null)
- {
- activeEdges.addAll(bucket);
- edgeTable[yindex].clear();
- }
-
- // Sort current edges. We are using a bubble sort, because the order
- // of the intersections will not change in most situations. They
- // will only change, when edges intersect each other.
- int size = activeEdges.size();
- if (size > 1)
- {
- for (int i = 1; i < size; i++)
- {
- PolyEdge e1 = (PolyEdge) activeEdges.get(i - 1);
- PolyEdge e2 = (PolyEdge) activeEdges.get(i);
- if (comparator.compare(e1, e2) > 0)
- {
- // Swap e2 with its left neighbor until it 'fits'.
- int j = i;
- do
- {
- activeEdges.set(j, e1);
- activeEdges.set(j - 1, e2);
- j--;
- if (j >= 1)
- e1 = (PolyEdge) activeEdges.get(j - 1);
- } while (j >= 1 && comparator.compare(e1, e2) > 0);
- }
- }
- }
-
- // Now draw all pixels inside the polygon.
- // This is the last edge that intersected the scanline.
- PolyEdge previous = null; // Gets initialized below.
- boolean insideClip = false;
- boolean insideShape = false;
- //System.err.println("scanline: " + y + ", subscanline: " + subY);
- for (Iterator i = activeEdges.iterator(); i.hasNext();)
- {
- PolyEdge edge = (PolyEdge) i.next();
- if (edge.y1 <= (y + (subY / (double) AA_SAMPLING)))
- continue;
-
- if (insideClip && insideShape)
- {
- // TODO: Use integer arithmetics here.
- if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))
- {
- //System.err.println(edge);
- // TODO: Eliminate the aligments.
- int x0 = (int) Math.min(Math.max(previous.xIntersection, minX), maxX);
- int x1 = (int) Math.min(Math.max(edge.xIntersection, minX), maxX);
- //System.err.println("minX: " + minX + ", x0: " + x0 + ", x1: " + x1 + ", maxX: " + maxX);
- // TODO: Pull out cast.
- int left = x0 - (int) minX;
- int right = x1 - (int) minX + 1;
- alpha[left]++;
- alpha[right]--;
- leftX = Math.min(x0, leftX);
- rightX = Math.max(x1+2, rightX);
- emptyScanline = false;
- }
- }
- previous = edge;
- if (edge.isClip)
- insideClip = ! insideClip;
- else
- insideShape = ! insideShape;
- }
- yindex++;
- }
- firstSubline = 0;
- // Render full scanline.
- //System.err.println("scanline: " + y);
- if (! emptyScanline)
- fillScanlineAA(alpha, leftX, y, rightX - leftX, pCtx, (int) minX);
- }
-
- pCtx.dispose();
- }
/**
* Fills a horizontal line between x0 and x1 for anti aliased rendering.
@@ -2113,7 +1793,6 @@ public abstract class AbstractGraphics2D
cCtx.dispose();
}
-
/**
* Initializes this graphics object. This must be called by subclasses in
* order to correctly initialize the state of this object.
@@ -2121,13 +1800,8 @@ public abstract class AbstractGraphics2D
protected void init()
{
setPaint(Color.BLACK);
- setFont(new Font("SansSerif", Font.PLAIN, 12));
+ setFont(FONT);
isOptimized = true;
-
- // FIXME: Should not be necessary. A clip of null should mean
- // 'clip against device bounds.
- destinationRaster = getDestinationRaster();
- clip = getDeviceBounds();
}
/**
@@ -2267,91 +1941,33 @@ public abstract class AbstractGraphics2D
}
/**
- * Converts the specified shape into a list of segments.
- *
- * @param s the shape to convert
- * @param t the transformation to apply before converting
- * @param deviceBounds an output parameter; holds the bounding rectangle of
- * s in device space after return
- * @param isClip true when the shape is a clip, false for normal shapes;
- * this influences the settings in the created PolyEdge instances.
+ * Returns the ShapeCache for the calling thread.
*
- * @return a list of PolyEdge that form the shape in device space
+ * @return the ShapeCache for the calling thread
*/
- private ArrayList getSegments(Shape s, AffineTransform t,
- Rectangle2D deviceBounds, boolean isClip)
+ private ShapeCache getShapeCache()
{
- // Flatten the path. TODO: Determine the best flattening factor
- // wrt to speed and quality.
- PathIterator path = s.getPathIterator(getTransform(), 1.0);
-
- // Build up polygons and let the native backend render this using
- // rawFillShape() which would provide a default implementation for
- // drawPixel using a PolyScan algorithm.
- double[] seg = new double[6];
-
- // TODO: Use ArrayList<PolyEdge> here when availble.
- ArrayList segs = new ArrayList();
- double segX = 0.; // The start point of the current edge.
- double segY = 0.;
- double polyX = 0.; // The start point of the current polygon.
- double polyY = 0.;
-
- double minX = Integer.MAX_VALUE;
- double maxX = Integer.MIN_VALUE;
- double minY = Integer.MAX_VALUE;
- double maxY = Integer.MIN_VALUE;
-
- //System.err.println("fill polygon");
- while (! path.isDone())
+ ShapeCache sc = shapeCache.get();
+ if (sc == null)
{
- int segType = path.currentSegment(seg);
- minX = Math.min(minX, seg[0]);
- maxX = Math.max(maxX, seg[0]);
- minY = Math.min(minY, seg[1]);
- maxY = Math.max(maxY, seg[1]);
-
- //System.err.println("segment: " + segType + ", " + seg[0] + ", " + seg[1]);
- if (segType == PathIterator.SEG_MOVETO)
- {
- segX = seg[0];
- segY = seg[1];
- polyX = seg[0];
- polyY = seg[1];
- }
- else if (segType == PathIterator.SEG_CLOSE)
- {
- // Close the polyline.
- PolyEdge edge = new PolyEdge(segX, segY,
- polyX, polyY, isClip);
- segs.add(edge);
- }
- else if (segType == PathIterator.SEG_LINETO)
- {
- PolyEdge edge = new PolyEdge(segX, segY,
- seg[0], seg[1], isClip);
- segs.add(edge);
- segX = seg[0];
- segY = seg[1];
- }
- path.next();
+ sc = new ShapeCache();
+ shapeCache.set(sc);
}
- deviceBounds.setRect(minX, minY, maxX - minX, maxY - minY);
- return segs;
+ return sc;
}
/**
- * Returns the ShapeCache for the calling thread.
+ * Returns the scanline converter for this thread.
*
- * @return the ShapeCache for the calling thread
+ * @return the scanline converter for this thread
*/
- private ShapeCache getShapeCache()
+ private ScanlineConverter getScanlineConverter()
{
- ShapeCache sc = (ShapeCache) shapeCache.get();
+ ScanlineConverter sc = scanlineConverters.get();
if (sc == null)
{
- sc = new ShapeCache();
- shapeCache.set(sc);
+ sc = new ScanlineConverter();
+ scanlineConverters.set(sc);
}
return sc;
}
diff --git a/libjava/classpath/gnu/java/awt/java2d/ActiveEdges.java b/libjava/classpath/gnu/java/awt/java2d/ActiveEdges.java
new file mode 100644
index 00000000000..4d1e777ccf5
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/ActiveEdges.java
@@ -0,0 +1,195 @@
+/* ActiveEdges.java -- A collection of active edges for scanline conversion
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+/**
+ * A collection of active edges for scanline conversion.
+ */
+final class ActiveEdges
+{
+
+ /**
+ * The active edges. This can contain null values at arbirary locations.
+ * The method #sort() packs this together.
+ */
+ private PolyEdge[] activeEdges;
+
+ /**
+ * The actual number of active edges. The array can be bigger than this
+ * number.
+ */
+ private int numActiveEdges;
+
+ /**
+ * Creates a new ActiveEdges object.
+ */
+ ActiveEdges()
+ {
+ activeEdges = new PolyEdge[8];
+ numActiveEdges = 0;
+ }
+
+ /**
+ * Clears out all active edges. This is cheap as it simply resets the
+ * counter to 0. It does not release all references to PolyEdge instances.
+ */
+ void clear()
+ {
+ numActiveEdges = 0;
+ }
+
+ /**
+ * Adds the specified edge to the list of active edges. This does not yet
+ * sort the edges and therefore does destroy any order of the list.
+ *
+ * @param edge the edge to add
+ */
+ void add(PolyEdge edge)
+ {
+ // Grow array when necessary.
+ int oldSize = activeEdges.length;
+ if (numActiveEdges >= oldSize)
+ {
+ int newSize = oldSize + oldSize / 4 + 1;
+ PolyEdge[] newEdges = new PolyEdge[newSize];
+ System.arraycopy(activeEdges, 0, newEdges, 0, oldSize);
+ activeEdges = newEdges;
+ }
+ activeEdges[numActiveEdges] = edge;
+ numActiveEdges++;
+ }
+
+ /**
+ * Intersects all active edges, sorts them according to their intersection
+ * points and packs the array to remove unneeded edges. This does also
+ * remove any edges that do not intersect the scanline (i.e. they end above
+ * of the scanline).
+ *
+ * @param y the scanline height
+ */
+ void intersectSortAndPack(int n, int y)
+ {
+ // Intersect and pack in one go.
+ int last = 0;
+ PolyEdge tmp;
+ for (int i = 0; i < numActiveEdges; i++)
+ {
+ PolyEdge edge = activeEdges[i];
+ // Clear out edge that ends above the scanline.
+ if (edge != null && edge.y1 >= y)
+ {
+ assert edge.y1 >= y && edge.y0 <= y : "edge must cross scanline";
+ edge.intersect(n, y);
+ activeEdges[last] = edge;
+ last++;
+
+ // Bubble up the added edge.
+ for (int j = last - 1; j > 0; j--)
+ {
+ if (activeEdges[j].xIntersection
+ < activeEdges[j - 1].xIntersection)
+ {
+ tmp = activeEdges[j];
+ activeEdges[j] = activeEdges[j - 1];
+ activeEdges[j - 1] = tmp;
+ }
+ else
+ {
+ // The beginning of the list is already sorted.
+ break;
+ }
+ }
+ }
+ }
+ numActiveEdges = last;
+
+ }
+
+ /**
+ * Returns the number of active edges. This is only reliable after a
+ * call to {@link #intersectSortAndPack(int, int)}.
+ *
+ * @return the number of active edges
+ */
+ int getNumActiveEdges()
+ {
+ return numActiveEdges;
+ }
+
+ /**
+ * Returns the active edge at the position <code>i</code>.
+ *
+ * @param i the index
+ *
+ * @return the active edge at the specified index
+ */
+ PolyEdge getActiveEdge(int i)
+ {
+ return activeEdges[i];
+ }
+
+ /**
+ * Removes all edges that end above the specified height.
+ *
+ * @param y the cut-off height
+ */
+ void remove(int y)
+ {
+ for (int i = 0; i < numActiveEdges; i++)
+ {
+ PolyEdge edge = activeEdges[i];
+ if (edge != null && edge.y1 < y)
+ {
+ activeEdges[i] = null;
+ }
+ }
+ }
+
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("[ActiveEdges] ");
+ for (int i = 0; i < numActiveEdges; i++)
+ {
+ s.append(activeEdges[i]);
+ s.append(',');
+ }
+ return s.toString();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/java2d/PolyEdge.java b/libjava/classpath/gnu/java/awt/java2d/PolyEdge.java
index 6c3b546881a..eb0cc7f8f3e 100644
--- a/libjava/classpath/gnu/java/awt/java2d/PolyEdge.java
+++ b/libjava/classpath/gnu/java/awt/java2d/PolyEdge.java
@@ -38,31 +38,38 @@ exception statement from your version. */
package gnu.java.awt.java2d;
+import gnu.java.math.Fixed;
+
/**
- * An edge in a polygon. This is used by the scanline conversion algorithm
- * implemented in {@link AbstractGraphics2D#rawFillShape}.
+ * An edge in a polygon.
*
* @author Roman Kennke (kennke@aicas.com)
*/
-public class PolyEdge
+final class PolyEdge
implements Comparable
{
/**
* The start and end coordinates of the edge. y0 is always smaller or equal
* than y1.
+ *
+ * These values are stored as fixed-point decimals.
*/
- public double x0, y0, x1, y1;
+ public int x0, y0, x1, y1;
/**
* The slope of the edge. This is dx / dy.
+ *
+ * This is a fixed point decimal.
*/
- double slope;
+ private int slope;
/**
* The intersection of this edge with the current scanline.
+ *
+ * This is a fixed point decimal.
*/
- double xIntersection;
+ int xIntersection;
/**
* Indicates whether this edge is from the clip or from the target shape.
@@ -70,6 +77,24 @@ public class PolyEdge
boolean isClip;
/**
+ * Implements a linked list for the edge pool.
+ */
+ PolyEdge poolNext;
+
+ /**
+ * Implements a linked list for the scanline edge lists.
+ */
+ PolyEdge scanlineNext;
+
+ /**
+ * Create an uninitialized edge.
+ */
+ PolyEdge()
+ {
+ // Nothing to do here.
+ }
+
+ /**
* Creates a new PolyEdge with the specified coordinates.
*
* @param x0 the starting point, x coordinate
@@ -77,7 +102,20 @@ public class PolyEdge
* @param x1 the end point, x coordinate
* @param y1 the end point, y coordinate
*/
- PolyEdge(double x0, double y0, double x1, double y1, boolean clip)
+ PolyEdge(int n, int x0, int y0, int x1, int y1, boolean clip)
+ {
+ init(n, x0, y0, x1, y1, clip);
+ }
+
+ /**
+ * (Re-) Initializes this edge.
+ *
+ * @param x0
+ * @param y0
+ * @param x1
+ * @param y1
+ */
+ void init(int n, int x0, int y0, int x1, int y1, boolean clip)
{
isClip = clip;
if (y0 < y1)
@@ -94,11 +132,7 @@ public class PolyEdge
this.x1 = x0;
this.y1 = y0;
}
- slope = (this.x1 - this.x0) / (this.y1 - this.y0);
- if (this.y0 == this.y1) // Horizontal edge.
- xIntersection = Math.min(this.x0, this.x1);
- else
- xIntersection = this.x0 + slope * (Math.ceil(this.y0) - this.y0);
+ slope = Fixed.div(n, this.x1 - this.x0, this.y1 - this.y0);
}
/**
@@ -115,6 +149,19 @@ public class PolyEdge
return comp;
}
+ /**
+ * Intersects this edge with the scanline at height y. The result is
+ * stored in {@link #xIntersection}.
+ *
+ * @param y the scanline
+ */
+ void intersect(int n, int y)
+ {
+ int dy = y - y0;
+ int dx = Fixed.mul(n, slope, dy);
+ xIntersection = x0 + dx;
+ }
+
public String toString()
{
return "Edge: " + x0 + ", " + y0 + ", " + x1 + ", " + y1 + ", slope: "
diff --git a/libjava/classpath/gnu/java/awt/java2d/Scanline.java b/libjava/classpath/gnu/java/awt/java2d/Scanline.java
new file mode 100644
index 00000000000..24c3d34d5c3
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/Scanline.java
@@ -0,0 +1,91 @@
+/* Scanline.java -- A scanline for the scanline converter
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+/**
+ * Represents a scanline in the {@link ScanlineConverter}. This is basically
+ * a sorted list of {@link PolyEdge}s that is made for maximum reuse.
+ */
+class Scanline
+{
+
+ /**
+ * The actual edges array. The fields can be null.
+ */
+ private PolyEdge edges;
+
+ /**
+ * Clears this scanline. This only resets the number of edges to 0. The
+ * actual PolyEdge objects are preserved for possible later reuse.
+ */
+ void clear()
+ {
+ edges = null;
+ }
+
+ /**
+ * Create a new Scanline.
+ */
+ Scanline()
+ {
+ // Nothing to do.
+ }
+
+ /**
+ * Inserts an edge into this scanline. This is performed in a sorted fashion,
+ * and so that it reuses as much existing resources as possible.
+ */
+ void addEdge(PolyEdge edge)
+ {
+
+ // Allocate PolyEdge when necessary or reuse an old one.
+ edge.scanlineNext = edges;
+ edges = edge;
+ }
+
+ /**
+ * Returns the edges queue.
+ *
+ * @return the edges queue
+ */
+ PolyEdge getEdges()
+ {
+ return edges;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
new file mode 100644
index 00000000000..9f9d8921f59
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
@@ -0,0 +1,404 @@
+/* ScanlineConverter.java -- Rasterizes Shapes
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.java2d;
+
+import gnu.java.math.Fixed;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+
+/**
+ * Rasterizes {@link Shape} objects on an AbstractGraphics2D.
+ */
+final class ScanlineConverter
+{
+
+ /**
+ * The number of digits to use for fixed point arithmetics.
+ */
+ private static int FIXED_DIGITS = 6;
+
+ /**
+ * The fixed value for the number 1.
+ */
+ private static int ONE = Fixed.fixedValue(FIXED_DIGITS, 1);
+
+ /**
+ * The actual number of scanlines.
+ */
+ private int numScanlines;
+
+ /**
+ * The number of scanlines. This can contain more elements than we have
+ * scanlines. The real number of scanlines is stored in
+ * {@link #numScanlines}. This can also contain null values for empty
+ * scanlines.
+ */
+ private Scanline[] scanlines;
+
+ /**
+ * The upper bounds which correspond to the index 0 in the scanline array.
+ *
+ * This is a fixed point value.
+ */
+ private int upperBounds;
+
+ /**
+ * The resolution of the scanline converter.
+ *
+ * This is a fixed point value.
+ */
+ private int resolution;
+
+ /**
+ * One half step according to the resolution. This is stored to avoid
+ * unnecessary operations during rendering.
+ */
+ private int halfStep;
+
+ /**
+ * This is used in {@link #addShape(PathIterator, boolean)} to
+ * receive the coordinates of the path.
+ */
+ private float[] coords;
+
+ /**
+ * The active edges.
+ */
+ private ActiveEdges activeEdges;
+
+ private PolyEdge edgePool;
+ private PolyEdge edgePoolLast;
+
+ private int minY;
+ private int maxY;
+
+ /**
+ * Create a new ScanlineConverter.
+ */
+ ScanlineConverter()
+ {
+ scanlines = new Scanline[10];
+ coords = new float[6];
+ activeEdges = new ActiveEdges();
+ edgePool = new PolyEdge();
+ edgePoolLast = edgePool;
+ }
+
+ /**
+ * Renders the specified shape using the specified clip and transform.
+ *
+ * @param shape the shape to render
+ * @param clip the clip
+ * @param trans the transform
+ */
+ void renderShape(AbstractGraphics2D g, Shape shape, Shape clip,
+ AffineTransform trans, int res)
+ {
+ // Prepare resolution and upper bounds.
+ clear();
+ setResolution(res);
+
+ boolean haveClip = clip != null;
+
+ // Add shapes.
+ PathIterator path = shape.getPathIterator(trans, resolution);
+ addShape(path, false);
+ if (haveClip)
+ {
+ path= clip.getPathIterator(trans, resolution);
+ addShape(path, true);
+ }
+
+ setUpperBounds(minY);
+
+ PolyEdge edge = edgePool;
+ while (edge != edgePoolLast)
+ {
+ addEdge(edge);
+ edge = edge.poolNext;
+ }
+
+ int y = upperBounds;
+ int lastIndex = scanlineIndex(y - resolution);
+ int index;
+ activeEdges.clear();
+ // The render loop...
+ Scanline scanline = null;
+ while (y <= maxY)
+ {
+ // First we put together our list of active edges.
+ index = scanlineIndex(y);
+ // If we go outside the scanline array we still need to render the
+ // remaining edges until they end.
+ scanline = index < scanlines.length ? scanlines[index] : null;
+ if (scanline != null)
+ {
+ edge = scanline.getEdges();
+ while (edge != null)
+ {
+ activeEdges.add(edge);
+ edge = edge.scanlineNext;
+ }
+ }
+
+ // Then we intersect all active edges with the current scanline
+ // and sort them according to their intersection points.
+ activeEdges.intersectSortAndPack(FIXED_DIGITS, y + halfStep);
+
+ // Ok, now we can perform the actual scanlining.
+ boolean push = lastIndex != index;
+ doScanline(g, y, push, haveClip);
+
+ // Remove obsolete active edges.
+ //activeEdges.remove(y + halfStep);
+
+ // Go on with the next line...
+ y += resolution;
+ lastIndex = index;
+ }
+ }
+
+ /**
+ * Clears all scanlines.
+ */
+ private void clear()
+ {
+ // Reset edge pool.
+ edgePoolLast = edgePool;
+
+ // Reset scanlines.
+ for (int i = scanlines.length - 1; i >= 0 ; i--)
+ {
+ Scanline sl = scanlines[i];
+ if (sl != null)
+ sl.clear();
+ }
+
+ // Reset bounds.
+ minY = Integer.MAX_VALUE;
+ maxY = Integer.MIN_VALUE;
+ }
+
+ /**
+ * Performs the scanlining on the current set of active edges.
+ */
+ private void doScanline(AbstractGraphics2D g, int y, boolean push,
+ boolean haveClip)
+ {
+ // We begin outside the clip and outside the shape. We only draw when
+ // we are inside the clip AND inside the shape.
+ boolean inClip = ! haveClip;
+ boolean inShape = false;
+ PolyEdge lastEdge = null;
+ int numEdges = activeEdges.getNumActiveEdges();
+ for (int i = 0; i < numEdges; i++)
+ {
+ PolyEdge edge = activeEdges.getActiveEdge(i);
+ if (inClip && inShape)
+ {
+ assert lastEdge != null;
+ int x0 = lastEdge.xIntersection;
+ int x1 = edge.xIntersection;
+ assert x0 <= x1;
+ if (push)
+ {
+ if (resolution == ONE)
+ {
+ // Non-AA rendering.
+ g.fillScanline(Fixed.intValue(FIXED_DIGITS, x0),
+ Fixed.intValue(FIXED_DIGITS, x1 - resolution),
+ Fixed.intValue(FIXED_DIGITS, y));
+ }
+ else
+ {
+ // AA rendering.
+ // FIXME: Implement.
+ System.err.println("Implement AA rendering.");
+ }
+ }
+ }
+ if (edge.isClip)
+ inClip = ! inClip;
+ else
+ inShape = ! inShape;
+
+ lastEdge = edge;
+ }
+ }
+
+ /**
+ * Sets the resolution. A value of 0 rasterizes the shape normally without
+ * anti-aliasing. Greater values renders with a resolution of 2 ^ res.
+ *
+ * @param res the resolution
+ */
+ private void setResolution(int res)
+ {
+ int one = Fixed.fixedValue(FIXED_DIGITS, 1);
+ resolution = one / (1 << res);
+ halfStep = resolution / 2;
+ }
+
+ /**
+ * Sets the vertical bounds of that shape that is beeing rendered.
+ *
+ * @param y0 the upper bounds
+ */
+ private void setUpperBounds(int y0)
+ {
+ upperBounds = fit(y0);
+ }
+
+ /**
+ * Add a shape to the scanline converter.
+ *
+ * @param path
+ * @param clip
+ */
+ private void addShape(PathIterator path, boolean clip)
+ {
+ int startX = 0;
+ int startY = 0;
+ int lastX = 0;
+ int lastY = 0;
+ while (! path.isDone())
+ {
+ int type = path.currentSegment(coords);
+ switch (type)
+ {
+ case PathIterator.SEG_MOVETO:
+ startX = lastX = Fixed.fixedValue(FIXED_DIGITS, coords[0]);
+ startY = lastY = Fixed.fixedValue(FIXED_DIGITS, coords[1]);
+ minY = Math.min(startY, minY);
+ maxY = Math.max(startY, maxY);
+ break;
+ case PathIterator.SEG_LINETO:
+ int x = Fixed.fixedValue(FIXED_DIGITS, coords[0]);
+ int y = Fixed.fixedValue(FIXED_DIGITS, coords[1]);
+ edgePoolAdd(lastX, lastY, x, y, clip);
+ lastX = x;
+ lastY = y;
+ minY = Math.min(lastY, minY);
+ maxY = Math.max(lastY, maxY);
+ break;
+ case PathIterator.SEG_CLOSE:
+ edgePoolAdd(lastX, lastY, startX, startY, clip);
+ lastX = startX;
+ lastY = startY;
+ break;
+ case PathIterator.SEG_CUBICTO:
+ case PathIterator.SEG_QUADTO:
+ default:
+ assert false;
+ }
+ path.next();
+ }
+ }
+
+ /**
+ * Adds an edge into the scanline array.
+ */
+ private void addEdge(PolyEdge edge)
+ {
+ // Determine index.
+ int upper = Math.min(edge.y0, edge.y1);
+ // Fit to raster.
+ int index = scanlineIndex(upper);
+ // Grow array when necessary.
+ if (index >= scanlines.length)
+ {
+ int oldSize = scanlines.length;
+ int newSize = Math.max(oldSize + oldSize / 2 + 1, index + 10);
+ Scanline[] newScanlines = new Scanline[newSize];
+ System.arraycopy(scanlines, 0, newScanlines, 0, oldSize);
+ scanlines = newScanlines;
+ }
+
+ // Add edge.
+ if (scanlines[index] == null)
+ {
+ scanlines[index] = new Scanline();
+ }
+ scanlines[index].addEdge(edge);
+ }
+
+ /**
+ * Fits an Y coordinate to the grid.
+ *
+ * @param y the Y coordinate to fit
+ *
+ * @return the fitted Y coordinate
+ */
+ private int fit(int y)
+ {
+ int val1 = Fixed.div(FIXED_DIGITS, y, resolution);
+ int rounded = Fixed.round(FIXED_DIGITS, val1);
+ return Fixed.div(FIXED_DIGITS, rounded, resolution);
+ }
+
+ /**
+ * Calculates the scanline index for the specified y coordinate.
+ *
+ * @param y the y coordinate as fixed point value
+ *
+ * @return the scanline index
+ */
+ private int scanlineIndex(int y)
+ {
+ int fitted = fit(y);
+ // Cleverly skip the fixed point conversions here.
+ return (fitted - upperBounds)/ resolution;
+ }
+
+ private void edgePoolAdd(int x0, int y0, int x1, int y1, boolean clip)
+ {
+ // Don't need no horizontal edges.
+ if (y0 != y1)
+ {
+ edgePoolLast.init(FIXED_DIGITS, x0, y0, x1, y1, clip);
+ if (edgePoolLast.poolNext == null)
+ {
+ edgePoolLast.poolNext = new PolyEdge();
+ }
+ edgePoolLast = edgePoolLast.poolNext;
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathDesktopPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathDesktopPeer.java
new file mode 100644
index 00000000000..bef42dcea34
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/ClasspathDesktopPeer.java
@@ -0,0 +1,301 @@
+/* ClasspathDesktopPeer.java -- Offers a concrete implementation for DesktopPeer
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+package gnu.java.awt.peer;
+
+import java.awt.AWTPermission;
+import java.awt.Desktop.Action;
+import java.awt.peer.DesktopPeer;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.net.URI;
+
+import java.util.prefs.Preferences;
+
+/**
+ * Offers a common implementation for the Desktop peers, that enables
+ * access to default system application within java processes.
+ *
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class ClasspathDesktopPeer
+ implements DesktopPeer
+{
+ /** This is the fallback browser, if no desktop was detected. */
+ protected static final String _DEFAULT_BROWSER = "firefox";
+
+ /** gnu.java.awt.peer.Desktop.html.command */
+ protected static final String _BROWSE = "html";
+
+ /** gnu.java.awt.peer.Desktop.mail.command */
+ protected static final String _MAIL = "mail";
+
+ /** gnu.java.awt.peer.Desktop.edit.command */
+ protected static final String _EDIT = "edit";
+
+ /** gnu.java.awt.peer.Desktop.print.command */
+ protected static final String _PRINT = "print";
+
+ /** gnu.java.awt.peer.Desktop.open.command */
+ protected static final String _OPEN = "open";
+
+ /** */
+ protected static final KDEDesktopPeer kde = new KDEDesktopPeer();
+
+ /** */
+ protected static final GnomeDesktopPeer gnome = new GnomeDesktopPeer();
+
+ /** */
+ protected static final ClasspathDesktopPeer classpath =
+ new ClasspathDesktopPeer();
+
+ /**
+ * Preference subsystem. Packagers and users can override the default
+ * behaviour of this class via preferences and system properties.
+ */
+ protected Preferences prefs =
+ Preferences.userNodeForPackage(ClasspathDesktopPeer.class).node("Desktop");
+
+ /**
+ * @param target
+ */
+ protected ClasspathDesktopPeer()
+ {
+ /* nothing to do */
+ }
+
+ public boolean isSupported(Action action)
+ {
+ String check = null;
+
+ switch(action)
+ {
+ case BROWSE:
+ check = _BROWSE;
+ break;
+
+ case MAIL:
+ check = _MAIL;
+ break;
+
+ case EDIT:
+ check = _EDIT;
+ break;
+
+ case PRINT:
+ check = _PRINT;
+ break;
+
+ case OPEN: default:
+ check = _OPEN;
+ break;
+ }
+
+ return this.supportCommand(check);
+ }
+
+ public void browse(URI url) throws IOException
+ {
+ checkPermissions();
+
+ String browser = getCommand(_BROWSE);
+
+ if (browser == null)
+ throw new UnsupportedOperationException();
+
+ browser = browser + " " + url.toString();
+
+ Runtime.getRuntime().exec(browser);
+ }
+
+ public void edit(File file) throws IOException
+ {
+ checkPermissions(file, false);
+
+ String edit = getCommand(_EDIT);
+
+ if (edit == null)
+ throw new UnsupportedOperationException();
+
+ edit = edit + " " + file.getAbsolutePath();
+ Runtime.getRuntime().exec(edit);
+ }
+
+ public void mail(URI mailtoURL) throws IOException
+ {
+ checkPermissions();
+
+ String scheme = mailtoURL.getScheme();
+ if (scheme == null || !scheme.equalsIgnoreCase("mailto"))
+ throw new IllegalArgumentException("URI Scheme not of type mailto");
+
+ String mail = getCommand(_MAIL);
+
+ if (mail == null)
+ throw new UnsupportedOperationException();
+
+ mail = mail + " " + mailtoURL.toString();
+
+ Runtime.getRuntime().exec(mail);
+ }
+
+ public void mail() throws IOException
+ {
+ checkPermissions();
+
+ String mail = getCommand(_MAIL);
+
+ if (mail == null)
+ throw new UnsupportedOperationException();
+
+ Runtime.getRuntime().exec(mail);
+ }
+
+ public void open(File file) throws IOException
+ {
+ checkPermissions(file, true);
+
+ String open = getCommand(_OPEN);
+
+ if (open == null)
+ throw new UnsupportedOperationException();
+
+ open = open + " " + file.getAbsolutePath();
+ Runtime.getRuntime().exec(open);
+ }
+
+ public void print(File file) throws IOException
+ {
+ checkPrintPermissions(file);
+
+ String print = getCommand(_PRINT);
+
+ if (print == null)
+ throw new UnsupportedOperationException();
+
+ print = print + " " + file.getAbsolutePath();
+ Runtime.getRuntime().exec(print);
+ }
+
+ protected String getCommand(String action)
+ {
+ // check if a system property exist
+ String command =
+ System.getProperty("gnu.java.awt.peer.Desktop." + action + ".command");
+
+ // otherwise, get it from preferences, if any
+ if (command == null)
+ {
+ command = prefs.node(action).get("command", null);
+ }
+
+ return command;
+ }
+
+ /**
+ * Note: Checks for AWTPermission("showWindowWithoutWarningBanner") only.
+ */
+ protected void checkPermissions()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new AWTPermission("showWindowWithoutWarningBanner"));
+ }
+ }
+
+ /**
+ * Calls checkPermissions() and checks for SecurityManager.checkRead()
+ * and, if readOnly is false, for SecurityManager.checkWrite()
+ */
+ protected void checkPermissions(File file, boolean readOnly)
+ {
+ checkPermissions();
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkRead(file.toString());
+ if (!readOnly) sm.checkWrite(file.toString());
+ }
+ }
+
+ /**
+ * Calls checkPermissions(file, true) and checks for
+ * SecurityManager.checkPrintJobAccess()
+ */
+ protected void checkPrintPermissions(File file)
+ {
+ checkPermissions(file, true);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPrintJobAccess();
+ }
+ }
+
+ /**
+ * @param check
+ * @return
+ */
+ protected boolean supportCommand(String check)
+ {
+ return ((this.getCommand(check) != null) ? true : false);
+ }
+
+ /**
+ * @return
+ */
+ public static DesktopPeer getDesktop()
+ {
+ // check if we are under Gnome or KDE or anything else
+ String desktopSession = System.getenv("GNOME_DESKTOP_SESSION_ID");
+ if (desktopSession == null)
+ {
+ desktopSession = System.getenv("KDE_FULL_SESSION");
+ if (desktopSession != null)
+ return kde;
+ }
+ else
+ {
+ return gnome;
+ }
+
+ // revert to this class for default values
+ return classpath;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java
index 2176f34a5f1..60fde2557ac 100644
--- a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java
@@ -54,6 +54,7 @@ import java.awt.peer.FontPeer;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
@@ -120,6 +121,23 @@ public abstract class ClasspathFontPeer
*/
protected AffineTransform transform;
+ static class LRUCache<K,V> extends LinkedHashMap<K,V>
+ {
+ int max_entries;
+ public LRUCache(int max)
+ {
+ super(max, 0.75f, true);
+ max_entries = max;
+ }
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ {
+ return size() > max_entries;
+ }
+ }
+
+ private static LRUCache<AffineTransform,TransformAttribute> transCache =
+ new LRUCache<AffineTransform,TransformAttribute>(50);
+
protected static ClasspathToolkit tk()
{
return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
@@ -200,7 +218,19 @@ public abstract class ClasspathFontPeer
protected static void copyTransformToAttrs (AffineTransform trans, Map attrs)
{
if (trans != null)
- attrs.put(TextAttribute.TRANSFORM, new TransformAttribute (trans));
+ {
+ TransformAttribute ta;
+ synchronized(transCache)
+ {
+ ta = transCache.get(trans);
+ if (ta == null)
+ {
+ ta = new TransformAttribute(trans);
+ transCache.put(trans, ta);
+ }
+ }
+ attrs.put(TextAttribute.TRANSFORM, ta);
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/GnomeDesktopPeer.java b/libjava/classpath/gnu/java/awt/peer/GnomeDesktopPeer.java
new file mode 100644
index 00000000000..be216318140
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/GnomeDesktopPeer.java
@@ -0,0 +1,153 @@
+/* GnomeDesktopPeer.java -- Offers a GNOME Desktop peer for DesktopPeer
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+package gnu.java.awt.peer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+/**
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class GnomeDesktopPeer
+ extends ClasspathDesktopPeer
+{
+ /**
+ * Query string to use if a GNOME desktop is detected to get the name of the
+ * default browser. This requires gconftool-2 (part of GNOME).
+ */
+ private static final String BROWSER_QUERY_GNOME =
+ "gconftool-2 -g /desktop/gnome/url-handlers/http/command";
+
+ protected String getCommand(String action)
+ {
+ // check if a command already exists
+ String command = super.getCommand(action);
+
+ if (command == null)
+ {
+ try
+ {
+ if (action == _BROWSE)
+ {
+ command = execQuery(BROWSER_QUERY_GNOME);
+ }
+ else if (action == _PRINT)
+ {
+ command = null;
+ }
+ else
+ {
+ command = "gnome-open";
+ }
+ }
+ catch (Exception e)
+ {
+ command = null;
+ }
+ }
+
+ return command;
+ }
+
+ public void browse(URI url) throws IOException
+ {
+ checkPermissions();
+
+ String browser = getCommand(_BROWSE);
+
+ if (browser == null)
+ throw new UnsupportedOperationException();
+
+ browser = browser + " " + url.toString();
+
+ Runtime.getRuntime().exec(browser);
+ }
+
+ protected boolean supportCommand(String check)
+ {
+ if (check == _PRINT)
+ {
+ return super.supportCommand(check);
+ }
+
+ return true;
+ }
+
+ public void mail() throws IOException
+ {
+ checkPermissions();
+
+ String mail = getCommand(_MAIL);
+
+ if (mail == null)
+ throw new UnsupportedOperationException();
+
+ Runtime.getRuntime().exec(mail + " mailto:");
+ }
+
+ protected String execQuery(String command) throws IOException
+ {
+ InputStream in = null;
+ StringBuilder output = new StringBuilder();
+
+ try
+ {
+ Process process = Runtime.getRuntime().exec(command);
+
+ // Get the input stream and read from it
+ in = process.getInputStream();
+ int c;
+ while ((c = in.read()) != - 1)
+ {
+ output.append((char) c);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ in.close();
+ }
+
+ // remove %s from the string, leave only the command line
+ int index = output.indexOf("%s");
+ output.delete(index, index + 1);
+
+ return output.toString().trim();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java b/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java
new file mode 100644
index 00000000000..676bd891758
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java
@@ -0,0 +1,135 @@
+/* GnomeDesktopPeer.java -- Offers a KDE Desktop peer for DesktopPeer
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+package gnu.java.awt.peer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+/**
+ * @author Mario Torre <neugens@limasoftware.net>
+ */
+public class KDEDesktopPeer
+ extends ClasspathDesktopPeer
+{
+ /**
+ * Query string to use if a GNOME desktop is detected to get the name of the
+ * default browser. This requires gconftool-2 (part of GNOME).
+ */
+ private static final String BROWSER_QUERY_GNOME =
+ "gconftool-2 -g /desktop/gnome/url-handlers/http/command";
+
+ protected String getCommand(String action)
+ {
+ // check if a command already exists
+ String command = super.getCommand(action);
+
+ if (command == null)
+ {
+ try
+ {
+ if (action == _MAIL)
+ {
+ command = "kfmclient exec";
+ }
+ else if (action == _PRINT)
+ {
+ command = "kprinter";
+ }
+ else
+ {
+ command = "kfmclient openURL";
+ }
+ }
+ catch (Exception e)
+ {
+ command = null;
+ }
+ }
+
+ return command;
+ }
+
+ protected boolean supportCommand(String check)
+ {
+ return true;
+ }
+
+ public void mail() throws IOException
+ {
+ checkPermissions();
+
+ String mail = getCommand(_MAIL);
+
+ if (mail == null)
+ throw new UnsupportedOperationException();
+
+ Runtime.getRuntime().exec(mail + " 'mailto: '");
+ }
+
+ protected String execQuery(String command) throws IOException
+ {
+ InputStream in = null;
+ StringBuilder output = new StringBuilder();
+
+ try
+ {
+ Process process = Runtime.getRuntime().exec(command);
+
+ // Get the input stream and read from it
+ in = process.getInputStream();
+ int c;
+ while ((c = in.read()) != - 1)
+ {
+ output.append((char) c);
+ }
+ }
+ finally
+ {
+ if (in != null)
+ in.close();
+ }
+
+ // remove %s from the string, leave only the command line
+ int index = output.indexOf("%s");
+ output.delete(index, index + 1);
+
+ return output.toString().trim();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/AsyncImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/AsyncImage.java
index 5238bfe7410..dad537aa748 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/AsyncImage.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/AsyncImage.java
@@ -61,11 +61,11 @@ public class AsyncImage
private class NullImageSource
implements ImageProducer
{
- private ArrayList consumers;
+ private ArrayList<ImageConsumer> consumers;
NullImageSource()
{
- consumers = new ArrayList();
+ consumers = new ArrayList<ImageConsumer>();
}
public void addConsumer(ImageConsumer ic)
@@ -145,14 +145,14 @@ public class AsyncImage
*
* This is package private to avoid accessor methods.
*/
- HashSet observers;
+ HashSet<ImageObserver> observers;
/**
* Creates a new AsyncImage that loads from the specified URL.
*/
AsyncImage(URL url)
{
- observers = new HashSet();
+ observers = new HashSet<ImageObserver>();
Loader l = new Loader(url);
Thread t = new Thread(l);
t.start();
@@ -221,7 +221,7 @@ public class AsyncImage
{
// This field gets null when image loading is complete and we don't
// need to store any more observers.
- HashSet observs = observers;
+ HashSet<ImageObserver> observs = observers;
if (observs != null)
{
observs.add(obs);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
index c792645d3e8..31c5e641ec8 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
@@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk;
import java.awt.AlphaComposite;
import java.awt.Color;
+import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -49,7 +50,6 @@ import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
@@ -75,12 +75,6 @@ public class BufferedImageGraphics extends CairoGraphics2D
private BufferedImage image, buffer;
/**
- * Allows us to lock the image from updates (if we want to perform a few
- * intermediary operations on the cairo surface, then update it all at once)
- */
- private boolean locked;
-
- /**
* Image size.
*/
private int imageWidth, imageHeight;
@@ -93,7 +87,8 @@ public class BufferedImageGraphics extends CairoGraphics2D
/**
* Cache BufferedImageGraphics surfaces.
*/
- static WeakHashMap bufferedImages = new WeakHashMap();
+ static WeakHashMap<BufferedImage, CairoSurface> bufferedImages
+ = new WeakHashMap<BufferedImage, CairoSurface>();
/**
* Its corresponding cairo_t.
@@ -109,30 +104,30 @@ public class BufferedImageGraphics extends CairoGraphics2D
this.image = bi;
imageWidth = bi.getWidth();
imageHeight = bi.getHeight();
- locked = false;
if (!(image.getSampleModel() instanceof SinglePixelPackedSampleModel))
hasFastCM = false;
else if(bi.getColorModel().equals(CairoSurface.cairoCM_opaque))
{
- hasFastCM = true;
- hasAlpha = false;
+ hasFastCM = true;
+ hasAlpha = false;
}
- else if(bi.getColorModel().equals(CairoSurface.cairoColorModel))
+ else if(bi.getColorModel().equals(CairoSurface.cairoColorModel)
+ || bi.getColorModel().equals(CairoSurface.cairoCM_pre))
{
- hasFastCM = true;
- hasAlpha = true;
+ hasFastCM = true;
+ hasAlpha = true;
}
else
hasFastCM = false;
// Cache surfaces.
if( bufferedImages.get( bi ) != null )
- surface = (CairoSurface)bufferedImages.get( bi );
+ surface = bufferedImages.get( bi );
else
{
- surface = new CairoSurface( imageWidth, imageHeight );
- bufferedImages.put(bi, surface);
+ surface = new CairoSurface( imageWidth, imageHeight );
+ bufferedImages.put(bi, surface);
}
cairo_t = surface.newCairoContext();
@@ -148,10 +143,7 @@ public class BufferedImageGraphics extends CairoGraphics2D
int minY = image.getRaster().getSampleModelTranslateY();
// Pull pixels directly out of data buffer
- if(raster instanceof CairoSurface)
- pixels = ((CairoSurface)raster).getPixels(raster.getWidth() * raster.getHeight());
- else
- pixels = ((DataBufferInt)raster.getDataBuffer()).getData();
+ pixels = ((DataBufferInt)raster.getDataBuffer()).getData();
// Discard pixels that fall outside of the image's bounds
// (ie, this image is actually a subimage of a different image)
@@ -161,7 +153,8 @@ public class BufferedImageGraphics extends CairoGraphics2D
int scanline = sm.getScanlineStride();
for (int i = 0; i < imageHeight; i++)
- System.arraycopy(pixels, (i - minY) * scanline - minX, pixels2, i * imageWidth, imageWidth);
+ System.arraycopy(pixels, (i - minY) * scanline - minX, pixels2,
+ i * imageWidth, imageWidth);
pixels = pixels2;
}
@@ -173,11 +166,13 @@ public class BufferedImageGraphics extends CairoGraphics2D
}
else
{
- pixels = CairoGraphics2D.findSimpleIntegerArray(image.getColorModel(),image.getData());
+ pixels = CairoGraphics2D.findSimpleIntegerArray(image.getColorModel(),
+ image.getData());
+ if (pixels != null)
+ System.arraycopy(pixels, 0, surface.getData(),
+ 0, pixels.length);
}
- surface.setPixels( pixels );
-
setup( cairo_t );
setClip(0, 0, imageWidth, imageHeight);
}
@@ -189,7 +184,6 @@ public class BufferedImageGraphics extends CairoGraphics2D
cairo_t = surface.newCairoContext();
imageWidth = copyFrom.imageWidth;
imageHeight = copyFrom.imageHeight;
- locked = false;
hasFastCM = copyFrom.hasFastCM;
hasAlpha = copyFrom.hasAlpha;
@@ -202,17 +196,14 @@ public class BufferedImageGraphics extends CairoGraphics2D
*/
private void updateBufferedImage(int x, int y, int width, int height)
{
- if (locked)
- return;
-
- double[] points = new double[]{x, y, width+x, height+y};
- transform.transform(points, 0, points, 0, 2);
- x = (int)points[0];
- y = (int)points[1];
- width = (int)Math.ceil(points[2] - points[0]);
- height = (int)Math.ceil(points[3] - points[1]);
+ Rectangle bounds = new Rectangle(x, y, width, height);
+ bounds = getTransformedBounds(bounds, transform).getBounds();
+ x = bounds.x;
+ y = bounds.y;
+ width = bounds.width;
+ height = bounds.height;
- int[] pixels = surface.getPixels(imageWidth * imageHeight);
+ int[] pixels = surface.getData();
if( x > imageWidth || y > imageHeight )
return;
@@ -403,14 +394,10 @@ public class BufferedImageGraphics extends CairoGraphics2D
BufferedImage bImg = (BufferedImage) img;
// Find translated bounds
- Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY());
- Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(),
- bImg.getHeight() + bImg.getMinY());
+ Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
+ bImg.getWidth(), bImg.getHeight());
if (xform != null)
- {
- origin = xform.transform(origin, origin);
- pt = xform.transform(pt, pt);
- }
+ bounds = getTransformedBounds(bounds, xform);
// Create buffer and draw image
createBuffer();
@@ -420,10 +407,7 @@ public class BufferedImageGraphics extends CairoGraphics2D
g2d.drawImage(img, xform, obs);
// Perform compositing
- return drawComposite(new Rectangle2D.Double(origin.getX(),
- origin.getY(),
- pt.getX(), pt.getY()),
- obs);
+ return drawComposite(bounds, obs);
}
}
@@ -438,6 +422,11 @@ public class BufferedImageGraphics extends CairoGraphics2D
if (comp == null || comp instanceof AlphaComposite)
{
super.drawGlyphVector(gv, x, y);
+
+ // this returns an integer-based Rectangle (rather than a
+ // Rectangle2D), which takes care of any necessary rounding for us.
+ bounds = bounds.getBounds();
+
updateBufferedImage((int)bounds.getX(), (int)bounds.getY(),
(int)bounds.getWidth(), (int)bounds.getHeight());
}
@@ -468,12 +457,7 @@ public class BufferedImageGraphics extends CairoGraphics2D
private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
{
// Find bounds in device space
- double[] points = new double[] {bounds.getX(), bounds.getY(),
- bounds.getMaxX(), bounds.getMaxY()};
- transform.transform(points, 0, points, 0, 2);
- bounds = new Rectangle2D.Double(points[0], points[1],
- (points[2] - points[0]),
- (points[3] - points[1]));
+ bounds = getTransformedBounds(bounds, transform);
// Clip bounds by the stored clip, and by the internal buffer
Rectangle2D devClip = this.getClipInDevSpace();
@@ -482,17 +466,15 @@ public class BufferedImageGraphics extends CairoGraphics2D
buffer.getWidth(), buffer.getHeight());
Rectangle2D.intersect(bounds, devClip, bounds);
- // Round bounds as needed, but be conservative in our rounding
+ // Round bounds as needed, but be careful in our rounding
// (otherwise it may leave unpainted stripes)
double x = bounds.getX();
double y = bounds.getY();
- double w = bounds.getWidth();
- double h = bounds.getHeight();
- if (Math.floor(x) != x)
- w--;
- if (Math.floor(y) != y)
- h--;
- bounds.setRect(Math.ceil(x), Math.ceil(y), Math.floor(w), Math.floor(h));
+ double maxX = x + bounds.getWidth();
+ double maxY = y + bounds.getHeight();
+ x = Math.round(x);
+ y = Math.round(y);
+ bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));
// Find subimage of internal buffer for updating
BufferedImage buffer2 = buffer;
@@ -511,9 +493,10 @@ public class BufferedImageGraphics extends CairoGraphics2D
compCtx.compose(buffer2.getRaster(), current.getRaster(),
current.getRaster());
- // Prevent the clearRect in CairoGraphics2D.drawImage from clearing
- // our composited image
- locked = true;
+ // Set cairo's composite to direct SRC, since we've already done our own
+ // compositing
+ Composite oldcomp = comp;
+ setComposite(AlphaComposite.Src);
// This MUST call directly into the "action" method in CairoGraphics2D,
// not one of the wrappers, to ensure that the composite isn't processed
@@ -521,8 +504,9 @@ public class BufferedImageGraphics extends CairoGraphics2D
boolean rv = super.drawImage(current,
AffineTransform.getTranslateInstance(bounds.getX(),
bounds.getY()),
- new Color(0,0,0,0), null);
- locked = false;
+ null, null);
+ setComposite(oldcomp);
+ updateColor();
return rv;
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
index 4a6ad008259..3a386075a69 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java
@@ -172,6 +172,12 @@ public abstract class CairoGraphics2D extends Graphics2D
* Rendering hint map.
*/
private RenderingHints hints;
+
+ /**
+ * Status of the anti-alias flag in cairo.
+ */
+ private boolean antialias = false;
+ private boolean ignoreAA = false;
/**
* Some operations (drawing rather than filling) require that their
@@ -228,6 +234,7 @@ public abstract class CairoGraphics2D extends Graphics2D
setPaint(Color.black);
setStroke(new BasicStroke());
setTransform(new AffineTransform());
+ cairoSetAntialias(nativePointer, antialias);
}
/**
@@ -244,7 +251,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (g.fg.getAlpha() != -1)
foreground = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(),
- g.fg.getAlpha());
+ g.fg.getAlpha());
else
foreground = new Color(g.fg.getRGB());
@@ -274,6 +281,9 @@ public abstract class CairoGraphics2D extends Graphics2D
setTransformImpl(transform);
setClip(clip);
setComposite(comp);
+
+ antialias = !g.antialias;
+ setAntialias(g.antialias);
}
/**
@@ -311,8 +321,8 @@ public abstract class CairoGraphics2D extends Graphics2D
public abstract GraphicsConfiguration getDeviceConfiguration();
- protected abstract void copyAreaImpl(int x, int y,
- int width, int height, int dx, int dy);
+ protected abstract void copyAreaImpl(int x, int y, int width, int height,
+ int dx, int dy);
/**
@@ -345,8 +355,8 @@ public abstract class CairoGraphics2D extends Graphics2D
int g2, int b2, int a2, boolean cyclic);
protected native void setPaintPixels(long pointer, int[] pixels, int w,
- int h, int stride, boolean repeat,
- int x, int y);
+ int h, int stride, boolean repeat,
+ int x, int y);
/**
* Set the current transform matrix
@@ -390,9 +400,9 @@ public abstract class CairoGraphics2D extends Graphics2D
/*
* Draws a Glyph Vector
*/
- native void cairoDrawGlyphVector(long pointer, GdkFontPeer font,
+ protected native void cairoDrawGlyphVector(long pointer, GdkFontPeer font,
float x, float y, int n,
- int[] codes, float[] positions);
+ int[] codes, float[] positions, long[] fontset);
/**
* Set the font in cairo.
@@ -454,9 +464,15 @@ public abstract class CairoGraphics2D extends Graphics2D
protected native void cairoClip(long pointer);
/**
- * Save clip
+ * Clear clip
*/
protected native void cairoResetClip(long pointer);
+
+ /**
+ * Set antialias.
+ */
+ protected native void cairoSetAntialias(long pointer, boolean aa);
+
///////////////////////// TRANSFORMS ///////////////////////////////////
/**
@@ -648,33 +664,35 @@ public abstract class CairoGraphics2D extends Graphics2D
setColor((Color) paint);
customPaint = false;
}
+
else if (paint instanceof TexturePaint)
{
- TexturePaint tp = (TexturePaint) paint;
- BufferedImage img = tp.getImage();
+ TexturePaint tp = (TexturePaint) paint;
+ BufferedImage img = tp.getImage();
- // map the image to the anchor rectangle
- int width = (int) tp.getAnchorRect().getWidth();
- int height = (int) tp.getAnchorRect().getHeight();
+ // map the image to the anchor rectangle
+ int width = (int) tp.getAnchorRect().getWidth();
+ int height = (int) tp.getAnchorRect().getHeight();
- double scaleX = width / (double) img.getWidth();
- double scaleY = height / (double) img.getHeight();
+ double scaleX = width / (double) img.getWidth();
+ double scaleY = height / (double) img.getHeight();
- AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
- AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
- BufferedImage texture = op.filter(img, null);
- int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
- setPaintPixels(nativePointer, pixels, width, height, width, true, 0, 0);
+ AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
+ AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
+ BufferedImage texture = op.filter(img, null);
+ int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
+ setPaintPixels(nativePointer, pixels, width, height, width, true, 0, 0);
customPaint = false;
}
+
else if (paint instanceof GradientPaint)
{
- GradientPaint gp = (GradientPaint) paint;
- Point2D p1 = gp.getPoint1();
- Point2D p2 = gp.getPoint2();
- Color c1 = gp.getColor1();
- Color c2 = gp.getColor2();
- setGradient(nativePointer, p1.getX(), p1.getY(), p2.getX(), p2.getY(),
+ GradientPaint gp = (GradientPaint) paint;
+ Point2D p1 = gp.getPoint1();
+ Point2D p2 = gp.getPoint2();
+ Color c1 = gp.getColor1();
+ Color c2 = gp.getColor2();
+ setGradient(nativePointer, p1.getX(), p1.getY(), p2.getX(), p2.getY(),
c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha(),
c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha(),
gp.isCyclic());
@@ -703,15 +721,11 @@ public abstract class CairoGraphics2D extends Graphics2D
int userHeight = bounds.height;
// Find bounds in device space
- Point2D origin = transform.transform(new Point2D.Double(userX, userY),
- null);
- Point2D extreme = transform.transform(new Point2D.Double(userWidth + userX,
- userHeight + userY),
- null);
- int deviceX = (int)origin.getX();
- int deviceY = (int)origin.getY();
- int deviceWidth = (int)Math.ceil(extreme.getX() - origin.getX());
- int deviceHeight = (int)Math.ceil(extreme.getY() - origin.getY());
+ Rectangle2D bounds2D = getTransformedBounds(bounds, transform);
+ int deviceX = (int)bounds2D.getX();
+ int deviceY = (int)bounds2D.getY();
+ int deviceWidth = (int)Math.ceil(bounds2D.getWidth());
+ int deviceHeight = (int)Math.ceil(bounds2D.getHeight());
// Get raster of the paint background
PaintContext pc = paint.createContext(CairoSurface.cairoColorModel,
@@ -792,21 +806,22 @@ public abstract class CairoGraphics2D extends Graphics2D
stroke = st;
if (stroke instanceof BasicStroke)
{
- BasicStroke bs = (BasicStroke) stroke;
- cairoSetLine(nativePointer, bs.getLineWidth(), bs.getEndCap(),
- bs.getLineJoin(), bs.getMiterLimit());
-
- float[] dashes = bs.getDashArray();
- if (dashes != null)
- {
- double[] double_dashes = new double[dashes.length];
- for (int i = 0; i < dashes.length; i++)
- double_dashes[i] = dashes[i];
- cairoSetDash(nativePointer, double_dashes, double_dashes.length,
- (double) bs.getDashPhase());
- }
- else
- cairoSetDash(nativePointer, new double[0], 0, 0.0);
+ BasicStroke bs = (BasicStroke) stroke;
+ cairoSetLine(nativePointer, bs.getLineWidth(), bs.getEndCap(),
+ bs.getLineJoin(), bs.getMiterLimit());
+
+ float[] dashes = bs.getDashArray();
+ if (dashes != null)
+ {
+ double[] double_dashes = new double[dashes.length];
+ for (int i = 0; i < dashes.length; i++)
+ double_dashes[i] = dashes[i];
+
+ cairoSetDash(nativePointer, double_dashes, double_dashes.length,
+ (double) bs.getDashPhase());
+ }
+ else
+ cairoSetDash(nativePointer, new double[0], 0, 0.0);
}
}
@@ -864,6 +879,7 @@ public abstract class CairoGraphics2D extends Graphics2D
{
if (fg == null)
fg = Color.BLACK;
+
cairoSetRGBAColor(nativePointer, fg.getRed() / 255.0,
fg.getGreen() / 255.0,fg.getBlue() / 255.0,
fg.getAlpha() / 255.0);
@@ -916,18 +932,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (transform == null)
return uclip;
else
- {
- Point2D pos = transform.transform(new Point2D.Double(uclip.getX(),
- uclip.getY()),
- (Point2D) null);
- Point2D extent = transform.deltaTransform(new Point2D.Double(uclip
- .getWidth(),
- uclip
- .getHeight()),
- (Point2D) null);
- return new Rectangle2D.Double(pos.getX(), pos.getY(), extent.getX(),
- extent.getY());
- }
+ return getTransformedBounds(clip.getBounds2D(), transform);
}
public void setClip(int x, int y, int width, int height)
@@ -946,8 +951,8 @@ public abstract class CairoGraphics2D extends Graphics2D
// initial clip properly.
if( firstClip )
{
- originalClip = s;
- firstClip = false;
+ originalClip = s;
+ firstClip = false;
}
clip = s;
@@ -1007,7 +1012,7 @@ public abstract class CairoGraphics2D extends Graphics2D
if (comp instanceof AlphaComposite)
{
- AlphaComposite a = (AlphaComposite) comp;
+ AlphaComposite a = (AlphaComposite) comp;
cairoSetOperator(nativePointer, a.getRule());
}
@@ -1066,7 +1071,9 @@ public abstract class CairoGraphics2D extends Graphics2D
Rectangle r = findStrokedBounds(s);
setCustomPaint(r);
}
-
+
+ setAntialias(!hints.get(RenderingHints.KEY_ANTIALIASING)
+ .equals(RenderingHints.VALUE_ANTIALIAS_OFF));
createPath(s, true);
cairoStroke(nativePointer);
}
@@ -1077,7 +1084,9 @@ public abstract class CairoGraphics2D extends Graphics2D
if (customPaint)
setCustomPaint(s.getBounds());
-
+
+ setAntialias(!hints.get(RenderingHints.KEY_ANTIALIASING)
+ .equals(RenderingHints.VALUE_ANTIALIAS_OFF));
double alpha = 1.0;
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
@@ -1263,13 +1272,15 @@ public abstract class CairoGraphics2D extends Graphics2D
public void copyArea(int ox, int oy, int owidth, int oheight,
int odx, int ody)
{
+ // FIXME: does this handle a rotation transform properly?
+ // (the width/height might not be correct)
Point2D pos = transform.transform(new Point2D.Double(ox, oy),
- (Point2D) null);
+ (Point2D) null);
Point2D dim = transform.transform(new Point2D.Double(ox + owidth,
- oy + oheight),
- (Point2D) null);
+ oy + oheight),
+ (Point2D) null);
Point2D p2 = transform.transform(new Point2D.Double(ox + odx, oy + ody),
- (Point2D) null);
+ (Point2D) null);
int x = (int)pos.getX();
int y = (int)pos.getY();
int width = (int)(dim.getX() - pos.getX());
@@ -1291,14 +1302,14 @@ public abstract class CairoGraphics2D extends Graphics2D
// Clip edges if necessary
if( x + dx < r.getX() ) // left
{
- width = x + dx + width;
- x = (int)r.getX() - dx;
+ width = x + dx + width;
+ x = (int)r.getX() - dx;
}
if( y + dy < r.getY() ) // top
{
- height = y + dy + height;
- y = (int)r.getY() - dy;
+ height = y + dy + height;
+ y = (int)r.getY() - dy;
}
if( x + dx + width >= r.getWidth() ) // right
@@ -1325,10 +1336,10 @@ public abstract class CairoGraphics2D extends Graphics2D
return hints.get(hintKey);
}
- public void setRenderingHints(Map hints)
+ public void setRenderingHints(Map<?,?> hints)
{
this.hints = new RenderingHints(getDefaultHints());
- this.hints.add(new RenderingHints(hints));
+ this.hints.putAll(hints);
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
|| hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
@@ -1342,7 +1353,7 @@ public abstract class CairoGraphics2D extends Graphics2D
public void addRenderingHints(Map hints)
{
- this.hints.add(new RenderingHints(hints));
+ this.hints.putAll(hints);
}
public RenderingHints getRenderingHints()
@@ -1373,6 +1384,24 @@ public abstract class CairoGraphics2D extends Graphics2D
// Do bilinear interpolation as default
return INTERPOLATION_BILINEAR;
}
+
+ /**
+ * Set antialias if needed. If the ignoreAA flag is set, this method will
+ * return without doing anything.
+ *
+ * @param needAA RenderingHints.VALUE_ANTIALIAS_ON or RenderingHints.VALUE_ANTIALIAS_OFF
+ */
+ private void setAntialias(boolean needAA)
+ {
+ if (ignoreAA)
+ return;
+
+ if (needAA != antialias)
+ {
+ antialias = !antialias;
+ cairoSetAntialias(nativePointer, antialias);
+ }
+ }
///////////////////////// IMAGE. METHODS ///////////////////////////////////
@@ -1396,12 +1425,12 @@ public abstract class CairoGraphics2D extends Graphics2D
try
{
- invertedXform = xform.createInverse();
+ invertedXform = xform.createInverse();
}
catch (NoninvertibleTransformException e)
{
- throw new ImagingOpException("Unable to invert transform "
- + xform.toString());
+ throw new ImagingOpException("Unable to invert transform "
+ + xform.toString());
}
// Unrecognized image - convert to a BufferedImage
@@ -1411,10 +1440,10 @@ public abstract class CairoGraphics2D extends Graphics2D
img = AsyncImage.realImage(img, obs);
if( !(img instanceof BufferedImage) )
{
- ImageProducer source = img.getSource();
- if (source == null)
- return false;
- img = Toolkit.getDefaultToolkit().createImage(source);
+ ImageProducer source = img.getSource();
+ if (source == null)
+ return false;
+ img = Toolkit.getDefaultToolkit().createImage(source);
}
BufferedImage b = (BufferedImage) img;
@@ -1427,7 +1456,7 @@ public abstract class CairoGraphics2D extends Graphics2D
// use the cached CairoSurface that BIG is drawing onto
if( BufferedImageGraphics.bufferedImages.get( b ) != null )
- raster = (Raster)BufferedImageGraphics.bufferedImages.get( b );
+ raster = BufferedImageGraphics.bufferedImages.get( b );
else
raster = b.getRaster();
@@ -1437,12 +1466,12 @@ public abstract class CairoGraphics2D extends Graphics2D
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
- if(raster instanceof CairoSurface)
+ if(raster instanceof CairoSurface
+ && ((CairoSurface)raster).sharedBuffer == true)
{
- ((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha,
- getInterpolation());
+ drawCairoSurface((CairoSurface)raster, xform, alpha, getInterpolation());
updateColor();
- return true;
+ return true;
}
if( bgcolor != null )
@@ -1450,24 +1479,31 @@ public abstract class CairoGraphics2D extends Graphics2D
Color oldColor = bg;
setBackground(bgcolor);
- double[] origin = new double[] {0,0};
- double[] dimensions = new double[] {width, height};
- xform.transform(origin, 0, origin, 0, 1);
- xform.deltaTransform(dimensions, 0, dimensions, 0, 1);
- clearRect((int)origin[0], (int)origin[1],
- (int)dimensions[0], (int)dimensions[1]);
+ Rectangle2D bounds = new Rectangle2D.Double(0, 0, width, height);
+ bounds = getTransformedBounds(bounds, xform);
+
+ clearRect((int)bounds.getX(), (int)bounds.getY(),
+ (int)bounds.getWidth(), (int)bounds.getHeight());
setBackground(oldColor);
}
int[] pixels = b.getRGB(0, 0, width, height, null, 0, width);
-
// FIXME: The above method returns data in the standard ARGB colorspace,
// meaning data should NOT be alpha pre-multiplied; however Cairo expects
// data to be premultiplied.
+
+ cairoSave(nativePointer);
+ Rectangle2D bounds = new Rectangle2D.Double(0, 0, width, height);
+ bounds = getTransformedBounds(bounds, xform);
+ cairoRectangle(nativePointer, bounds.getX(), bounds.getY(),
+ bounds.getWidth(), bounds.getHeight());
+ cairoClip(nativePointer);
drawPixels(nativePointer, pixels, width, height, width, i2u, alpha,
getInterpolation());
+
+ cairoRestore(nativePointer);
// Cairo seems to lose the current color which must be restored.
updateColor();
@@ -1578,6 +1614,66 @@ public abstract class CairoGraphics2D extends Graphics2D
{
return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer);
}
+
+ /**
+ * Optimized method for drawing a CairoSurface onto this graphics context.
+ *
+ * @param surface The surface to draw.
+ * @param tx The transformation matrix (cannot be null).
+ * @param alpha The alpha value to paint with ( 0 <= alpha <= 1).
+ * @param interpolation The interpolation type.
+ */
+ protected void drawCairoSurface(CairoSurface surface, AffineTransform tx,
+ double alpha, int interpolation)
+ {
+ // Find offset required if this surface is a sub-raster, and append offset
+ // to transformation.
+ if (surface.getSampleModelTranslateX() != 0
+ || surface.getSampleModelTranslateY() != 0)
+ {
+ Point2D origin = new Point2D.Double(0, 0);
+ Point2D offset = new Point2D.Double(surface.getSampleModelTranslateX(),
+ surface.getSampleModelTranslateY());
+
+ tx.transform(origin, origin);
+ tx.transform(offset, offset);
+
+ tx.translate(offset.getX() - origin.getX(),
+ offset.getY() - origin.getY());
+ }
+
+ // Find dimensions of this surface relative to the root parent surface
+ Rectangle bounds = new Rectangle(-surface.getSampleModelTranslateX(),
+ -surface.getSampleModelTranslateY(),
+ surface.width, surface.height);
+
+ // Clip to the translated image
+ // We use direct cairo methods to avoid the overhead of maintaining a
+ // java copy of the clip, since we will be reverting it immediately
+ // after drawing
+ Shape newBounds = tx.createTransformedShape(bounds);
+ cairoSave(nativePointer);
+ walkPath(newBounds.getPathIterator(null), false);
+ cairoClip(nativePointer);
+
+ // Draw the surface
+ try
+ {
+ double[] i2u = new double[6];
+ tx.createInverse().getMatrix(i2u);
+ surface.nativeDrawSurface(surface.surfacePointer, nativePointer, i2u,
+ alpha, interpolation);
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // This should never happen(?), so we don't need to do anything here.
+ ;
+ }
+
+ // Restore clip
+ cairoRestore(nativePointer);
+ }
+
///////////////////////// TEXT METHODS ////////////////////////////////////
@@ -1592,7 +1688,15 @@ public abstract class CairoGraphics2D extends Graphics2D
tl = new TextLayout( str, getFont(), getFontRenderContext() );
fontPeer.textLayoutCache.put(str, tl);
}
+
+ // Set antialias to text_antialiasing, and set the ignoreAA flag so that
+ // the setting doesn't get overridden in a draw() or fill() call.
+ setAntialias(!hints.get(RenderingHints.KEY_TEXT_ANTIALIASING)
+ .equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
+ ignoreAA = true;
+
tl.draw(this, x, y);
+ ignoreAA = false;
}
public void drawString(String str, int x, int y)
@@ -1617,19 +1721,25 @@ public abstract class CairoGraphics2D extends Graphics2D
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
+
+ setAntialias(!hints.get(RenderingHints.KEY_TEXT_ANTIALIASING)
+ .equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
+ ignoreAA = true;
+
if (gv instanceof FreetypeGlyphVector && alpha == 1.0)
{
int n = gv.getNumGlyphs ();
int[] codes = gv.getGlyphCodes (0, n, null);
+ long[] fontset = ((FreetypeGlyphVector)gv).getGlyphFonts (0, n, null);
float[] positions = gv.getGlyphPositions (0, n, null);
setFont (gv.getFont ());
GdkFontPeer fontPeer = (GdkFontPeer) font.getPeer();
- synchronized (fontPeer)
- {
- cairoDrawGlyphVector(nativePointer, fontPeer,
- x, y, n, codes, positions);
- }
+ synchronized (fontPeer)
+ {
+ cairoDrawGlyphVector(nativePointer, fontPeer,
+ x, y, n, codes, positions, fontset);
+ }
}
else
{
@@ -1637,6 +1747,8 @@ public abstract class CairoGraphics2D extends Graphics2D
fill(gv.getOutline());
translate(-x, -y);
}
+
+ ignoreAA = false;
}
public void drawString(AttributedCharacterIterator ci, float x, float y)
@@ -1702,9 +1814,9 @@ public abstract class CairoGraphics2D extends Graphics2D
{
if( onStroke )
{
- Shape stroked = stroke.createStrokedShape( s );
- return stroked.intersects( (double)rect.x, (double)rect.y,
- (double)rect.width, (double)rect.height );
+ Shape stroked = stroke.createStrokedShape( s );
+ return stroked.intersects( (double)rect.x, (double)rect.y,
+ (double)rect.width, (double)rect.height );
}
return s.intersects( (double)rect.x, (double)rect.y,
(double)rect.width, (double)rect.height );
@@ -1747,34 +1859,34 @@ public abstract class CairoGraphics2D extends Graphics2D
imageToUser.getMatrix(i2u);
else
{
- i2u[0] = 1;
- i2u[1] = 0;
- i2u[2] = 0;
- i2u[3] = 1;
- i2u[4] = 0;
- i2u[5] = 0;
+ i2u[0] = 1;
+ i2u[1] = 0;
+ i2u[2] = 0;
+ i2u[3] = 1;
+ i2u[4] = 0;
+ i2u[5] = 0;
}
int[] pixels = findSimpleIntegerArray(cm, r);
if (pixels == null)
{
- // FIXME: I don't think this code will work correctly with a non-RGB
- // MultiPixelPackedSampleModel. Although this entire method should
- // probably be rewritten to better utilize Cairo's different supported
- // data formats.
- if (sm instanceof MultiPixelPackedSampleModel)
- {
- pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
- for (int i = 0; i < pixels.length; i++)
- pixels[i] = cm.getRGB(pixels[i]);
- }
- else
- {
- pixels = new int[r.getWidth() * r.getHeight()];
- for (int i = 0; i < pixels.length; i++)
- pixels[i] = cm.getRGB(db.getElem(i));
- }
+ // FIXME: I don't think this code will work correctly with a non-RGB
+ // MultiPixelPackedSampleModel. Although this entire method should
+ // probably be rewritten to better utilize Cairo's different supported
+ // data formats.
+ if (sm instanceof MultiPixelPackedSampleModel)
+ {
+ pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(pixels[i]);
+ }
+ else
+ {
+ pixels = new int[r.getWidth() * r.getHeight()];
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(db.getElem(i));
+ }
}
// Change all transparent pixels in the image to the specified bgcolor,
@@ -1782,20 +1894,21 @@ public abstract class CairoGraphics2D extends Graphics2D
// correctly.
if (cm.hasAlpha())
{
- if (bgcolor != null && cm.hasAlpha())
- for (int i = 0; i < pixels.length; i++)
- {
- if (cm.getAlpha(pixels[i]) == 0)
- pixels[i] = bgcolor.getRGB();
- }
+ if (bgcolor != null && cm.hasAlpha())
+ for (int i = 0; i < pixels.length; i++)
+ {
+ if (cm.getAlpha(pixels[i]) == 0)
+ pixels[i] = bgcolor.getRGB();
+ }
}
else
for (int i = 0; i < pixels.length; i++)
- pixels[i] |= 0xFF000000;
+ pixels[i] |= 0xFF000000;
double alpha = 1.0;
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
+
drawPixels(nativePointer, pixels, r.getWidth(), r.getHeight(),
r.getWidth(), i2u, alpha, getInterpolation());
@@ -1815,7 +1928,7 @@ public abstract class CairoGraphics2D extends Graphics2D
double shift = 0.5;
if (!transform.isIdentity())
shift /= transform.getScaleX();
- return Math.round(coord) + shift;
+ return (coord + shift);
}
else
return coord;
@@ -1831,7 +1944,7 @@ public abstract class CairoGraphics2D extends Graphics2D
double shift = 0.5;
if (!transform.isIdentity())
shift /= transform.getScaleY();
- return Math.round(coord) + shift;
+ return (coord + shift);
}
else
return coord;
@@ -1849,53 +1962,54 @@ public abstract class CairoGraphics2D extends Graphics2D
cairoSetFillRule(nativePointer, p.getWindingRule());
for (; ! p.isDone(); p.next())
{
- int seg = p.currentSegment(coords);
- switch (seg)
- {
- case PathIterator.SEG_MOVETO:
- x = shiftX(coords[0], doShift);
- y = shiftY(coords[1], doShift);
- cairoMoveTo(nativePointer, x, y);
- break;
- case PathIterator.SEG_LINETO:
- x = shiftX(coords[0], doShift);
- y = shiftY(coords[1], doShift);
- cairoLineTo(nativePointer, x, y);
- break;
- case PathIterator.SEG_QUADTO:
- // splitting a quadratic bezier into a cubic:
- // see: http://pfaedit.sourceforge.net/bezier.html
- double x1 = x + (2.0 / 3.0) * (shiftX(coords[0], doShift) - x);
- double y1 = y + (2.0 / 3.0) * (shiftY(coords[1], doShift) - y);
-
- double x2 = x1 + (1.0 / 3.0) * (shiftX(coords[2], doShift) - x);
- double y2 = y1 + (1.0 / 3.0) * (shiftY(coords[3], doShift) - y);
-
- x = shiftX(coords[2], doShift);
- y = shiftY(coords[3], doShift);
- cairoCurveTo(nativePointer, x1, y1, x2, y2, x, y);
- break;
- case PathIterator.SEG_CUBICTO:
- x = shiftX(coords[4], doShift);
- y = shiftY(coords[5], doShift);
- cairoCurveTo(nativePointer, shiftX(coords[0], doShift),
- shiftY(coords[1], doShift),
- shiftX(coords[2], doShift),
- shiftY(coords[3], doShift), x, y);
- break;
- case PathIterator.SEG_CLOSE:
- cairoClosePath(nativePointer);
- break;
- }
+ int seg = p.currentSegment(coords);
+ switch (seg)
+ {
+ case PathIterator.SEG_MOVETO:
+ x = shiftX(coords[0], doShift);
+ y = shiftY(coords[1], doShift);
+ cairoMoveTo(nativePointer, x, y);
+ break;
+ case PathIterator.SEG_LINETO:
+ x = shiftX(coords[0], doShift);
+ y = shiftY(coords[1], doShift);
+ cairoLineTo(nativePointer, x, y);
+ break;
+ case PathIterator.SEG_QUADTO:
+ // splitting a quadratic bezier into a cubic:
+ // see: http://pfaedit.sourceforge.net/bezier.html
+ double x1 = x + (2.0 / 3.0) * (shiftX(coords[0], doShift) - x);
+ double y1 = y + (2.0 / 3.0) * (shiftY(coords[1], doShift) - y);
+
+ double x2 = x1 + (1.0 / 3.0) * (shiftX(coords[2], doShift) - x);
+ double y2 = y1 + (1.0 / 3.0) * (shiftY(coords[3], doShift) - y);
+
+ x = shiftX(coords[2], doShift);
+ y = shiftY(coords[3], doShift);
+ cairoCurveTo(nativePointer, x1, y1, x2, y2, x, y);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ x = shiftX(coords[4], doShift);
+ y = shiftY(coords[5], doShift);
+ cairoCurveTo(nativePointer, shiftX(coords[0], doShift),
+ shiftY(coords[1], doShift),
+ shiftX(coords[2], doShift),
+ shiftY(coords[3], doShift), x, y);
+ break;
+ case PathIterator.SEG_CLOSE:
+ cairoClosePath(nativePointer);
+ break;
+ }
}
}
/**
* Used by setRenderingHints()
*/
- private Map getDefaultHints()
+ private Map<RenderingHints.Key, Object> getDefaultHints()
{
- HashMap defaultHints = new HashMap();
+ HashMap<RenderingHints.Key, Object> defaultHints =
+ new HashMap<RenderingHints.Key, Object>();
defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
@@ -1972,11 +2086,27 @@ public abstract class CairoGraphics2D extends Graphics2D
if (clip == null)
return;
- if (! (clip instanceof GeneralPath))
- clip = new GeneralPath(clip);
-
- GeneralPath p = (GeneralPath) clip;
- p.transform(t);
+ // If the clip is a rectangle, and the transformation preserves the shape
+ // (translate/stretch only), then keep the clip as a rectangle
+ double[] matrix = new double[4];
+ t.getMatrix(matrix);
+ if (clip instanceof Rectangle2D && matrix[1] == 0 && matrix[2] == 0)
+ {
+ Rectangle2D rect = (Rectangle2D)clip;
+ double[] origin = new double[] {rect.getX(), rect.getY()};
+ double[] dimensions = new double[] {rect.getWidth(), rect.getHeight()};
+ t.transform(origin, 0, origin, 0, 1);
+ t.deltaTransform(dimensions, 0, dimensions, 0, 1);
+ rect.setRect(origin[0], origin[1], dimensions[0], dimensions[1]);
+ }
+ else
+ {
+ if (! (clip instanceof GeneralPath))
+ clip = new GeneralPath(clip);
+
+ GeneralPath p = (GeneralPath) clip;
+ p.transform(t);
+ }
}
private static Rectangle computeIntersection(int x, int y, int w, int h,
@@ -1999,4 +2129,39 @@ public abstract class CairoGraphics2D extends Graphics2D
return rect;
}
+
+ static Rectangle2D getTransformedBounds(Rectangle2D bounds, AffineTransform tx)
+ {
+ double x1 = bounds.getX();
+ double x2 = bounds.getX() + bounds.getWidth();
+ double x3 = x1;
+ double x4 = x2;
+ double y1 = bounds.getY();
+ double y2 = y1;
+ double y3 = bounds.getY() + bounds.getHeight();
+ double y4 = y3;
+
+ double[] points = new double[] {x1, y1, x2, y2, x3, y3, x4, y4};
+ tx.transform(points, 0, points, 0, 4);
+
+ double minX = points[0];
+ double maxX = minX;
+ double minY = points[1];
+ double maxY = minY;
+ for (int i = 0; i < 8; i++)
+ {
+ if (points[i] < minX)
+ minX = points[i];
+ if (points[i] > maxX)
+ maxX = points[i];
+ i++;
+
+ if (points[i] < minY)
+ minY = points[i];
+ if (points[i] > maxY)
+ maxY = points[i];
+ }
+
+ return new Rectangle2D.Double(minX, minY, (maxX - minX), (maxY - minY));
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
index 5b63e62e7ed..b45a79fd6e7 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java
@@ -1,5 +1,5 @@
/* CairoSurface.java
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,15 +42,22 @@ import gnu.java.awt.Buffers;
import java.awt.Graphics2D;
import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RasterFormatException;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
import java.nio.ByteOrder;
+import java.util.Arrays;
import java.util.Hashtable;
/**
@@ -68,9 +75,9 @@ public class CairoSurface extends WritableRaster
long surfacePointer;
/**
- * The native pointer to the image's data buffer
+ * Whether the data buffer is shared between java and cairo.
*/
- long bufferPointer;
+ boolean sharedBuffer;
// FIXME: use only the cairoCM_pre colormodel
// since that's what Cairo really uses (is there a way to do this cheaply?
@@ -98,22 +105,12 @@ public class CairoSurface extends WritableRaster
* @param width, height - the image size
* @param stride - the buffer row stride. (in ints)
*/
- private native void create(int width, int height, int stride);
+ private native void create(int width, int height, int stride, int[] buf);
/**
* Destroys the cairo surface and frees the buffer.
*/
- private native void destroy(long surfacePointer, long bufferPointer);
-
- /**
- * Gets buffer elements
- */
- private native int nativeGetElem(long bufferPointer, int i);
-
- /**
- * Sets buffer elements.
- */
- private native void nativeSetElem(long bufferPointer, int i, int val);
+ private native void destroy(long surfacePointer, int[] buf);
/**
* Draws this image to a given CairoGraphics context,
@@ -123,33 +120,30 @@ public class CairoSurface extends WritableRaster
double[] i2u, double alpha,
int interpolation);
- public void drawSurface(long contextPointer, double[] i2u, double alpha,
- int interpolation)
- {
- nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha, interpolation);
- }
-
/**
- * getPixels -return the pixels as a java array.
+ * Synchronizes the image's data buffers, copying any changes made in the
+ * Java array into the native array.
+ *
+ * This method should only be called if (sharedBuffers == false).
*/
- native int[] nativeGetPixels(long bufferPointer, int size);
-
- public int[] getPixels(int size)
- {
- return nativeGetPixels(bufferPointer, size);
- }
-
+ native void syncNativeToJava(long surfacePointer, int[] buffer);
+
/**
- * getPixels -return the pixels as a java array.
+ * Synchronizes the image's data buffers, copying any changes made in the
+ * native array into the Java array.
+ *
+ * This method should only be called if (sharedBuffers == false).
*/
- native void nativeSetPixels(long bufferPointer, int[] pixels);
-
- public void setPixels(int[] pixels)
- {
- nativeSetPixels(bufferPointer, pixels);
- }
-
- native long getFlippedBuffer(long bufferPointer, int size);
+ native void syncJavaToNative(long surfacePointer, int[] buffer);
+
+ /**
+ * Return the buffer, with the sample values of each pixel reversed
+ * (ie, in ABGR instead of ARGB).
+ *
+ * @return A pointer to a flipped buffer. The memory is allocated in native
+ * code, and must be explicitly freed when it is no longer needed.
+ */
+ native long getFlippedBuffer(long surfacePointer);
/**
* Create a cairo_surface_t with specified width and height.
@@ -158,20 +152,38 @@ public class CairoSurface extends WritableRaster
*/
public CairoSurface(int width, int height)
{
- super(createCairoSampleModel(width, height),
- null, new Point(0, 0));
+ this(0, 0, width, height);
+ }
+
+ public CairoSurface(int x, int y, int width, int height)
+ {
+ super(createCairoSampleModel(width, height), null, new Point(x, y));
if(width <= 0 || height <= 0)
throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
this.width = width;
this.height = height;
- create(width, height, width);
+ dataBuffer = new DataBufferInt(width * height);
+ create(width, height, width, getData());
- if(surfacePointer == 0 || bufferPointer == 0)
+ if(surfacePointer == 0)
throw new Error("Could not allocate bitmap.");
-
- dataBuffer = new CairoDataBuffer();
+ }
+
+ /**
+ * Create a Cairo Surface that is a subimage of another Cairo Surface
+ */
+ public CairoSurface(SampleModel sm, CairoSurface parent, Rectangle bounds,
+ Point origin)
+ {
+ super(sm, parent.dataBuffer, bounds, origin, parent);
+
+ this.width = super.width;
+ this.height = super.height;
+ this.surfacePointer = parent.surfacePointer;
+ this.sharedBuffer = parent.sharedBuffer;
+ this.dataBuffer = parent.dataBuffer;
}
/**
@@ -188,39 +200,39 @@ public class CairoSurface extends WritableRaster
// Swap ordering from GdkPixbuf to Cairo
if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
{
- for (int i = 0; i < data.length; i++ )
- {
- // On a big endian system we get a RRGGBBAA data array.
- int alpha = data[i] & 0xFF;
- if( alpha == 0 ) // I do not know why we need this, but it works.
- data[i] = 0;
- else
- {
- // Cairo needs a ARGB32 native array.
- data[i] = (data[i] >>> 8) | (alpha << 24);
- }
- }
+ for (int i = 0; i < data.length; i++ )
+ {
+ // On a big endian system we get a RRGGBBAA data array.
+ int alpha = data[i] & 0xFF;
+ if( alpha == 0 ) // I do not know why we need this, but it works.
+ data[i] = 0;
+ else
+ {
+ // Cairo needs a ARGB32 native array.
+ data[i] = (data[i] >>> 8) | (alpha << 24);
+ }
+ }
}
else
{
- for (int i = 0; i < data.length; i++ )
- {
- // On a little endian system we get a AABBGGRR data array.
- int alpha = data[i] & 0xFF000000;
- if( alpha == 0 ) // I do not know why we need this, but it works.
- data[i] = 0;
- else
- {
- int b = (data[i] & 0xFF0000) >> 16;
- int g = (data[i] & 0xFF00);
- int r = (data[i] & 0xFF) << 16;
- // Cairo needs a ARGB32 native array.
- data[i] = alpha | r | g | b;
- }
- }
+ for (int i = 0; i < data.length; i++ )
+ {
+ // On a little endian system we get a AABBGGRR data array.
+ int alpha = data[i] & 0xFF000000;
+ if( alpha == 0 ) // I do not know why we need this, but it works.
+ data[i] = 0;
+ else
+ {
+ int b = (data[i] & 0xFF0000) >> 16;
+ int g = (data[i] & 0xFF00);
+ int r = (data[i] & 0xFF) << 16;
+ // Cairo needs a ARGB32 native array.
+ data[i] = alpha | r | g | b;
+ }
+ }
}
- setPixels( data );
+ System.arraycopy(data, 0, getData(), 0, data.length);
}
/**
@@ -228,8 +240,8 @@ public class CairoSurface extends WritableRaster
*/
public void dispose()
{
- if(surfacePointer != 0)
- destroy(surfacePointer, bufferPointer);
+ if(surfacePointer != 0 && parent == null)
+ destroy(surfacePointer, getData());
}
/**
@@ -245,8 +257,17 @@ public class CairoSurface extends WritableRaster
*/
public GtkImage getGtkImage()
{
- return new GtkImage( width, height,
- getFlippedBuffer(bufferPointer, width * height ));
+ return new GtkImage(width, height, getFlippedBuffer(surfacePointer));
+ }
+
+ /**
+ * Convenience method to quickly grab the data array backing this Raster.
+ *
+ * @return The array behind the databuffer.
+ */
+ public int[] getData()
+ {
+ return ((DataBufferInt)dataBuffer).getData();
}
/**
@@ -276,34 +297,6 @@ public class CairoSurface extends WritableRaster
new Hashtable());
}
- private class CairoDataBuffer extends DataBuffer
- {
- public CairoDataBuffer()
- {
- super(DataBuffer.TYPE_INT, width * height);
- }
-
- /**
- * DataBuffer.getElem implementation
- */
- public int getElem(int bank, int i)
- {
- if(bank != 0 || i < 0 || i >= width * height)
- throw new IndexOutOfBoundsException(i+" size: "+width * height);
- return nativeGetElem(bufferPointer, i);
- }
-
- /**
- * DataBuffer.setElem implementation
- */
- public void setElem(int bank, int i, int val)
- {
- if(bank != 0 || i < 0 || i >= width*height)
- throw new IndexOutOfBoundsException(i+" size: "+width * height);
- nativeSetElem(bufferPointer, i, val);
- }
- }
-
/**
* Return a Graphics2D drawing to the CairoSurface.
*/
@@ -325,16 +318,25 @@ public class CairoSurface extends WritableRaster
}
/**
- * Copy an area of the surface. Expects parameters must be within bounds.
- * Count on a segfault otherwise.
+ * Copy a portion of this surface to another area on the surface. The given
+ * parameters must be within bounds - count on a segfault otherwise.
+ *
+ * @param x The x coordinate of the area to be copied from.
+ * @param y The y coordinate of the area to be copied from.
+ * @param width The width of the area to be copied.
+ * @param height The height of the area to be copied.
+ * @param dx The destination x coordinate.
+ * @param dy The destination y coordinate.
+ * @param stride The scanline stride.
*/
- native void copyAreaNative2(long bufferPointer, int x, int y, int width,
- int height, int dx, int dy, int stride);
public void copyAreaNative(int x, int y, int width,
int height, int dx, int dy, int stride)
{
- copyAreaNative2(bufferPointer, x, y, width, height, dx, dy, stride);
+ copyAreaNative2(surfacePointer, x, y, width, height, dx, dy, stride);
}
+ native void copyAreaNative2(long surfacePointer,
+ int x, int y, int width, int height,
+ int dx, int dy, int stride);
/**
* Creates a SampleModel that matches Cairo's native format
@@ -345,4 +347,83 @@ public class CairoSurface extends WritableRaster
new int[]{0x00FF0000, 0x0000FF00,
0x000000FF, 0xFF000000});
}
+
+ /**
+ * Returns whether this ColorModel is compatible with Cairo's native types.
+ *
+ * @param cm The color model to check.
+ * @return Whether it is compatible.
+ */
+ public static boolean isCompatibleColorModel(ColorModel cm)
+ {
+ return (cm.equals(cairoCM_pre) || cm.equals(cairoCM_opaque) ||
+ cm.equals(cairoColorModel));
+ }
+
+ /**
+ * Returns whether this SampleModel is compatible with Cairo's native types.
+ *
+ * @param sm The sample model to check.
+ * @return Whether it is compatible.
+ */
+ public static boolean isCompatibleSampleModel(SampleModel sm)
+ {
+ return (sm instanceof SinglePixelPackedSampleModel
+ && sm.getDataType() == DataBuffer.TYPE_INT
+ && Arrays.equals(((SinglePixelPackedSampleModel)sm).getBitMasks(),
+ new int[]{0x00FF0000, 0x0000FF00,
+ 0x000000FF, 0xFF000000}));
+ }
+
+ ///// Methods interhited from Raster and WritableRaster /////
+ public Raster createChild(int parentX, int parentY, int width, int height,
+ int childMinX, int childMinY, int[] bandList)
+ {
+ return createWritableChild(parentX, parentY, width, height,
+ childMinX, childMinY, bandList);
+ }
+
+ public WritableRaster createCompatibleWritableRaster()
+ {
+ return new CairoSurface(width, height);
+ }
+
+ public WritableRaster createCompatibleWritableRaster (int x, int y,
+ int w, int h)
+ {
+ return new CairoSurface(x, y, w, h);
+ }
+
+ public Raster createTranslatedChild(int childMinX, int childMinY)
+ {
+ return createWritableTranslatedChild(childMinX, childMinY);
+ }
+
+ public WritableRaster createWritableChild(int parentX, int parentY,
+ int w, int h, int childMinX,
+ int childMinY, int[] bandList)
+ {
+ if (parentX < minX || parentX + w > minX + width
+ || parentY < minY || parentY + h > minY + height)
+ throw new RasterFormatException("Child raster extends beyond parent");
+
+ SampleModel sm = (bandList == null) ?
+ sampleModel :
+ sampleModel.createSubsetSampleModel(bandList);
+
+ return new CairoSurface(sm, this,
+ new Rectangle(childMinX, childMinY, w, h),
+ new Point(sampleModelTranslateX + childMinX - parentX,
+ sampleModelTranslateY + childMinY - parentY));
+ }
+
+ public WritableRaster createWritableTranslatedChild(int x, int y)
+ {
+ int tcx = sampleModelTranslateX - minX + x;
+ int tcy = sampleModelTranslateY - minY + y;
+
+ return new CairoSurface(sampleModel, this,
+ new Rectangle(x, y, width, height),
+ new Point(tcx, tcy));
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
index 36743b9c2da..35b015f3200 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
@@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk;
import java.awt.AlphaComposite;
import java.awt.Color;
+import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
@@ -50,7 +51,6 @@ import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
@@ -116,6 +116,18 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
*/
public void draw(Shape s)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
+ // Find total bounds of shape
+ Rectangle r = findStrokedBounds(s);
+ if (shiftDrawCalls)
+ {
+ r.width++;
+ r.height++;
+ }
+
+ // Do the drawing
if (comp == null || comp instanceof AlphaComposite)
super.draw(s);
@@ -126,14 +138,21 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setStroke(this.getStroke());
g2d.setColor(this.getColor());
+ g2d.setTransform(transform);
g2d.draw(s);
- drawComposite(s.getBounds2D(), null);
+ drawComposite(r.getBounds2D(), null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
public void fill(Shape s)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.fill(s);
@@ -144,14 +163,21 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setPaint(this.getPaint());
g2d.setColor(this.getColor());
+ g2d.setTransform(transform);
g2d.fill(s);
drawComposite(s.getBounds2D(), null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.drawRenderedImage(image, xform);
@@ -161,18 +187,25 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setRenderingHints(this.getRenderingHints());
+ g2d.setTransform(transform);
g2d.drawRenderedImage(image, xform);
drawComposite(buffer.getRaster().getBounds(), null);
}
-
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
+ boolean ret;
if (comp == null || comp instanceof AlphaComposite)
- return super.drawImage(img, xform, bgcolor, obs);
+ ret = super.drawImage(img, xform, bgcolor, obs);
else
{
@@ -187,14 +220,10 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
BufferedImage bImg = (BufferedImage) img;
// Find translated bounds
- Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY());
- Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(),
- bImg.getHeight() + bImg.getMinY());
+ Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
+ bImg.getWidth(), bImg.getHeight());
if (xform != null)
- {
- origin = xform.transform(origin, origin);
- pt = xform.transform(pt, pt);
- }
+ bounds = getTransformedBounds(bounds, xform);
// Create buffer and draw image
createBuffer();
@@ -204,15 +233,20 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
g2d.drawImage(img, xform, obs);
// Perform compositing
- return drawComposite(new Rectangle2D.Double(origin.getX(),
- origin.getY(),
- pt.getX(), pt.getY()),
- obs);
+ ret = drawComposite(bounds, obs);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
+
+ return ret;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
+ if (!surface.sharedBuffer)
+ surface.syncJavaToNative(surface.surfacePointer, surface.getData());
+
if (comp == null || comp instanceof AlphaComposite)
super.drawGlyphVector(gv, x, y);
@@ -230,51 +264,64 @@ public class CairoSurfaceGraphics extends CairoGraphics2D
bounds.getWidth(), bounds.getHeight());
drawComposite(bounds, null);
}
+
+ if (!surface.sharedBuffer)
+ surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
{
- // Clip source to visible areas that need updating
- Rectangle2D clip = this.getClipBounds();
- Rectangle2D.intersect(bounds, clip, bounds);
- clip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
- buffer.getWidth(), buffer.getHeight());
- Rectangle2D.intersect(bounds, clip, bounds);
+ // Find bounds in device space
+ bounds = getTransformedBounds(bounds, transform);
+
+ // Clip bounds by the stored clip, and by the internal buffer
+ Rectangle2D devClip = this.getClipInDevSpace();
+ Rectangle2D.intersect(bounds, devClip, bounds);
+ devClip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
+ buffer.getWidth(), buffer.getHeight());
+ Rectangle2D.intersect(bounds, devClip, bounds);
+
+ // Round bounds as needed, but be careful in our rounding
+ // (otherwise it may leave unpainted stripes)
+ double x = bounds.getX();
+ double y = bounds.getY();
+ double maxX = x + bounds.getWidth();
+ double maxY = y + bounds.getHeight();
+ x = Math.round(x);
+ y = Math.round(y);
+ bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));
+ // Find subimage of internal buffer for updating
BufferedImage buffer2 = buffer;
if (!bounds.equals(buffer2.getRaster().getBounds()))
buffer2 = buffer2.getSubimage((int)bounds.getX(), (int)bounds.getY(),
(int)bounds.getWidth(),
(int)bounds.getHeight());
-
- // Get destination clip to bounds
- double[] points = new double[] {bounds.getX(), bounds.getY(),
- bounds.getMaxX(), bounds.getMaxY()};
- transform.transform(points, 0, points, 0, 2);
-
- Rectangle2D deviceBounds = new Rectangle2D.Double(points[0], points[1],
- points[2] - points[0],
- points[3] - points[1]);
-
- Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds);
-
+
+ // Find subimage of main image for updating
BufferedImage current = CairoSurface.getBufferedImage(surface);
- current = current.getSubimage((int)deviceBounds.getX(),
- (int)deviceBounds.getY(),
- (int)deviceBounds.getWidth(),
- (int)deviceBounds.getHeight());
+ current = current.getSubimage((int)bounds.getX(), (int)bounds.getY(),
+ (int)bounds.getWidth(),
+ (int)bounds.getHeight());
// Perform actual composite operation
compCtx.compose(buffer2.getRaster(), current.getRaster(),
buffer2.getRaster());
+ // Set cairo's composite to direct SRC, since we've already done our own
+ // compositing
+ Composite oldcomp = comp;
+ setComposite(AlphaComposite.Src);
+
// This MUST call directly into the "action" method in CairoGraphics2D,
// not one of the wrappers, to ensure that the composite isn't processed
// more than once!
boolean rv = super.drawImage(buffer2,
AffineTransform.getTranslateInstance(bounds.getX(),
bounds.getY()),
- new Color(0,0,0,0), null);
+ null, null);
+ setComposite(oldcomp);
+ updateColor();
return rv;
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
index 8adf275ad44..e54320697d8 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java
@@ -52,7 +52,6 @@ import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -78,7 +77,7 @@ public class ComponentGraphics extends CairoGraphics2D
protected long cairo_t;
private BufferedImage buffer, componentBuffer;
- private static ThreadLocal hasLock = new ThreadLocal();
+ private static ThreadLocal<Integer> hasLock = new ThreadLocal<Integer>();
private static Integer ONE = Integer.valueOf(1);
ComponentGraphics()
@@ -122,11 +121,11 @@ public class ComponentGraphics extends CairoGraphics2D
*/
private void lock()
{
- Integer i = (Integer) hasLock.get();
+ Integer i = hasLock.get();
if (i == null)
{
- start_gdk_drawing();
- hasLock.set(ONE);
+ start_gdk_drawing();
+ hasLock.set(ONE);
}
else
hasLock.set(Integer.valueOf(i.intValue() + 1));
@@ -137,14 +136,16 @@ public class ComponentGraphics extends CairoGraphics2D
*/
private void unlock()
{
- Integer i = (Integer) hasLock.get();
+ Integer i = hasLock.get();
if (i == null)
throw new IllegalStateException();
if (i == ONE)
{
- hasLock.set(null);
- end_gdk_drawing();
+ hasLock.set(null);
+ end_gdk_drawing();
}
+ else if (i.intValue() == 2)
+ hasLock.set(ONE);
else
hasLock.set(Integer.valueOf(i.intValue() - 1));
}
@@ -176,11 +177,11 @@ public class ComponentGraphics extends CairoGraphics2D
private static native Pointer nativeGrab(GtkComponentPeer component);
private native void copyAreaNative(GtkComponentPeer component, int x, int y,
- int width, int height, int dx, int dy);
+ int width, int height, int dx, int dy);
private native void drawVolatile(GtkComponentPeer component,
- long vimg, int x, int y,
- int width, int height, int cx, int cy,
+ long vimg, int x, int y,
+ int width, int height, int cx, int cy,
int cw, int ch);
/**
@@ -232,16 +233,16 @@ public class ComponentGraphics extends CairoGraphics2D
{
if (comp == null || comp instanceof AlphaComposite)
super.draw(s);
-
+
else
{
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setStroke(this.getStroke());
g2d.setColor(this.getColor());
g2d.draw(s);
-
+
drawComposite(s.getBounds2D(), null);
}
}
@@ -250,16 +251,16 @@ public class ComponentGraphics extends CairoGraphics2D
{
if (comp == null || comp instanceof AlphaComposite)
super.fill(s);
-
+
else
{
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setPaint(this.getPaint());
g2d.setColor(this.getColor());
g2d.fill(s);
-
+
drawComposite(s.getBounds2D(), null);
}
}
@@ -268,7 +269,7 @@ public class ComponentGraphics extends CairoGraphics2D
{
if (comp == null || comp instanceof AlphaComposite)
super.drawRenderedImage(image, xform);
-
+
else
{
createBuffer();
@@ -276,7 +277,7 @@ public class ComponentGraphics extends CairoGraphics2D
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setRenderingHints(this.getRenderingHints());
g2d.drawRenderedImage(image, xform);
-
+
drawComposite(buffer.getRaster().getBounds(), null);
}
}
@@ -287,7 +288,7 @@ public class ComponentGraphics extends CairoGraphics2D
boolean rv;
if (comp == null || comp instanceof AlphaComposite)
rv = super.drawImage(img, xform, bgcolor, obs);
-
+
else
{
// Get buffered image of source
@@ -299,7 +300,7 @@ public class ComponentGraphics extends CairoGraphics2D
img = Toolkit.getDefaultToolkit().createImage(source);
}
BufferedImage bImg = (BufferedImage) img;
-
+
// Find translated bounds
Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY());
Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(),
@@ -309,18 +310,18 @@ public class ComponentGraphics extends CairoGraphics2D
origin = xform.transform(origin, origin);
pt = xform.transform(pt, pt);
}
-
+
// Create buffer and draw image
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setRenderingHints(this.getRenderingHints());
g2d.drawImage(img, xform, obs);
// Perform compositing
rv = drawComposite(new Rectangle2D.Double(origin.getX(),
- origin.getY(),
- pt.getX(), pt.getY()),
+ origin.getY(),
+ pt.getX(), pt.getY()),
obs);
}
return rv;
@@ -330,7 +331,7 @@ public class ComponentGraphics extends CairoGraphics2D
{
if (comp == null || comp instanceof AlphaComposite)
super.drawGlyphVector(gv, x, y);
-
+
else
{
createBuffer();
@@ -339,7 +340,7 @@ public class ComponentGraphics extends CairoGraphics2D
g2d.setPaint(this.getPaint());
g2d.setStroke(this.getStroke());
g2d.drawGlyphVector(gv, x, y);
-
+
Rectangle2D bounds = gv.getLogicalBounds();
bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(),
bounds.getWidth(), bounds.getHeight());
@@ -373,8 +374,8 @@ public class ComponentGraphics extends CairoGraphics2D
(int) r.getHeight());
return true;
}
- else
- return super.drawImage(vimg.getSnapshot(), x, y, observer);
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y, observer);
}
BufferedImage bimg;
@@ -382,7 +383,7 @@ public class ComponentGraphics extends CairoGraphics2D
bimg = (BufferedImage) img;
else
{
- ImageProducer source = img.getSource();
+ ImageProducer source = img.getSource();
if (source == null)
return false;
bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
@@ -418,9 +419,9 @@ public class ComponentGraphics extends CairoGraphics2D
(int) r.getHeight());
return true;
}
- else
- return super.drawImage(vimg.getSnapshot(), x, y,
- width, height, observer);
+ else
+ return super.drawImage(vimg.getSnapshot(), x, y,
+ width, height, observer);
}
BufferedImage bimg;
@@ -429,7 +430,7 @@ public class ComponentGraphics extends CairoGraphics2D
bimg = (BufferedImage) img;
else
{
- ImageProducer source = img.getSource();
+ ImageProducer source = img.getSource();
if (source == null)
return false;
bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
@@ -458,8 +459,8 @@ public class ComponentGraphics extends CairoGraphics2D
transform.transform(points, 0, points, 0, 2);
Rectangle2D deviceBounds = new Rectangle2D.Double(points[0], points[1],
- points[2] - points[0],
- points[3] - points[1]);
+ points[2] - points[0],
+ points[3] - points[1]);
Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds);
@@ -519,8 +520,8 @@ public class ComponentGraphics extends CairoGraphics2D
new Point(0,0));
componentBuffer = new BufferedImage(GtkVolatileImage.gdkColorModel, rst,
- GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(),
- new Hashtable());
+ GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(),
+ new Hashtable());
}
}
@@ -723,7 +724,7 @@ public class ComponentGraphics extends CairoGraphics2D
unlock();
}
}
-
+
@Override
protected void cairoRectangle(long pointer, double x, double y,
double width, double height)
@@ -908,4 +909,33 @@ public class ComponentGraphics extends CairoGraphics2D
unlock();
}
}
+
+ @Override
+ protected void cairoSetAntialias(long pointer, boolean aa)
+ {
+ try
+ {
+ lock();
+ super.cairoSetAntialias(pointer, aa);
+ }
+ finally
+ {
+ unlock();
+ }
+ }
+
+ @Override
+ protected void drawCairoSurface(CairoSurface surface, AffineTransform tx,
+ double alpha, int interpolation)
+ {
+ try
+ {
+ lock();
+ super.drawCairoSurface(surface, tx, alpha, interpolation);
+ }
+ finally
+ {
+ unlock();
+ }
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
index 131a964488f..280f3e6fbcd 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
@@ -79,6 +79,11 @@ public class FreetypeGlyphVector extends GlyphVector
* The glyph codes
*/
private int[] glyphCodes;
+
+ /**
+ * The set of fonts used in this glyph vector.
+ */
+ private long[] fontSet = null;
/**
* Glyph transforms. (de facto only the translation is used)
@@ -86,6 +91,19 @@ public class FreetypeGlyphVector extends GlyphVector
private AffineTransform[] glyphTransforms;
private GlyphMetrics[] metricsCache;
+
+ private native void dispose(long[] fonts);
+
+ /**
+ * Returns a pointer to the native PangoFcFont object.
+ *
+ * The object will be referenced with g_object_ref n times before being
+ * returned, and must be unreferenced a corresponding number of times.
+ *
+ * @param n Number of times to reference the object.
+ * @return Pointer to the native default font.
+ */
+ private native long getNativeFontPointer(int n);
/**
* Create a glyphvector from a given (Freetype) font and a String.
@@ -112,11 +130,11 @@ public class FreetypeGlyphVector extends GlyphVector
getGlyphs();
if( flags == Font.LAYOUT_RIGHT_TO_LEFT )
{
- // reverse the glyph ordering.
- int[] temp = new int[ nGlyphs ];
- for(int i = 0; i < nGlyphs; i++)
- temp[ i ] = glyphCodes[ nGlyphs - i - 1];
- glyphCodes = temp;
+ // reverse the glyph ordering.
+ int[] temp = new int[ nGlyphs ];
+ for(int i = 0; i < nGlyphs; i++)
+ temp[i] = glyphCodes[nGlyphs - i - 1];
+ glyphCodes = temp;
}
performDefaultLayout();
}
@@ -135,6 +153,13 @@ public class FreetypeGlyphVector extends GlyphVector
glyphCodes = new int[ codes.length ];
System.arraycopy(codes, 0, glyphCodes, 0, codes.length);
nGlyphs = glyphCodes.length;
+
+ if (fontSet == null)
+ {
+ fontSet = new long[nGlyphs];
+ Arrays.fill(fontSet, getNativeFontPointer(nGlyphs));
+ }
+
performDefaultLayout();
}
@@ -152,11 +177,12 @@ public class FreetypeGlyphVector extends GlyphVector
if( gv.metricsCache != null )
{
- metricsCache = new GlyphMetrics[ nGlyphs ];
- System.arraycopy(gv.metricsCache, 0, metricsCache, 0, nGlyphs);
+ metricsCache = new GlyphMetrics[ nGlyphs ];
+ System.arraycopy(gv.metricsCache, 0, metricsCache, 0, nGlyphs);
}
glyphCodes = new int[ nGlyphs ];
+ fontSet = new long[nGlyphs];
glyphPositions = new float[(nGlyphs + 1) * 2];
glyphTransforms = new AffineTransform[ nGlyphs ];
for(int i = 0; i < nGlyphs; i++ )
@@ -166,6 +192,13 @@ public class FreetypeGlyphVector extends GlyphVector
}
System.arraycopy(gv.glyphPositions, 0, glyphPositions, 0,
glyphPositions.length);
+ System.arraycopy(gv.glyphCodes, 0, glyphCodes, 0, nGlyphs);
+ System.arraycopy(gv.fontSet, 0, fontSet, 0, nGlyphs);
+ }
+
+ public void finalize()
+ {
+ dispose(fontSet);
}
/**
@@ -175,16 +208,17 @@ public class FreetypeGlyphVector extends GlyphVector
{
nGlyphs = s.codePointCount( 0, s.length() );
glyphCodes = new int[ nGlyphs ];
+ fontSet = new long[ nGlyphs ];
int[] codePoints = new int[ nGlyphs ];
int stringIndex = 0;
for(int i = 0; i < nGlyphs; i++)
{
- codePoints[i] = s.codePointAt( stringIndex );
+ codePoints[i] = s.codePointAt( stringIndex );
// UTF32 surrogate handling
- if( codePoints[i] != (int)s.charAt( stringIndex ) )
- stringIndex ++;
- stringIndex ++;
+ if( codePoints[i] != (int)s.charAt( stringIndex ) )
+ stringIndex ++;
+ stringIndex ++;
if (Character.isISOControl(codePoints[i]))
{
@@ -194,22 +228,22 @@ public class FreetypeGlyphVector extends GlyphVector
}
}
- glyphCodes = getGlyphs( codePoints );
+ getGlyphs( codePoints, glyphCodes, fontSet );
}
/**
* Returns the glyph code within the font for a given character
*/
- public native int[] getGlyphs(int[] codepoints);
+ public native void getGlyphs(int[] codepoints, int[] glyphs, long[] fonts);
/**
* Returns the kerning of a glyph pair
*/
- private native Point2D getKerning(int leftGlyph, int rightGlyph);
+ private native Point2D getKerning(int leftGlyph, int rightGlyph, long font);
- private native double[] getMetricsNative( int glyphCode );
+ private native double[] getMetricsNative(int glyphCode, long font);
- private native GeneralPath getGlyphOutlineNative(int glyphIndex);
+ private native GeneralPath getGlyphOutlineNative(int glyphIndex, long font);
public Object clone()
@@ -267,10 +301,12 @@ public class FreetypeGlyphVector extends GlyphVector
x += gm.getAdvanceX();
y += gm.getAdvanceY();
-
- if (i != nGlyphs-1)
+
+ // Get the kerning only if it's not the last glyph, and the two glyphs are
+ // using the same font
+ if (i != nGlyphs-1 && fontSet[i] == fontSet[i+1])
{
- Point2D p = getKerning(glyphCodes[i], glyphCodes[i + 1]);
+ Point2D p = getKerning(glyphCodes[i], glyphCodes[i + 1], fontSet[i]);
x += p.getX();
y += p.getY();
}
@@ -291,7 +327,7 @@ public class FreetypeGlyphVector extends GlyphVector
* Returns multiple glyphcodes.
*/
public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
- int[] codeReturn)
+ int[] codeReturn)
{
int[] rval;
@@ -305,6 +341,26 @@ public class FreetypeGlyphVector extends GlyphVector
return rval;
}
+ /**
+ * Returns pointers to the fonts used in this glyph vector.
+ *
+ * The array index matches that of the glyph vector itself.
+ */
+ protected long[] getGlyphFonts(int beginGlyphIndex, int numEntries,
+ long[] codeReturn)
+ {
+ long[] rval;
+
+ if( codeReturn == null || codeReturn.length < numEntries)
+ rval = new long[ numEntries ];
+ else
+ rval = codeReturn;
+
+ System.arraycopy(fontSet, beginGlyphIndex, rval, 0, numEntries);
+
+ return rval;
+ }
+
public Shape getGlyphLogicalBounds(int glyphIndex)
{
GlyphMetrics gm = getGlyphMetrics( glyphIndex );
@@ -335,26 +391,24 @@ public class FreetypeGlyphVector extends GlyphVector
for(int i = 0; i < nGlyphs; i++)
{
- GlyphMetrics gm = (GlyphMetrics)
- peer.getGlyphMetrics( glyphCodes[ i ] );
- if( gm == null )
- {
- double[] val = getMetricsNative( glyphCodes[ i ] );
- if( val == null )
- gm = null;
- else
- {
- gm = new GlyphMetrics( true,
- (float)val[1],
- (float)val[2],
- new Rectangle2D.Double
- ( val[3], val[4],
- val[5], val[6] ),
- GlyphMetrics.STANDARD );
- peer.putGlyphMetrics( glyphCodes[ i ], gm );
- }
- }
- metricsCache[ i ] = gm;
+ GlyphMetrics gm = (GlyphMetrics)peer.getGlyphMetrics(glyphCodes[i]);
+ if( gm == null )
+ {
+ double[] val = getMetricsNative(glyphCodes[i], fontSet[i]);
+ if( val == null )
+ gm = null;
+ else
+ {
+ gm = new GlyphMetrics(true,
+ (float)val[1],
+ (float)val[2],
+ new Rectangle2D.Double(val[3], val[4],
+ val[5], val[6] ),
+ GlyphMetrics.STANDARD );
+ peer.putGlyphMetrics( glyphCodes[ i ], gm );
+ }
+ }
+ metricsCache[ i ] = gm;
}
}
@@ -371,13 +425,21 @@ public class FreetypeGlyphVector extends GlyphVector
/**
* Returns the outline of a single glyph.
+ *
+ * Despite what the Sun API says, this method returns the glyph relative to
+ * the origin of the *entire string*, not each individual glyph.
*/
public Shape getGlyphOutline(int glyphIndex)
{
- GeneralPath gp = getGlyphOutlineNative( glyphCodes[ glyphIndex ] );
- if (glyphTransforms[glyphIndex] != null)
- gp.transform( glyphTransforms[glyphIndex]);
+ GeneralPath gp = getGlyphOutlineNative(glyphCodes[glyphIndex],
+ fontSet[glyphIndex]);
+ AffineTransform tx = AffineTransform.getTranslateInstance(glyphPositions[glyphIndex*2],
+ glyphPositions[glyphIndex*2+1]);
+ if (glyphTransforms[glyphIndex] != null)
+ tx.concatenate( glyphTransforms[glyphIndex]);
+
+ gp.transform(tx);
return gp;
}
@@ -432,7 +494,6 @@ public class FreetypeGlyphVector extends GlyphVector
return logicalBounds;
Rectangle2D rect = (Rectangle2D)getGlyphLogicalBounds( 0 );
- AffineTransform tx = new AffineTransform();
for( int i = 1; i < nGlyphs; i++ )
{
Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i );
@@ -458,14 +519,8 @@ public class FreetypeGlyphVector extends GlyphVector
public Shape getOutline()
{
GeneralPath path = new GeneralPath();
- AffineTransform tx = new AffineTransform();
for( int i = 0; i < getNumGlyphs(); i++ )
- {
- Shape outline = getGlyphOutline(i);
- tx.setToTranslation(glyphPositions[i*2], glyphPositions[i*2 +1]);
- outline = tx.createTransformedShape(outline);
- path.append(outline, false);
- }
+ path.append(getGlyphOutline(i), false);
return path;
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java
deleted file mode 100644
index e73df9e5509..00000000000
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* GThreadMutex.java -- Implements a mutex object for glib's gthread
- abstraction, for use with GNU Classpath's --portable-native-sync option.
- This is used in gthread-jni.c
-
- Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.java.awt.peer.gtk;
-
-/** Implements a mutex object for glib's gthread
- abstraction, for use with GNU Classpath's --portable-native-sync option.
- This is used in gthread-jni.c.
-
- We use this object to implement the POSIX semantics for Mutexes. They are
- needed are needed for the function vector that is passed to glib's
- g_thread subpackage's initialization function.
-
- The GThreadMutex object itself serves as the Real Lock; if code has
- entered the monitor for this GThreadMutex object (in Java language, if
- it's synchronized on this object) then it holds the lock that this object
- represents.
-
- @author Steven Augart
- May, 2004
-
-
-*/
-
-class GThreadMutex
-{
- /** Might "lock" be locked? Is anyone waiting
- to get that lock? How long is the queue?
-
- If zero, nobody holds a lock on this GThreadMutex object, and nobody is
- trying to get one. Before someone attempts to acquire a lock on this
- object, they must increment potentialLockers. After they release their
- lock on this object, they must decrement potentialLockers.
-
- Access to this field is guarded by synchronizing on the object
- <code>lockForPotentialLockers</code>.
-
- After construction, we only access this field via JNI.
- */
- volatile int potentialLockers;
-
- /** An object to synchronize to if you want to examine or modify the
- <code>potentialLockers</code> field. Only hold this lock for brief
- moments, just long enough to check or set the value of
- <code>lockForPotentialLockers</code>.
-
- We use this representation so that g_thread_mutex_trylock() will work
- with the POSIX semantics. This is the only case in which you ever hold a
- lock on <code>lockForPotentialLockers</code> while trying to get another
- lock -- if you are the mutex_trylock() implementation, and you have just
- checked that <code>potentialLockers</code> has the value zero. In that
- case, mutex_trylock() holds the lock on lockForPotentialLockers so that
- another thread calling mutex_trylock() or mutex_lock() won't increment
- potentialLockers after we've checked it and before we've gained the lock
- on the POSIX mutex. Of course, in that case the operation of gaining
- the POSIX lock itself will succeed immediately, and once it has
- succeeded, trylock releases lockForPotentialLockers right away,
- incremented to 1 (one).
-
- After construction, we only access this field via JNI.
- */
- Object lockForPotentialLockers;
-
- GThreadMutex()
- {
- potentialLockers = 0;
- lockForPotentialLockers = new Object();
- }
-}
-// Local Variables:
-// c-file-style: "gnu"
-// End:
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
deleted file mode 100644
index 9a1b8e3a30a..00000000000
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/* GThreadNativeMethodRunner.java -- Implements pthread_create(), under
- glib's gthread abstraction, for use with GNU Classpath's
- --portable-native-sync option.
- This is used by gthread-jni.c
-
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.java.awt.peer.gtk;
-
-import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/** Implements pthread_create(), under glib's gthread abstraction, for use
- with GNU Classpath's --portable-native-sync option. This is used in
- gthread-jni.c
-
- Also implements a registry for threads, mapping Thread objects to small
- integers. The registry uses weak references for threads that aren't
- joinable, so that they will be garbage collected.
-
- There are a number of possible alternative implementations.
-
-
- The rest of this comment consists of an answer to a question that was
- raised on the commit-classpath mailing list:
-
- Mark Wielaard wrote:
-
- > Can't we assume that jobject and gpointer are both (void *) so we don't
- > need the int <-> Thread (global jobject ref) mapping?
- > Maybe there are platforms where jobject and gpointer aren't the same,
- > but I guess that is pretty unlikely.
-
-
- I agree with you on the pointer size issues. A gpointer is a void *, so
- it's certainly guaranteed to be at least as large as any other
- pointer. And a jobject is implicitly an opaque pointer (in Jikes RVM, we
- use small integers, but we coerce them into the representation of a
- pointer).
-
- The int <==> Thread mapping addresses a different issue. I realize that I
- did not document this properly (two and a half lines in thread_create),
- and the point is subtle (at least to me; took me a while to figure out).
-
- The int => Thread mapping always returns jobjects that are local
- references, not global ones. This is because Thread objects need to be
- able to go away and be garbage collected after the thread they refer to
- has died.
-
- If we keep a global object reference to a thread, then when do we delete
- that global object reference? We have an answer in the case of GThread
- objects that were explicitly created with the joinable attribute. It is
- safe for us to maintain a global reference to any joinable thread, since
- the joinable thread must linger (even if only in a zombie state)
- until it's explicitly joined via a g_thread_join() call. The global ref
- could be cleaned up at that point too.
-
- However, in the case of GThreads that were created non-joinable by
- g_thread_create(), and in the case of Java threads that were created
- within pure Java code (not via g_thread_create()), we don't want them to
- linger forever, and there is no way to tell when the last reference
- to such threads needs to expire. In the case of this application -- AWT
- with GTK peers -- it would probably be safe anyway, since there are not
- very many threads we create, but I was going for correctness even in the
- case of long-running programs that might set up and tear down AWT
- interfaces many times.
-
- So, I duplicated the POSIX thread-ID semantics. The thread ID of a
- non-joinable thread remains valid as long as that thread is still alive.
- Once that thread dies, the old thread ID may be reused at any moment. And
- that's why the array indexed by thread ID numbers is an array of weak
- references.
-
- That's also why the int => Thread jobject mapping function always returns
- local references, since global references would lock the Thread in memory
- forever.
-
- I would dearly love there to be a cleaner solution. I dislike the
- repeated dips from C code into Java that are necessary to look up thread
- ID numbers. If anyone can think of one, I'm all ears.
-*/
-
-class GThreadNativeMethodRunner
- extends Thread
-{
- /** The C function pointer that was passed to g_thread_create().
- Specifically, this the numeric address of an object of
- C type "void *(*funcPtr)(void *funcArg)".
- */
- private final long funcPtr;
-
- /** The argument for the function "funcPtr(funcArg)". */
- private final long funcArg;
-
- GThreadNativeMethodRunner(long funcPtr, long funcArg, boolean joinable)
- {
- this.funcPtr = funcPtr;
- this.funcArg = funcArg;
-
- if (joinable)
- registerSelfJoinable();
- }
-
- public void run()
- {
- nativeRun(funcPtr, funcArg);
- }
-
- private native void nativeRun(long funcPtr, long funcArg);
-
- /** THREADS is an array of threads, indexed by thread ID codes. Not sure
- whether this is the "best" approach but it does make it O(1) to look up a
- thread by its ID.
-
- Zero is a valid thread ID code. Any negative number is invalid.
-
- Possible future fixes (TODO?)
-
- - The THREADS array will only grow. probably not a problem.
- But we could keep count when nulling entries and shrink when we have
- lots of nulls at the end. Probably not worth it. --mjw
-
- - Could make this a set of Object; see the comment on "joinable" below.
-
- The initial size of 17 is just a starting point. Any number will do,
- including zero.
- */
- private static WeakReference[] threads = new WeakReference[17];
-
- /** Used by threadToThreadID, below. Returns the registration number of
- the newly-registered thread.
- */
- private static synchronized int registerThread(Thread t)
- {
- int i;
-
- for (i = 0; i < threads.length; ++i)
- {
- WeakReference ref = threads[i];
- if (ref == null)
- break; // found an empty spot.
- }
-
- if (i == threads.length)
- {
- /* expand the array */
- WeakReference[] bigger = new WeakReference[threads.length * 2];
- System.arraycopy(threads, 0, bigger, 0, threads.length);
- threads = bigger;
- }
-
- threads[i] = new WeakReference(t);
-
- return i;
- }
-
- /** Look up the Thread ID # for a Thread. Assign a Thread ID # if none
- exists. This is a general routine for handling all threads, including
- the VM's main thread, if appropriate.
-
-
- Runs in O(n/2) time.
-
- We can't just issue a threadID upon thread creation. If we were to do
- that, not all threads would have a threadID, because not all threads
- are launched by GThreadNativeMethodRunner.
- */
- static synchronized int threadToThreadID(Thread t)
- {
- for (int i = 0; i < threads.length; ++i )
- {
- if (threads[i] == null)
- continue;
- Thread referent = (Thread) threads[i].get();
- if (referent == null)
- {
- threads[i] = null; // Purge the dead WeakReference.
- continue;
- }
- if (referent.equals(t))
- return i;
- } // for()
-
- /* No match found. */
- return registerThread(t);
- }
-
- /** @param threadID Must be a non-negative integer.
-
- Used to return null if the thread number was out of range or if
- the thread was unregistered. Now we throw an exception.
-
- Possible Alternative Interface: We could go back to returning null in
- some sort of check-free mode, so code that calls this function must
- be prepared to get null.
- */
- static Thread threadIDToThread(int threadID)
- throws IllegalArgumentException
- {
- if (threadID < 0)
- throw new IllegalArgumentException("Received a negative threadID, "
- + threadID);
- if (threadID >= threads.length)
- throw new IllegalArgumentException("Received a threadID (" + threadID
- + ") higher than was"
- + " ever issued");
-
- /* Note: if the user is using a stale reference, things will just
- break. We might end up getting a different thread than the one
- expected.
-
- TODO: Add an error-checking mode where the user's problems with threads
- are announced. For instance, if the user asks for the thread
- associated with a threadID that was never issued, we could print a
- warning or even abort.
-
- TODO: Consider optionally disabling all of the error-checking we
- already have; it probably slows down the implementation. We could
- just return NULL. This is just the reverse of the above TODO item.
- */
-
- WeakReference threadRef = threads[threadID];
-
- if (threadRef == null)
- throw new IllegalArgumentException("Asked to look up a stale or unissued"
- + "threadID (" + threadID + ")" );
-
-
- Thread referent = (Thread) threadRef.get();
- if (referent == null)
- throw new IllegalArgumentException ("Asked to look up a stale threadID ("
- + threadID + ")");
- return referent;
- }
-
- /** Joinable threads need a hard reference, so that they won't go away when
- they die. That is because their thread IDs need to stay valid until the
- thread is joined via thread_join(threadID). Joinable threads have to be
- explicitly joined before they are allowed to go away completely.
-
- Possible Alternative Implementation: Eliminate the Joinable set. When
- calling getThreadIDFromThread() you know whether or not the thread
- is joinable. So just store the Thread itself in the threads array?
- Make that array an Object array and check with instanceof. This
- looks cleaner and more robust to me and it saves a native -> Java
- call. But instanceof might be expensive. --mjw
- */
- private static final Set joinable =
- Collections.synchronizedSet(new HashSet());
-
- /** Only called from the constructor. */
- private void registerSelfJoinable()
- {
- joinable.add(this);
- }
-
- /** This method is only called from JNI, and only after we have succeeded in
- a thread_join() operation. */
- static void deRegisterJoinable(Thread thread)
- {
- joinable.remove(thread);
- }
-}
-
-// Local Variables:
-// c-file-style: "gnu"
-// End:
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
index 5f5126ac590..c3c94d8a935 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
@@ -67,7 +67,7 @@ public class GdkFontPeer extends ClasspathFontPeer
* The size of the cache has been chosen so that relativly large GUIs with
* text documents are still efficient.
*/
- HashMap textLayoutCache = new GtkToolkit.LRUCache(500);
+ HashMap<String,TextLayout> textLayoutCache = new GtkToolkit.LRUCache<String,TextLayout>(500);
private class GdkFontMetrics extends FontMetrics
{
@@ -79,7 +79,7 @@ public class GdkFontPeer extends ClasspathFontPeer
public int stringWidth (String str)
{
- TextLayout tl = (TextLayout) textLayoutCache.get(str);
+ TextLayout tl = textLayoutCache.get(str);
if (tl == null)
{
tl = new TextLayout(str, font, DEFAULT_CTX);
@@ -140,7 +140,7 @@ public class GdkFontPeer extends ClasspathFontPeer
/**
* Cache GlyphMetrics objects.
*/
- private HashMap metricsCache;
+ private HashMap<Integer,GlyphMetrics> metricsCache;
private static final int FONT_METRICS_ASCENT = 0;
private static final int FONT_METRICS_MAX_ASCENT = 1;
@@ -235,7 +235,7 @@ public class GdkFontPeer extends ClasspathFontPeer
super(name, style, size);
initState ();
setFont (this.familyName, this.style, (int)this.size);
- metricsCache = new HashMap();
+ metricsCache = new HashMap<Integer,GlyphMetrics>();
setupMetrics();
}
@@ -244,7 +244,7 @@ public class GdkFontPeer extends ClasspathFontPeer
super(name, attributes);
initState ();
setFont (this.familyName, this.style, (int)this.size);
- metricsCache = new HashMap();
+ metricsCache = new HashMap<Integer,GlyphMetrics>();
setupMetrics();
}
@@ -261,9 +261,9 @@ public class GdkFontPeer extends ClasspathFontPeer
return font;
else
{
- ClasspathToolkit toolkit;
- toolkit = (ClasspathToolkit) Toolkit.getDefaultToolkit();
- return toolkit.getFont(font.getName(), font.getAttributes());
+ ClasspathToolkit toolkit;
+ toolkit = (ClasspathToolkit) Toolkit.getDefaultToolkit();
+ return toolkit.getFont(font.getName(), font.getAttributes());
}
}
@@ -294,9 +294,9 @@ public class GdkFontPeer extends ClasspathFontPeer
name = getName(NameDecoder.NAME_SUBFAMILY, locale);
if (name == null)
{
- name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
- if ("Regular".equals(name))
- name = null;
+ name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
+ if ("Regular".equals(name))
+ name = null;
}
return name;
@@ -340,12 +340,12 @@ public class GdkFontPeer extends ClasspathFontPeer
{
if (nameTable == null)
{
- byte[] data = getTrueTypeTable((byte)'n', (byte) 'a',
- (byte) 'm', (byte) 'e');
- if( data == null )
- return null;
+ byte[] data = getTrueTypeTable((byte)'n', (byte) 'a',
+ (byte) 'm', (byte) 'e');
+ if( data == null )
+ return null;
- nameTable = ByteBuffer.wrap( data );
+ nameTable = ByteBuffer.wrap( data );
}
return NameDecoder.getName(nameTable, name, locale);
@@ -492,8 +492,8 @@ public class GdkFontPeer extends ClasspathFontPeer
char[] chars, int start, int limit,
int flags)
{
- return new FreetypeGlyphVector( font, chars, start, limit - start,
- frc, flags);
+ return new FreetypeGlyphVector(font, chars, start, limit - start,
+ frc, flags);
}
public LineMetrics getLineMetrics (Font font, String str,
@@ -515,13 +515,13 @@ public class GdkFontPeer extends ClasspathFontPeer
*/
GlyphMetrics getGlyphMetrics( int glyphCode )
{
- return (GlyphMetrics)metricsCache.get( new Integer( glyphCode ) );
+ return metricsCache.get(new Integer(glyphCode));
}
/**
* Put a GlyphMetrics object in the cache.
*/
- void putGlyphMetrics( int glyphCode, Object metrics )
+ void putGlyphMetrics( int glyphCode, GlyphMetrics metrics )
{
metricsCache.put( new Integer( glyphCode ), metrics );
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
index db725b697df..bd6daa2d1e5 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
@@ -38,16 +38,21 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
+import gnu.java.awt.ClasspathGraphicsEnvironment;
+
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
import java.util.Locale;
-public class GdkGraphicsEnvironment extends GraphicsEnvironment
+public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
{
private final int native_state = GtkGenericPeer.getUniqueInteger ();
@@ -139,4 +144,13 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment
* Used by GtkMouseInfoPeer.
*/
native int[] getMouseCoordinates();
+
+ public WritableRaster createRaster(ColorModel cm, SampleModel sm)
+ {
+ if (CairoSurface.isCompatibleSampleModel(sm)
+ && CairoSurface.isCompatibleColorModel(cm))
+ return new CairoSurface(sm.getWidth(), sm.getHeight());
+ else
+ return null;
+ }
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
index 6d0a52b91be..6f6ea560db7 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -184,22 +184,22 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
int len = 0;
synchronized(pixbufLock)
{
- initState();
+ initState();
}
needsClose = true;
// Note: We don't want the pixbufLock while reading from the InputStream.
while ((len = is.read (bytes)) != -1)
{
- synchronized(pixbufLock)
- {
- pumpBytes (bytes, len);
- }
+ synchronized(pixbufLock)
+ {
+ pumpBytes (bytes, len);
+ }
}
synchronized(pixbufLock)
{
- pumpDone();
+ pumpDone();
}
needsClose = false;
@@ -217,7 +217,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
{
synchronized(pixbufLock)
{
- finish(needsClose);
+ finish(needsClose);
}
}
@@ -226,8 +226,8 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
{
public String name;
public boolean writable = false;
- public ArrayList mimeTypes = new ArrayList();
- public ArrayList extensions = new ArrayList();
+ public ArrayList<String> mimeTypes = new ArrayList<String>();
+ public ArrayList<String> extensions = new ArrayList<String>();
public ImageFormatSpec(String name, boolean writable)
{
@@ -246,7 +246,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
}
}
- static ArrayList imageFormatSpecs;
+ static ArrayList<ImageFormatSpec> imageFormatSpecs;
public static ImageFormatSpec registerFormat(String name, boolean writable)
{
@@ -254,7 +254,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
synchronized(GdkPixbufDecoder.class)
{
if (imageFormatSpecs == null)
- imageFormatSpecs = new ArrayList();
+ imageFormatSpecs = new ArrayList<ImageFormatSpec>();
imageFormatSpecs.add(ifs);
}
return ifs;
@@ -262,13 +262,13 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
static String[] getFormatNames(boolean writable)
{
- ArrayList names = new ArrayList();
+ ArrayList<String> names = new ArrayList<String>();
synchronized (imageFormatSpecs)
{
- Iterator i = imageFormatSpecs.iterator();
+ Iterator<ImageFormatSpec> i = imageFormatSpecs.iterator();
while (i.hasNext())
{
- ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ ImageFormatSpec ifs = i.next();
if (writable && !ifs.writable)
continue;
names.add(ifs.name);
@@ -279,62 +279,50 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
* This generally means "all the extensions people might use".
*/
- Iterator j = ifs.extensions.iterator();
+ Iterator<String> j = ifs.extensions.iterator();
while (j.hasNext())
- names.add((String) j.next());
+ names.add(j.next());
}
}
- Object[] objs = names.toArray();
- String[] strings = new String[objs.length];
- for (int i = 0; i < objs.length; ++i)
- strings[i] = (String) objs[i];
- return strings;
+ return names.toArray(new String[names.size()]);
}
static String[] getFormatExtensions(boolean writable)
{
- ArrayList extensions = new ArrayList();
+ ArrayList<String> extensions = new ArrayList<String>();
synchronized (imageFormatSpecs)
{
- Iterator i = imageFormatSpecs.iterator();
+ Iterator<ImageFormatSpec> i = imageFormatSpecs.iterator();
while (i.hasNext())
{
- ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ ImageFormatSpec ifs = i.next();
if (writable && !ifs.writable)
continue;
- Iterator j = ifs.extensions.iterator();
+ Iterator<String> j = ifs.extensions.iterator();
while (j.hasNext())
- extensions.add((String) j.next());
+ extensions.add(j.next());
}
}
- Object[] objs = extensions.toArray();
- String[] strings = new String[objs.length];
- for (int i = 0; i < objs.length; ++i)
- strings[i] = (String) objs[i];
- return strings;
+ return extensions.toArray(new String[extensions.size()]);
}
static String[] getFormatMimeTypes(boolean writable)
{
- ArrayList mimeTypes = new ArrayList();
+ ArrayList<String> mimeTypes = new ArrayList<String>();
synchronized (imageFormatSpecs)
{
- Iterator i = imageFormatSpecs.iterator();
+ Iterator<ImageFormatSpec> i = imageFormatSpecs.iterator();
while (i.hasNext())
{
- ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ ImageFormatSpec ifs = i.next();
if (writable && !ifs.writable)
continue;
- Iterator j = ifs.mimeTypes.iterator();
+ Iterator<String> j = ifs.mimeTypes.iterator();
while (j.hasNext())
- mimeTypes.add((String) j.next());
+ mimeTypes.add(j.next());
}
}
- Object[] objs = mimeTypes.toArray();
- String[] strings = new String[objs.length];
- for (int i = 0; i < objs.length; ++i)
- strings[i] = (String) objs[i];
- return strings;
+ return mimeTypes.toArray(new String[mimeTypes.size()]);
}
@@ -348,10 +336,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
String str = (String) ext;
- Iterator i = imageFormatSpecs.iterator();
+ Iterator<ImageFormatSpec> i = imageFormatSpecs.iterator();
while (i.hasNext())
{
- ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ ImageFormatSpec ifs = i.next();
if (needWritable && !ifs.writable)
continue;
@@ -359,10 +347,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
if (ifs.name.equals(str))
return str;
- Iterator j = ifs.extensions.iterator();
+ Iterator<String> j = ifs.extensions.iterator();
while (j.hasNext())
{
- String extension = (String)j.next();
+ String extension = j.next();
if (extension.equals(str))
return ifs.name;
}
@@ -370,7 +358,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
j = ifs.mimeTypes.iterator();
while (j.hasNext())
{
- String mimeType = (String)j.next();
+ String mimeType = j.next();
if (mimeType.equals(str))
return ifs.name;
}
@@ -510,10 +498,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
if (pixels == null)
{
- BufferedImage img;
- if(model != null && model.hasAlpha())
- img = CairoSurface.getBufferedImage(width, height);
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ BufferedImage img;
+ if(model != null && model.hasAlpha())
+ img = CairoSurface.getBufferedImage(width, height);
+ img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] pix = new int[4];
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
@@ -527,10 +515,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
workerThread.start();
processImageStarted(1);
synchronized(pixbufLock)
- {
- streamImage(pixels, this.ext, width, height, model.hasAlpha(),
- this);
- }
+ {
+ streamImage(pixels, this.ext, width, height, model.hasAlpha(),
+ this);
+ }
synchronized(data)
{
data.add(DATADONE);
@@ -539,18 +527,18 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
while (workerThread.isAlive())
{
- try
- {
- workerThread.join();
- }
- catch (InterruptedException ioe)
- {
- // Ignored.
- }
+ try
+ {
+ workerThread.join();
+ }
+ catch (InterruptedException ioe)
+ {
+ // Ignored.
+ }
}
if (exception != null)
- throw exception;
+ throw exception;
processImageComplete();
}
@@ -566,7 +554,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
* Needs to be synchronized for access.
* The special object DATADONE is added when all data has been delivered.
*/
- private ArrayList data = new ArrayList();
+ private ArrayList<Object> data = new ArrayList<Object>();
/**
* Holds any IOException thrown by the run method that needs
@@ -643,7 +631,8 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
this.ext = findFormatName(ext, false);
}
- public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext, GdkPixbufDecoder d)
+ public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext,
+ GdkPixbufDecoder d)
{
this(ownerSpi, ext);
dec = d;
@@ -680,10 +669,12 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
if (bufferedImage == null)
{
- if(model != null && model.hasAlpha())
- bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
- else
- bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
+ if(model != null && model.hasAlpha())
+ bufferedImage = new BufferedImage (width, height,
+ BufferedImage.TYPE_INT_ARGB);
+ else
+ bufferedImage = new BufferedImage (width, height,
+ BufferedImage.TYPE_INT_RGB);
}
int pixels2[];
@@ -735,11 +726,11 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
return null;
}
- public Iterator getImageTypes(int imageIndex)
+ public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
throws IOException
{
BufferedImage img = getBufferedImage();
- Vector vec = new Vector();
+ Vector<ImageTypeSpecifier> vec = new Vector<ImageTypeSpecifier>();
vec.add(new ImageTypeSpecifier(img));
return vec.iterator();
}
@@ -767,8 +758,8 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
else if (get instanceof DataInput)
dec = new GdkPixbufDecoder((DataInput) get);
else
- throw new IllegalArgumentException("input object not supported: "
- + get);
+ throw new IllegalArgumentException("input object not supported: "
+ + get);
}
public BufferedImage read(int imageIndex, ImageReadParam param)
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java
index 62116a3226c..a69c6f0659e 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java
@@ -188,7 +188,7 @@ class GdkScreenGraphicsDevice extends GraphicsDevice
displayModes = nativeGetDisplayModes(env);
}
- ArrayList list = new ArrayList();
+ ArrayList<DisplayMode> list = new ArrayList<DisplayMode>();
for(int i=0;i<displayModes.length;i++)
for(int j=0;j<displayModes[i].rates.length;j++)
list.add(new DisplayMode(displayModes[i].width,
@@ -196,7 +196,7 @@ class GdkScreenGraphicsDevice extends GraphicsDevice
DisplayMode.BIT_DEPTH_MULTI,
displayModes[i].rates[j]));
- return (DisplayMode[]) list.toArray(new DisplayMode[list.size()]);
+ return list.toArray(new DisplayMode[list.size()]);
}
native X11DisplayMode[] nativeGetDisplayModes(GdkGraphicsEnvironment env);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
index 90d16c57282..4a41d0696c3 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
@@ -57,7 +57,8 @@ public class GtkCheckboxPeer extends GtkComponentPeer
private boolean currentState;
// A map from CheckboxGroup to GSList* GTK option group pointer.
- private static WeakHashMap groupMap = new WeakHashMap();
+ private static WeakHashMap<CheckboxGroup,Long> groupMap
+ = new WeakHashMap<CheckboxGroup,Long>();
public native void createCheckButton ();
public native void createRadioButton (long groupPointer);
@@ -98,7 +99,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer
Long groupPointer = null;
synchronized (groupMap)
{
- groupPointer = (Long) groupMap.get(current_group);
+ groupPointer = groupMap.get(current_group);
}
if (groupPointer == null)
@@ -133,8 +134,8 @@ public class GtkCheckboxPeer extends GtkComponentPeer
{
if (currentState != state)
{
- currentState = state;
- gtkToggleButtonSetActive(state);
+ currentState = state;
+ gtkToggleButtonSetActive(state);
}
}
@@ -158,7 +159,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer
Long groupPointer = null;
synchronized (groupMap)
{
- groupPointer = (Long) groupMap.get(current_group);
+ groupPointer = groupMap.get(current_group);
}
if (groupPointer == null)
@@ -203,7 +204,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer
Long groupPointer = null;
synchronized (groupMap)
{
- groupPointer = (Long) groupMap.get(current_group);
+ groupPointer = groupMap.get(current_group);
}
if (groupPointer == null)
@@ -230,9 +231,9 @@ public class GtkCheckboxPeer extends GtkComponentPeer
// Only fire event is state actually changed.
if (currentState != state)
{
- currentState = state;
- super.postItemEvent(awtComponent,
- state ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
+ currentState = state;
+ super.postItemEvent(awtComponent,
+ state ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java
index d866cefd33c..ff061d35c74 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java
@@ -55,12 +55,12 @@ public class GtkChoicePeer extends GtkComponentPeer
int count = c.getItemCount ();
if (count > 0)
{
- for (int i = 0; i < count; i++)
- add( c.getItem(i), i );
+ for (int i = 0; i < count; i++)
+ add(c.getItem(i), i);
- selected = c.getSelectedIndex();
- if( selected >= 0 )
- select( selected );
+ selected = c.getSelectedIndex();
+ if (selected >= 0)
+ select( selected );
}
else
selected = -1;
@@ -121,9 +121,9 @@ public class GtkChoicePeer extends GtkComponentPeer
{
if( selected != index )
{
- selected = index;
- postItemEvent (((Choice) awtComponent).getItem( selected ),
- ItemEvent.SELECTED);
+ selected = index;
+ postItemEvent (((Choice) awtComponent).getItem( selected ),
+ ItemEvent.SELECTED);
}
}
@@ -133,11 +133,11 @@ public class GtkChoicePeer extends GtkComponentPeer
*/
public void handleEvent (AWTEvent event)
{
- super.handleEvent( event );
- if( event instanceof ItemEvent )
- if( ((ItemEvent)event).getItemSelectable() == awtComponent &&
- ((ItemEvent)event).getStateChange() == ItemEvent.SELECTED )
- ((Choice)awtComponent).select( selected );
+ super.handleEvent (event);
+ if (event instanceof ItemEvent)
+ if (((ItemEvent)event).getItemSelectable() == awtComponent
+ && ((ItemEvent)event).getStateChange() == ItemEvent.SELECTED)
+ ((Choice)awtComponent).select( selected );
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java
index f520fe224b1..e41754641bb 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java
@@ -71,9 +71,9 @@ public class GtkClipboard extends Clipboard
// cached by GtkSelection. True if
// gdk_display_supports_selection_notification.
static final boolean canCache = initNativeState(clipboard, selection,
- stringMimeType,
- imageMimeType,
- filesMimeType);
+ stringMimeType,
+ imageMimeType,
+ filesMimeType);
/**
* Creates the clipboard and sets the initial contents to the
@@ -140,8 +140,8 @@ public class GtkClipboard extends Clipboard
if (contents == null)
{
- advertiseContent(null, false, false, false);
- return;
+ advertiseContent(null, false, false, false);
+ return;
}
// We don't need to do anything for a GtkSelection facade.
@@ -153,46 +153,45 @@ public class GtkClipboard extends Clipboard
boolean files = false;
if (contents instanceof StringSelection
- || contents.isDataFlavorSupported(DataFlavor.stringFlavor)
- || contents.isDataFlavorSupported(DataFlavor.plainTextFlavor)
- || contents.isDataFlavorSupported(DataFlavor
- .getTextPlainUnicodeFlavor()))
+ || contents.isDataFlavorSupported(DataFlavor.stringFlavor)
+ || contents.isDataFlavorSupported(DataFlavor.plainTextFlavor)
+ || contents.isDataFlavorSupported(DataFlavor.getTextPlainUnicodeFlavor()))
text = true;
DataFlavor[] flavors = contents.getTransferDataFlavors();
String[] mimeTargets = new String[flavors.length];
for (int i = 0; i < flavors.length; i++)
{
- DataFlavor flavor = flavors[i];
- String mimeType = flavor.getMimeType();
- mimeTargets[i] = mimeType;
-
- if (! text)
- if ("text".equals(flavor.getPrimaryType())
- || flavor.isRepresentationClassReader())
- text = true;
-
- if (! images && flavors[i].equals(DataFlavor.imageFlavor))
- {
- try
- {
- Object o = contents.getTransferData(DataFlavor.imageFlavor);
- if (o instanceof Image)
- images = true;
- }
- catch (UnsupportedFlavorException ufe)
- {
- }
- catch (IOException ioe)
- {
- }
- catch (ClassCastException cce)
- {
- }
- }
-
- if (flavors[i].equals(DataFlavor.javaFileListFlavor))
- files = true;
+ DataFlavor flavor = flavors[i];
+ String mimeType = flavor.getMimeType();
+ mimeTargets[i] = mimeType;
+
+ if (! text)
+ if ("text".equals(flavor.getPrimaryType())
+ || flavor.isRepresentationClassReader())
+ text = true;
+
+ if (! images && flavors[i].equals(DataFlavor.imageFlavor))
+ {
+ try
+ {
+ Object o = contents.getTransferData(DataFlavor.imageFlavor);
+ if (o instanceof Image)
+ images = true;
+ }
+ catch (UnsupportedFlavorException ufe)
+ {
+ }
+ catch (IOException ioe)
+ {
+ }
+ catch (ClassCastException cce)
+ {
+ }
+ }
+
+ if (flavors[i].equals(DataFlavor.javaFileListFlavor))
+ files = true;
}
advertiseContent(mimeTargets, text, images, files);
@@ -207,9 +206,9 @@ public class GtkClipboard extends Clipboard
* selection has explicitly been erased.
*/
private native void advertiseContent(String[] targets,
- boolean text,
- boolean images,
- boolean files);
+ boolean text,
+ boolean images,
+ boolean files);
/**
* Called by the gtk+ clipboard when an application has requested
@@ -228,7 +227,7 @@ public class GtkClipboard extends Clipboard
try
{
return (String) contents.getTransferData(DataFlavor.stringFlavor);
- }
+ }
catch (UnsupportedFlavorException ufe)
{
}
@@ -244,20 +243,20 @@ public class GtkClipboard extends Clipboard
// turn the result into a string.
try
{
- DataFlavor plainText = DataFlavor.getTextPlainUnicodeFlavor();
- Reader r = plainText.getReaderForText(contents);
- if (r != null)
- {
- StringBuffer sb = new StringBuffer();
- char[] cs = new char[1024];
- int l = r.read(cs);
- while (l != -1)
- {
- sb.append(cs, 0, l);
- l = r.read(cs);
- }
- return sb.toString();
- }
+ DataFlavor plainText = DataFlavor.getTextPlainUnicodeFlavor();
+ Reader r = plainText.getReaderForText(contents);
+ if (r != null)
+ {
+ StringBuffer sb = new StringBuffer();
+ char[] cs = new char[1024];
+ int l = r.read(cs);
+ while (l != -1)
+ {
+ sb.append(cs, 0, l);
+ l = r.read(cs);
+ }
+ return sb.toString();
+ }
}
catch (IllegalArgumentException iae)
{
@@ -288,11 +287,11 @@ public class GtkClipboard extends Clipboard
try
{
- Object o = contents.getTransferData(DataFlavor.imageFlavor);
- if( o instanceof GtkImage )
- return (GtkImage) o;
- else
- return new GtkImage(((Image)o).getSource());
+ Object o = contents.getTransferData(DataFlavor.imageFlavor);
+ if( o instanceof GtkImage )
+ return (GtkImage) o;
+ else
+ return new GtkImage(((Image)o).getSource());
}
catch (UnsupportedFlavorException ufe)
{
@@ -321,14 +320,13 @@ public class GtkClipboard extends Clipboard
try
{
- List list = (List) contents.getTransferData
- (DataFlavor.javaFileListFlavor);
- String[] uris = new String[list.size()];
- int u = 0;
- Iterator it = list.iterator();
- while (it.hasNext())
- uris[u++] = ((File) it.next()).toURI().toString();
- return uris;
+ List list = (List) contents.getTransferData(DataFlavor.javaFileListFlavor);
+ String[] uris = new String[list.size()];
+ int u = 0;
+ Iterator it = list.iterator();
+ while (it.hasNext())
+ uris[u++] = ((File) it.next()).toURI().toString();
+ return uris;
}
catch (UnsupportedFlavorException ufe)
{
@@ -365,34 +363,34 @@ public class GtkClipboard extends Clipboard
// the other provideXXX() methods.
try
{
- DataFlavor flavor = new DataFlavor(target);
- Object o = contents.getTransferData(flavor);
-
- if (o instanceof byte[])
- return (byte[]) o;
-
- if (o instanceof InputStream)
- {
- InputStream is = (InputStream) o;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] bs = new byte[1024];
- int l = is.read(bs);
- while (l != -1)
- {
- baos.write(bs, 0, l);
- l = is.read(bs);
- }
- return baos.toByteArray();
- }
-
- if (o instanceof Serializable)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(o);
- oos.close();
- return baos.toByteArray();
- }
+ DataFlavor flavor = new DataFlavor(target);
+ Object o = contents.getTransferData(flavor);
+
+ if (o instanceof byte[])
+ return (byte[]) o;
+
+ if (o instanceof InputStream)
+ {
+ InputStream is = (InputStream) o;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] bs = new byte[1024];
+ int l = is.read(bs);
+ while (l != -1)
+ {
+ baos.write(bs, 0, l);
+ l = is.read(bs);
+ }
+ return baos.toByteArray();
+ }
+
+ if (o instanceof Serializable)
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(o);
+ oos.close();
+ return baos.toByteArray();
+ }
}
catch (ClassNotFoundException cnfe)
{
@@ -416,8 +414,8 @@ public class GtkClipboard extends Clipboard
* Clipboard can be cached (gdk_display_supports_selection_notification).
*/
private static native boolean initNativeState(GtkClipboard clipboard,
- GtkClipboard selection,
- String stringTarget,
- String imageTarget,
- String filesTarget);
+ GtkClipboard selection,
+ String stringTarget,
+ String imageTarget,
+ String filesTarget);
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java
index 61df796dc00..8e593455774 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java
@@ -74,11 +74,11 @@ class GtkClipboardNotifier extends Thread
{
synchronized (notifier)
{
- if (clipboard == GtkClipboard.clipboard)
- announceClipboardChange = true;
- else
- announcePrimaryChange = true;
- notifier.notifyAll();
+ if (clipboard == GtkClipboard.clipboard)
+ announceClipboardChange = true;
+ else
+ announcePrimaryChange = true;
+ notifier.notifyAll();
}
}
@@ -87,44 +87,43 @@ class GtkClipboardNotifier extends Thread
GtkClipboard clipboard;
while (true)
{
- synchronized (this)
- {
- while (! announceClipboardChange && ! announcePrimaryChange)
- {
- try
- {
- this.wait();
- }
- catch (InterruptedException ie)
- {
- // ignore
- }
- }
-
- if (announceClipboardChange)
- {
- clipboard = GtkClipboard.clipboard;
- announceClipboardChange = false;
- }
- else
- {
- clipboard = GtkClipboard.selection;
- announcePrimaryChange = false;
- }
- }
-
- // Do the actual announcement without the lock held. We will
- // notice a new change after this notification has finished.
- try
- {
- clipboard.setContents(new GtkSelection(clipboard), null);
- }
- catch (Throwable t)
- {
- // should never happen, but might if we have some faulty
- // listener.
- t.printStackTrace();
- }
+ synchronized (this)
+ {
+ while (! announceClipboardChange && ! announcePrimaryChange)
+ {
+ try
+ {
+ this.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignore
+ }
+ }
+
+ if (announceClipboardChange)
+ {
+ clipboard = GtkClipboard.clipboard;
+ announceClipboardChange = false;
+ }
+ else
+ {
+ clipboard = GtkClipboard.selection;
+ announcePrimaryChange = false;
+ }
+ }
+
+ // Do the actual announcement without the lock held. We will
+ // notice a new change after this notification has finished.
+ try
+ {
+ clipboard.setContents(new GtkSelection(clipboard), null);
+ }
+ catch (Throwable t)
+ {
+ // should never happen, but might if we have some faulty listener.
+ t.printStackTrace();
+ }
}
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index b1ef09d6e1b..a7ae8e17f2b 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -109,7 +109,7 @@ public class GtkComponentPeer extends GtkGenericPeer
native void gtkWidgetGetLocationOnScreen (int[] point);
native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y);
native void gtkWidgetSetCursorUnlocked (int type, GtkImage image,
- int x, int y);
+ int x, int y);
native void gtkWidgetSetBackground (int red, int green, int blue);
native void gtkWidgetSetForeground (int red, int green, int blue);
native void gtkWidgetSetSensitive (boolean sensitive);
@@ -206,7 +206,7 @@ public class GtkComponentPeer extends GtkGenericPeer
}
public int checkImage (Image image, int width, int height,
- ImageObserver observer)
+ ImageObserver observer)
{
return getToolkit().checkImage(image, width, height, observer);
}
@@ -402,7 +402,7 @@ public class GtkComponentPeer extends GtkGenericPeer
}
public boolean prepareImage (Image image, int width, int height,
- ImageObserver observer)
+ ImageObserver observer)
{
return getToolkit().prepareImage(image, width, height, observer);
}
@@ -539,17 +539,17 @@ public class GtkComponentPeer extends GtkGenericPeer
int type = cursor.getType();
if (cursor instanceof GtkCursor)
{
- GtkCursor gtkCursor = (GtkCursor) cursor;
- image = gtkCursor.getGtkImage();
- Point hotspot = gtkCursor.getHotspot();
- x = hotspot.x;
- y = hotspot.y;
+ GtkCursor gtkCursor = (GtkCursor) cursor;
+ image = gtkCursor.getGtkImage();
+ Point hotspot = gtkCursor.getHotspot();
+ x = hotspot.x;
+ y = hotspot.y;
}
else
{
- image = null;
- x = 0;
- y = 0;
+ image = null;
+ x = 0;
+ y = 0;
}
if (Thread.currentThread() == GtkMainThread.mainThread)
@@ -597,7 +597,7 @@ public class GtkComponentPeer extends GtkGenericPeer
if (b && ! (awtComponent instanceof Window))
{
Rectangle bounds = awtComponent.getBounds();
- b = (bounds.width > 0) && (bounds.height > 0);
+ b = (bounds.width > 0) && (bounds.height > 0);
}
if (Thread.currentThread() == GtkMainThread.mainThread)
@@ -617,23 +617,23 @@ public class GtkComponentPeer extends GtkGenericPeer
}
protected void postMouseEvent(int id, long when, int mods, int x, int y,
- int clickCount, boolean popupTrigger)
+ int clickCount, boolean popupTrigger)
{
q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y,
- clickCount, popupTrigger));
+ clickCount, popupTrigger));
}
/**
* Callback for component_scroll_cb.
*/
protected void postMouseWheelEvent(int id, long when, int mods,
- int x, int y, int clickCount,
- boolean popupTrigger,
- int type, int amount, int rotation)
+ int x, int y, int clickCount,
+ boolean popupTrigger,
+ int type, int amount, int rotation)
{
q().postEvent(new MouseWheelEvent(awtComponent, id, when, mods,
- x, y, clickCount, popupTrigger,
- type, amount, rotation));
+ x, y, clickCount, popupTrigger,
+ type, amount, rotation));
}
protected void postExposeEvent (int x, int y, int width, int height)
@@ -659,12 +659,12 @@ public class GtkComponentPeer extends GtkGenericPeer
&& keyCode != KeyEvent.VK_ALT))
{
synchronized(q)
- {
- q.postEvent(keyEvent);
- keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when,
- mods, KeyEvent.VK_UNDEFINED, keyChar,
- keyLocation);
- q.postEvent(keyEvent);
+ {
+ q.postEvent(keyEvent);
+ keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when,
+ mods, KeyEvent.VK_UNDEFINED, keyChar,
+ keyLocation);
+ q.postEvent(keyEvent);
}
}
else
@@ -685,8 +685,8 @@ public class GtkComponentPeer extends GtkGenericPeer
protected void postItemEvent (Object item, int stateChange)
{
q().postEvent (new ItemEvent ((ItemSelectable)awtComponent,
- ItemEvent.ITEM_STATE_CHANGED,
- item, stateChange));
+ ItemEvent.ITEM_STATE_CHANGED,
+ item, stateChange));
}
protected void postTextEvent ()
@@ -828,8 +828,8 @@ public class GtkComponentPeer extends GtkGenericPeer
// buffer and one front buffer.
if (numBuffers == 2)
backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(),
- awtComponent.getHeight(),
- caps.getBackBufferCapabilities());
+ awtComponent.getHeight(),
+ caps.getBackBufferCapabilities());
else
throw new AWTException("GtkComponentPeer.createBuffers:"
+ " multi-buffering not supported");
@@ -846,18 +846,18 @@ public class GtkComponentPeer extends GtkGenericPeer
public void flip (BufferCapabilities.FlipContents contents)
{
getGraphics().drawImage(backBuffer,
- awtComponent.getWidth(),
- awtComponent.getHeight(),
- null);
+ awtComponent.getWidth(),
+ awtComponent.getHeight(),
+ null);
// create new back buffer and clear it to the background color.
if (contents == BufferCapabilities.FlipContents.BACKGROUND)
{
backBuffer = createVolatileImage(awtComponent.getWidth(),
- awtComponent.getHeight());
+ awtComponent.getHeight());
backBuffer.getGraphics().clearRect(0, 0,
- awtComponent.getWidth(),
- awtComponent.getHeight());
+ awtComponent.getWidth(),
+ awtComponent.getHeight());
}
// FIXME: support BufferCapabilities.FlipContents.PRIOR
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
index 8650578f70e..7d5ef91de13 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
@@ -40,7 +40,6 @@ package gnu.java.awt.peer.gtk;
import java.awt.Dialog;
import java.awt.FileDialog;
-import java.awt.Graphics;
import java.awt.event.PaintEvent;
import java.awt.peer.FileDialogPeer;
import java.io.File;
@@ -160,7 +159,8 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer
in turn call the filter's accept() method and give back the return
value. */
// called back by native side: filename_filter_cb
- boolean filenameFilterCallback (String fullname) {
+ boolean filenameFilterCallback (String fullname)
+ {
String filename = fullname.substring(fullname.lastIndexOf(FS) + 1);
String dirname = fullname.substring(0, fullname.lastIndexOf(FS));
File dir = new File(dirname);
@@ -205,19 +205,19 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer
if (sepIndex < 0)
{
/* This should never happen on Unix (all paths start with '/') */
- currentFile = fileName;
+ currentFile = fileName;
}
else
{
if (fileName.length() > (sepIndex + 1))
- {
- String fn = fileName.substring (sepIndex + 1);
- currentFile = fn;
- }
- else
- {
+ {
+ String fn = fileName.substring (sepIndex + 1);
+ currentFile = fn;
+ }
+ else
+ {
currentFile = null;
- }
+ }
String dn = fileName.substring (0, sepIndex + 1);
currentDirectory = dn;
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java
index d113e92f5b4..b35be522746 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java
@@ -1,5 +1,5 @@
/* GtkFramePeer.java -- Implements FramePeer with GTK
- Copyright (C) 1999, 2002, 2004, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -176,13 +176,17 @@ public class GtkFramePeer extends GtkWindowPeer
public void setIconImage (Image image)
{
- if (image != null)
- {
- if (image instanceof GtkImage)
- nativeSetIconImage((GtkImage) image);
- else
- nativeSetIconImage(new GtkImage(image.getSource()));
- }
+ if (image != null)
+ {
+ GtkImage gtkImage;
+ if (image instanceof GtkImage)
+ gtkImage = (GtkImage) image;
+ else
+ gtkImage = new GtkImage(image.getSource());
+
+ if (gtkImage.isLoaded && ! gtkImage.errorLoading)
+ nativeSetIconImage(gtkImage);
+ }
}
protected void postConfigureEvent (int x, int y, int width, int height)
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java
index 0fd98bbd7b4..719669eae0d 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java
@@ -71,7 +71,7 @@ public class GtkImage extends Image
/**
* Properties.
*/
- Hashtable props;
+ Hashtable<?,?> props;
/**
* Loaded or not flag, for asynchronous compatibility.
@@ -87,7 +87,7 @@ public class GtkImage extends Image
/**
* Observer queue.
*/
- Vector observers;
+ Vector<ImageObserver> observers;
/**
* Error flag for loading.
@@ -103,10 +103,10 @@ public class GtkImage extends Image
* The 32-bit AABBGGRR format the GDK uses.
*/
static ColorModel nativeModel = new DirectColorModel(32,
- 0x000000FF,
- 0x0000FF00,
- 0x00FF0000,
- 0xFF000000);
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000);
/**
* The singleton GtkImage that is returned on errors by GtkToolkit.
@@ -178,7 +178,7 @@ public class GtkImage extends Image
public GtkImage (ImageProducer producer)
{
isLoaded = false;
- observers = new Vector();
+ observers = new Vector<ImageObserver>();
source = producer;
errorLoading = false;
source.startProduction(new GtkImageConsumer(this, source));
@@ -194,7 +194,7 @@ public class GtkImage extends Image
{
isLoaded = true;
observers = null;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
errorLoading = false;
}
@@ -208,26 +208,26 @@ public class GtkImage extends Image
File f = new File(filename);
try
{
- String path = f.getCanonicalPath();
- synchronized(pixbufLock)
- {
- if (loadPixbuf(f.getCanonicalPath()) != true)
- throw new IllegalArgumentException("Couldn't load image: "
- + filename);
- }
+ String path = f.getCanonicalPath();
+ synchronized(pixbufLock)
+ {
+ if (loadPixbuf(f.getCanonicalPath()) != true)
+ throw new IllegalArgumentException("Couldn't load image: "
+ + filename);
+ }
}
catch(IOException e)
{
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("Couldn't load image: "
- + filename);
- iae.initCause(e);
- throw iae;
+ IllegalArgumentException iae;
+ iae = new IllegalArgumentException("Couldn't load image: "
+ + filename);
+ iae.initCause(e);
+ throw iae;
}
isLoaded = true;
observers = null;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
}
/**
@@ -240,13 +240,13 @@ public class GtkImage extends Image
{
synchronized(pixbufLock)
{
- if (loadImageFromData (data) != true)
- throw new IllegalArgumentException ("Couldn't load image.");
+ if (loadImageFromData (data) != true)
+ throw new IllegalArgumentException ("Couldn't load image.");
}
isLoaded = true;
observers = null;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
errorLoading = false;
}
@@ -256,7 +256,7 @@ public class GtkImage extends Image
public GtkImage (URL url)
{
isLoaded = false;
- observers = new Vector();
+ observers = new Vector<ImageObserver>();
errorLoading = false;
if( url == null)
return;
@@ -269,23 +269,23 @@ public class GtkImage extends Image
int n = 0;
while ((n = bis.read(buf)) != -1)
- baos.write(buf, 0, n);
+ baos.write(buf, 0, n);
bis.close();
}
catch(IOException e)
{
- throw new IllegalArgumentException ("Couldn't load image.");
+ throw new IllegalArgumentException ("Couldn't load image.");
}
byte[] array = baos.toByteArray();
synchronized(pixbufLock)
{
- if (loadImageFromData(array) != true)
- throw new IllegalArgumentException ("Couldn't load image.");
+ if (loadImageFromData(array) != true)
+ throw new IllegalArgumentException ("Couldn't load image.");
}
isLoaded = true;
observers = null;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
}
/**
@@ -295,14 +295,14 @@ public class GtkImage extends Image
{
this.width = width;
this.height = height;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
isLoaded = true;
observers = null;
// Use the GDK scaling method.
synchronized(pixbufLock)
{
- createScaledPixbuf(src, hints);
+ createScaledPixbuf(src, hints);
}
}
@@ -315,11 +315,11 @@ public class GtkImage extends Image
this.pixbuf = pixbuf;
synchronized(pixbufLock)
{
- createFromPixbuf();
+ createFromPixbuf();
}
isLoaded = true;
observers = null;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
}
/**
@@ -331,7 +331,7 @@ public class GtkImage extends Image
{
this.width = width;
this.height = height;
- props = new Hashtable();
+ props = new Hashtable<String,Object>();
isLoaded = true;
observers = null;
initFromBuffer( bufferPointer );
@@ -346,8 +346,8 @@ public class GtkImage extends Image
{
if (errorImage == null)
{
- errorImage = new GtkImage();
- errorImage.errorLoading = true;
+ errorImage = new GtkImage();
+ errorImage.errorLoading = true;
}
return errorImage;
}
@@ -362,25 +362,25 @@ public class GtkImage extends Image
* Callback from the image consumer.
*/
public void setImage(int width, int height,
- int[] pixels, Hashtable properties)
+ int[] pixels, Hashtable<?,?> properties)
{
this.width = width;
this.height = height;
- props = (properties != null) ? properties : new Hashtable();
+ props = (properties != null) ? properties : new Hashtable<String,Object>();
if (width <= 0 || height <= 0 || pixels == null)
{
- errorLoading = true;
- return;
+ errorLoading = true;
+ return;
}
- isLoaded = true;
- deliver();
synchronized(pixbufLock)
{
- createPixbuf();
- setPixels(pixels);
+ createPixbuf();
+ setPixels(pixels);
}
+ isLoaded = true;
+ deliver();
}
// java.awt.Image methods ////////////////////////////////////////////////
@@ -427,7 +427,7 @@ public class GtkImage extends Image
return null;
}
return new MemoryImageSource(width, height, nativeModel, pixels,
- 0, width);
+ 0, width);
}
/**
@@ -436,19 +436,19 @@ public class GtkImage extends Image
public Graphics getGraphics ()
{
throw new IllegalAccessError("This method only works for off-screen"
- +" Images.");
+ +" Images.");
}
/**
* Returns a scaled instance of this pixbuf.
*/
public Image getScaledInstance(int width,
- int height,
- int hints)
+ int height,
+ int hints)
{
if (width <= 0 || height <= 0)
- throw new IllegalArgumentException("Width and height of scaled bitmap"+
- "must be >= 0");
+ throw new IllegalArgumentException("Width and height of scaled bitmap"
+ + "must be >= 0");
return new GtkImage(this, width, height, hints);
}
@@ -465,13 +465,13 @@ public class GtkImage extends Image
{
if (isLoaded && source != null)
{
- observers = new Vector();
- isLoaded = false;
- synchronized(pixbufLock)
+ observers = new Vector<ImageObserver>();
+ isLoaded = false;
+ synchronized(pixbufLock)
{
freePixbuf();
}
- source.startProduction(new GtkImageConsumer(this, source));
+ source.startProduction(new GtkImageConsumer(this, source));
}
}
@@ -479,10 +479,10 @@ public class GtkImage extends Image
{
if (isLoaded)
{
- synchronized(pixbufLock)
- {
- freePixbuf();
- }
+ synchronized(pixbufLock)
+ {
+ freePixbuf();
+ }
}
}
@@ -493,10 +493,10 @@ public class GtkImage extends Image
{
if (addObserver(observer))
{
- if (errorLoading == true)
- return ImageObserver.ERROR;
- else
- return 0;
+ if (errorLoading == true)
+ return ImageObserver.ERROR;
+ else
+ return 0;
}
return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
@@ -517,8 +517,8 @@ public class GtkImage extends Image
if (observers != null)
for(int i=0; i < observers.size(); i++)
- ((ImageObserver)observers.elementAt(i)).
- imageUpdate(this, flags, 0, 0, width, height);
+ ((ImageObserver)observers.elementAt(i)).imageUpdate(this, flags, 0, 0,
+ width, height);
observers = null;
}
@@ -531,10 +531,10 @@ public class GtkImage extends Image
{
if (!isLoaded)
{
- if(observer != null)
- if (!observers.contains (observer))
- observers.addElement (observer);
- return true;
+ if(observer != null)
+ if (!observers.contains (observer))
+ observers.addElement (observer);
+ return true;
}
return false;
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java
index 53e97bb1a8a..44cfaf9266a 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java
@@ -55,7 +55,7 @@ public class GtkImageConsumer implements ImageConsumer
{
private GtkImage target;
private int width, height;
- private Hashtable properties;
+ private Hashtable<?,?> properties;
private int[] pixelCache = null;
private ImageProducer source;
@@ -97,55 +97,55 @@ public class GtkImageConsumer implements ImageConsumer
}
public synchronized void setPixels (int x, int y, int width, int height,
- ColorModel cm, byte[] pixels,
- int offset, int scansize)
+ ColorModel cm, byte[] pixels,
+ int offset, int scansize)
{
setPixels (x, y, width, height, cm, convertPixels (pixels), offset,
scansize);
}
public synchronized void setPixels (int x, int y, int width, int height,
- ColorModel cm, int[] pixels,
- int offset, int scansize)
+ ColorModel cm, int[] pixels,
+ int offset, int scansize)
{
if (pixelCache == null)
return; // Not sure this should ever happen.
if (cm.equals(GtkImage.nativeModel))
for (int i = 0; i < height; i++)
- System.arraycopy (pixels, offset + (i * scansize),
- pixelCache, (y + i) * this.width + x,
- width);
+ System.arraycopy (pixels, offset + (i * scansize),
+ pixelCache, (y + i) * this.width + x,
+ width);
else
{
- if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
- {
- for (int i = 0; i < height; i++)
- for (int j = 0; j < width; j++)
- {
- // get in RRGGBBAA and convert to AARRGGBB
- int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
- int a = ((pix & 0xFF000000) >> 24) & 0xFF;
- int rgb = (pix & 0x00FFFFFF) << 8;
- pix = rgb | a;
- pixelCache[(y + i) * this.width + x + j] = pix;
- }
- }
- else
- {
- for (int i = 0; i < height; i++)
- for (int j = 0; j < width; j++)
- {
- // get in AARRGGBB and convert to AABBGGRR
- int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
- byte b = (byte)(pix & 0xFF);
- byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF);
- pix &= 0xFF00FF00;
- pix |= ((b & 0xFF) << 16);
- pix |= (r & 0xFF);
- pixelCache[(y + i) * this.width + x + j] = pix;
- }
- }
+ if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
+ {
+ for (int i = 0; i < height; i++)
+ for (int j = 0; j < width; j++)
+ {
+ // get in RRGGBBAA and convert to AARRGGBB
+ int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
+ int a = ((pix & 0xFF000000) >> 24) & 0xFF;
+ int rgb = (pix & 0x00FFFFFF) << 8;
+ pix = rgb | a;
+ pixelCache[(y + i) * this.width + x + j] = pix;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < height; i++)
+ for (int j = 0; j < width; j++)
+ {
+ // get in AARRGGBB and convert to AABBGGRR
+ int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
+ byte b = (byte)(pix & 0xFF);
+ byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF);
+ pix &= 0xFF00FF00;
+ pix |= ((b & 0xFF) << 16);
+ pix |= (r & 0xFF);
+ pixelCache[(y + i) * this.width + x + j] = pix;
+ }
+ }
}
}
@@ -162,7 +162,7 @@ public class GtkImageConsumer implements ImageConsumer
return ret;
}
- public synchronized void setProperties (Hashtable props)
+ public synchronized void setProperties (Hashtable<?,?> props)
{
this.properties = props;
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java
index 02db90d72bd..76f8e5fe331 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java
@@ -90,11 +90,11 @@ public class GtkLabelPeer extends GtkComponentPeer
switch (alignment)
{
case Label.LEFT:
- return 0.0f;
+ return 0.0f;
case Label.CENTER:
- return 0.5f;
+ return 0.5f;
case Label.RIGHT:
- return 1.0f;
+ return 1.0f;
}
return 0.0f;
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java
index bd6ec0aef75..f943a75d171 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java
@@ -148,33 +148,33 @@ public class GtkListPeer extends GtkComponentPeer
{
// Only generate the ActionEvent on the second click of a
// multiple click.
- MouseEvent me = (MouseEvent) e;
- if (!me.isConsumed ()
- && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
- && me.getClickCount() == 2)
- {
+ MouseEvent me = (MouseEvent) e;
+ if (!me.isConsumed ()
+ && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
+ && me.getClickCount() == 2)
+ {
String selectedItem = ((List) awtComponent).getSelectedItem ();
// Double-click only generates an Action event if
// something is selected.
if (selectedItem != null)
- postActionEvent (((List) awtComponent).getSelectedItem (),
- me.getModifiersEx ());
- }
+ postActionEvent (((List) awtComponent).getSelectedItem (),
+ me.getModifiersEx ());
+ }
}
if (e.getID () == KeyEvent.KEY_PRESSED)
{
- KeyEvent ke = (KeyEvent) e;
- if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_ENTER)
- {
+ KeyEvent ke = (KeyEvent) e;
+ if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_ENTER)
+ {
String selectedItem = ((List) awtComponent).getSelectedItem ();
// Enter only generates an Action event if something is
// selected.
if (selectedItem != null)
- postActionEvent (selectedItem, ke.getModifiersEx ());
- }
+ postActionEvent (selectedItem, ke.getModifiersEx ());
+ }
}
super.handleEvent (e);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java
index a4e280fe45f..e40a04eed92 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java
@@ -40,8 +40,6 @@ package gnu.java.awt.peer.gtk;
import gnu.java.awt.peer.NativeEventLoopRunningEvent;
-import java.awt.AWTEvent;
-
/**
* The Java thread representing the native GTK main loop, that is,
* GtkMainThread.mainThread, terminates when GtkToolkit.gtkMain()
@@ -172,9 +170,9 @@ public class GtkMainThread extends Thread
{
synchronized (nWindowsLock)
{
- if (numberOfWindows == 0)
- startMainThread();
- numberOfWindows++;
+ if (numberOfWindows == 0)
+ startMainThread();
+ numberOfWindows++;
}
}
@@ -182,9 +180,9 @@ public class GtkMainThread extends Thread
{
synchronized (nWindowsLock)
{
- numberOfWindows--;
- if (numberOfWindows == 0)
- endMainThread();
+ numberOfWindows--;
+ if (numberOfWindows == 0)
+ endMainThread();
}
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
index 898f224f5e1..c3427b18f36 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
@@ -76,15 +76,15 @@ public class GtkMenuBarPeer extends GtkMenuComponentPeer
{
if (hasHelpMenu)
{
- // Remove the (help) menu, which is after all the other items.
- delMenu(((MenuBar) awtWidget).getMenuCount());
- hasHelpMenu = false;
+ // Remove the (help) menu, which is after all the other items.
+ delMenu(((MenuBar) awtWidget).getMenuCount());
+ hasHelpMenu = false;
}
if (menu != null)
{
- addMenu(menu);
- hasHelpMenu = true;
+ addMenu(menu);
+ hasHelpMenu = true;
}
}
@@ -103,9 +103,9 @@ public class GtkMenuBarPeer extends GtkMenuComponentPeer
// Make sure the help menu is the last one.
if (hasHelpMenu)
{
- addHelpMenu(null);
- addMenu((GtkMenuPeer) m.getPeer());
- addHelpMenu(((MenuBar) awtWidget).getHelpMenu());
+ addHelpMenu(null);
+ addMenu((GtkMenuPeer) m.getPeer());
+ addHelpMenu(((MenuBar) awtWidget).getHelpMenu());
}
else
addMenu((GtkMenuPeer) m.getPeer());
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
index 55b95a18d0f..1e37cefc144 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
@@ -64,9 +64,9 @@ public abstract class GtkMenuComponentPeer extends GtkGenericPeer
if (f == null)
{
MenuContainer parent = mc.getParent ();
- // Submenus inherit the font of their containing Menu(Bar).
- if (parent instanceof MenuComponent)
- f = parent.getFont ();
+ // Submenus inherit the font of their containing Menu(Bar).
+ if (parent instanceof MenuComponent)
+ f = parent.getFont ();
}
setFont(f);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java
index 1d581c1a15c..ff6bdca9fbe 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java
@@ -96,8 +96,8 @@ public class GtkMenuPeer extends GtkMenuItemPeer
MenuShortcut ms = item.getShortcut ();
if (ms != null)
{
- key = ms.getKey ();
- shiftModifier = ms.usesShiftModifier ();
+ key = ms.getKey ();
+ shiftModifier = ms.usesShiftModifier ();
}
addItem ((MenuItemPeer) item.getPeer (), key, shiftModifier);
@@ -110,8 +110,8 @@ public class GtkMenuPeer extends GtkMenuItemPeer
if (ms != null)
{
- key = ms.getKey ();
- shiftModifier = ms.usesShiftModifier ();
+ key = ms.getKey ();
+ shiftModifier = ms.usesShiftModifier ();
}
addItem (item, key, shiftModifier);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
index 02bf84d4e8e..7aea50991df 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
@@ -53,9 +53,9 @@ public class GtkMouseInfoPeer implements MouseInfoPeer
public int fillPointWithCoords(Point p)
{
int[] coords = gde.getMouseCoordinates();
- p.x = coords[1];
- p.y = coords[2];
- return coords[0];
+ p.x = coords[1];
+ p.y = coords[2];
+ return coords[0];
}
public boolean isWindowUnderMouse(Window w)
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
index 69f8b494625..657a2760876 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
@@ -74,10 +74,8 @@ public class GtkScrollPanePeer extends GtkContainerPeer
// If the child is in this range, GTK adds both scrollbars, but
// the AWT doesn't. So set the peer's scroll policy to
// GTK_POLICY_NEVER.
- if ((width > dim[0] - getVScrollbarWidth ()
- && width <= dim[0])
- && (height > dim[1] - getHScrollbarHeight ()
- && height <= dim[1]))
+ if ((width > dim[0] - getVScrollbarWidth () && width <= dim[0])
+ && (height > dim[1] - getHScrollbarHeight () && height <= dim[1]))
setPolicy (ScrollPane.SCROLLBARS_NEVER);
else
setPolicy (((ScrollPane) awtComponent).getScrollbarDisplayPolicy ());
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java
index e4147d36c97..c29706f408f 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java
@@ -50,14 +50,14 @@ public class GtkScrollbarPeer extends GtkComponentPeer
Scrollbar sb = (Scrollbar) awtComponent;
create (sb.getOrientation (), sb.getValue (),
- sb.getMinimum (), sb.getMaximum (),
- sb.getUnitIncrement (), sb.getBlockIncrement (),
- sb.getVisibleAmount ());
+ sb.getMinimum (), sb.getMaximum (),
+ sb.getUnitIncrement (), sb.getBlockIncrement (),
+ sb.getVisibleAmount ());
}
native void create (int orientation, int value,
- int min, int max, int stepIncr, int pageIncr,
- int visibleAmount);
+ int min, int max, int stepIncr, int pageIncr,
+ int visibleAmount);
native void connectSignals ();
@@ -86,7 +86,7 @@ public class GtkScrollbarPeer extends GtkComponentPeer
{
Scrollbar bar = (Scrollbar) awtComponent;
q().postEvent(new AdjustmentEvent(bar,
- AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
- type, value, true));
+ AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+ type, value, true));
}
}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java
index 6a92f86e8b0..967a2edb432 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java
@@ -130,7 +130,7 @@ public class GtkSelection implements Transferable
* Set as response to a requestURIs() call. Only valid when
* urisDelivered is true
*/
- private List uris;
+ private List<File> uris;
/**
* Indicates a requestBytes(String) call was made and the
@@ -163,51 +163,51 @@ public class GtkSelection implements Transferable
DataFlavor[] result;
synchronized (requestLock)
{
- // Did we request already and cache the result?
- if (mimeTypesDelivered)
- result = (DataFlavor[]) dataFlavors.clone();
- else
- {
- // Wait till there are no pending requests.
- while (requestInProgress)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
-
- // If nobody else beat us and cached the result we try
- // ourselves to get it.
- if (! mimeTypesDelivered)
- {
- requestInProgress = true;
- requestMimeTypes(clipboard);
- while (! mimeTypesDelivered)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
- requestInProgress = false;
- }
- result = dataFlavors;
- if (! GtkClipboard.canCache)
- {
- dataFlavors = null;
- mimeTypesDelivered = false;
- }
- requestLock.notifyAll();
- }
+ // Did we request already and cache the result?
+ if (mimeTypesDelivered)
+ result = (DataFlavor[]) dataFlavors.clone();
+ else
+ {
+ // Wait till there are no pending requests.
+ while (requestInProgress)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+
+ // If nobody else beat us and cached the result we try
+ // ourselves to get it.
+ if (! mimeTypesDelivered)
+ {
+ requestInProgress = true;
+ requestMimeTypes(clipboard);
+ while (! mimeTypesDelivered)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+ requestInProgress = false;
+ }
+ result = dataFlavors;
+ if (! GtkClipboard.canCache)
+ {
+ dataFlavors = null;
+ mimeTypesDelivered = false;
+ }
+ requestLock.notifyAll();
+ }
}
return result;
}
@@ -220,53 +220,55 @@ public class GtkSelection implements Transferable
{
synchronized (requestLock)
{
- if (mimeTypes == null)
- dataFlavors = new DataFlavor[0];
- else
- {
- // Most likely the mimeTypes include text in which case we add an
- // extra element.
- ArrayList flavorsList = new ArrayList(mimeTypes.length + 1);
- for (int i = 0; i < mimeTypes.length; i++)
- {
- try
- {
- if (mimeTypes[i] == GtkClipboard.stringMimeType)
- {
- // XXX - Fix DataFlavor.getTextPlainUnicodeFlavor()
- // and also add it to the list.
- flavorsList.add(DataFlavor.stringFlavor);
- flavorsList.add(DataFlavor.plainTextFlavor);
- }
- else if (mimeTypes[i] == GtkClipboard.imageMimeType)
- flavorsList.add(DataFlavor.imageFlavor);
- else if (mimeTypes[i] == GtkClipboard.filesMimeType)
- flavorsList.add(DataFlavor.javaFileListFlavor);
- else
- {
- // We check the target to prevent duplicates
- // of the "magic" targets above.
- DataFlavor target = new DataFlavor(mimeTypes[i]);
- if (! flavorsList.contains(target))
- flavorsList.add(target);
- }
- }
- catch (ClassNotFoundException cnfe)
- {
- cnfe.printStackTrace();
- }
- catch (NullPointerException npe)
- {
- npe.printStackTrace();
- }
- }
+ if (mimeTypes == null)
+ dataFlavors = new DataFlavor[0];
+ else
+ {
+ // Most likely the mimeTypes include text in which case we add an
+ // extra element.
+ ArrayList<DataFlavor> flavorsList =
+ new ArrayList<DataFlavor>(mimeTypes.length + 1);
+
+ for (int i = 0; i < mimeTypes.length; i++)
+ {
+ try
+ {
+ if (mimeTypes[i] == GtkClipboard.stringMimeType)
+ {
+ // XXX - Fix DataFlavor.getTextPlainUnicodeFlavor()
+ // and also add it to the list.
+ flavorsList.add(DataFlavor.stringFlavor);
+ flavorsList.add(DataFlavor.plainTextFlavor);
+ }
+ else if (mimeTypes[i] == GtkClipboard.imageMimeType)
+ flavorsList.add(DataFlavor.imageFlavor);
+ else if (mimeTypes[i] == GtkClipboard.filesMimeType)
+ flavorsList.add(DataFlavor.javaFileListFlavor);
+ else
+ {
+ // We check the target to prevent duplicates
+ // of the "magic" targets above.
+ DataFlavor target = new DataFlavor(mimeTypes[i]);
+ if (! flavorsList.contains(target))
+ flavorsList.add(target);
+ }
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ cnfe.printStackTrace();
+ }
+ catch (NullPointerException npe)
+ {
+ npe.printStackTrace();
+ }
+ }
- dataFlavors = new DataFlavor[flavorsList.size()];
- flavorsList.toArray(dataFlavors);
- }
+ dataFlavors = new DataFlavor[flavorsList.size()];
+ flavorsList.toArray(dataFlavors);
+ }
- mimeTypesDelivered = true;
- requestLock.notifyAll();
+ mimeTypesDelivered = true;
+ requestLock.notifyAll();
}
}
@@ -279,7 +281,7 @@ public class GtkSelection implements Transferable
DataFlavor[] dfs = getTransferDataFlavors();
for (int i = 0; i < dfs.length; i++)
if (flavor.equals(dfs[i]))
- return true;
+ return true;
return false;
}
@@ -294,51 +296,51 @@ public class GtkSelection implements Transferable
String result;
synchronized (requestLock)
{
- // Did we request already and cache the result?
- if (textDelivered)
- result = text;
- else
- {
- // Wait till there are no pending requests.
- while (requestInProgress)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
-
- // If nobody else beat us we try ourselves to get and
- // caching the result.
- if (! textDelivered)
- {
- requestInProgress = true;
- requestText(clipboard);
- while (! textDelivered)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
- requestInProgress = false;
- }
- result = text;
- if (! GtkClipboard.canCache)
- {
- text = null;
- textDelivered = false;
- }
- requestLock.notifyAll();
- }
+ // Did we request already and cache the result?
+ if (textDelivered)
+ result = text;
+ else
+ {
+ // Wait till there are no pending requests.
+ while (requestInProgress)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+
+ // If nobody else beat us we try ourselves to get and
+ // caching the result.
+ if (! textDelivered)
+ {
+ requestInProgress = true;
+ requestText(clipboard);
+ while (! textDelivered)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+ requestInProgress = false;
+ }
+ result = text;
+ if (! GtkClipboard.canCache)
+ {
+ text = null;
+ textDelivered = false;
+ }
+ requestLock.notifyAll();
+ }
}
return result;
}
@@ -351,9 +353,9 @@ public class GtkSelection implements Transferable
{
synchronized (requestLock)
{
- this.text = text;
- textDelivered = true;
- requestLock.notifyAll();
+ this.text = text;
+ textDelivered = true;
+ requestLock.notifyAll();
}
}
@@ -367,54 +369,56 @@ public class GtkSelection implements Transferable
Image result;
synchronized (requestLock)
{
- // Did we request already and cache the result?
- if (imageDelivered)
- result = image;
- else
- {
- // Wait till there are no pending requests.
- while (requestInProgress)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
-
- // If nobody else beat us we try ourselves to get and
- // caching the result.
- if (! imageDelivered)
- {
- requestInProgress = true;
- requestImage(clipboard);
- while (! imageDelivered)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
- requestInProgress = false;
- }
- if (imagePointer != null)
- image = new GtkImage(imagePointer);
- imagePointer = null;
- result = image;
- if (! GtkClipboard.canCache)
- {
- image = null;
- imageDelivered = false;
- }
- requestLock.notifyAll();
- }
+ // Did we request already and cache the result?
+ if (imageDelivered)
+ result = image;
+ else
+ {
+ // Wait till there are no pending requests.
+ while (requestInProgress)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+
+ // If nobody else beat us we try ourselves to get and
+ // caching the result.
+ if (! imageDelivered)
+ {
+ requestInProgress = true;
+ requestImage(clipboard);
+ while (! imageDelivered)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+ requestInProgress = false;
+ }
+
+ if (imagePointer != null)
+ image = new GtkImage(imagePointer);
+
+ imagePointer = null;
+ result = image;
+ if (! GtkClipboard.canCache)
+ {
+ image = null;
+ imageDelivered = false;
+ }
+ requestLock.notifyAll();
+ }
}
return result;
}
@@ -430,9 +434,9 @@ public class GtkSelection implements Transferable
{
synchronized (requestLock)
{
- this.imagePointer = pointer;
- imageDelivered = true;
- requestLock.notifyAll();
+ this.imagePointer = pointer;
+ imageDelivered = true;
+ requestLock.notifyAll();
}
}
@@ -441,56 +445,56 @@ public class GtkSelection implements Transferable
* URIs/Files and if not requests them and waits till they are
* available.
*/
- private List getURIs()
+ private List<File> getURIs()
{
- List result;
+ List<File> result;
synchronized (requestLock)
{
- // Did we request already and cache the result?
- if (urisDelivered)
- result = uris;
- else
- {
- // Wait till there are no pending requests.
- while (requestInProgress)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
-
- // If nobody else beat us we try ourselves to get and
- // caching the result.
- if (! urisDelivered)
- {
- requestInProgress = true;
- requestURIs(clipboard);
- while (! urisDelivered)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
- requestInProgress = false;
- }
- result = uris;
- if (! GtkClipboard.canCache)
- {
- uris = null;
- urisDelivered = false;
- }
- requestLock.notifyAll();
- }
+ // Did we request already and cache the result?
+ if (urisDelivered)
+ result = uris;
+ else
+ {
+ // Wait till there are no pending requests.
+ while (requestInProgress)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+
+ // If nobody else beat us we try ourselves to get and
+ // caching the result.
+ if (! urisDelivered)
+ {
+ requestInProgress = true;
+ requestURIs(clipboard);
+ while (! urisDelivered)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+ requestInProgress = false;
+ }
+ result = uris;
+ if (! GtkClipboard.canCache)
+ {
+ uris = null;
+ urisDelivered = false;
+ }
+ requestLock.notifyAll();
+ }
}
return result;
}
@@ -503,26 +507,26 @@ public class GtkSelection implements Transferable
{
synchronized (requestLock)
{
- if (uris != null && uris.length != 0)
- {
- ArrayList list = new ArrayList(uris.length);
- for (int i = 0; i < uris.length; i++)
- {
- try
- {
- URI uri = new URI(uris[i]);
- if (uri.getScheme().equals("file"))
- list.add(new File(uri));
- }
- catch (URISyntaxException use)
- {
- }
- }
- this.uris = list;
- }
-
- urisDelivered = true;
- requestLock.notifyAll();
+ if (uris != null && uris.length != 0)
+ {
+ ArrayList<File> list = new ArrayList<File>(uris.length);
+ for (int i = 0; i < uris.length; i++)
+ {
+ try
+ {
+ URI uri = new URI(uris[i]);
+ if (uri.getScheme().equals("file"))
+ list.add(new File(uri));
+ }
+ catch (URISyntaxException use)
+ {
+ }
+ }
+ this.uris = list;
+ }
+
+ urisDelivered = true;
+ requestLock.notifyAll();
}
}
@@ -537,39 +541,39 @@ public class GtkSelection implements Transferable
byte[] result;
synchronized (requestLock)
{
- // Wait till there are no pending requests.
- while (requestInProgress)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
-
- // Request bytes and wait till they are available.
- requestInProgress = true;
- requestBytes(clipboard, target);
- while (! bytesDelivered)
- {
- try
- {
- requestLock.wait();
- }
- catch (InterruptedException ie)
- {
- // ignored
- }
- }
- result = bytes;
- bytes = null;
- bytesDelivered = false;
- requestInProgress = false;
+ // Wait till there are no pending requests.
+ while (requestInProgress)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+
+ // Request bytes and wait till they are available.
+ requestInProgress = true;
+ requestBytes(clipboard, target);
+ while (! bytesDelivered)
+ {
+ try
+ {
+ requestLock.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // ignored
+ }
+ }
+ result = bytes;
+ bytes = null;
+ bytesDelivered = false;
+ requestInProgress = false;
- requestLock.notifyAll();
+ requestLock.notifyAll();
}
return result;
}
@@ -583,9 +587,9 @@ public class GtkSelection implements Transferable
{
synchronized (requestLock)
{
- this.bytes = bytes;
- bytesDelivered = true;
- requestLock.notifyAll();
+ this.bytes = bytes;
+ bytesDelivered = true;
+ requestLock.notifyAll();
}
}
@@ -596,30 +600,30 @@ public class GtkSelection implements Transferable
// try one more time through getBytes().
if (flavor.equals(DataFlavor.stringFlavor))
{
- String text = getText();
- if (text != null)
- return text;
+ String text = getText();
+ if (text != null)
+ return text;
}
if (flavor.equals(DataFlavor.plainTextFlavor))
{
- String text = getText();
- if (text != null)
- return new StringBufferInputStream(text);
+ String text = getText();
+ if (text != null)
+ return new StringBufferInputStream(text);
}
if (flavor.equals(DataFlavor.imageFlavor))
{
- Image image = getImage();
- if (image != null)
- return image;
+ Image image = getImage();
+ if (image != null)
+ return image;
}
if (flavor.equals(DataFlavor.javaFileListFlavor))
{
- List uris = getURIs();
- if (uris != null)
- return uris;
+ List<File> uris = getURIs();
+ if (uris != null)
+ return uris;
}
byte[] bytes = getBytes(flavor.getMimeType());
@@ -628,20 +632,20 @@ public class GtkSelection implements Transferable
if (flavor.isMimeTypeSerializedObject())
{
- try
- {
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais);
- return ois.readObject();
- }
- catch (IOException ioe)
- {
- ioe.printStackTrace();
- }
- catch (ClassNotFoundException cnfe)
- {
- cnfe.printStackTrace();
- }
+ try
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ return ois.readObject();
+ }
+ catch (IOException ioe)
+ {
+ ioe.printStackTrace();
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ cnfe.printStackTrace();
+ }
}
if (flavor.isRepresentationClassInputStream())
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
index 5d9be1aec63..0c7d3a860e8 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
@@ -100,8 +100,8 @@ public class GtkTextAreaPeer extends GtkComponentPeer
// GtkComponent.create.
if (f == null)
{
- f = new Font ("Dialog", Font.PLAIN, 12);
- awtComponent.setFont (f);
+ f = new Font ("Dialog", Font.PLAIN, 12);
+ awtComponent.setFont (f);
}
FontMetrics fm = getFontMetrics (f);
@@ -154,11 +154,11 @@ public class GtkTextAreaPeer extends GtkComponentPeer
int width = 0;
if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
- || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
height = getHScrollbarHeight ();
if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
- || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
width = getVScrollbarWidth ();
Font f = awtComponent.getFont ();
@@ -183,11 +183,11 @@ public class GtkTextAreaPeer extends GtkComponentPeer
int width = 0;
if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
- || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
height = getHScrollbarHeight ();
if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
- || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
width = getVScrollbarWidth ();
Font f = awtComponent.getFont ();
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
index 763304864e0..9e62c8e7975 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
@@ -94,8 +94,8 @@ public class GtkTextFieldPeer extends GtkComponentPeer
// GtkComponent.create.
if (f == null)
{
- f = new Font ("Dialog", Font.PLAIN, 12);
- awtComponent.setFont (f);
+ f = new Font ("Dialog", Font.PLAIN, 12);
+ awtComponent.setFont (f);
}
FontMetrics fm = getFontMetrics (f);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java
index f746a47479f..df18d39c9d2 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java
@@ -1,5 +1,5 @@
/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
- Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
+import gnu.java.awt.AWTUtilities;
import gnu.java.awt.EmbeddedWindow;
import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer;
import gnu.java.awt.dnd.peer.gtk.GtkDragSourceContextPeer;
@@ -86,6 +87,7 @@ import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
@@ -104,8 +106,8 @@ import java.awt.peer.LabelPeer;
import java.awt.peer.ListPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
-import java.awt.peer.MouseInfoPeer;
import java.awt.peer.MenuPeer;
+import java.awt.peer.MouseInfoPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.RobotPeer;
@@ -132,9 +134,11 @@ import javax.imageio.spi.IIORegistry;
public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
+ static final Object GTK_LOCK;
+
private static EventQueue q;
- static native void gtkInit(int portableNativeSync);
+ static native void gtkInit(int portableNativeSync, Object lock);
static native void gtkMain();
@@ -154,8 +158,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
portableNativeSync = 1; // true
else
portableNativeSync = 0; // false
-
- gtkInit(portableNativeSync);
+
+ GTK_LOCK = new String("GTK LOCK");
+ gtkInit(portableNativeSync, GTK_LOCK);
}
public GtkToolkit ()
@@ -167,14 +172,14 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
private native void getScreenSizeDimensions(int[] xy);
public int checkImage (Image image, int width, int height,
- ImageObserver observer)
+ ImageObserver observer)
{
int status = ImageObserver.ALLBITS
| ImageObserver.WIDTH
| ImageObserver.HEIGHT;
if (image instanceof GtkImage)
- return ((GtkImage) image).checkImage (observer);
+ return ((GtkImage) image).checkImage (observer);
if (image instanceof AsyncImage)
return ((AsyncImage) image).checkImage(observer);
@@ -208,11 +213,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
+ image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
}
catch (IllegalArgumentException iae)
{
- image = null;
+ image = null;
}
return imageOrError(image);
}
@@ -230,11 +235,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
+ image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
}
catch (IllegalArgumentException iae)
{
- image = null;
+ image = null;
}
return imageOrError(image);
}
@@ -245,13 +250,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- byte[] data = new byte[ imagelength ];
- System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
- image = CairoSurface.getBufferedImage( new GtkImage( data ) );
+ byte[] data = new byte[ imagelength ];
+ System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
+ image = CairoSurface.getBufferedImage( new GtkImage( data ) );
}
catch (IllegalArgumentException iae)
{
- image = null;
+ image = null;
}
return imageOrError(image);
}
@@ -275,22 +280,22 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
/* Return the GDK-native ABGR format */
return new DirectColorModel(32,
- 0x000000FF,
- 0x0000FF00,
- 0x00FF0000,
- 0xFF000000);
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000);
}
public String[] getFontList ()
{
return (new String[] { "Dialog",
- "DialogInput",
- "Monospaced",
- "Serif",
- "SansSerif" });
+ "DialogInput",
+ "Monospaced",
+ "Serif",
+ "SansSerif" });
}
- static class LRUCache extends LinkedHashMap
+ static class LRUCache<K,V> extends LinkedHashMap<K,V>
{
int max_entries;
public LRUCache(int max)
@@ -304,8 +309,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
}
}
- private LRUCache fontCache = new LRUCache(50);
- private LRUCache imageCache = new LRUCache(50);
+ private LRUCache<Map,ClasspathFontPeer> fontCache =
+ new LRUCache<Map,ClasspathFontPeer>(50);
+ private LRUCache<Object,Image> imageCache = new LRUCache<Object,Image>(50);
public FontMetrics getFontMetrics (Font font)
{
@@ -315,7 +321,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
public Image getImage (String filename)
{
if (imageCache.containsKey(filename))
- return (Image) imageCache.get(filename);
+ return imageCache.get(filename);
else
{
Image im = createImage(filename);
@@ -327,7 +333,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
public Image getImage (URL url)
{
if (imageCache.containsKey(url))
- return (Image) imageCache.get(url);
+ return imageCache.get(url);
else
{
Image im = createImage(url);
@@ -378,12 +384,12 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
* assumes the image is already prepared for rendering.
*/
public boolean prepareImage (Image image, int width, int height,
- ImageObserver observer)
+ ImageObserver observer)
{
/* GtkImages are always prepared, as long as they're loaded. */
if (image instanceof GtkImage)
- return ((((GtkImage)image).checkImage (observer) &
- ImageObserver.ALLBITS) != 0);
+ return ((((GtkImage)image).checkImage (observer)
+ & ImageObserver.ALLBITS) != 0);
if (image instanceof AsyncImage)
{
@@ -411,11 +417,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
/* Make the Peer reflect the state of the Component */
if (! (c instanceof Window))
{
- cp.setCursor (c.getCursor ());
+ cp.setCursor (c.getCursor ());
- Rectangle bounds = c.getBounds ();
- cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
- cp.setVisible (c.isVisible ());
+ Rectangle bounds = c.getBounds ();
+ cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+ cp.setVisible (c.isVisible ());
}
}
@@ -563,7 +569,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
*/
private FontPeer getFontPeer (String name, int style, int size)
{
- Map attrs = new HashMap ();
+ Map<TextAttribute,Object> attrs = new HashMap<TextAttribute,Object>();
ClasspathFontPeer.copyStyleToAttrs (style, attrs);
ClasspathFontPeer.copySizeToAttrs (size, attrs);
return getClasspathFontPeer (name, attrs);
@@ -575,16 +581,17 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
* model, hence "ClasspathFontPeer".
*/
- public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
+ public ClasspathFontPeer getClasspathFontPeer (String name,
+ Map<?,?> attrs)
{
- Map keyMap = new HashMap (attrs);
+ Map<Object,Object> keyMap = new HashMap<Object,Object>(attrs);
// We don't know what kind of "name" the user requested (logical, face,
// family), and we don't actually *need* to know here. The worst case
// involves failure to consolidate fonts with the same backend in our
// cache. This is harmless.
keyMap.put ("GtkToolkit.RequestedFontName", name);
if (fontCache.containsKey (keyMap))
- return (ClasspathFontPeer) fontCache.get (keyMap);
+ return fontCache.get (keyMap);
else
{
ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
@@ -619,11 +626,10 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
return new GtkDragSourceContextPeer(e);
}
- public DragGestureRecognizer createDragGestureRecognizer(Class recognizer,
- DragSource ds,
- Component comp,
- int actions,
- DragGestureListener l)
+ public <T extends DragGestureRecognizer> T
+ createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
+ Component comp, int actions,
+ DragGestureListener l)
{
if (recognizer.getName().equals("java.awt.dnd.MouseDragGestureRecognizer")
&& ! GraphicsEnvironment.isHeadless())
@@ -631,7 +637,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
GtkMouseDragGestureRecognizer gestureRecognizer
= new GtkMouseDragGestureRecognizer(ds, comp, actions, l);
gestureRecognizer.registerListeners();
- return gestureRecognizer;
+ return recognizer.cast(gestureRecognizer);
}
else
{
@@ -639,7 +645,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
}
}
- public Map mapInputMethodHighlight(InputMethodHighlight highlight)
+ public Map<TextAttribute,?> mapInputMethodHighlight(InputMethodHighlight highlight)
{
throw new Error("not implemented");
}
@@ -668,6 +674,22 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
return new GdkRobotPeer (screen);
}
+ public boolean getLockingKeyState(int keyCode)
+ {
+ int state = getLockState(keyCode);
+
+ if (state != -1)
+ return state == 1;
+
+ if (AWTUtilities.isValidKey(keyCode))
+ throw new UnsupportedOperationException
+ ("cannot get locking state of key code " + keyCode);
+
+ throw new IllegalArgumentException("invalid key code " + keyCode);
+ }
+
+ protected native int getLockState(int keyCode);
+
public void registerImageIOSpis(IIORegistry reg)
{
GdkPixbufDecoder.registerSpis(reg);
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
index 8d49719b1d3..1451dd93354 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
@@ -172,19 +172,17 @@ public class GtkWindowPeer extends GtkContainerPeer
public void setBounds (int x, int y, int width, int height)
{
- if (x != getX()
- || y != getY()
- || width != getWidth()
- || height != getHeight())
+ if (x != getX() || y != getY() || width != getWidth()
+ || height != getHeight())
{
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
- nativeSetBounds (x, y,
- width - insets.left - insets.right,
- height - insets.top - insets.bottom);
+ nativeSetBounds (x, y,
+ width - insets.left - insets.right,
+ height - insets.top - insets.bottom);
}
}
@@ -211,7 +209,7 @@ public class GtkWindowPeer extends GtkContainerPeer
width = awtComponent.getWidth();
height = awtComponent.getHeight();
setSize (width - insets.left - insets.right,
- height - insets.top - insets.bottom);
+ height - insets.top - insets.bottom);
gtkWindowSetResizable (resizable);
}
@@ -253,22 +251,20 @@ public class GtkWindowPeer extends GtkContainerPeer
awtComponent.dispatchEvent(ev);
}
- if (frame_width != getWidth()
- || frame_height != getHeight())
+ if (frame_width != getWidth() || frame_height != getHeight())
{
- this.width = frame_width;
- this.height = frame_height;
- q().postEvent(new ComponentEvent(awtComponent,
- ComponentEvent.COMPONENT_RESIZED));
+ this.width = frame_width;
+ this.height = frame_height;
+ q().postEvent(new ComponentEvent(awtComponent,
+ ComponentEvent.COMPONENT_RESIZED));
}
- if (frame_x != getX()
- || frame_y != getY())
+ if (frame_x != getX() || frame_y != getY())
{
- this.x = frame_x;
- this.y = frame_y;
- q().postEvent(new ComponentEvent(awtComponent,
- ComponentEvent.COMPONENT_MOVED));
+ this.x = frame_x;
+ this.y = frame_y;
+ q().postEvent(new ComponentEvent(awtComponent,
+ ComponentEvent.COMPONENT_MOVED));
}
}
@@ -287,8 +283,8 @@ public class GtkWindowPeer extends GtkContainerPeer
{
if (id == WindowEvent.WINDOW_STATE_CHANGED)
{
- if (windowState != newState)
- {
+ if (windowState != newState)
+ {
// Post old styleWindowEvent with WINDOW_ICONIFIED or
// WINDOW_DEICONIFIED if appropriate.
if ((windowState & Frame.ICONIFIED) != 0
@@ -302,10 +298,10 @@ public class GtkWindowPeer extends GtkContainerPeer
WindowEvent.WINDOW_ICONIFIED,
opposite, 0, 0));
// Post new-style WindowStateEvent.
- q().postEvent (new WindowEvent ((Window) awtComponent, id,
+ q().postEvent (new WindowEvent ((Window) awtComponent, id,
opposite, windowState, newState));
- windowState = newState;
- }
+ windowState = newState;
+ }
}
else
q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite));
@@ -384,7 +380,7 @@ public class GtkWindowPeer extends GtkContainerPeer
}
protected void postMouseEvent(int id, long when, int mods, int x, int y,
- int clickCount, boolean popupTrigger)
+ int clickCount, boolean popupTrigger)
{
// Translate AWT co-ordinates, which include a window frame's
// insets, to GTK co-ordinates, which do not include a window
@@ -392,8 +388,8 @@ public class GtkWindowPeer extends GtkContainerPeer
// insets but GtkFramePeer and GtkDialogPeer insets will be
// non-zero.
super.postMouseEvent (id, when, mods,
- x + insets.left, y + insets.top,
- clickCount, popupTrigger);
+ x + insets.left, y + insets.top,
+ clickCount, popupTrigger);
}
// We override this to keep it in sync with our internal
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
index 62dbb45d81a..88438862b34 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
@@ -207,11 +207,11 @@ public class VolatileImageGraphics extends ComponentGraphics
if (img instanceof GtkVolatileImage
&& (comp == null || comp instanceof AlphaComposite))
{
- owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
- x, y,
- ((GtkVolatileImage)img).width,
- ((GtkVolatileImage)img).height );
- return true;
+ owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
+ x, y,
+ ((GtkVolatileImage)img).width,
+ ((GtkVolatileImage)img).height );
+ return true;
}
return super.drawImage( img, x, y, observer );
}
@@ -222,9 +222,9 @@ public class VolatileImageGraphics extends ComponentGraphics
if ((img instanceof GtkVolatileImage)
&& (comp == null || comp instanceof AlphaComposite))
{
- owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
- x, y, width, height );
- return true;
+ owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
+ x, y, width, height );
+ return true;
}
return super.drawImage( img, x, y, width, height, observer );
}
@@ -254,8 +254,8 @@ public class VolatileImageGraphics extends ComponentGraphics
transform.transform(points, 0, points, 0, 2);
Rectangle2D deviceBounds = new Rectangle2D.Double(points[0], points[1],
- points[2] - points[0],
- points[3] - points[1]);
+ points[2] - points[0],
+ points[3] - points[1]);
Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds);
current = current.getSubimage((int)deviceBounds.getX(),
diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java
index 5116769389e..9b53b278b26 100644
--- a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java
+++ b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java
@@ -1,5 +1,5 @@
/* QtToolkit.java --
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.java.awt.peer.qt;
+import gnu.java.awt.ClasspathToolkit;
import gnu.java.awt.EmbeddedWindow;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.peer.EmbeddedWindowPeer;
@@ -50,56 +51,56 @@ import java.awt.Choice;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
+import java.awt.FileDialog;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Label;
import java.awt.List;
-import java.awt.MenuBar;
import java.awt.Menu;
+import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
-import java.awt.TextArea;
-import java.awt.TextField;
-import java.awt.FileDialog;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
import java.awt.PopupMenu;
import java.awt.PrintJob;
-import java.awt.Scrollbar;
import java.awt.ScrollPane;
+import java.awt.Scrollbar;
+import java.awt.TextArea;
+import java.awt.TextField;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.AWTEventListener;
+import java.awt.im.InputMethodHighlight;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
-import java.awt.im.InputMethodHighlight;
import java.awt.peer.ButtonPeer;
-import java.awt.peer.FontPeer;
-import java.awt.peer.PanelPeer;
import java.awt.peer.CanvasPeer;
-import java.awt.peer.FramePeer;
-import java.awt.peer.PopupMenuPeer;
import java.awt.peer.CheckboxMenuItemPeer;
-import java.awt.peer.LabelPeer;
-import java.awt.peer.RobotPeer;
import java.awt.peer.CheckboxPeer;
-import java.awt.peer.ScrollPanePeer;
import java.awt.peer.ChoicePeer;
+import java.awt.peer.DialogPeer;
+import java.awt.peer.FileDialogPeer;
+import java.awt.peer.FontPeer;
+import java.awt.peer.FramePeer;
+import java.awt.peer.LabelPeer;
import java.awt.peer.ListPeer;
-import java.awt.peer.ScrollbarPeer;
import java.awt.peer.MenuBarPeer;
-import java.awt.peer.TextAreaPeer;
-import java.awt.peer.DialogPeer;
import java.awt.peer.MenuItemPeer;
-import java.awt.peer.TextFieldPeer;
-import java.awt.peer.FileDialogPeer;
import java.awt.peer.MenuPeer;
+import java.awt.peer.PanelPeer;
+import java.awt.peer.PopupMenuPeer;
+import java.awt.peer.RobotPeer;
+import java.awt.peer.ScrollPanePeer;
+import java.awt.peer.ScrollbarPeer;
+import java.awt.peer.TextAreaPeer;
+import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
import java.io.InputStream;
import java.net.URL;
@@ -107,8 +108,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
-import gnu.java.awt.ClasspathToolkit;
-
public class QtToolkit extends ClasspathToolkit
{
public static EventQueue eventQueue = null; // the native event queue
@@ -163,7 +162,9 @@ public class QtToolkit extends ClasspathToolkit
if( guiThread == null )
initToolkit();
- while (!guiThread.isRunning()); // make sure the GUI thread has started.
+ // make sure the GUI thread has started.
+ while (!guiThread.isRunning())
+ ;
if( graphicsEnv == null )
graphicsEnv = new QtGraphicsEnvironment( this );
diff --git a/libjava/classpath/gnu/java/awt/print/JavaPrinterGraphics.java b/libjava/classpath/gnu/java/awt/print/JavaPrinterGraphics.java
index 9a3db012583..b86eea50b20 100644
--- a/libjava/classpath/gnu/java/awt/print/JavaPrinterGraphics.java
+++ b/libjava/classpath/gnu/java/awt/print/JavaPrinterGraphics.java
@@ -135,7 +135,8 @@ public class JavaPrinterGraphics extends Graphics implements PrinterGraphics
{
int index = 0;
while(spoolPage(out, printable, pageFormat, index++) ==
- Printable.PAGE_EXISTS);
+ Printable.PAGE_EXISTS)
+ ;
}
out.println("%%Trailer");
out.println("%%EOF");
diff --git a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java
index e4cc8199a54..4e052a1d3f4 100644
--- a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java
+++ b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java
@@ -191,7 +191,8 @@ class PostScriptGraphics2D extends Graphics2D
{
int index = 0;
while(spoolPage(out, printable, pageFormat, index++) ==
- Printable.PAGE_EXISTS);
+ Printable.PAGE_EXISTS)
+ ;
}
out.println("%%Trailer");
out.println("%%EOF");
diff --git a/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java b/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java
index edf07d760d3..b78a8141384 100644
--- a/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java
+++ b/libjava/classpath/gnu/java/beans/encoder/ScanEngine.java
@@ -153,7 +153,7 @@ public class ScanEngine
writer = new StAXWriter(os);
root = new Root();
- final ScannerState start = current = new GenericScannerState(root);;
+ final ScannerState start = current = new GenericScannerState(root);
ScannerState conf;
// Use the ReportingScannerState to debug serialization issues.
diff --git a/libjava/classpath/gnu/java/io/Base64InputStream.java b/libjava/classpath/gnu/java/io/Base64InputStream.java
index b0824ab6935..1f5d220dbb6 100644
--- a/libjava/classpath/gnu/java/io/Base64InputStream.java
+++ b/libjava/classpath/gnu/java/io/Base64InputStream.java
@@ -139,7 +139,9 @@ public class Base64InputStream extends FilterInputStream
while (count < len)
{
int i;
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
+
int pos = BASE_64.indexOf((char) i);
if (pos >= 0)
{
@@ -173,11 +175,13 @@ public class Base64InputStream extends FilterInputStream
case 1:
throw new IOException("malformed Base-64 input");
case 2:
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
if (i != BASE_64_PAD)
throw new IOException("malformed Base-64 input");
case 3:
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
}
eof = true;
break;
diff --git a/libjava/classpath/gnu/java/io/class-dependencies.conf b/libjava/classpath/gnu/java/io/class-dependencies.conf
deleted file mode 100644
index 2500f6b14b5..00000000000
--- a/libjava/classpath/gnu/java/io/class-dependencies.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-# This property file contains dependencies of classes, methods, and
-# field on other methods or classes.
-#
-# Syntax:
-#
-# <used>: <needed 1> [... <needed N>]
-#
-# means that when <used> is included, <needed 1> (... <needed N>) must
-# be included as well.
-#
-# <needed X> and <used> are of the form
-#
-# <class.methodOrField(signature)>
-#
-# or just
-#
-# <class>
-#
-# Within dependencies, variables can be used. A variable is defined as
-# follows:
-#
-# {variable}: value1 value2 ... value<n>
-#
-# variables can be used on the right side of dependencies as follows:
-#
-# <used>: com.bla.blu.{variable}.Class.m()V
-#
-# The use of the variable will expand to <n> dependencies of the form
-#
-# <used>: com.bla.blu.value1.Class.m()V
-# <used>: com.bla.blu.value2.Class.m()V
-# ...
-# <used>: com.bla.blu.value<n>.Class.m()V
-#
-# Variables can be redefined when building a system to select the
-# required support for features like encodings, protocols, etc.
-#
-# Hints:
-#
-# - For methods and fields, the signature is mandatory. For
-# specification, please see the Java Virtual Machine Specification by
-# SUN. Unlike in the spec, field signatures (types) are in brackets.
-#
-# - Package names must be separated by '/' (and not '.'). E.g.,
-# java/lang/Class (this is necessary, because the '.' is used to
-# separate method or field names from classes)
-#
-# - In case <needed> refers to a class, only the class itself will be
-# included in the resulting binary, NOT necessarily all its methods
-# and fields. If you want to refer to all methods and fields, you can
-# write class.* as an abbreviation.
-#
-# - Abbreviations for packages are also possible: my/package/* means all
-# methods and fields of all classes in my/package.
-#
-# - A line with a trailing '\' continues in the next line.
-
-
-# All encodings supported are loaded via gnu/java/io/EncodingManager.findEncoderConstructor
-# or gnu/java/io/EncodingManager.findDecoderConstructor from class
-# gnu/java/io/decode/Decoder<encoding>.
-#
-# This introduces a dependency for all encodings. To allow an easy selection
-# and addition of encodings, the library variable {encodings} can be set to
-# the set of supported encodings.
-#
-{encodings}: 8859_1 8859_2 8859_3 8859_4 8859_5 UTF8
-
-gnu/java/io/EncodingManager.findEncoderConstructor(Ljava/lang/String;Z)Ljava/lang/reflect/Constructor;: \
- gnu/java/io/decode/Decoder{encodings}.*
-
-gnu/java/io/EncodingManager.findDecoderConstructor(Ljava/lang/String;Z)Ljava/lang/reflect/Constructor;: \
- gnu/java/io/encode/Encoder{encodings}.* \
-
-# end of file
diff --git a/libjava/classpath/gnu/java/lang/management/BeanImpl.java b/libjava/classpath/gnu/java/lang/management/BeanImpl.java
index e5b47181273..59e79a550d3 100644
--- a/libjava/classpath/gnu/java/lang/management/BeanImpl.java
+++ b/libjava/classpath/gnu/java/lang/management/BeanImpl.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package gnu.java.lang.management;
+import gnu.javax.management.Translator;
+
import java.lang.management.ManagementPermission;
import java.lang.reflect.Array;
@@ -124,7 +126,7 @@ public class BeanImpl
new OpenMBeanAttributeInfoSupport[oldA.length];
for (int a = 0; a < oldA.length; ++a)
{
- OpenMBeanParameterInfo param = translate(oldA[a].getType());
+ OpenMBeanParameterInfo param = Translator.translate(oldA[a].getType());
if (param.getMinValue() == null)
{
Object[] lv;
@@ -134,7 +136,8 @@ public class BeanImpl
lv = param.getLegalValues().toArray();
attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
oldA[a].getDescription(),
- param.getOpenType(),
+ ((OpenType<Object>)
+ param.getOpenType()),
oldA[a].isReadable(),
oldA[a].isWritable(),
oldA[a].isIs(),
@@ -144,13 +147,16 @@ public class BeanImpl
else
attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
oldA[a].getDescription(),
- param.getOpenType(),
+ ((OpenType<Object>)
+ param.getOpenType()),
oldA[a].isReadable(),
oldA[a].isWritable(),
oldA[a].isIs(),
param.getDefaultValue(),
- param.getMinValue(),
- param.getMaxValue());
+ ((Comparable<Object>)
+ param.getMinValue()),
+ ((Comparable<Object>)
+ param.getMaxValue()));
}
MBeanConstructorInfo[] oldC = info.getConstructors();
OpenMBeanConstructorInfo[] cons = new OpenMBeanConstructorInfoSupport[oldC.length];
@@ -166,7 +172,7 @@ public class BeanImpl
new OpenMBeanOperationInfoSupport(oldO[a].getName(),
oldO[a].getDescription(),
translateSignature(oldO[a].getSignature()),
- translate(oldO[a].getReturnType()).getOpenType(),
+ Translator.translate(oldO[a].getReturnType()).getOpenType(),
oldO[a].getImpact());
openInfo = new OpenMBeanInfoSupport(info.getClassName(), info.getDescription(),
attribs, cons, ops, info.getNotifications());
@@ -201,32 +207,36 @@ public class BeanImpl
return ((Enum) value).name();
Class vClass = value.getClass();
if (vClass.isArray())
- return value;
+ vClass = vClass.getComponentType();
String cName = vClass.getName();
String[] allowedTypes = OpenType.ALLOWED_CLASSNAMES;
for (int a = 0; a < allowedTypes.length; ++a)
if (cName.equals(allowedTypes[a]))
return value;
- if (value instanceof List)
- {
- List l = (List) value;
- Class e = null;
- TypeVariable[] vars = vClass.getTypeParameters();
- for (int a = 0; a < vars.length; ++a)
- if (vars[a].getName().equals("E"))
- e = (Class) vars[a].getGenericDeclaration();
- if (e == null)
- e = Object.class;
- Object[] array = (Object[]) Array.newInstance(e, l.size());
- return l.toArray(array);
- }
OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo();
- OpenMBeanAttributeInfo[] attribs =
- (OpenMBeanAttributeInfo[]) info.getAttributes();
+ MBeanAttributeInfo[] attribs =
+ (MBeanAttributeInfo[]) info.getAttributes();
OpenType type = null;
for (int a = 0; a < attribs.length; ++a)
- if (attribs[a].getName().equals("attribute"))
- type = attribs[a].getOpenType();
+ if (attribs[a].getName().equals(attribute))
+ type = ((OpenMBeanAttributeInfo) attribs[a]).getOpenType();
+ if (value instanceof List)
+ {
+ try
+ {
+ Class e =
+ Class.forName(((ArrayType) type).getElementOpenType().getClassName());
+ List l = (List) value;
+ Object[] array = (Object[]) Array.newInstance(e, l.size());
+ return l.toArray(array);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw (InternalError) (new InternalError("The class of the list " +
+ "element type could not " +
+ "be created").initCause(e));
+ }
+ }
if (value instanceof Map)
{
TabularType ttype = (TabularType) type;
@@ -319,19 +329,13 @@ public class BeanImpl
return getCachedMBeanInfo();
}
- private OpenType getTypeFromClass(Class c)
- throws OpenDataException
- {
- return translate(c.getName()).getOpenType();
- }
-
private OpenMBeanParameterInfo[] translateSignature(MBeanParameterInfo[] oldS)
throws OpenDataException
{
OpenMBeanParameterInfo[] sig = new OpenMBeanParameterInfoSupport[oldS.length];
for (int a = 0; a < oldS.length; ++a)
{
- OpenMBeanParameterInfo param = translate(oldS[a].getType());
+ OpenMBeanParameterInfo param = Translator.translate(oldS[a].getType());
if (param.getMinValue() == null)
{
Object[] lv;
@@ -341,179 +345,24 @@ public class BeanImpl
lv = param.getLegalValues().toArray();
sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
oldS[a].getDescription(),
- param.getOpenType(),
+ ((OpenType<Object>)
+ param.getOpenType()),
param.getDefaultValue(),
lv);
}
else
sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
oldS[a].getDescription(),
- param.getOpenType(),
+ ((OpenType<Object>)
+ param.getOpenType()),
param.getDefaultValue(),
- param.getMinValue(),
- param.getMaxValue());
+ ((Comparable<Object>)
+ param.getMinValue()),
+ ((Comparable<Object>)
+ param.getMaxValue()));
}
return sig;
}
- private OpenMBeanParameterInfo translate(String type)
- throws OpenDataException
- {
- if (type.equals("boolean") || type.equals(Boolean.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.BOOLEAN,
- null,
- new Object[] {
- Boolean.TRUE,
- Boolean.FALSE
- });
- if (type.equals("byte") || type.equals(Byte.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.BYTE,
- null,
- Byte.valueOf(Byte.MIN_VALUE),
- Byte.valueOf(Byte.MAX_VALUE));
- if (type.equals("char") || type.equals(Character.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.CHARACTER,
- null,
- Character.valueOf(Character.MIN_VALUE),
- Character.valueOf(Character.MAX_VALUE));
- if (type.equals("double") || type.equals(Double.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.DOUBLE,
- null,
- Double.valueOf(Double.MIN_VALUE),
- Double.valueOf(Double.MAX_VALUE));
- if (type.equals("float") || type.equals(Float.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.FLOAT,
- null,
- Float.valueOf(Float.MIN_VALUE),
- Float.valueOf(Float.MAX_VALUE));
- if (type.equals("int") || type.equals(Integer.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.INTEGER,
- null,
- Integer.valueOf(Integer.MIN_VALUE),
- Integer.valueOf(Integer.MAX_VALUE));
- if (type.equals("long") || type.equals(Long.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.LONG,
- null,
- Long.valueOf(Long.MIN_VALUE),
- Long.valueOf(Long.MAX_VALUE));
- if (type.equals("short") || type.equals(Short.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.SHORT,
- null,
- Short.valueOf(Short.MIN_VALUE),
- Short.valueOf(Short.MAX_VALUE));
- if (type.equals(String.class.getName()))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.STRING);
- if (type.equals("void"))
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.VOID);
- if (type.startsWith("java.util.Map"))
- {
- int lparam = type.indexOf("<");
- int comma = type.indexOf(",", lparam);
- int rparam = type.indexOf(">", comma);
- String key = type.substring(lparam + 1, comma).trim();
- OpenType k = translate(key).getOpenType();
- OpenType v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
- CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
- new String[] { "key", "value" },
- new String[] { "Map key", "Map value"},
- new OpenType[] { k, v});
- TabularType ttype = new TabularType(key, key, ctype,
- new String[] { "key" });
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- ttype);
- }
- if (type.startsWith("java.util.List"))
- {
- int lparam = type.indexOf("<");
- int rparam = type.indexOf(">");
- OpenType e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- new ArrayType(1, e)
- );
- }
- Class c;
- try
- {
- c = Class.forName(type);
- }
- catch (ClassNotFoundException e)
- {
- throw (InternalError)
- (new InternalError("The class for a type used in a management bean " +
- "could not be loaded.").initCause(e));
- }
- if (c.isEnum())
- {
- Object[] values = c.getEnumConstants();
- String[] names = new String[values.length];
- for (int a = 0; a < values.length; ++a)
- names[a] = values[a].toString();
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- SimpleType.STRING,
- null,
- (Object[]) names);
- }
- try
- {
- c.getMethod("from", new Class[] { CompositeData.class });
- Method[] methods = c.getMethods();
- List names = new ArrayList();
- List types = new ArrayList();
- for (int a = 0; a < methods.length; ++a)
- {
- String name = methods[a].getName();
- if (name.startsWith("get"))
- {
- names.add(name.substring(3));
- types.add(getTypeFromClass(methods[a].getReturnType()));
- }
- }
- String[] fields = (String[]) names.toArray();
- CompositeType ctype = new CompositeType(c.getName(), c.getName(),
- fields, fields,
- (OpenType[]) types.toArray());
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- ctype);
- }
- catch (NoSuchMethodException e)
- {
- /* Ignored; we expect this if this isn't a from(CompositeData) class */
- }
- if (c.isArray())
- {
- int depth;
- for (depth = 0; c.getName().charAt(depth) == '['; ++depth);
- OpenType ot = getTypeFromClass(c.getComponentType());
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- new ArrayType(depth, ot)
- );
- }
- throw new InternalError("The type used does not have an open type translation.");
- }
}
diff --git a/libjava/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java b/libjava/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
index 9eefc0d9db5..07fb7bf0355 100644
--- a/libjava/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
+++ b/libjava/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
@@ -82,6 +82,11 @@ public final class OperatingSystemMXBeanImpl
return System.getProperty("os.name");
}
+ public double getSystemLoadAverage()
+ {
+ return VMOperatingSystemMXBeanImpl.getSystemLoadAverage();
+ }
+
public String getVersion()
{
return System.getProperty("os.version");
diff --git a/libjava/classpath/gnu/java/lang/management/ThreadMXBeanImpl.java b/libjava/classpath/gnu/java/lang/management/ThreadMXBeanImpl.java
index 609b58da737..5d0282301e3 100644
--- a/libjava/classpath/gnu/java/lang/management/ThreadMXBeanImpl.java
+++ b/libjava/classpath/gnu/java/lang/management/ThreadMXBeanImpl.java
@@ -83,7 +83,19 @@ public final class ThreadMXBeanImpl
*/
private static final String TIME_ENABLED =
"gnu.java.lang.management.ThreadTimeInitallyEnabled";
-
+
+ /**
+ * Constant for monitor usage monitoring support.
+ */
+ private static final String MONITOR_SUPPORT =
+ "gnu.java.lang.management.MonitorUsageMonitoringSupport";
+
+ /**
+ * Constant for ownable synchronizer usage monitoring support.
+ */
+ private static final String SYNCHRONIZER_SUPPORT =
+ "gnu.java.lang.management.OwnableSynchronizerUsageMonitoringSupport";
+
/**
* Flag to indicate whether time monitoring is enabled or not.
*/
@@ -112,6 +124,23 @@ public final class ThreadMXBeanImpl
contentionEnabled = false;
}
+ public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
+ boolean lockedSynchronizers)
+ {
+ return getThreadInfo(getAllThreadIds(), lockedMonitors,
+ lockedSynchronizers);
+ }
+
+ public long[] findDeadlockedThreads()
+ {
+ checkMonitorPermissions();
+ if (!isSynchronizerUsageSupported())
+ throw new UnsupportedOperationException("Ownable synchronizer usage " +
+ "monitoring is not provided " +
+ "by this VM.");
+ return VMThreadMXBeanImpl.findDeadlockedThreads();
+ }
+
public long[] findMonitorDeadlockedThreads()
{
checkMonitorPermissions();
@@ -207,6 +236,27 @@ public final class ThreadMXBeanImpl
return infos;
}
+ public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors,
+ boolean lockedSynchronizers)
+ {
+ checkMonitorPermissions();
+ if (lockedMonitors && !isObjectMonitorUsageSupported())
+ throw new UnsupportedOperationException("Monitor usage monitoring is " +
+ "not provided by this VM.");
+ if (lockedSynchronizers && !isSynchronizerUsageSupported())
+ throw new UnsupportedOperationException("Ownable synchronizer usage " +
+ "monitoring is not provided " +
+ "by this VM.");
+ ThreadInfo[] infos = getThreadInfo(ids, Integer.MAX_VALUE);
+ if (lockedMonitors)
+ for (ThreadInfo info : infos)
+ VMThreadMXBeanImpl.getMonitorInfo(info);
+ if (lockedSynchronizers)
+ for (ThreadInfo info : infos)
+ VMThreadMXBeanImpl.getLockInfo(info);
+ return infos;
+ }
+
public long getThreadUserTime(long id)
{
if (!isThreadCpuTimeSupported())
@@ -231,6 +281,16 @@ public final class ThreadMXBeanImpl
return SystemProperties.getProperty(CURRENT_THREAD_TIME_SUPPORT) != null;
}
+ public boolean isObjectMonitorUsageSupported()
+ {
+ return SystemProperties.getProperty(MONITOR_SUPPORT) != null;
+ }
+
+ public boolean isSynchronizerUsageSupported()
+ {
+ return SystemProperties.getProperty(SYNCHRONIZER_SUPPORT) != null;
+ }
+
public boolean isThreadContentionMonitoringEnabled()
{
if (isThreadContentionMonitoringSupported())
diff --git a/libjava/classpath/gnu/java/locale/LocaleHelper.java b/libjava/classpath/gnu/java/locale/LocaleHelper.java
index cec0147179f..4fefd163979 100644
--- a/libjava/classpath/gnu/java/locale/LocaleHelper.java
+++ b/libjava/classpath/gnu/java/locale/LocaleHelper.java
@@ -55,105 +55,44 @@ import java.util.ResourceBundle;
public class LocaleHelper
{
/**
- * This method is used by the localized name lookup methods to retrieve
- * the localized name of a particular piece of locale data.
- * If the display name can not be localized to the supplied
- * locale, it will fall back on other output in the following order:
- *
- * <ul>
- * <li>the localized name in the default locale</li>
- * <li>the localized name in English (optional)</li>
- * <li>the localized name in the root locale bundle (optional)</li>
- * <li>the localized input string</li>
- * </ul>
* <p>
- * If the supplied key is merely the empty string, then the empty string is
- * returned.
+ * This method is used by the localized name lookup methods to
+ * retrieve the next locale to try. The next locale is derived
+ * from the supplied locale by applying the first applicable
+ * rule from the following:
+ * </p>
+ * <ol>
+ * <li>If the variant contains a <code>'_'</code>, then
+ * this and everything following it is trimmed.</li>
+ * <li>If the variant is non-empty, it is converted to
+ * an empty string.</li>
+ * <li>If the country is non-empty, it is converted to
+ * an empty string.</li>
+ * <li>If the language is non-empty, it is converted to
+ * an empty string (forming {@link java.util.Locale#ROOT})</li>
+ * </ol>
+ * <p>
+ * The base fallback locale is {@link java.util.Locale#ROOT}.
* </p>
*
- * @param inLocale the locale to use for formatting the display string.
- * @param key the locale data used as a key to the localized lookup tables.
- * @param name the name of the hashtable containing the localized data.
- * @param checkEnglish true if the method should fall back on data
- * from the English locale.
- * @param checkRoot true if the method should fall back on data from the
- * unlocalized root locale.
- * @return a <code>String</code>, hopefully containing the localized
- * variant of the input data.
- * @throws NullPointerException if <code>inLocale</code> is null.
+ * @param locale the locale for which a localized piece of
+ * data could not be obtained.
+ * @return the next fallback locale to try.
*/
- public static String getLocalizedString(Locale inLocale, String key,
- String name, boolean checkEnglish,
- boolean checkRoot)
+ public static Locale getFallbackLocale(Locale locale)
{
- String localizedString;
- String property;
-
- if (key.equals(""))
- return "";
- property = name + "." + key;
- /* Localize to inLocale */
- try
- {
- localizedString =
- ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
- inLocale).getString(property);
- }
- catch (MissingResourceException exception)
- {
- localizedString = null;
- }
- /* Localize to default locale */
- if (localizedString == null)
- {
- try
- {
- ResourceBundle bundle;
-
- bundle =
- ResourceBundle.getBundle("gnu.java.locale.LocaleInformation");
- localizedString = bundle.getString(property);
- }
- catch (MissingResourceException exception)
- {
- localizedString = null;
- }
- }
- /* Localize to English */
- if (localizedString == null && checkEnglish)
- {
- try
- {
- localizedString =
- ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
- Locale.ENGLISH).getString(property);
- }
- catch (MissingResourceException exception)
- {
- localizedString = null;
- }
- }
- /* Return unlocalized version */
- if (localizedString == null && checkRoot)
- {
- try
- {
- localizedString =
- ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
- new Locale("","","")
- ).getString(property);
- }
- catch (MissingResourceException exception)
- {
- localizedString = null;
- }
- }
- /* Return original input string */
- if (localizedString == null)
- {
- localizedString = key;
- }
- return localizedString;
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+ int uscore = variant.indexOf('_');
+ if (uscore != -1)
+ return new Locale(language, country,
+ variant.substring(0, uscore));
+ if (!variant.isEmpty())
+ return new Locale(language, country, "");
+ if (!country.isEmpty())
+ return new Locale(language, "", "");
+ return Locale.ROOT;
}
/**
diff --git a/libjava/classpath/gnu/java/math/Fixed.java b/libjava/classpath/gnu/java/math/Fixed.java
new file mode 100644
index 00000000000..e0284c329b9
--- /dev/null
+++ b/libjava/classpath/gnu/java/math/Fixed.java
@@ -0,0 +1,207 @@
+/* Fixed.java -- Utility methods for fixed point arithmetics
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.math;
+
+/**
+ * Utility methods for fixed point arithmetics.
+ */
+public final class Fixed
+{
+
+ /**
+ * Private constructor to avoid instantiation.
+ */
+ private Fixed()
+ {
+ // Forbidden constructor.
+ }
+
+ /**
+ * Divides two fixed point values with <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the first operand as fixed point value
+ * @param b the second operand as fixed point value
+ *
+ * @return <code>a / b</code> as fixed point value
+ */
+ public static int div(int n, int a, int b)
+ {
+ return (int) ((((long) a) << n) / b);
+ }
+
+ /**
+ * Multiplies two fixed point values with <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the first operand as fixed point value
+ * @param b the second operand as fixed point value
+ *
+ * @return <code>a * b</code> as fixed point value
+ */
+ public static int mul(int n, int a, int b)
+ {
+ return (int) ((((long) a) * b) >> n);
+ }
+
+ /**
+ * Returns the ceiling value of a fixed point value <code>a</code> with
+ * the <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return <code>ceil(a)</code> as fixed point value
+ */
+ public static int ceil(int n, int a)
+ {
+ return (a + (1 << n - 1)) & -(1 << n);
+ }
+
+ /**
+ * Returns the floor value of a fixed point value <code>a</code> with
+ * <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return <code>floor(a)</code> as fixed point value
+ */
+ public static int floor(int n, int a)
+ {
+ return a & -(1 << n);
+ }
+
+ /**
+ * Returns the round value of a fixed point value <code>a</code> with
+ * the <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return <code>round(a)</code> as fixed point value
+ */
+ public static int round(int n, int a)
+ {
+ return (a + (1 << (n - 1))) & -(1 << n);
+ }
+
+ /**
+ * Returns the fixed point value <code>a</code> with <code>n</code> digits
+ * as float.
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return the float value of <code>a</code>
+ */
+ public static float floatValue(int n, int a)
+ {
+ return ((float) a) / (1 << n);
+ }
+
+ /**
+ * Returns the fixed point value <code>a</code> with <code>n</code> digits
+ * as double.
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return the double value of <code>a</code>
+ */
+ public static double doubleValue(int n, int a)
+ {
+ return ((double) a) / (1 << n);
+ }
+
+ /**
+ * Returns the fixed point value that corresponds to the specified float
+ * value <code>a</code> with <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the float value
+ *
+ * @return the fixed point value
+ */
+ public static int fixedValue(int n, float a)
+ {
+ return (int) (a * (1 << n));
+ }
+
+ /**
+ * Returns the fixed point value that corresponds to the specified double
+ * value <code>a</code> with <code>n</code> digits.
+ *
+ * @param n the number of digits
+ * @param a the double value
+ *
+ * @return the fixed point value
+ */
+ public static int fixedValue(int n, double a)
+ {
+ return (int) (a * (1 << n));
+ }
+
+ /**
+ * Returns the integer value of the specified fixed point value
+ * <code>a</code>. This simply cuts of the digits (== floor(a)).
+ *
+ * @param n the number of digits
+ * @param a the fixed point value
+ *
+ * @return the integer value
+ */
+ public static int intValue(int n, int a)
+ {
+ return a >> n;
+ }
+
+ /**
+ * Returns a fixed point decimal as rounded integer value.
+ *
+ * @param n the number of digits
+ * @param a the fixed point number
+ *
+ * @return the fixed point decimal as rounded integer value
+ */
+ public static int roundIntValue(int n, int a)
+ {
+ return (a + (1 << (n - 1))) >> n;
+ }
+}
diff --git a/libjava/classpath/gnu/java/net/BASE64.java b/libjava/classpath/gnu/java/net/BASE64.java
deleted file mode 100644
index 901aa0c35fc..00000000000
--- a/libjava/classpath/gnu/java/net/BASE64.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/* BASE.java --
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.net;
-
-/**
- * Encodes and decodes text according to the BASE64 encoding.
- *
- * @author Chris Burdess (dog@gnu.org)
- */
-public final class BASE64
-{
- private static final byte[] src = {
- 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
- 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x2b, 0x2f
- };
-
- private static final byte[] dst;
- static
- {
- dst = new byte[0x100];
- for (int i = 0x0; i < 0xff; i++)
- {
- dst[i] = -1;
- }
- for (int i = 0; i < src.length; i++)
- {
- dst[src[i]] = (byte) i;
- }
- }
-
- private BASE64()
- {
- }
-
- /**
- * Encode the specified byte array using the BASE64 algorithm.
- *
- * @param bs the source byte array
- */
- public static byte[] encode(byte[] bs)
- {
- int si = 0, ti = 0; // source/target array indices
- byte[] bt = new byte[((bs.length + 2) * 4) / 3]; // target byte array
- for (; si < bs.length; si += 3)
- {
- int buflen = bs.length - si;
- if (buflen == 1)
- {
- byte b = bs[si];
- int i = 0;
- bt[ti++] = src[b >>> 2 & 0x3f];
- bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)];
- }
- else if (buflen == 2)
- {
- byte b1 = bs[si], b2 = bs[si + 1];
- int i = 0;
- bt[ti++] = src[b1 >>> 2 & 0x3f];
- bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
- bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)];
- }
- else
- {
- byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2];
- bt[ti++] = src[b1 >>> 2 & 0x3f];
- bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
- bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)];
- bt[ti++] = src[b3 & 0x3f];
- }
- }
- if (ti < bt.length)
- {
- byte[] tmp = new byte[ti];
- System.arraycopy(bt, 0, tmp, 0, ti);
- bt = tmp;
- }
- /*while (ti < bt.length)
- {
- bt[ti++] = 0x3d;
- }*/
- return bt;
- }
-
- /**
- * Decode the specified byte array using the BASE64 algorithm.
- *
- * @param bs the source byte array
- */
- public static byte[] decode(byte[] bs)
- {
- int srclen = bs.length;
- while (srclen > 0 && bs[srclen - 1] == 0x3d)
- {
- srclen--; /* strip padding character */
- }
- byte[] buffer = new byte[srclen];
- int buflen = 0;
- int si = 0;
- int len = srclen - si;
- while (len > 0)
- {
- byte b0 = dst[bs[si++] & 0xff];
- byte b2 = dst[bs[si++] & 0xff];
- buffer[buflen++] = (byte) (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);
- if (len > 2)
- {
- b0 = b2;
- b2 = dst[bs[si++] & 0xff];
- buffer[buflen++] = (byte) (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);
- if (len > 3)
- {
- b0 = b2;
- b2 = dst[bs[si++] & 0xff];
- buffer[buflen++] = (byte) (b0 << 6 & 0xc0 | b2 & 0x3f);
- }
- }
- len = srclen - si;
- }
- byte[] bt = new byte[buflen];
- System.arraycopy(buffer, 0, bt, 0, buflen);
- return bt;
- }
-
- public static void main(String[] args)
- {
- boolean decode = false;
- for (int i = 0; i < args.length; i++)
- {
- if (args[i].equals("-d"))
- {
- decode = true;
- }
- else
- {
- try
- {
- byte[] in = args[i].getBytes("US-ASCII");
- byte[] out = decode ? decode(in) : encode(in);
- System.out.println(args[i] + " = " +
- new String(out, "US-ASCII"));
- }
- catch (java.io.UnsupportedEncodingException e)
- {
- e.printStackTrace(System.err);
- }
- }
- }
- }
-}
diff --git a/libjava/classpath/gnu/java/net/DefaultContentHandlerFactory.java b/libjava/classpath/gnu/java/net/DefaultContentHandlerFactory.java
index bb0a7ce5d21..e3d1b8e5a96 100644
--- a/libjava/classpath/gnu/java/net/DefaultContentHandlerFactory.java
+++ b/libjava/classpath/gnu/java/net/DefaultContentHandlerFactory.java
@@ -81,8 +81,8 @@ public class DefaultContentHandlerFactory implements ContentHandlerFactory
"image/x-xpixmap"
};
- private static HashSet imageTypes
- = new HashSet(Arrays.asList(known_image_types));
+ private static HashSet<String> imageTypes
+ = new HashSet<String>(Arrays.asList(known_image_types));
public ContentHandler createContentHandler(String mimeType)
{
diff --git a/libjava/classpath/gnu/java/net/GetLocalHostAction.java b/libjava/classpath/gnu/java/net/GetLocalHostAction.java
index 7483b025773..fa76015552b 100644
--- a/libjava/classpath/gnu/java/net/GetLocalHostAction.java
+++ b/libjava/classpath/gnu/java/net/GetLocalHostAction.java
@@ -48,9 +48,9 @@ import java.security.PrivilegedAction;
* @author Chris Burdess (dog@gnu.org)
*/
public class GetLocalHostAction
- implements PrivilegedAction
+ implements PrivilegedAction<InetAddress>
{
- public Object run()
+ public InetAddress run()
{
try
{
diff --git a/libjava/classpath/gnu/java/net/HeaderFieldHelper.java b/libjava/classpath/gnu/java/net/HeaderFieldHelper.java
index 0fb8d953d21..a8d13ce153b 100644
--- a/libjava/classpath/gnu/java/net/HeaderFieldHelper.java
+++ b/libjava/classpath/gnu/java/net/HeaderFieldHelper.java
@@ -49,8 +49,8 @@ import java.util.Vector;
*/
public class HeaderFieldHelper
{
- private Vector headerFieldKeys;
- private Vector headerFieldValues;
+ private Vector<String> headerFieldKeys;
+ private Vector<String> headerFieldValues;
public HeaderFieldHelper()
{
@@ -59,8 +59,8 @@ public class HeaderFieldHelper
public HeaderFieldHelper (int size)
{
- headerFieldKeys = new Vector (size);
- headerFieldValues = new Vector (size);
+ headerFieldKeys = new Vector<String> (size);
+ headerFieldValues = new Vector<String> (size);
}
public void addHeaderField (String key, String value)
@@ -75,7 +75,7 @@ public class HeaderFieldHelper
try
{
- key = (String) headerFieldKeys.elementAt (index);
+ key = headerFieldKeys.elementAt (index);
}
catch (ArrayIndexOutOfBoundsException e)
{
@@ -90,7 +90,7 @@ public class HeaderFieldHelper
try
{
- value = (String) headerFieldValues.elementAt (index);
+ value = headerFieldValues.elementAt (index);
}
catch (ArrayIndexOutOfBoundsException e)
{
@@ -105,8 +105,7 @@ public class HeaderFieldHelper
try
{
- value = (String) headerFieldValues.elementAt
- (headerFieldKeys.indexOf(key));
+ value = headerFieldValues.elementAt(headerFieldKeys.indexOf(key));
}
catch (ArrayIndexOutOfBoundsException e)
{
@@ -115,9 +114,9 @@ public class HeaderFieldHelper
return value;
}
- public Map getHeaderFields()
+ public Map<String, String> getHeaderFields()
{
- HashMap headers = new HashMap();
+ HashMap<String, String> headers = new HashMap<String, String>();
int max = headerFieldKeys.size();
for (int index = 0; index < max; index++)
diff --git a/libjava/classpath/gnu/java/net/IndexListParser.java b/libjava/classpath/gnu/java/net/IndexListParser.java
index 1165929fc35..2d90ceb6433 100644
--- a/libjava/classpath/gnu/java/net/IndexListParser.java
+++ b/libjava/classpath/gnu/java/net/IndexListParser.java
@@ -43,6 +43,7 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Set;
import java.util.jar.JarFile;
/**
@@ -70,7 +71,8 @@ public class IndexListParser
double versionNumber;
// Map each jar to the prefixes defined for the jar.
// This is intentionally kept in insertion order.
- LinkedHashMap prefixes = new LinkedHashMap();
+ LinkedHashMap<URL, Set<String>> prefixes
+ = new LinkedHashMap<URL, Set<String>>();
/**
* Parses the given jarfile's INDEX.LIST file if it exists.
@@ -107,7 +109,7 @@ public class IndexListParser
while ((line = br.readLine()) != null)
{
URL jarURL = new URL(baseURL, line);
- HashSet values = new HashSet();
+ HashSet<String> values = new HashSet<String>();
// Read the names in the section.
while ((line = br.readLine()) != null)
@@ -174,7 +176,7 @@ public class IndexListParser
*
* @return an map of all the headers, or null if no INDEX.LIST was found
*/
- public LinkedHashMap getHeaders()
+ public LinkedHashMap<URL, Set<String>> getHeaders()
{
return prefixes;
}
diff --git a/libjava/classpath/gnu/java/net/loader/JarURLLoader.java b/libjava/classpath/gnu/java/net/loader/JarURLLoader.java
index 9385760d547..40194be799a 100644
--- a/libjava/classpath/gnu/java/net/loader/JarURLLoader.java
+++ b/libjava/classpath/gnu/java/net/loader/JarURLLoader.java
@@ -32,7 +32,7 @@ public final class JarURLLoader extends URLLoader
// Base jar: url for all resources loaded from jar.
final URL baseJarURL;
// The "Class-Path" attribute of this Jar's manifest.
- ArrayList classPath;
+ ArrayList<URLLoader> classPath;
// If not null, a mapping from INDEX.LIST for this jar only.
// This is a set of all prefixes and top-level files that
// ought to be available in this jar.
@@ -90,20 +90,20 @@ public final class JarURLLoader extends URLLoader
IndexListParser parser = new IndexListParser(jarfile, baseJarURL,
baseURL);
- LinkedHashMap indexMap = parser.getHeaders();
+ LinkedHashMap<URL, Set<String>> indexMap = parser.getHeaders();
if (indexMap != null)
{
// Note that the index also computes
// the resulting Class-Path -- there are jars out there
// where the index lists some required jars which do
// not appear in the Class-Path attribute in the manifest.
- this.classPath = new ArrayList();
- Iterator it = indexMap.entrySet().iterator();
+ this.classPath = new ArrayList<URLLoader>();
+ Iterator<Map.Entry<URL, Set<String>>> it = indexMap.entrySet().iterator();
while (it.hasNext())
{
- Map.Entry entry = (Map.Entry) it.next();
- URL subURL = (URL) entry.getKey();
- Set prefixes = (Set) entry.getValue();
+ Map.Entry<URL, Set<String>> entry = it.next();
+ URL subURL = entry.getKey();
+ Set<String> prefixes = entry.getValue();
if (subURL.equals(baseURL))
this.indexSet = prefixes;
else
@@ -127,7 +127,7 @@ public final class JarURLLoader extends URLLoader
= attributes.getValue(Attributes.Name.CLASS_PATH))
!= null))
{
- this.classPath = new ArrayList();
+ this.classPath = new ArrayList<URLLoader>();
StringTokenizer st = new StringTokenizer(classPathString, " ");
while (st.hasMoreElements ())
{
@@ -144,7 +144,7 @@ public final class JarURLLoader extends URLLoader
cache, factory,
subURL, subURL);
this.classPath.add(subLoader);
- ArrayList extra = subLoader.getClassPath();
+ ArrayList<URLLoader> extra = subLoader.getClassPath();
if (extra != null)
this.classPath.addAll(extra);
}
@@ -208,7 +208,7 @@ public final class JarURLLoader extends URLLoader
}
}
- public ArrayList getClassPath()
+ public ArrayList<URLLoader> getClassPath()
{
return classPath;
}
diff --git a/libjava/classpath/gnu/java/net/loader/URLLoader.java b/libjava/classpath/gnu/java/net/loader/URLLoader.java
index d073c54296a..5228bcac96d 100644
--- a/libjava/classpath/gnu/java/net/loader/URLLoader.java
+++ b/libjava/classpath/gnu/java/net/loader/URLLoader.java
@@ -140,7 +140,7 @@ public abstract class URLLoader
* Return a list of new URLLoader objects representing any
* class path entries added by this container.
*/
- public ArrayList getClassPath()
+ public ArrayList<URLLoader> getClassPath()
{
return null;
}
diff --git a/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java b/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java
index 295a15d2b53..b7b8bf12bf1 100644
--- a/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java
+++ b/libjava/classpath/gnu/java/net/loader/URLStreamHandlerCache.java
@@ -51,7 +51,8 @@ public class URLStreamHandlerCache
* private protocol handler cache (also a HashMap), so we can avoid
* creating handlers each time the same protocol comes.
*/
- private HashMap factoryCache = new HashMap(5);
+ private HashMap<URLStreamHandlerFactory, HashMap<String, URLStreamHandler>> factoryCache
+ = new HashMap<URLStreamHandlerFactory, HashMap<String, URLStreamHandler>>(5);
public URLStreamHandlerCache()
{
@@ -62,7 +63,7 @@ public class URLStreamHandlerCache
// Since we only support three protocols so far, 5 is enough
// for cache initial size.
if (factory != null && factoryCache.get(factory) == null)
- factoryCache.put(factory, new HashMap(5));
+ factoryCache.put(factory, new HashMap<String, URLStreamHandler>(5));
}
public synchronized URLStreamHandler get(URLStreamHandlerFactory factory,
@@ -71,8 +72,8 @@ public class URLStreamHandlerCache
if (factory == null)
return null;
// Check if there're handler for the same protocol in cache.
- HashMap cache = (HashMap) factoryCache.get(factory);
- URLStreamHandler handler = (URLStreamHandler) cache.get(protocol);
+ HashMap<String, URLStreamHandler> cache = factoryCache.get(factory);
+ URLStreamHandler handler = cache.get(protocol);
if (handler == null)
{
// Add it to cache.
diff --git a/libjava/classpath/gnu/java/net/local/LocalServerSocket.java b/libjava/classpath/gnu/java/net/local/LocalServerSocket.java
index 15163f243a8..9d8a6ccdf32 100644
--- a/libjava/classpath/gnu/java/net/local/LocalServerSocket.java
+++ b/libjava/classpath/gnu/java/net/local/LocalServerSocket.java
@@ -44,7 +44,6 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
-import java.net.SocketException;
public final class LocalServerSocket extends ServerSocket
{
diff --git a/libjava/classpath/gnu/java/net/local/LocalSocket.java b/libjava/classpath/gnu/java/net/local/LocalSocket.java
index b262c794e3d..92acc65bb62 100644
--- a/libjava/classpath/gnu/java/net/local/LocalSocket.java
+++ b/libjava/classpath/gnu/java/net/local/LocalSocket.java
@@ -46,7 +46,6 @@ import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
-import java.net.SocketImpl;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;
diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java
index f5317d479bc..fd79019183a 100644
--- a/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java
+++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java
@@ -1139,7 +1139,7 @@ public class FTPConnection
* @param pathname the directory pathname, or null
* @return a list of filenames(strings)
*/
- public List nameList(String pathname)
+ public List<String> nameList(String pathname)
throws IOException
{
if (dtp == null || transferMode == MODE_STREAM)
@@ -1164,7 +1164,7 @@ public class FTPConnection
in = new BufferedInputStream(in);
in = new CRLFInputStream(in); // TODO ensure that TYPE is correct
LineInputStream li = new LineInputStream(in);
- List ret = new ArrayList();
+ ArrayList<String> ret = new ArrayList<String>();
for (String line = li.readLine();
line != null;
line = li.readLine())
diff --git a/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java b/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java
index f937e51f606..cfad5a7c1a6 100644
--- a/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java
+++ b/libjava/classpath/gnu/java/net/protocol/ftp/FTPURLConnection.java
@@ -50,7 +50,9 @@ import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -112,7 +114,7 @@ public class FTPURLConnection
{
username = "anonymous";
GetLocalHostAction a = new GetLocalHostAction();
- InetAddress localhost =(InetAddress) AccessController.doPrivileged(a);
+ InetAddress localhost = AccessController.doPrivileged(a);
password = SystemProperties.getProperty("user.name") + "@" +
((localhost == null) ? "localhost" : localhost.getHostName());
}
@@ -232,9 +234,9 @@ public class FTPURLConnection
return null;
}
- public Map getRequestProperties()
+ public Map<String, List<String>> getRequestProperties()
{
- Map map = new HashMap();
+ Map<String, List<String>> map = new HashMap<String, List<String>>();
addRequestPropertyValue(map, "passive");
addRequestPropertyValue(map, "representationType");
addRequestPropertyValue(map, "fileStructure");
@@ -242,10 +244,13 @@ public class FTPURLConnection
return map;
}
- private void addRequestPropertyValue(Map map, String key)
+ private void addRequestPropertyValue(Map<String, List<String>> map,
+ String key)
{
String value = getRequestProperty(key);
- map.put(key, value);
+ ArrayList<String> l = new ArrayList<String>();
+ l.add(value);
+ map.put(key, l);
}
public void setRequestProperty(String key, String value)
diff --git a/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java
index 9870412f2da..8abef71d521 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java
@@ -58,10 +58,6 @@ import java.net.ProtocolException;
public class ChunkedInputStream
extends InputStream
{
-
- private static final byte CR = 0x0d;
- private static final byte LF = 0x0a;
-
Headers headers;
/** The underlying stream. */
diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java
index 3956d2aba3a..9d19bfbdba4 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java
@@ -129,7 +129,7 @@ public class HTTPConnection
*/
protected int minorVersion;
- private final List handshakeCompletedListeners;
+ private final List<HandshakeCompletedListener> handshakeCompletedListeners;
/**
* The socket this connection communicates on.
@@ -154,7 +154,7 @@ public class HTTPConnection
/**
* Nonce values seen by this connection.
*/
- private Map nonceCounts;
+ private Map<String, Integer> nonceCounts;
/**
* The cookie manager for this connection.
@@ -244,7 +244,8 @@ public class HTTPConnection
this.connectionTimeout = connectionTimeout;
this.timeout = timeout;
majorVersion = minorVersion = 1;
- handshakeCompletedListeners = new ArrayList(2);
+ handshakeCompletedListeners
+ = new ArrayList<HandshakeCompletedListener>(2);
}
/**
@@ -357,7 +358,8 @@ public class HTTPConnection
/**
* The pool
*/
- final LinkedList connectionPool = new LinkedList();
+ final LinkedList<HTTPConnection> connectionPool
+ = new LinkedList<HTTPConnection>();
/**
* Maximum size of the pool.
@@ -857,7 +859,7 @@ public class HTTPConnection
{
return 0;
}
- return((Integer) nonceCounts.get(nonce)).intValue();
+ return nonceCounts.get(nonce).intValue();
}
/**
@@ -868,7 +870,7 @@ public class HTTPConnection
int current = getNonceCount(nonce);
if (nonceCounts == null)
{
- nonceCounts = new HashMap();
+ nonceCounts = new HashMap<String, Integer>();
}
nonceCounts.put(nonce, new Integer(current + 1));
}
diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java
index 6c926b72fb4..b31f426695f 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java
@@ -50,11 +50,11 @@ import java.net.URL;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.Date;
+import java.util.List;
import java.util.Map;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocketFactory;
@@ -170,7 +170,8 @@ public class HTTPURLConnection
if (secure)
{
SSLSocketFactory factory = getSSLSocketFactory();
- HostnameVerifier verifier = getHostnameVerifier();
+ // FIXME: use the verifier
+ // HostnameVerifier verifier = getHostnameVerifier();
if (factory != null)
{
connection.setSSLSocketFactory(factory);
@@ -428,12 +429,12 @@ public class HTTPURLConnection
return requestHeaders.getValue(key);
}
- public Map getRequestProperties()
+ public Map<String, List<String>> getRequestProperties()
{
if (connected)
throw new IllegalStateException("Already connected");
- Map m = requestHeaders.getAsMap();
+ Map<String, List<String>> m = requestHeaders.getAsMap();
return Collections.unmodifiableMap(m);
}
@@ -509,7 +510,7 @@ public class HTTPURLConnection
return errorSink;
}
- public Map getHeaderFields()
+ public Map<String,List<String>> getHeaderFields()
{
if (!connected)
{
@@ -522,7 +523,7 @@ public class HTTPURLConnection
return null;
}
}
- Map m = response.getHeaders().getAsMap();
+ Map<String,List<String>> m = response.getHeaders().getAsMap();
m.put(null, Collections.singletonList(getStatusLine(response)));
return Collections.unmodifiableMap(m);
}
diff --git a/libjava/classpath/gnu/java/net/protocol/http/Headers.java b/libjava/classpath/gnu/java/net/protocol/http/Headers.java
index a793bbd9728..c8736bbac8f 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/Headers.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/Headers.java
@@ -42,6 +42,7 @@ import gnu.java.net.LineInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.Iterable;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
@@ -49,6 +50,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -60,12 +62,13 @@ import java.util.Map;
* @author Chris Burdess (dog@gnu.org)
* @author David Daney (ddaney@avtrex.com)
*/
-class Headers
+class Headers implements Iterable<Headers.HeaderElement>
{
/**
* A list of HeaderElements
*/
- private final ArrayList headers = new ArrayList();
+ private final ArrayList<HeaderElement> headers
+ = new ArrayList<HeaderElement>();
/**
* The HTTP dateformat used to parse date header fields.
@@ -102,7 +105,7 @@ class Headers
*
* @return the Iterator.
*/
- Iterator iterator()
+ public Iterator<HeaderElement> iterator()
{
return headers.iterator();
}
@@ -118,7 +121,7 @@ class Headers
{
for (int i = headers.size() - 1; i >= 0; i--)
{
- HeaderElement e = (HeaderElement)headers.get(i);
+ HeaderElement e = headers.get(i);
if (e.name.equalsIgnoreCase(header))
{
return e.value;
@@ -219,7 +222,7 @@ class Headers
{
for (int i = headers.size() - 1; i >= 0; i--)
{
- HeaderElement e = (HeaderElement)headers.get(i);
+ HeaderElement e = headers.get(i);
if (e.name.equalsIgnoreCase(name))
{
e.value = value;
@@ -240,9 +243,9 @@ class Headers
*/
public void putAll(Headers o)
{
- for (Iterator it = o.iterator(); it.hasNext(); )
+ for (Iterator<HeaderElement> it = o.iterator(); it.hasNext(); )
{
- HeaderElement e = (HeaderElement)it.next();
+ HeaderElement e = it.next();
remove(e.name);
addValue(e.name, e.value);
}
@@ -256,9 +259,9 @@ class Headers
*/
public void remove(String name)
{
- for (Iterator it = headers.iterator(); it.hasNext(); )
+ for (Iterator<HeaderElement> it = headers.iterator(); it.hasNext(); )
{
- HeaderElement e = (HeaderElement)it.next();
+ HeaderElement e = it.next();
if (e.name.equalsIgnoreCase(name))
it.remove();
}
@@ -358,26 +361,26 @@ class Headers
*
* @return a Map containing all the headers.
*/
- public Map getAsMap()
+ public Map<String,List<String>> getAsMap()
{
- LinkedHashMap m = new LinkedHashMap();
- for (Iterator it = headers.iterator(); it.hasNext(); )
+ LinkedHashMap<String,List<String>> m = new LinkedHashMap<String,List<String>>();
+ for (Iterator<HeaderElement> it = headers.iterator(); it.hasNext(); )
{
- HeaderElement e = (HeaderElement)it.next();
- ArrayList l = (ArrayList)m.get(e.name);
+ HeaderElement e = it.next();
+ ArrayList<String> l = (ArrayList<String>)m.get(e.name);
if (l == null)
{
- l = new ArrayList(1);
+ l = new ArrayList<String>(1);
l.add(e.value);
m.put(e.name, l);
}
else
l.add(0, e.value);
}
- for (Iterator it = m.entrySet().iterator(); it.hasNext(); )
+ for (Iterator<Map.Entry<String,List<String>>> it = m.entrySet().iterator(); it.hasNext(); )
{
- Map.Entry me = (Map.Entry)it.next();
- ArrayList l = (ArrayList)me.getValue();
+ Map.Entry<String,List<String>> me = it.next();
+ List<String> l = me.getValue();
me.setValue(Collections.unmodifiableList(l));
}
return m;
@@ -397,7 +400,7 @@ class Headers
if (i >= headers.size() || i < 0)
return null;
- return ((HeaderElement)headers.get(i)).name;
+ return headers.get(i).name;
}
/**
@@ -414,8 +417,6 @@ class Headers
if (i >= headers.size() || i < 0)
return null;
- return ((HeaderElement)headers.get(i)).value;
+ return headers.get(i).value;
}
-
}
-
diff --git a/libjava/classpath/gnu/java/net/protocol/http/Request.java b/libjava/classpath/gnu/java/net/protocol/http/Request.java
index cd9d7ea4423..06a779f3311 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/Request.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/Request.java
@@ -1,5 +1,5 @@
/* Request.java --
- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package gnu.java.net.protocol.http;
-import gnu.java.net.BASE64;
import gnu.java.net.LineInputStream;
+import gnu.java.util.Base64;
import java.io.IOException;
import java.io.InputStream;
@@ -96,7 +96,7 @@ public class Request
/**
* Map of response header handlers.
*/
- protected Map responseHeaderHandlers;
+ protected Map<String, ResponseHeaderHandler> responseHeaderHandlers;
/**
* The authenticator.
@@ -121,7 +121,7 @@ public class Request
this.method = method;
this.path = path;
requestHeaders = new Headers();
- responseHeaderHandlers = new HashMap();
+ responseHeaderHandlers = new HashMap<String, ResponseHeaderHandler>();
}
/**
@@ -302,9 +302,8 @@ public class Request
String line = method + ' ' + requestUri + ' ' + version + CRLF;
out.write(line.getBytes(US_ASCII));
// Request headers
- for (Iterator i = requestHeaders.iterator(); i.hasNext(); )
+ for (Headers.HeaderElement elt : requestHeaders)
{
- Headers.HeaderElement elt = (Headers.HeaderElement)i.next();
line = elt.name + HEADER_SEP + elt.value + CRLF;
out.write(line.getBytes(US_ASCII));
}
@@ -439,9 +438,8 @@ public class Request
void notifyHeaderHandlers(Headers headers)
{
- for (Iterator i = headers.iterator(); i.hasNext(); )
+ for (Headers.HeaderElement entry : headers)
{
- Headers.HeaderElement entry = (Headers.HeaderElement) i.next();
// Handle Set-Cookie
if ("Set-Cookie".equalsIgnoreCase(entry.name))
handleSetCookie(entry.value);
@@ -461,7 +459,6 @@ public class Request
throws IOException
{
long contentLength = -1;
- Headers trailer = null;
// Persistent connections are the default in HTTP/1.1
boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
@@ -532,7 +529,7 @@ public class Request
Credentials creds = authenticator.getCredentials(realm, attempts);
String userPass = creds.getUsername() + ':' + creds.getPassword();
byte[] b_userPass = userPass.getBytes("US-ASCII");
- byte[] b_encoded = BASE64.encode(b_userPass);
+ byte[] b_encoded = Base64.encode(b_userPass).getBytes("US-ASCII");
String authorization =
scheme + " " + new String(b_encoded, "US-ASCII");
setHeader("Authorization", authorization);
diff --git a/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java b/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java
index 8947471885c..fe05ba09e5e 100644
--- a/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java
+++ b/libjava/classpath/gnu/java/net/protocol/http/SimpleCookieManager.java
@@ -1,5 +1,5 @@
/* CookieManager.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,7 +42,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
/**
@@ -59,23 +58,23 @@ public class SimpleCookieManager
* The cookie cache.
* This is a dictionary mapping domains to maps of cookies by name.
*/
- protected Map cookies;
+ protected Map<String, Map<String, Cookie>> cookies;
/**
* Constructor.
*/
public SimpleCookieManager()
{
- cookies = new HashMap();
+ cookies = new HashMap<String, Map<String, Cookie>>();
}
public void setCookie(Cookie cookie)
{
String domain = cookie.getDomain();
- Map map =(Map) cookies.get(domain);
+ Map<String, Cookie> map = cookies.get(domain);
if (map == null)
{
- map = new HashMap();
+ map = new HashMap<String, Cookie>();
cookies.put(domain, map);
}
String name = cookie.getName();
@@ -84,7 +83,7 @@ public class SimpleCookieManager
public Cookie[] getCookies(String host, boolean secure, String path)
{
- List matches = new ArrayList();
+ ArrayList<Cookie> matches = new ArrayList<Cookie>();
Date now = new Date();
if (Character.isLetter(host.charAt(0)))
{
@@ -102,17 +101,16 @@ public class SimpleCookieManager
return ret;
}
- private void addCookies(List matches, String domain, boolean secure,
- String path, Date now)
+ private void addCookies(ArrayList<Cookie> matches, String domain,
+ boolean secure, String path, Date now)
{
- Map map = (Map) cookies.get(domain);
+ Map<String, Cookie> map = cookies.get(domain);
if (map != null)
{
- List expired = new ArrayList();
- for (Iterator i = map.entrySet().iterator(); i.hasNext(); )
+ ArrayList<String> expired = new ArrayList<String>();
+ for (Map.Entry<String, Cookie> entry : map.entrySet())
{
- Map.Entry entry = (Map.Entry) i.next();
- Cookie cookie = (Cookie) entry.getValue();
+ Cookie cookie = entry.getValue();
Date expires = cookie.getExpiryDate();
if (expires != null && expires.before(now))
{
@@ -129,7 +127,7 @@ public class SimpleCookieManager
}
}
// Good housekeeping
- for (Iterator i = expired.iterator(); i.hasNext(); )
+ for (Iterator<String> i = expired.iterator(); i.hasNext(); )
{
map.remove(i.next());
}
diff --git a/libjava/classpath/gnu/java/net/protocol/jar/Connection.java b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java
index f99806ae42d..386aacef63e 100644
--- a/libjava/classpath/gnu/java/net/protocol/jar/Connection.java
+++ b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java
@@ -76,7 +76,8 @@ public final class Connection extends JarURLConnection
public static class JarFileCache
{
- private static Hashtable cache = new Hashtable();
+ private static Hashtable<URL, JarFile> cache
+ = new Hashtable<URL, JarFile>();
private static final int READBUFSIZE = 4*1024;
public static synchronized JarFile get (URL url, boolean useCaches)
@@ -85,7 +86,7 @@ public final class Connection extends JarURLConnection
JarFile jf;
if (useCaches)
{
- jf = (JarFile) cache.get (url);
+ jf = cache.get (url);
if (jf != null)
return jf;
}
diff --git a/libjava/classpath/gnu/java/net/protocol/jar/Handler.java b/libjava/classpath/gnu/java/net/protocol/jar/Handler.java
index 7c09766a557..c57d0a36016 100644
--- a/libjava/classpath/gnu/java/net/protocol/jar/Handler.java
+++ b/libjava/classpath/gnu/java/net/protocol/jar/Handler.java
@@ -164,7 +164,7 @@ public class Handler extends URLStreamHandler
if (jar_path.indexOf("/.") < 0)
return url_string;
- ArrayList tokens = new ArrayList();
+ ArrayList<String> tokens = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(jar_path, "/");
while (st.hasMoreTokens())
{
@@ -183,7 +183,7 @@ public class Handler extends URLStreamHandler
StringBuffer path = new StringBuffer(url_string.length());
path.append(url_string.substring(0, jar_stop + 1));
- Iterator it = tokens.iterator();
+ Iterator<String> it = tokens.iterator();
while (it.hasNext())
path.append('/').append(it.next());
diff --git a/libjava/classpath/gnu/java/nio/ChannelInputStream.java b/libjava/classpath/gnu/java/nio/ChannelInputStream.java
index 675a62f3d88..f56536d65ad 100644
--- a/libjava/classpath/gnu/java/nio/ChannelInputStream.java
+++ b/libjava/classpath/gnu/java/nio/ChannelInputStream.java
@@ -59,6 +59,16 @@ public final class ChannelInputStream extends InputStream
this.ch = ch;
}
+ public int read(byte[] buf, int off, int len) throws IOException
+ {
+ if (ch instanceof SelectableChannel
+ && (! ((SelectableChannel) ch).isBlocking()))
+ throw new IllegalBlockingModeException();
+
+ ByteBuffer b = ByteBuffer.wrap(buf, off, len);
+ return ch.read(b);
+ }
+
public int read() throws IOException
{
if (ch instanceof SelectableChannel
@@ -74,6 +84,6 @@ public final class ChannelInputStream extends InputStream
if (result == 0)
throw new IOException("Could not read from channel");
- return buffer.get(0);
+ return buffer.get(0) & 0xff;
}
}
diff --git a/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java b/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java
index 56167b69ea8..0c509b985ff 100644
--- a/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java
+++ b/libjava/classpath/gnu/java/nio/SelectorProviderImpl.java
@@ -117,4 +117,5 @@ public class SelectorProviderImpl extends SelectorProvider
{
return new SocketChannelImpl (this);
}
+
}
diff --git a/libjava/classpath/gnu/java/nio/charset/ByteCharset.java b/libjava/classpath/gnu/java/nio/charset/ByteCharset.java
index da0fdcbcdb3..e2025482956 100644
--- a/libjava/classpath/gnu/java/nio/charset/ByteCharset.java
+++ b/libjava/classpath/gnu/java/nio/charset/ByteCharset.java
@@ -115,8 +115,11 @@ abstract class ByteCharset extends Charset
return CoderResult.OVERFLOW;
}
- if((c = lookup[(int) (b & 0xFF)]) == NONE);
- // return CoderResult.unmappableForLength (1);
+ if((c = lookup[(int) (b & 0xFF)]) == NONE)
+ {
+ in.position (in.position () - 1);
+ return CoderResult.unmappableForLength (1);
+ }
out.put (c);
}
diff --git a/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java b/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java
index 033440d5da2..be7b4afe05d 100644
--- a/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java
+++ b/libjava/classpath/gnu/java/nio/charset/EncodingHelper.java
@@ -148,6 +148,17 @@ public class EncodingHelper
throw new UnsupportedEncodingException("Charset "+name+" not found.");
}
}
+
+ /**
+ * Returns the default charset without throwing any exceptions. The default
+ * charset is UTF8.
+ *
+ * @return the default charset
+ */
+ public static Charset getDefaultCharset()
+ {
+ return new UTF_8();
+ }
}
diff --git a/libjava/classpath/gnu/java/security/util/Base64.java b/libjava/classpath/gnu/java/security/util/Base64.java
deleted file mode 100644
index 9b2ae12dc27..00000000000
--- a/libjava/classpath/gnu/java/security/util/Base64.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/* Base64.java --
- Copyright (C) 2003, 2006 Free Software Foundation, Inc.
-
-This file is a part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
-USA
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.security.util;
-
-import gnu.java.security.Configuration;
-
-import java.io.UnsupportedEncodingException;
-import java.util.logging.Logger;
-
-/**
- * Most of this implementation is from Robert Harder's public domain Base64
- * code (version 1.4.1 available from &lt;http://iharder.net/xmlizable>).
- */
-public class Base64
-{
- private static final Logger log = Logger.getLogger(Base64.class.getName());
-
- /** Maximum line length (76) of Base64 output. */
- private static final int MAX_LINE_LENGTH = 76;
-
- /** The new line character (\n) as one byte. */
- private static final byte NEW_LINE = (byte) '\n';
-
- /** The equals sign (=) as a byte. */
- private static final byte EQUALS_SIGN = (byte) '=';
-
- private static final byte WHITE_SPACE_ENC = -5; // white space in encoding
-
- private static final byte EQUALS_SIGN_ENC = -1; // equals sign in encoding
-
- /** The 64 valid Base64 values. */
- private static final byte[] ALPHABET = {
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
- (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
- (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R',
- (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X',
- (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd',
- (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
- (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
- (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v',
- (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1',
- (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
- (byte) '8', (byte) '9', (byte) '+', (byte) '/'
- };
-
- /**
- * Translates a Base64 value to either its 6-bit reconstruction value or a
- * negative number indicating some other meaning.
- */
- private static final byte[] DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- 62, // Plus sign at decimal 43
- -9, -9, -9, // Decimal 44 - 46
- 63, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9 // Decimal 123 - 126
- };
-
- /** Trivial private ctor to enfore Singleton pattern. */
- private Base64()
- {
- super();
- }
-
- /**
- * Encodes a byte array into Base64 notation. Equivalent to calling
- * <code>encode(source, 0, source.length)</code>.
- *
- * @param src the data to convert.
- */
- public static final String encode(final byte[] src)
- {
- return encode(src, 0, src.length, true);
- }
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * @param src the data to convert.
- * @param off offset in array where conversion should begin.
- * @param len length of data to convert.
- * @param breakLines break lines at 80 characters or less.
- */
- public static final String encode(final byte[] src, final int off,
- final int len, final boolean breakLines)
- {
- final int len43 = len * 4 / 3;
- final byte[] outBuff = new byte[len43 // Main 4:3
- + ((len % 3) > 0 ? 4 : 0) // Account for padding
- + (breakLines ? (len43 / MAX_LINE_LENGTH)
- : 0)]; // New lines
- int d = 0;
- int e = 0;
- final int len2 = len - 2;
- int lineLength = 0;
- for (; d < len2; d += 3, e += 4)
- {
- encode3to4(src, d + off, 3, outBuff, e);
- lineLength += 4;
- if (breakLines && lineLength == MAX_LINE_LENGTH)
- {
- outBuff[e + 4] = NEW_LINE;
- e++;
- lineLength = 0;
- }
- }
- if (d < len) // padding needed
- {
- encode3to4(src, d + off, len - d, outBuff, e);
- e += 4;
- }
- return new String(outBuff, 0, e);
- }
-
- /**
- * Decodes data from Base64 notation.
- *
- * @param s the string to decode.
- * @return the decoded data.
- */
- public static final byte[] decode(final String s)
- throws UnsupportedEncodingException
- {
- final byte[] bytes;
- bytes = s.getBytes("US-ASCII");
- return decode(bytes, 0, bytes.length);
- }
-
- /**
- * Decodes Base64 content in byte array format and returns the decoded byte
- * array.
- *
- * @param src the Base64 encoded data.
- * @param off the offset of where to begin decoding.
- * @param len the length of characters to decode.
- * @return the decoded data.
- * @throws IllegalArgumentException if <code>src</code> contains an illegal
- * Base-64 character.
- */
- public static byte[] decode(final byte[] src, final int off, final int len)
- {
- final int len34 = len * 3 / 4;
- final byte[] outBuff = new byte[len34]; // Upper limit on size of output
- int outBuffPosn = 0;
- final byte[] b4 = new byte[4];
- int b4Posn = 0;
- int i;
- byte sbiCrop, sbiDecode;
- for (i = off; i < off + len; i++)
- {
- sbiCrop = (byte) (src[i] & 0x7F); // Only the low seven bits
- sbiDecode = DECODABET[sbiCrop];
- if (sbiDecode >= WHITE_SPACE_ENC)
- { // White space, Equals sign or better
- if (sbiDecode >= EQUALS_SIGN_ENC)
- {
- b4[b4Posn++] = sbiCrop;
- if (b4Posn > 3)
- {
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn);
- b4Posn = 0;
- // If that was the equals sign, break out of 'for' loop
- if (sbiCrop == EQUALS_SIGN)
- break;
- } // end if: quartet built
- } // end if: equals sign or better
- }
- throw new IllegalArgumentException("Illegal BASE-64 character at #"
- + i + ": " + src[i] + "(decimal)");
- }
- final byte[] result = new byte[outBuffPosn];
- System.arraycopy(outBuff, 0, result, 0, outBuffPosn);
- return result;
- }
-
- /**
- * Encodes up to three bytes of the array <code>src</code> and writes the
- * resulting four Base64 bytes to <code>dest</code>. The source and
- * destination arrays can be manipulated anywhere along their length by
- * specifying <code>sOffset</code> and <code>dOffset</code>.
- * <p>
- * This method does not check to make sure the arrays are large enough to
- * accomodate <code>sOffset + 3</code> for the <code>src</code> array or
- * <code>dOffset + 4</code> for the <code>dest</code> array. The actual
- * number of significant bytes in the input array is given by
- * <code>numBytes</code>.
- *
- * @param src the array to convert.
- * @param sOffset the index where conversion begins.
- * @param numBytes the number of significant bytes in your array.
- * @param dest the array to hold the conversion.
- * @param dOffset the index where output will be put.
- * @return the <code>destination</code> array.
- */
- private static final byte[] encode3to4(final byte[] src, final int sOffset,
- final int numBytes, final byte[] dest,
- final int dOffset)
- {
- // 1 2 3
- // 01234567890123456789012345678901 Bit position
- // --------000000001111111122222222 Array position from threeBytes
- // --------| || || || | Six bit groups to index ALPHABET
- // >>18 >>12 >> 6 >> 0 Right shift necessary
- // 0x3F 0x3F 0x3F Additional AND
-
- // Create buffer with zero-padding if there are only one or two
- // significant bytes passed in the array.
- // We have to shift left 24 in order to flush out the 1's that appear
- // when Java treats a value as negative that is cast from a byte to an int.
- final int inBuff = (numBytes > 0 ? ((src[sOffset] << 24) >>> 8) : 0)
- | (numBytes > 1 ? ((src[sOffset + 1] << 24) >>> 16) : 0)
- | (numBytes > 2 ? ((src[sOffset + 2] << 24) >>> 24) : 0);
- switch (numBytes)
- {
- case 3:
- dest[dOffset ] = ALPHABET[(inBuff >>> 18)];
- dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F];
- dest[dOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3F];
- dest[dOffset + 3] = ALPHABET[(inBuff) & 0x3F];
- break;
- case 2:
- dest[dOffset ] = ALPHABET[(inBuff >>> 18)];
- dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F];
- dest[dOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3F];
- dest[dOffset + 3] = EQUALS_SIGN;
- break;
- case 1:
- dest[dOffset ] = ALPHABET[(inBuff >>> 18)];
- dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F];
- dest[dOffset + 2] = EQUALS_SIGN;
- dest[dOffset + 3] = EQUALS_SIGN;
- break;
- }
- return dest;
- }
-
- /**
- * Decodes four bytes from array <code>src</code> and writes the resulting
- * bytes (up to three of them) to <code>dest</code>.
- * <p>
- * The source and destination arrays can be manipulated anywhere along their
- * length by specifying <code>sOffset</code> and <code>dOffset</code>.
- * <p>
- * This method does not check to make sure your arrays are large enough to
- * accomodate <code>sOffset + 4</code> for the <code>src</code> array or
- * <code>dOffset + 3</code> for the <code>dest</code> array. This method
- * returns the actual number of bytes that were converted from the Base64
- * encoding.
- *
- * @param src the array to convert.
- * @param sOffset the index where conversion begins.
- * @param dest the array to hold the conversion.
- * @param dOffset the index where output will be put.
- * @return the number of decoded bytes converted.
- */
- private static final int decode4to3(final byte[] src, final int sOffset,
- final byte[] dest, final int dOffset)
- {
- if (src[sOffset + 2] == EQUALS_SIGN) // Example: Dk==
- {
- final int outBuff = ((DECODABET[src[sOffset ]] & 0xFF) << 18)
- | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12);
- dest[dOffset] = (byte)(outBuff >>> 16);
- return 1;
- }
- if (src[sOffset + 3] == EQUALS_SIGN) // Example: DkL=
- {
- final int outBuff = ((DECODABET[src[sOffset ]] & 0xFF) << 18)
- | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[src[sOffset + 2]] & 0xFF) << 6);
- dest[dOffset ] = (byte)(outBuff >>> 16);
- dest[dOffset + 1] = (byte)(outBuff >>> 8);
- return 2;
- }
- try // Example: DkLE
- {
- final int outBuff = ((DECODABET[src[sOffset ]] & 0xFF) << 18)
- | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[src[sOffset + 2]] & 0xFF) << 6)
- | ((DECODABET[src[sOffset + 3]] & 0xFF));
- dest[dOffset ] = (byte)(outBuff >> 16);
- dest[dOffset + 1] = (byte)(outBuff >> 8);
- dest[dOffset + 2] = (byte) outBuff;
- return 3;
- }
- catch (Exception x)
- {
- if (Configuration.DEBUG)
- {
- log.fine("" + src[sOffset ] + ": " + (DECODABET[src[sOffset ]]));
- log.fine("" + src[sOffset + 1] + ": " + (DECODABET[src[sOffset + 1]]));
- log.fine("" + src[sOffset + 2] + ": " + (DECODABET[src[sOffset + 2]]));
- log.fine("" + src[sOffset + 3] + ": " + (DECODABET[src[sOffset + 3]]));
- }
- return -1;
- }
- }
-}
diff --git a/libjava/classpath/gnu/java/security/x509/X509Certificate.java b/libjava/classpath/gnu/java/security/x509/X509Certificate.java
index b3f8a696a85..14c5652648a 100644
--- a/libjava/classpath/gnu/java/security/x509/X509Certificate.java
+++ b/libjava/classpath/gnu/java/security/x509/X509Certificate.java
@@ -1,5 +1,5 @@
/* X509Certificate.java -- X.509 certificate.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,6 +48,7 @@ import gnu.java.security.der.DERValue;
import gnu.java.security.x509.ext.BasicConstraints;
import gnu.java.security.x509.ext.ExtendedKeyUsage;
import gnu.java.security.x509.ext.Extension;
+import gnu.java.security.x509.ext.GeneralName;
import gnu.java.security.x509.ext.IssuerAlternativeNames;
import gnu.java.security.x509.ext.KeyUsage;
import gnu.java.security.x509.ext.SubjectAlternativeNames;
@@ -103,6 +104,7 @@ public class X509Certificate extends java.security.cert.X509Certificate
// Constants and fields.
// ------------------------------------------------------------------------
+ private static final long serialVersionUID = -2491127588187038216L;
private static final Logger logger = SystemLogger.SYSTEM;
protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1");
@@ -133,7 +135,7 @@ public class X509Certificate extends java.security.cert.X509Certificate
protected transient PublicKey subjectKey;
protected transient BitString issuerUniqueId;
protected transient BitString subjectUniqueId;
- protected transient Map extensions;
+ protected transient Map<OID, Extension> extensions;
// Signature.
protected transient OID sigAlgId;
@@ -157,7 +159,7 @@ public class X509Certificate extends java.security.cert.X509Certificate
throws CertificateException, IOException
{
super();
- extensions = new HashMap();
+ extensions = new HashMap<OID, Extension>();
try
{
parse(encoded);
@@ -178,7 +180,7 @@ public class X509Certificate extends java.security.cert.X509Certificate
protected X509Certificate()
{
- extensions = new HashMap();
+ extensions = new HashMap<OID, Extension>();
}
// X509Certificate methods.
@@ -316,17 +318,15 @@ public class X509Certificate extends java.security.cert.X509Certificate
return null;
}
- public List getExtendedKeyUsage() throws CertificateParsingException
+ public List<String> getExtendedKeyUsage() throws CertificateParsingException
{
Extension e = getExtension(ExtendedKeyUsage.ID);
if (e != null)
{
- List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
- List b = new ArrayList(a.size());
- for (Iterator it = a.iterator(); it.hasNext(); )
- {
- b.add(it.next().toString());
- }
+ List<OID> a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
+ List<String> b = new ArrayList<String>(a.size());
+ for (OID oid : a)
+ b.add(oid.toString());
return Collections.unmodifiableList(b);
}
return null;
@@ -342,24 +342,44 @@ public class X509Certificate extends java.security.cert.X509Certificate
return -1;
}
- public Collection getSubjectAlternativeNames()
+ public Collection<List<?>> getSubjectAlternativeNames()
throws CertificateParsingException
{
Extension e = getExtension(SubjectAlternativeNames.ID);
if (e != null)
{
- return ((SubjectAlternativeNames) e.getValue()).getNames();
+ List<GeneralName> names
+ = ((SubjectAlternativeNames) e.getValue()).getNames();
+ List<List<?>> list = new ArrayList<List<?>>(names.size());
+ for (GeneralName name : names)
+ {
+ List<Object> n = new ArrayList<Object>(2);
+ n.add(name.kind().tag());
+ n.add(name.name());
+ list.add(n);
+ }
+ return list;
}
return null;
}
- public Collection getIssuerAlternativeNames()
+ public Collection<List<?>> getIssuerAlternativeNames()
throws CertificateParsingException
{
Extension e = getExtension(IssuerAlternativeNames.ID);
if (e != null)
{
- return ((IssuerAlternativeNames) e.getValue()).getNames();
+ List<GeneralName> names
+ = ((IssuerAlternativeNames) e.getValue()).getNames();
+ List<List<?>> list = new ArrayList<List<?>>(names.size());
+ for (GeneralName name : names)
+ {
+ List<Object> n = new ArrayList<Object>(2);
+ n.add(name.kind().tag());
+ n.add(name.name());
+ list.add(n);
+ }
+ return list;
}
return null;
}
@@ -378,24 +398,22 @@ public class X509Certificate extends java.security.cert.X509Certificate
return false;
}
- public Set getCriticalExtensionOIDs()
+ public Set<String> getCriticalExtensionOIDs()
{
- HashSet s = new HashSet();
- for (Iterator it = extensions.values().iterator(); it.hasNext(); )
+ HashSet<String> s = new HashSet<String>();
+ for (Extension e : extensions.values())
{
- Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
- public Set getNonCriticalExtensionOIDs()
+ public Set<String> getNonCriticalExtensionOIDs()
{
- HashSet s = new HashSet();
- for (Iterator it = extensions.values().iterator(); it.hasNext(); )
+ HashSet<String> s = new HashSet<String>();
+ for (Extension e : extensions.values())
{
- Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java b/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java
index 50bc6d367d7..c451762f8e0 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/CertificatePolicies.java
@@ -1,5 +1,5 @@
/* CertificatePolicies.java -- certificate policy extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -61,8 +61,8 @@ public class CertificatePolicies extends Extension.Value
public static final OID ID = new OID("2.5.29.32");
- private final List policies;
- private final Map policyQualifierInfos;
+ private final List<OID> policies;
+ private final Map<OID, List<PolicyQualifierInfo>> policyQualifierInfos;
// Constructor.
// -------------------------------------------------------------------------
@@ -76,8 +76,9 @@ public class CertificatePolicies extends Extension.Value
throw new IOException("malformed CertificatePolicies");
int len = 0;
- LinkedList policyList = new LinkedList();
- HashMap qualifierMap = new HashMap();
+ LinkedList<OID> policyList = new LinkedList<OID>();
+ HashMap<OID, List<PolicyQualifierInfo>> qualifierMap
+ = new HashMap<OID, List<PolicyQualifierInfo>>();
while (len < pol.getLength())
{
DERValue policyInfo = der.read();
@@ -92,7 +93,7 @@ public class CertificatePolicies extends Extension.Value
{
DERValue qual = der.read();
int len2 = 0;
- LinkedList quals = new LinkedList();
+ LinkedList<PolicyQualifierInfo> quals = new LinkedList<PolicyQualifierInfo>();
while (len2 < qual.getLength())
{
val = der.read();
@@ -109,8 +110,8 @@ public class CertificatePolicies extends Extension.Value
policyQualifierInfos = Collections.unmodifiableMap(qualifierMap);
}
- public CertificatePolicies (final List policies,
- final Map policyQualifierInfos)
+ public CertificatePolicies (final List<OID> policies,
+ final Map<OID, List<PolicyQualifierInfo>> policyQualifierInfos)
{
for (Iterator it = policies.iterator(); it.hasNext(); )
if (!(it.next() instanceof OID))
@@ -129,54 +130,69 @@ public class CertificatePolicies extends Extension.Value
throw new IllegalArgumentException
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
}
- this.policies = Collections.unmodifiableList (new ArrayList (policies));
+ this.policies = Collections.unmodifiableList (new ArrayList<OID>(policies));
this.policyQualifierInfos = Collections.unmodifiableMap
- (new HashMap (policyQualifierInfos));
+ (new HashMap<OID, List<PolicyQualifierInfo>>(policyQualifierInfos));
}
// Instance methods.
// -------------------------------------------------------------------------
- public List getPolicies()
+ public List<OID> getPolicies()
{
return policies;
}
+
+ /**
+ * Returns the list of policy OIDs, formatted as dotted-decimal strings.
+ *
+ * @return
+ */
+ public List<String> getPolicyStrings()
+ {
+ List<String> l = new ArrayList<String>(policies.size());
+ for (OID oid : policies)
+ {
+ l.add(oid.toString());
+ }
+ return l;
+ }
- public List getPolicyQualifierInfos(OID oid)
+ public List<PolicyQualifierInfo> getPolicyQualifierInfos(OID oid)
{
- return (List) policyQualifierInfos.get(oid);
+ return policyQualifierInfos.get(oid);
}
public byte[] getEncoded()
{
if (encoded == null)
{
- List pol = new ArrayList (policies.size());
- for (Iterator it = policies.iterator(); it.hasNext(); )
+ List<DERValue> pol = new ArrayList<DERValue>(policies.size());
+ for (Iterator<OID> it = policies.iterator(); it.hasNext(); )
{
- OID policy = (OID) it.next();
- List qualifiers = getPolicyQualifierInfos (policy);
- List l = new ArrayList (qualifiers == null ? 1 : 2);
- l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy));
+ OID policy = it.next();
+ List<PolicyQualifierInfo> qualifiers = getPolicyQualifierInfos(policy);
+ List<DERValue> l = new ArrayList<DERValue>(qualifiers == null ? 1 : 2);
+ l.add(new DERValue(DER.OBJECT_IDENTIFIER, policy));
if (qualifiers != null)
{
- List ll = new ArrayList (qualifiers.size());
- for (Iterator it2 = qualifiers.iterator(); it.hasNext(); )
+ List<DERValue> ll = new ArrayList<DERValue>(qualifiers.size());
+ for (Iterator<PolicyQualifierInfo> it2 = qualifiers.iterator(); it.hasNext(); )
{
- PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next();
+ PolicyQualifierInfo info = it2.next();
try
{
- ll.add (DERReader.read (info.getEncoded()));
+ ll.add(DERReader.read(info.getEncoded()));
}
catch (IOException ioe)
{
}
}
- l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll));
+ l.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ll));
}
- pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l));
+ pol.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, l));
}
- encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
+ encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
}
return (byte[]) encoded.clone();
}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java b/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java
index 37b08acf43e..428013d04bd 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/ExtendedKeyUsage.java
@@ -1,5 +1,5 @@
/* ExtendedKeyUsage.java -- the extended key usage extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -56,7 +56,7 @@ public class ExtendedKeyUsage extends Extension.Value
public static final OID ID = new OID("2.5.29.37");
- private final List purposeIds;
+ private final List<OID> purposeIds;
// Constructor.
// -------------------------------------------------------------------------
@@ -69,13 +69,13 @@ public class ExtendedKeyUsage extends Extension.Value
if (!usageList.isConstructed())
throw new IOException("malformed ExtKeyUsageSyntax");
int len = 0;
- purposeIds = new LinkedList();
+ purposeIds = new LinkedList<OID>();
while (len < usageList.getLength())
{
DERValue val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed KeyPurposeId");
- purposeIds.add(val.getValue());
+ purposeIds.add((OID) val.getValue());
len += val.getEncodedLength();
}
}
@@ -83,7 +83,7 @@ public class ExtendedKeyUsage extends Extension.Value
// Instance method.
// -------------------------------------------------------------------------
- public List getPurposeIds()
+ public List<OID> getPurposeIds()
{
return Collections.unmodifiableList(purposeIds);
}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/Extension.java b/libjava/classpath/gnu/java/security/x509/ext/Extension.java
index 69251987ec9..2b7e96d5abc 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/Extension.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/Extension.java
@@ -1,5 +1,5 @@
/* Extension.java -- an X.509 certificate or CRL extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -171,6 +171,10 @@ public class Extension
{
value = new ReasonCode(encval);
}
+ else if (oid.equals(NameConstraints.ID))
+ {
+ value = new NameConstraints(encval);
+ }
else
{
value = new Value(encval);
@@ -226,11 +230,11 @@ public class Extension
public DERValue getDerValue()
{
- List ext = new ArrayList (3);
- ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid));
- ext.add (new DERValue (DER.BOOLEAN, Boolean.valueOf (critical)));
- ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded()));
- return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext);
+ List<DERValue> ext = new ArrayList<DERValue>(3);
+ ext.add(new DERValue(DER.OBJECT_IDENTIFIER, oid));
+ ext.add(new DERValue(DER.BOOLEAN, Boolean.valueOf(critical)));
+ ext.add(new DERValue(DER.OCTET_STRING, value.getEncoded()));
+ return new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ext);
}
// Own methods.
diff --git a/libjava/classpath/gnu/java/security/x509/ext/GeneralName.java b/libjava/classpath/gnu/java/security/x509/ext/GeneralName.java
new file mode 100644
index 00000000000..fbc05339f6d
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/x509/ext/GeneralName.java
@@ -0,0 +1,232 @@
+/* GeneralName.java -- a GeneralName.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.x509.ext;
+
+import gnu.java.security.der.DER;
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+import gnu.java.security.x509.Util;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * The GeneralName structure from X.509.
+ *
+ * <pre>
+ GeneralName ::= CHOICE {
+ otherName [0] OtherName,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER }
+
+ OtherName ::= SEQUENCE {
+ type-id OBJECT IDENTIFIER,
+ value [0] EXPLICIT ANY DEFINED BY type-id }
+
+ EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString OPTIONAL,
+ partyName [1] DirectoryString }
+</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class GeneralName
+{
+ public static enum Kind
+ {
+ otherName (0),
+ rfc822Name (1),
+ dNSName (2),
+ x400Address (3),
+ directoryName (4),
+ ediPartyName (5),
+ uniformResourceIdentifier (6),
+ iPAddress (7),
+ registeredId (8);
+
+ private int tag;
+
+ private Kind(int tag)
+ {
+ this.tag = tag;
+ }
+
+ public static Kind forTag(final int tag)
+ {
+ switch (tag)
+ {
+ case 0: return otherName;
+ case 1: return rfc822Name;
+ case 2: return dNSName;
+ case 3: return x400Address;
+ case 4: return directoryName;
+ case 5: return ediPartyName;
+ case 6: return uniformResourceIdentifier;
+ case 7: return iPAddress;
+ case 8: return registeredId;
+ }
+
+ throw new IllegalArgumentException("invalid tag: " + tag);
+ }
+
+ public int tag()
+ {
+ return tag;
+ }
+ };
+
+ private final Kind kind;
+ private final byte[] name;
+ private final byte[] encoded;
+
+ public GeneralName(byte[] encoded) throws IOException
+ {
+ DERReader reader = new DERReader(encoded);
+ DERValue value = reader.read();
+
+ if (value.getTagClass() != DER.CONTEXT)
+ throw new IOException("malformed GeneralName");
+
+ this.encoded = value.getEncoded();
+
+ kind = Kind.forTag(value.getTag());
+ switch (kind)
+ {
+ case otherName:
+ name = value.getEncoded();
+ name[0] = (byte) (DER.CONSTRUCTED | DER.SEQUENCE);
+ // Skip the two fields of the name.
+ reader.read(); // OID
+ reader.read(); // Octet string
+ break;
+
+ case rfc822Name:
+ name = (byte[]) value.getValue();
+ break;
+
+ case dNSName:
+ name = (byte[]) value.getValue();
+ break;
+
+ case x400Address:
+ name = (byte[]) value.getValue();
+ break;
+
+ case directoryName:
+ name = value.getEncoded();
+ name[0] = (byte) (DER.CONSTRUCTED | DER.SEQUENCE);
+ break;
+
+ case ediPartyName:
+ name = value.getEncoded();
+ name[0] = (byte) (DER.CONSTRUCTED | DER.SEQUENCE);
+ break;
+
+ case uniformResourceIdentifier:
+ name = (byte[]) value.getValue();
+ break;
+
+ case iPAddress:
+ name = (byte[]) value.getValue();
+ break;
+
+ case registeredId:
+ name = value.getEncoded();
+ name[0] = DER.OBJECT_IDENTIFIER;
+ break;
+
+ default:
+ name = null; // Not reached.
+ }
+ }
+
+ public GeneralName(Kind kind, byte[] name)
+ {
+ this.kind = kind;
+ this.name = (byte[]) name.clone();
+ this.encoded = null;
+ }
+
+ public Kind kind()
+ {
+ return kind;
+ }
+
+ public byte[] name()
+ {
+ return (byte[]) name.clone();
+ }
+
+ public byte[] encoded()
+ {
+ try
+ {
+ return (byte[]) encoded.clone();
+ }
+ catch (NullPointerException npe)
+ {
+ return null;
+ }
+ }
+
+ public boolean equals(Object o)
+ {
+ try
+ {
+ GeneralName that = (GeneralName) o;
+ return (that.kind() == kind() && Arrays.equals(name, that.name));
+ }
+ catch (ClassCastException cce)
+ {
+ return false;
+ }
+ }
+
+ public String toString()
+ {
+ return (super.toString() + " [ kind=" + kind + "; name=" +
+ Util.hexDump(name, "") + " ]");
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java
index b342cbd5f2e..f56ee963b9c 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java
@@ -38,106 +38,38 @@ exception statement from your version. */
package gnu.java.security.x509.ext;
-import gnu.java.security.OID;
-import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import java.io.IOException;
-import java.net.InetAddress;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import javax.security.auth.x500.X500Principal;
-
public class GeneralNames
{
// Instance methods.
// -------------------------------------------------------------------------
- public static final int OTHER_NAME = 0;
- public static final int RFC822_NAME = 1;
- public static final int DNS_NAME = 2;
- public static final int X400_ADDRESS = 3;
- public static final int DIRECTORY_NAME = 4;
- public static final int EDI_PARTY_NAME = 5;
- public static final int URI = 6;
- public static final int IP_ADDRESS = 7;
- public static final int REGISTERED_ID = 8;
-
- private List names;
+ private List<GeneralName> names;
// Constructor.
// -------------------------------------------------------------------------
public GeneralNames(final byte[] encoded) throws IOException
{
- names = new LinkedList();
+ names = new LinkedList<GeneralName>();
DERReader der = new DERReader(encoded);
DERValue nameList = der.read();
if (!nameList.isConstructed())
throw new IOException("malformed GeneralNames");
int len = 0;
- int i = 0;
while (len < nameList.getLength())
{
DERValue name = der.read();
- List namePair = new ArrayList(2);
- int tagClass = name.getTagClass();
- if (tagClass != DER.CONTEXT)
- throw new IOException("malformed GeneralName: Tag class is " + tagClass);
- namePair.add(Integer.valueOf(name.getTag()));
- DERValue val = null;
- switch (name.getTag())
- {
- case RFC822_NAME:
- case DNS_NAME:
- case X400_ADDRESS:
- case URI:
- namePair.add(new String((byte[]) name.getValue()));
- break;
-
- case OTHER_NAME:
- // MUST return the encoded bytes of the OID/OctetString sequence
- byte[] anotherName = name.getEncoded();
- anotherName[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
- namePair.add(anotherName);
- // DERReader goes back on Constructed things so we need to skip over them
- DERValue skip = der.read(); // skip OID
- skip = der.read(); // skip Octet String
- break;
-
- case EDI_PARTY_NAME:
- namePair.add(name.getValue());
- break;
-
- case DIRECTORY_NAME:
- byte[] b = name.getEncoded();
- b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
- DERReader r = new DERReader (b);
- r.read ();
- namePair.add(new X500Principal(r.read ().getEncoded ()).toString());
- break;
-
- case IP_ADDRESS:
- namePair.add(InetAddress.getByAddress((byte[]) name.getValue())
- .getHostAddress());
- break;
-
- case REGISTERED_ID:
- byte[] bb = name.getEncoded();
- bb[0] = (byte) DER.OBJECT_IDENTIFIER;
- namePair.add(new OID(bb).toString());
- break;
-
- default:
- throw new IOException("unknown tag " + name.getTag());
- }
- names.add(namePair);
+ GeneralName generalName = new GeneralName(name.getEncoded());
+ names.add(generalName);
len += name.getEncodedLength();
}
}
@@ -145,21 +77,9 @@ public class GeneralNames
// Instance methods.
// -------------------------------------------------------------------------
- public List getNames()
+ public List<GeneralName> getNames()
{
- List l = new ArrayList(names.size());
- for (Iterator it = names.iterator(); it.hasNext(); )
- {
- List ll = (List) it.next();
- List pair = new ArrayList(2);
- pair.add(ll.get(0));
- if (ll.get(1) instanceof byte[])
- pair.add(((byte[]) ll.get(1)).clone());
- else
- pair.add(ll.get(1));
- l.add(Collections.unmodifiableList(pair));
- }
- return Collections.unmodifiableList(l);
+ return Collections.unmodifiableList(names);
}
public String toString()
diff --git a/libjava/classpath/gnu/java/security/x509/ext/GeneralSubtree.java b/libjava/classpath/gnu/java/security/x509/ext/GeneralSubtree.java
new file mode 100644
index 00000000000..5f6ffd98701
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/x509/ext/GeneralSubtree.java
@@ -0,0 +1,156 @@
+/* GeneralSubtree.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.x509.ext;
+
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+/**
+ * The GeneralSubtree structure, a part of the {@link NameConstraints}
+ * extension.
+ *
+ * <pre>
+ GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL }
+
+ BaseDistance ::= INTEGER (0..MAX)</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class GeneralSubtree
+{
+ private final GeneralName base;
+ private final int minimum;
+ private final int maximum;
+
+ public GeneralSubtree(byte[] encoded) throws IOException
+ {
+ DERReader reader = new DERReader(encoded);
+ DERValue generalSubtree = reader.read();
+
+ if (!generalSubtree.isConstructed())
+ throw new IOException("malformed GeneralSubtree");
+
+ DERValue generalName = reader.read();
+ base = new GeneralName(generalName.getEncoded());
+ if (generalName.isConstructed())
+ reader.skip(generalName.getLength());
+
+ int len = generalName.getEncodedLength();
+ if (len < generalSubtree.getLength())
+ {
+ DERValue distance = reader.read();
+ if (distance.getTag() == 0)
+ {
+ minimum = ((BigInteger) distance.getValue()).intValue();
+ len += distance.getEncodedLength();
+ if (len < generalSubtree.getLength())
+ {
+ distance = reader.read();
+ if (distance.getTag() != 1)
+ throw new IOException("unexpected tag "
+ + distance.getTag() +
+ " (expected 1 for GeneralSubtree maximum distance)");
+ maximum = ((BigInteger) distance.getValue()).intValue();
+ }
+ else
+ {
+ maximum = -1;
+ }
+ }
+ else if (distance.getTag() == 1)
+ {
+ minimum = 1;
+ maximum = ((BigInteger) distance.getValue()).intValue();
+ }
+ else
+ {
+ throw new IOException("unexpected tag " + distance.getTag()
+ + " (expected 0 or 1 for GeneralSubtree distance)");
+ }
+ }
+ else
+ {
+ minimum = 0;
+ maximum = -1;
+ }
+ }
+
+ /**
+ * Returns the base name.
+ *
+ * @return The base name.
+ */
+ public GeneralName base()
+ {
+ return base;
+ }
+
+ /**
+ * Returns the minimum base distance, possibly zero.
+ *
+ * @return The minimum base distance.
+ */
+ public int minimum()
+ {
+ return minimum;
+ }
+
+ /**
+ * Returns the maximum base distance, or -1 if this value was not specified.
+ *
+ * @return The maximum base distance.
+ */
+ public int maximum()
+ {
+ return maximum;
+ }
+
+ public String toString()
+ {
+ return (GeneralSubtree.class.getName() + " [ base=" + base
+ + "; minimum=" + minimum + "; maximim=" + maximum
+ + " ]");
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java b/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java
index 8b017dc62d8..080070b9890 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/IssuerAlternativeNames.java
@@ -1,5 +1,5 @@
/* IssuerAlternatuveNames.java -- issuer alternative names extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -65,7 +65,7 @@ public class IssuerAlternativeNames extends Extension.Value
// Instance method.
// -------------------------------------------------------------------------
- public List getNames()
+ public List<GeneralName> getNames()
{
return names.getNames();
}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/NameConstraints.java b/libjava/classpath/gnu/java/security/x509/ext/NameConstraints.java
new file mode 100644
index 00000000000..607c4296642
--- /dev/null
+++ b/libjava/classpath/gnu/java/security/x509/ext/NameConstraints.java
@@ -0,0 +1,161 @@
+/* NameConstraints.java -- the NameConstraints X.509 extension.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.security.x509.ext;
+
+import gnu.java.security.OID;
+import gnu.java.security.der.DERReader;
+import gnu.java.security.der.DERValue;
+import gnu.java.security.x509.ext.Extension.Value;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * The NameConstraints extension. From RFC 3280, section 4.2.1.11, this
+ * extension is defined as:
+ *
+ * <pre>
+ id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+
+ NameConstraints ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+
+ GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+ GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL }
+
+ BaseDistance ::= INTEGER (0..MAX)
+ </pre>
+ *
+ * See also the classes {@link GeneralNames} and {@link GeneralSubtree}.
+ *
+ * @author csm
+ */
+public class NameConstraints extends Value
+{
+ public static final OID ID = new OID("2.5.29.30");
+
+ private List<GeneralSubtree> permittedSubtrees;
+ private List<GeneralSubtree> excludedSubtrees;
+
+ public NameConstraints(byte[] encoded) throws IOException
+ {
+ super(encoded);
+
+ DERReader der = new DERReader(encoded);
+ DERValue value = der.read();
+ if (!value.isConstructed())
+ {
+ throw new IOException("malformed NameConstraints");
+ }
+
+ permittedSubtrees = new LinkedList<GeneralSubtree>();
+ excludedSubtrees = new LinkedList<GeneralSubtree>();
+ int len = 0;
+ if (len < value.getLength())
+ {
+ DERValue subtrees = der.read();
+ if (subtrees.getTag() == 0)
+ {
+ int len2 = 0;
+ while (len2 < subtrees.getLength())
+ {
+ DERValue subtree = der.read();
+ permittedSubtrees.add(new GeneralSubtree(subtree.getEncoded()));
+ der.skip(subtree.getLength());
+ len2 += subtree.getEncodedLength();
+ }
+ len += subtrees.getEncodedLength();
+
+ if (len < value.getLength())
+ {
+ subtrees = der.read();
+ if (subtrees.getTag() != 1)
+ throw new IOException("unexpected tag " + subtrees.getTag()
+ + " (expecting 1 for excludedSubtrees)");
+ len2 = 0;
+ while (len2 < subtrees.getLength())
+ {
+ DERValue subtree = der.read();
+ excludedSubtrees.add(new GeneralSubtree(subtree.getEncoded()));
+ der.skip(subtree.getLength());
+ len2 += subtree.getEncodedLength();
+ }
+ }
+ }
+ else if (subtrees.getTag() == 1)
+ {
+ int len2 = 0;
+ while (len2 < subtrees.getLength())
+ {
+ DERValue subtree = der.read();
+ excludedSubtrees.add(new GeneralSubtree(subtree.getEncoded()));
+ der.skip(subtree.getLength());
+ len2 += subtree.getEncodedLength();
+ }
+ }
+ else
+ throw new IOException("unexpected tag " + subtrees.getTag()
+ + " (expecting 0 or 1)");
+ }
+ }
+
+ public List<GeneralSubtree> permittedSubtrees()
+ {
+ return Collections.unmodifiableList(permittedSubtrees);
+ }
+
+ public List<GeneralSubtree> excludedSubtrees()
+ {
+ return Collections.unmodifiableList(excludedSubtrees);
+ }
+
+ public String toString()
+ {
+ return NameConstraints.class.getName() + " [ permittedSubtrees="
+ + permittedSubtrees + "; excludedSubtrees=" + excludedSubtrees
+ + " ]";
+ }
+}
diff --git a/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java b/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java
index f88e854965f..8b6347d99a3 100644
--- a/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java
+++ b/libjava/classpath/gnu/java/security/x509/ext/SubjectAlternativeNames.java
@@ -1,5 +1,5 @@
/* SubjectAlternatuveNames.java -- subject alternative names extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -65,7 +65,7 @@ public class SubjectAlternativeNames extends Extension.Value
// Instance method.
// -------------------------------------------------------------------------
- public List getNames()
+ public List<GeneralName> getNames()
{
return names.getNames();
}
diff --git a/libjava/classpath/gnu/javax/net/ssl/Base64.java b/libjava/classpath/gnu/java/util/Base64.java
index 52989da69d3..592696bcc80 100644
--- a/libjava/classpath/gnu/javax/net/ssl/Base64.java
+++ b/libjava/classpath/gnu/java/util/Base64.java
@@ -1,5 +1,5 @@
/* Base64.java -- Base64 encoding and decoding.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
@@ -81,7 +81,7 @@ SOFTWARE, EVEN IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH
DAMAGES. */
-package gnu.javax.net.ssl;
+package gnu.java.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -103,6 +103,17 @@ public final class Base64
private static final char BASE_64_PAD = '=';
/**
+ * Base64 encode a byte array, with no line wrapping.
+ *
+ * @param buf The byte array to encode.
+ * @return <tt>buf</tt> encoded in Base64.
+ */
+ public static String encode(byte[] buf)
+ {
+ return encode(buf, 0);
+ }
+
+ /**
* Base64 encode a byte array, returning the returning string.
*
* @param buf The byte array to encode.
@@ -111,11 +122,29 @@ public final class Base64
*/
public static String encode(byte[] buf, int tw)
{
- int srcLength = buf.length;
+ return encode(buf, 0, buf.length, tw);
+ }
+
+ /**
+ * Base64 encode a byte array, returning the returning string.
+ *
+ * @param buf The byte array to encode.
+ * @param offset The offset in the byte array to start.
+ * @param length The number of bytes to encode.
+ * @param tw The total length of any line, 0 for unlimited.
+ * @return <tt>buf</tt> encoded in Base64.
+ */
+ public static String encode(byte[] buf, int offset, int length, int tw)
+ {
+ if (offset < 0 || length < 0 || offset + length > buf.length)
+ throw new ArrayIndexOutOfBoundsException(buf.length + " "
+ + offset + " "
+ + length);
+ int srcLength = buf.length - offset;
byte[] input = new byte[3];
int[] output = new int[4];
StringBuffer out = new StringBuffer();
- int i = 0;
+ int i = offset;
int chars = 0;
while (srcLength > 2)
@@ -270,6 +299,7 @@ public final class Base64
throw new IOException("malformed Base64 sequence");
case 2:
+ i++;
for ( ; i < b64.length(); i++)
{
if (!Character.isWhitespace(b64.charAt(i)))
@@ -292,7 +322,6 @@ public final class Base64
// We should only see whitespace after this.
if (!Character.isWhitespace(b64.charAt(i)))
{
- System.err.println(b64.charAt(i));
throw new IOException("malformed Base64 sequence");
}
}
diff --git a/libjava/classpath/gnu/java/util/prefs/EventDispatcher.java b/libjava/classpath/gnu/java/util/prefs/EventDispatcher.java
index ecddd3a55f2..f73c3e70311 100644
--- a/libjava/classpath/gnu/java/util/prefs/EventDispatcher.java
+++ b/libjava/classpath/gnu/java/util/prefs/EventDispatcher.java
@@ -53,7 +53,7 @@ public class EventDispatcher extends Thread
// This is a queue of events to dispatch. This thread waits on
// the queue and when notified will remove events until the queue
// is empty.
- private static final ArrayList queue = new ArrayList();
+ private static final ArrayList<Runnable> queue = new ArrayList<Runnable>();
// FIXME: this thread probably ought to go in some classpath-internal
// ThreadGroup. But we don't have that yet.
@@ -81,7 +81,7 @@ public class EventDispatcher extends Thread
// Ignore.
}
}
- r = (Runnable) queue.remove(0);
+ r = queue.remove(0);
}
// Invoke outside the synchronization, so that
// we aren't blocking other threads from posting events.
diff --git a/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java b/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
index a7e2322b524..0fd4df36616 100644
--- a/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
+++ b/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
@@ -41,7 +41,6 @@ import gnu.java.util.prefs.gconf.GConfNativePeer;
import java.security.Permission;
-import java.util.Iterator;
import java.util.List;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;
@@ -185,7 +184,7 @@ public class GConfBasedPreferences
*/
protected String[] childrenNamesSpi() throws BackingStoreException
{
- List nodeList = backend.getChildrenNodes(this.node);
+ List<String> nodeList = backend.getChildrenNodes(this.node);
String[] nodes = new String[nodeList.size()];
nodeList.toArray(nodes);
@@ -228,7 +227,7 @@ public class GConfBasedPreferences
*/
protected String[] keysSpi() throws BackingStoreException
{
- List keyList = backend.getKeys(this.node);
+ List<String> keyList = backend.getKeys(this.node);
String[] keys = new String[keyList.size()];
keyList.toArray(keys);
@@ -246,31 +245,24 @@ public class GConfBasedPreferences
try
{
// gets the listing of directories in this node
- List dirs = backend.getChildrenNodes(directory);
+ List<String> dirs = backend.getChildrenNodes(directory);
if (dirs.size() != 0)
{
- String currentDir = null;
-
- for (Iterator itr = dirs.iterator(); itr.hasNext();)
+ for (String currentDir : dirs)
{
- currentDir = (String) itr.next();
-
// recursive search inside this directory
postorderRemove(currentDir);
}
}
// remove all the keys associated to this directory
- List entries = backend.getKeys(directory);
+ List<String> entries = backend.getKeys(directory);
if (entries.size() != 0)
{
- String key = null;
-
- for (Iterator keys = entries.iterator(); keys.hasNext();)
+ for (String key : entries)
{
- key = (String) keys.next();
this.removeSpi(key);
}
}
diff --git a/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java b/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java
index cccb9bf2fc2..dc82379160b 100644
--- a/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java
+++ b/libjava/classpath/gnu/java/util/prefs/MemoryBasedPreferences.java
@@ -52,7 +52,7 @@ public class MemoryBasedPreferences extends AbstractPreferences {
private final boolean isUser;
/** Contains all the preference entries of this node. */
- private HashMap entries = new HashMap();
+ private HashMap<String, String> entries = new HashMap<String, String>();
/**
* Creates a new preferences node with the given name and parent.
@@ -98,7 +98,7 @@ public class MemoryBasedPreferences extends AbstractPreferences {
* this node.
*/
protected String[] keysSpi() throws BackingStoreException {
- return (String[]) entries.keySet().toArray(new String[entries.size()]);
+ return entries.keySet().toArray(new String[entries.size()]);
}
/**
@@ -106,7 +106,7 @@ public class MemoryBasedPreferences extends AbstractPreferences {
* null when the key has not been set.
*/
protected String getSpi(String key) {
- return (String) entries.get(key);
+ return entries.get(key);
}
/**
diff --git a/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java b/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
index 6049863e916..5e12c718b2c 100644
--- a/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
+++ b/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
@@ -147,7 +147,7 @@ public final class GConfNativePeer
* @return a java.util.List of keys. If there are no keys in the given node, a
* list of size 0 is returned.
*/
- public List getKeys(String node) throws BackingStoreException
+ public List<String> getKeys(String node) throws BackingStoreException
{
return gconf_client_all_keys(node);
}
@@ -159,7 +159,7 @@ public final class GConfNativePeer
* @param node the node to get subnodes from. If there are no subnodes in the
* given node, a list of size 0 is returned.
*/
- public List getChildrenNodes(String node) throws BackingStoreException
+ public List<String> getChildrenNodes(String node) throws BackingStoreException
{
return gconf_client_all_nodes(node);
}
@@ -295,7 +295,7 @@ public final class GConfNativePeer
* @return A list of nodes under the given source node.
*/
native
- static final protected List gconf_client_all_nodes(String node)
+ static final protected List<String> gconf_client_all_nodes(String node)
throws BackingStoreException;
/**
@@ -305,7 +305,7 @@ public final class GConfNativePeer
* @return A list of all keys stored in the given node.
*/
native
- static final protected List gconf_client_all_keys(String node)
+ static final protected List<String> gconf_client_all_keys(String node)
throws BackingStoreException;
/**
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenChar.java b/libjava/classpath/gnu/java/util/regex/RETokenChar.java
index b70e6b1d843..42dcd93268a 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenChar.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenChar.java
@@ -113,7 +113,6 @@ final class RETokenChar extends REToken {
boolean chain(REToken next) {
if (next instanceof RETokenChar && ((RETokenChar)next).insens == insens) {
RETokenChar cnext = (RETokenChar) next;
- // assume for now that next can only be one character
int newsize = ch.length + cnext.ch.length;
char[] chTemp = new char [newsize];
@@ -122,7 +121,9 @@ final class RETokenChar extends REToken {
System.arraycopy(cnext.ch,0,chTemp,ch.length,cnext.ch.length);
ch = chTemp;
- return false;
+ if (cnext.next == null)
+ return false;
+ return chain(cnext.next);
} else return super.chain(next);
}
diff --git a/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java b/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java
index d2696e1c6b8..b6dc21e19cd 100644
--- a/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java
+++ b/libjava/classpath/gnu/javax/imageio/png/PNGICCProfile.java
@@ -61,7 +61,9 @@ public class PNGICCProfile extends PNGChunk
{
super( type, data, crc );
int i = 0;
- while( data[i++] != 0 );
+ while( data[i++] != 0 )
+ ;
+
try
{
name = new String(data, 0, i, "8859_1");
diff --git a/libjava/classpath/gnu/javax/management/Translator.java b/libjava/classpath/gnu/javax/management/Translator.java
new file mode 100644
index 00000000000..69191d43f86
--- /dev/null
+++ b/libjava/classpath/gnu/javax/management/Translator.java
@@ -0,0 +1,544 @@
+/* Translator.java -- Performs MXBean data type translation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.management;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import javax.management.JMX;
+import javax.management.MBeanServerInvocationHandler;
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+/**
+ * Translates Java data types to their equivalent
+ * open data type, and vice versa, according to the
+ * {@link javax.management.MXBean} rules.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public final class Translator
+{
+
+ /**
+ * Translates the input Java data types to the equivalent
+ * open data types.
+ *
+ * @param jtypes the Java types supplied as parameters.
+ * @param method the method that was called.
+ * @return the equivalent open types required by the {@link MXBean}.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object[] fromJava(Object[] jtypes, Method method)
+ throws Throwable
+ {
+ Type[] gtypes = method.getGenericParameterTypes();
+ Object[] otypes = new Object[jtypes.length];
+ for (int a = 0; a < jtypes.length; ++a)
+ otypes[a] = fromJava(jtypes[a], (Class<?>) gtypes[a]);
+ return otypes;
+ }
+
+ /**
+ * Translates the input Java data type to the equivalent
+ * open data type.
+ *
+ * @param jtype the Java type supplied as a parameter.
+ * @param type the type of the parameter.
+ * @return the equivalent open type required by the {@link MXBean}.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object fromJava(Object jtype, Type type)
+ throws Throwable
+ {
+ if (jtype == null)
+ return null;
+ Class<?> jclass = jtype.getClass();
+ if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(jclass.getName()))
+ return jtype;
+ if (jclass.isArray())
+ {
+ Class<?> ctype = jclass.getComponentType();
+ if (ctype.isPrimitive())
+ return jtype;
+ if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(ctype.getName()))
+ return jtype;
+ Object[] elems = (Object[]) jtype;
+ Object[] celems = new Object[elems.length];
+ for (int a = 0; a < elems.length; ++a)
+ celems[a] = fromJava(elems[a], elems[a].getClass());
+ return makeArraySpecific(celems);
+ }
+ String tName = getTypeName(type);
+ if (jtype instanceof List || jtype instanceof Set ||
+ jtype instanceof SortedSet)
+ {
+ String elemType = tName.substring(tName.indexOf("<") + 1,
+ tName.indexOf(">")).trim();
+ if (jtype instanceof SortedSet)
+ {
+ Class<?> elemClass = Class.forName(elemType);
+ if (!Comparable.class.isAssignableFrom(elemClass))
+ throw new IllegalArgumentException(jtype + " has a " +
+ "non-comparable element " +
+ "type, " + elemClass);
+ if (((SortedSet) jtype).comparator() != null)
+ throw new IllegalArgumentException(jtype + " does not " +
+ "use natural ordering.");
+ }
+ List elems = (List) jtype;
+ Object[] celems = new Object[elems.size()];
+ for (int a = 0; a < elems.size(); ++a)
+ {
+ Object elem = elems.get(a);
+ celems[a] = fromJava(elem, elem.getClass());
+ }
+ return makeArraySpecific(celems);
+ }
+ if (jtype instanceof Enum)
+ return ((Enum) jtype).name();
+ if (jtype instanceof Map || jtype instanceof SortedMap)
+ {
+ int lparam = tName.indexOf("<");
+ int comma = tName.indexOf(",", lparam);
+ int rparam = tName.indexOf(">", comma);
+ String key = tName.substring(lparam + 1, comma).trim();
+ String value = tName.substring(comma + 1, rparam).trim();
+ String typeName = null;
+ if (jtype instanceof Map)
+ typeName = "java.util.Map" + tName.substring(lparam);
+ else
+ {
+ Class<?> keyClass = Class.forName(key);
+ if (!Comparable.class.isAssignableFrom(keyClass))
+ throw new IllegalArgumentException(jtype + " has a " +
+ "non-comparable element " +
+ "type, " + keyClass);
+ if (((SortedMap) jtype).comparator() != null)
+ throw new IllegalArgumentException(jtype + " does not " +
+ "use natural ordering.");
+ typeName = "java.util.SortedMap" + tName.substring(lparam);
+ }
+ OpenType k = translate(key).getOpenType();
+ OpenType v = translate(value).getOpenType();
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ new String[] { "key", "value" },
+ new String[] { "Map key", "Map value"},
+ new OpenType[] {k,v});
+ TabularType tabType = new TabularType(typeName, typeName, rowType,
+ new String[]{"key"});
+ TabularData data = new TabularDataSupport(tabType);
+ for (Map.Entry entry : (Set<Map.Entry>) ((Map) jtype).entrySet())
+ {
+ try
+ {
+ data.put(new CompositeDataSupport(rowType,
+ new String[] {
+ "key",
+ "value"
+ },
+ new Object[] {
+ entry.getKey(),
+ entry.getValue()
+ }));
+ }
+ catch (OpenDataException e)
+ {
+ throw (InternalError) (new InternalError("A problem occurred " +
+ "converting the map " +
+ "to a composite data " +
+ "structure.").initCause(e));
+ }
+ }
+ return data;
+ }
+ if (JMX.isMXBeanInterface(jclass))
+ {
+ try
+ {
+ MBeanServerInvocationHandler ih = (MBeanServerInvocationHandler)
+ Proxy.getInvocationHandler(jtype);
+ return ih.getObjectName();
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalArgumentException("For a MXBean to be translated " +
+ "to an open type, it must be a " +
+ "proxy.", e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new IllegalArgumentException("For a MXBean to be translated " +
+ "to an open type, it must have a " +
+ "MBeanServerInvocationHandler.", e);
+ }
+ }
+ /* FIXME: Handle other types */
+ throw new IllegalArgumentException("The type, " + jtype +
+ ", is not convertible.");
+ }
+
+ /**
+ * Translates the returned open data type to the value
+ * required by the interface.
+ *
+ * @param otype the open type returned by the method call.
+ * @param method the method that was called.
+ * @return the equivalent return type required by the interface.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object toJava(Object otype, Method method)
+ throws Throwable
+ {
+ Class<?> returnType = method.getReturnType();
+ if (returnType.isEnum())
+ {
+ String ename = (String) otype;
+ Enum[] constants = (Enum[]) returnType.getEnumConstants();
+ for (Enum c : constants)
+ if (c.name().equals(ename))
+ return c;
+ }
+ if (List.class.isAssignableFrom(returnType))
+ {
+ Object[] elems = (Object[]) otype;
+ List l = new ArrayList(elems.length);
+ for (Object elem : elems)
+ l.add(elem);
+ return l;
+ }
+ if (Map.class.isAssignableFrom(returnType))
+ {
+ TabularData data = (TabularData) otype;
+ Map m = new HashMap(data.size());
+ for (Object val : data.values())
+ {
+ CompositeData vals = (CompositeData) val;
+ m.put(vals.get("key"), vals.get("value"));
+ }
+ return m;
+ }
+ try
+ {
+ Method m = returnType.getMethod("from",
+ new Class[]
+ { CompositeData.class });
+ return m.invoke(null, (CompositeData) otype);
+ }
+ catch (NoSuchMethodException e)
+ {
+ /* Ignored; we expect this if this
+ isn't a from(CompositeData) class */
+ }
+ return otype;
+ }
+
+ /**
+ * Creates a new array which has the specific type
+ * used by the elements of the original {@link Object}
+ * array supplied.
+ *
+ * @param arr a series of elements in an {@link Object}
+ * array.
+ * @return the same elements in a new array of the specific
+ * type.
+ */
+ private static final Object[] makeArraySpecific(Object[] arr)
+ {
+ Object[] rcelems = (Object[]) Array.newInstance(arr[0].getClass(),
+ arr.length);
+ System.arraycopy(arr, 0, rcelems, 0, arr.length);
+ return rcelems;
+ }
+
+ /**
+ * Translates the name of a type into an equivalent
+ * {@link javax.management.openmbean.OpenMBeanParameterInfo}
+ * that describes it.
+ *
+ * @param type the type to describe.
+ * @return an instance of
+ * {@link javax.management.openmbean.OpenMBeanParameterInfo},
+ * describing the translated type and limits of the given type.
+ * @throws OpenDataException if a type is not open.
+ */
+ public static final OpenMBeanParameterInfo translate(String type)
+ throws OpenDataException
+ {
+ if (type.equals("boolean") || type.equals(Boolean.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.BOOLEAN,
+ null,
+ new Boolean[] {
+ Boolean.TRUE,
+ Boolean.FALSE
+ });
+ if (type.equals("byte") || type.equals(Byte.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.BYTE,
+ null,
+ Byte.valueOf(Byte.MIN_VALUE),
+ Byte.valueOf(Byte.MAX_VALUE));
+ if (type.equals("char") || type.equals(Character.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.CHARACTER,
+ null,
+ Character.valueOf(Character.MIN_VALUE),
+ Character.valueOf(Character.MAX_VALUE));
+ if (type.equals("double") || type.equals(Double.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.DOUBLE,
+ null,
+ Double.valueOf(Double.MIN_VALUE),
+ Double.valueOf(Double.MAX_VALUE));
+ if (type.equals("float") || type.equals(Float.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.FLOAT,
+ null,
+ Float.valueOf(Float.MIN_VALUE),
+ Float.valueOf(Float.MAX_VALUE));
+ if (type.equals("int") || type.equals(Integer.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.INTEGER,
+ null,
+ Integer.valueOf(Integer.MIN_VALUE),
+ Integer.valueOf(Integer.MAX_VALUE));
+ if (type.equals("long") || type.equals(Long.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.LONG,
+ null,
+ Long.valueOf(Long.MIN_VALUE),
+ Long.valueOf(Long.MAX_VALUE));
+ if (type.equals("short") || type.equals(Short.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.SHORT,
+ null,
+ Short.valueOf(Short.MIN_VALUE),
+ Short.valueOf(Short.MAX_VALUE));
+ if (type.equals(String.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.STRING);
+ if (type.equals("void"))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.VOID);
+ if (type.startsWith("java.util.Map"))
+ {
+ int lparam = type.indexOf("<");
+ int comma = type.indexOf(",", lparam);
+ int rparam = type.indexOf(">", comma);
+ String key = type.substring(lparam + 1, comma).trim();
+ OpenType k = translate(key).getOpenType();
+ OpenType v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
+ CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
+ new String[] { "key", "value" },
+ new String[] { "Map key", "Map value"},
+ new OpenType[] { k, v});
+ TabularType ttype = new TabularType(key, key, ctype,
+ new String[] { "key" });
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ ttype);
+ }
+ if (type.startsWith("java.util.List"))
+ {
+ int lparam = type.indexOf("<");
+ int rparam = type.indexOf(">");
+ OpenType e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ new ArrayType(1, e)
+ );
+ }
+ Class c;
+ try
+ {
+ c = Class.forName(type);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw (InternalError)
+ (new InternalError("The class for a type used in a management bean " +
+ "could not be loaded.").initCause(e));
+ }
+ if (c.isEnum())
+ {
+ Object[] values = c.getEnumConstants();
+ String[] names = new String[values.length];
+ for (int a = 0; a < values.length; ++a)
+ names[a] = values[a].toString();
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.STRING,
+ null, names);
+ }
+ try
+ {
+ c.getMethod("from", new Class[] { CompositeData.class });
+ Method[] methods = c.getDeclaredMethods();
+ List<String> names = new ArrayList<String>();
+ List<OpenType> types = new ArrayList<OpenType>();
+ for (int a = 0; a < methods.length; ++a)
+ {
+ String name = methods[a].getName();
+ if (name.startsWith("get"))
+ {
+ names.add(name.substring(3));
+ types.add(getTypeFromClass(methods[a].getReturnType()));
+ }
+ }
+ String[] fields = names.toArray(new String[names.size()]);
+ CompositeType ctype = new CompositeType(c.getName(), c.getName(),
+ fields, fields,
+ types.toArray(new OpenType[types.size()]));
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ ctype);
+ }
+ catch (NoSuchMethodException e)
+ {
+ /* Ignored; we expect this if this isn't a from(CompositeData) class */
+ }
+ if (c.isArray())
+ {
+ int depth;
+ for (depth = 0; c.getName().charAt(depth) == '['; ++depth)
+ ;
+ OpenType ot = getTypeFromClass(c.getComponentType());
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ new ArrayType(depth, ot)
+ );
+ }
+ throw new InternalError("The type used does not have an open type translation.");
+ }
+
+ /**
+ * Obtains the {@link javax.management.openmbean.OpenType}
+ * for a particular class.
+ *
+ * @param c the class to obtain the type for.
+ * @return the appropriate instance.
+ * @throws OpenDataException if the type is not open.
+ */
+ private static final OpenType getTypeFromClass(Class c)
+ throws OpenDataException
+ {
+ return Translator.translate(c.getName()).getOpenType();
+ }
+
+ /**
+ * <p>
+ * Returns the type name according to the rules described
+ * in {@link javax.management.MXBean}. Namely, for a type,
+ * {@code T}, {@code typename(T)} is computed as follows:
+ * </p>
+ * <ul>
+ * <li>If T is non-generic and not an array, then the value
+ * of {@link java.lang.Class#getName()} is returned.</li>
+ * <li>If T is an array type, {@code{E[]}, then the type name
+ * is {@code typename(E)} followed by an occurrence
+ * of {@code '[]'} for each dimension.</li>
+ * <li>If T is a generic or parameterized type, the type name
+ * is composed of {@code typename(P)}, where {@code P} is the
+ * parameterized type name, followed by {@code '<'}, the resulting
+ * list of type names of the parameters after applying {@code typename}
+ * to each, separated by commas, and {@code '>'}.</li>
+ * </ul>
+ *
+ * @param type the type to return the type name of.
+ * @return the type name computed according to the rules above.
+ */
+ private static final String getTypeName(Type type)
+ {
+ if (type instanceof Class)
+ {
+ Class<?> c = (Class<?>) type;
+ if (c.isArray())
+ {
+ StringBuilder b =
+ new StringBuilder(c.getComponentType().getName());
+ String normName = c.getName();
+ for (int a = 0; a < normName.length(); ++a)
+ {
+ if (normName.charAt(a) == '[')
+ b.append("[]");
+ else
+ break;
+ }
+ return b.toString();
+ }
+ return c.getName();
+ }
+ return type.toString();
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java b/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java
index 442629309e7..4a37cd8b1f9 100644
--- a/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java
+++ b/libjava/classpath/gnu/javax/net/ssl/PrivateCredentials.java
@@ -1,5 +1,5 @@
/* PrivateCredentials.java -- private key/certificate pairs.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package gnu.javax.net.ssl;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;
@@ -80,6 +78,7 @@ import gnu.javax.crypto.pad.WrongPaddingException;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
+import gnu.java.util.Base64;
/**
* An instance of a manager factory parameters for holding a single
diff --git a/libjava/classpath/gnu/javax/net/ssl/provider/SSLEngineImpl.java b/libjava/classpath/gnu/javax/net/ssl/provider/SSLEngineImpl.java
index 22c488d68c0..4a7f924e87d 100644
--- a/libjava/classpath/gnu/javax/net/ssl/provider/SSLEngineImpl.java
+++ b/libjava/classpath/gnu/javax/net/ssl/provider/SSLEngineImpl.java
@@ -99,7 +99,7 @@ public final class SSLEngineImpl extends SSLEngine
private Mode mode;
- private enum Mode { SERVER, CLIENT };
+ private enum Mode { SERVER, CLIENT }
SSLEngineImpl (SSLContextImpl contextImpl, String host, int port)
{
diff --git a/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java b/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java
index 415efc6f58d..e6981c9c79d 100644
--- a/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java
+++ b/libjava/classpath/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java
@@ -188,7 +188,8 @@ public class SSLRSASignatureImpl extends SignatureSpi
final byte[] eb = EB.toByteArray();
if (eb[0] == 0x00)
{
- for (i = 0; i < eb.length && eb[i] == 0x00; i++);
+ for (i = 0; i < eb.length && eb[i] == 0x00; i++)
+ ;
}
else if (eb[0] == 0x01)
{
diff --git a/libjava/classpath/gnu/javax/security/auth/login/ConfigFileParser.java b/libjava/classpath/gnu/javax/security/auth/login/ConfigFileParser.java
index b5b5069233c..40adb783ee1 100644
--- a/libjava/classpath/gnu/javax/security/auth/login/ConfigFileParser.java
+++ b/libjava/classpath/gnu/javax/security/auth/login/ConfigFileParser.java
@@ -122,7 +122,9 @@ public final class ConfigFileParser
initParser(r);
while (parseAppOrOtherEntry())
- ; // do nothing
+ {
+ /* do nothing */
+ }
}
private void initParser(Reader r) throws IOException
@@ -157,7 +159,9 @@ public final class ConfigFileParser
List lmis = new ArrayList();
while (parseACE(lmis))
- ; // do nothing
+ {
+ /* do nothing */
+ }
c = cft.nextToken();
if (c != '}')
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
index c91f1e39851..3810dff4736 100644
--- a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
@@ -1,5 +1,5 @@
/* AlsaMidiSequencerDevice.java -- The ALSA MIDI sequencer device
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -51,10 +51,6 @@ import javax.sound.midi.Sequencer;
import javax.sound.midi.Track;
import javax.sound.midi.Transmitter;
-// FIXME: These next two imports are only required by gcj it seems.
-import javax.sound.midi.MidiDevice.Info;
-import javax.sound.midi.Sequencer.SyncMode;
-
/**
* The ALSA MIDI sequencer device. This is a singleton device.
*
diff --git a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
index d666be1f1ba..0e59bc8d669 100644
--- a/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
+++ b/libjava/classpath/gnu/javax/sound/midi/alsa/AlsaPortDevice.java
@@ -1,5 +1,5 @@
/* AlsaPortDevice.java -- ALSA MIDI Port Devices
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,9 +43,6 @@ import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.Transmitter;
-// FIXME: This next import is only rquired for gcj it seems.
-import javax.sound.midi.MidiDevice.Info;
-
import gnu.javax.sound.midi.alsa.AlsaMidiDeviceProvider.AlsaPortInfo;
/**
diff --git a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
index ca09b305078..26821862691 100644
--- a/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
+++ b/libjava/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
@@ -1,5 +1,5 @@
/* DSSISynthesizer.java -- DSSI Synthesizer Provider
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -55,9 +55,6 @@ import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;
import javax.sound.midi.VoiceStatus;
-// FIXME: This import in only required for gcj it seems.
-import javax.sound.midi.MidiDevice.Info;
-
/**
* DSSI soft-synth support.
*
diff --git a/libjava/classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java b/libjava/classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
index 06732e401fe..77bac127dce 100644
--- a/libjava/classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
+++ b/libjava/classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
@@ -74,7 +74,7 @@ public class CharacterAttributeTranslator
colorMap.put("teal" , "#008080");
colorMap.put("white" , "#FFFFFF");
colorMap.put("yellow" , "#FFFF00");
- };
+ }
/**
* Convert the color string represenation into java.awt.Color. The valid
diff --git a/libjava/classpath/gnu/javax/swing/text/html/css/CSSParser.java b/libjava/classpath/gnu/javax/swing/text/html/css/CSSParser.java
index 5647e25069d..1f8fdfa2258 100644
--- a/libjava/classpath/gnu/javax/swing/text/html/css/CSSParser.java
+++ b/libjava/classpath/gnu/javax/swing/text/html/css/CSSParser.java
@@ -308,7 +308,9 @@ public class CSSParser
{
// FIXME: Handle block and ATKEYWORD.
boolean success = parseAny(s);
- while (parseAny(s));
+ while (parseAny(s))
+ ;
+
return success;
}
@@ -329,7 +331,8 @@ public class CSSParser
boolean ret = parseAny(sel);
if (ret)
{
- while (parseAny(sel));
+ while (parseAny(sel))
+ ;
}
return ret;
}
diff --git a/libjava/classpath/gnu/javax/swing/text/html/parser/gnuDTD.java b/libjava/classpath/gnu/javax/swing/text/html/parser/gnuDTD.java
index 1f4b3ec6adc..5924e0fb989 100644
--- a/libjava/classpath/gnu/javax/swing/text/html/parser/gnuDTD.java
+++ b/libjava/classpath/gnu/javax/swing/text/html/parser/gnuDTD.java
@@ -390,7 +390,6 @@ public class gnuDTD
allowed.add(allowed_values [ i ]);
}
}
- ;
AttributeList attr =
new AttributeList(name, type, modifier, default_value, allowed, null);
diff --git a/libjava/classpath/gnu/javax/swing/text/html/parser/support/Parser.java b/libjava/classpath/gnu/javax/swing/text/html/parser/support/Parser.java
index 3a407310e74..c0d1e636e92 100644
--- a/libjava/classpath/gnu/javax/swing/text/html/parser/support/Parser.java
+++ b/libjava/classpath/gnu/javax/swing/text/html/parser/support/Parser.java
@@ -1382,7 +1382,7 @@ public class Parser
if (c == '\r')
buffer.append(' '); // CR replaced by space
else if (c == '\n')
- ; // LF ignored
+ { /* LF ignored */ }
else if (c == '\t')
buffer.append(' '); // Tab replaced by space
else
diff --git a/libjava/classpath/gnu/xml/dom/DomDocumentBuilder.java b/libjava/classpath/gnu/xml/dom/DomDocumentBuilder.java
index 343f48c13fd..e62ce207639 100644
--- a/libjava/classpath/gnu/xml/dom/DomDocumentBuilder.java
+++ b/libjava/classpath/gnu/xml/dom/DomDocumentBuilder.java
@@ -1,5 +1,5 @@
/* DomDocumentBuilder.java --
- Copyright (C) 2004,2006 Free Software Foundation, Inc.
+ Copyright (C) 2004,2006,2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,6 +48,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSException;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSParser;
import org.xml.sax.EntityResolver;
@@ -122,7 +123,18 @@ class DomDocumentBuilder
{
LSInput input = ls.createLSInput();
input.setByteStream(in);
- return parser.parse(input);
+ try
+ {
+ return parser.parse(input);
+ }
+ catch (LSException e)
+ {
+ Throwable e2 = e.getCause();
+ if (e2 instanceof IOException)
+ throw (IOException) e2;
+ else
+ throw e;
+ }
}
public Document parse(InputStream in, String systemId)
@@ -131,13 +143,35 @@ class DomDocumentBuilder
LSInput input = ls.createLSInput();
input.setByteStream(in);
input.setSystemId(systemId);
- return parser.parse(input);
+ try
+ {
+ return parser.parse(input);
+ }
+ catch (LSException e)
+ {
+ Throwable e2 = e.getCause();
+ if (e2 instanceof IOException)
+ throw (IOException) e2;
+ else
+ throw e;
+ }
}
public Document parse(String systemId)
throws SAXException, IOException
{
- return parser.parseURI(systemId);
+ try
+ {
+ return parser.parseURI(systemId);
+ }
+ catch (LSException e)
+ {
+ Throwable e2 = e.getCause();
+ if (e2 instanceof IOException)
+ throw (IOException) e2;
+ else
+ throw e;
+ }
}
public Document parse(InputSource is)
@@ -176,7 +210,18 @@ class DomDocumentBuilder
input.setPublicId(is.getPublicId());
input.setSystemId(systemId);
input.setEncoding(is.getEncoding());
- return parser.parse(input);
+ try
+ {
+ return parser.parse(input);
+ }
+ catch (LSException e)
+ {
+ Throwable e2 = e.getCause();
+ if (e2 instanceof IOException)
+ throw (IOException) e2;
+ else
+ throw e;
+ }
}
}
diff --git a/libjava/classpath/gnu/xml/dom/ls/DomLSParser.java b/libjava/classpath/gnu/xml/dom/ls/DomLSParser.java
index 6bc069d3201..88f9bae23fe 100644
--- a/libjava/classpath/gnu/xml/dom/ls/DomLSParser.java
+++ b/libjava/classpath/gnu/xml/dom/ls/DomLSParser.java
@@ -1,5 +1,5 @@
/* DomLSParser.java --
- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
+ Copyright (C) 1999,2000,2001,2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -277,6 +277,15 @@ public class DomLSParser
validating);
try
{
+ reader.setFeature("http://gnu.org/sax/features/coalescing",
+ coalescing);
+ }
+ catch (SAXNotRecognizedException e)
+ {
+ // ignore
+ }
+ try
+ {
reader.setFeature("http://xml.org/sax/features/use-attributes2",
true);
}
diff --git a/libjava/classpath/gnu/xml/pipeline/DomConsumer.java b/libjava/classpath/gnu/xml/pipeline/DomConsumer.java
index bdbf9281880..da527b96587 100644
--- a/libjava/classpath/gnu/xml/pipeline/DomConsumer.java
+++ b/libjava/classpath/gnu/xml/pipeline/DomConsumer.java
@@ -365,7 +365,7 @@ public class DomConsumer implements EventConsumer
throws SAXException
{
SAXParseException e;
- ErrorHandler errHandler = consumer.getErrorHandler ();;
+ ErrorHandler errHandler = consumer.getErrorHandler ();
if (locator == null)
e = new SAXParseException (message, null, null, -1, -1, x);
diff --git a/libjava/classpath/gnu/xml/stream/SAXParser.java b/libjava/classpath/gnu/xml/stream/SAXParser.java
index 1329ab2971c..af4a6af4217 100644
--- a/libjava/classpath/gnu/xml/stream/SAXParser.java
+++ b/libjava/classpath/gnu/xml/stream/SAXParser.java
@@ -1,5 +1,5 @@
/* SAXParser.java --
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -187,6 +187,8 @@ public class SAXParser
lexicalHandler = (LexicalHandler) value;
else if ((GNU_FEATURES + "xml-base").equals(name))
baseAware = Boolean.TRUE.equals(value);
+ else if ((GNU_FEATURES + "coalescing").equals(name))
+ coalescing = Boolean.TRUE.equals(value);
else
throw new SAXNotSupportedException(name);
}
diff --git a/libjava/classpath/gnu/xml/stream/XMLParser.java b/libjava/classpath/gnu/xml/stream/XMLParser.java
index 663a300f88c..fae4afec808 100644
--- a/libjava/classpath/gnu/xml/stream/XMLParser.java
+++ b/libjava/classpath/gnu/xml/stream/XMLParser.java
@@ -439,6 +439,7 @@ public class XMLParser
throw e2;
}
}
+ systemId = canonicalize(systemId);
pushInput(new Input(in, null, null, systemId, null, null, false, true));
}
@@ -513,6 +514,7 @@ public class XMLParser
throw e2;
}
}
+ systemId = canonicalize(systemId);
pushInput(new Input(null, reader, null, systemId, null, null, false, true));
}
@@ -1540,7 +1542,7 @@ public class XMLParser
{
if (!externalEntities)
return;
- String url = absolutize(input.systemId, ids.systemId);
+ String url = canonicalize(absolutize(input.systemId, ids.systemId));
// Check for recursion
for (Iterator i = inputStack.iterator(); i.hasNext(); )
{
@@ -1587,6 +1589,20 @@ public class XMLParser
}
/**
+ * Returns a canonicalized version of the specified URL.
+ * This is largely to work around a problem with the specification of
+ * file URLs.
+ */
+ static String canonicalize(String url)
+ {
+ if (url == null)
+ return null;
+ if (url.startsWith("file:") && !url.startsWith("file://"))
+ url = "file://" + url.substring(5);
+ return url;
+ }
+
+ /**
* "Absolutize" a URL. This resolves a relative URL into an absolute one.
* @param base the current base URL
* @param href the (absolute or relative) URL to resolve
diff --git a/libjava/classpath/gnu/xml/util/XCat.java b/libjava/classpath/gnu/xml/util/XCat.java
index 0f163387081..f3704cd25c7 100644
--- a/libjava/classpath/gnu/xml/util/XCat.java
+++ b/libjava/classpath/gnu/xml/util/XCat.java
@@ -274,7 +274,7 @@ public class XCat implements EntityResolver2
InputSource retval;
retval = catalogs [i].resolve (usingPublic, publicId, systemId);
if (retval != null)
- return retval;;
+ return retval;
}
} catch (DoneDelegation x) {
// done!