summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-05-01 21:45:41 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-05-01 21:45:41 +0000
commit480ccb4bfcc622c1ce320c20ce992188187f7573 (patch)
treeaebfd0e230d0370ec1ac1a9b1a99b478abdc6854
parent4d80ae24073737202d4c51bf9efd2466fea8696d (diff)
downloadclasspath-480ccb4bfcc622c1ce320c20ce992188187f7573.tar.gz
2006-05-01 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge HEAD-->generics-branch for the period 2006-04-13 to 2006-05-01.
-rw-r--r--ChangeLog1529
-rw-r--r--NEWS29
-rw-r--r--configure.ac27
-rw-r--r--doc/vmintegration.texinfo194
-rw-r--r--doc/www.gnu.org/include/layout.wml1
-rw-r--r--doc/www.gnu.org/stories.wml6
-rw-r--r--examples/gnu/classpath/examples/swing/Demo.java6
-rw-r--r--examples/gnu/classpath/examples/swing/DocumentFilterDemo.java289
-rw-r--r--examples/gnu/classpath/examples/swing/NavigationFilterDemo.java206
-rw-r--r--examples/gnu/classpath/examples/swing/TreeDemo.java79
-rw-r--r--gnu/classpath/jdwp/util/Value.java4
-rw-r--r--gnu/java/awt/font/FontDelegate.java313
-rw-r--r--gnu/java/awt/font/FontFactory.java90
-rw-r--r--gnu/java/awt/font/GNUGlyphVector.java596
-rw-r--r--gnu/java/awt/font/opentype/CharGlyphMap.java1027
-rw-r--r--gnu/java/awt/font/opentype/GlyphNamer.java1133
-rw-r--r--gnu/java/awt/font/opentype/MacResourceFork.java235
-rw-r--r--gnu/java/awt/font/opentype/NameDecoder.java686
-rw-r--r--gnu/java/awt/font/opentype/OpenTypeFont.java825
-rw-r--r--gnu/java/awt/font/opentype/OpenTypeFontFactory.java140
-rw-r--r--gnu/java/awt/font/opentype/Scaler.java192
-rw-r--r--gnu/java/awt/font/opentype/truetype/Fixed.java161
-rw-r--r--gnu/java/awt/font/opentype/truetype/GlyphLoader.java437
-rw-r--r--gnu/java/awt/font/opentype/truetype/GlyphLocator.java187
-rw-r--r--gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java228
-rw-r--r--gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java372
-rw-r--r--gnu/java/awt/font/opentype/truetype/VirtualMachine.java1809
-rw-r--r--gnu/java/awt/font/opentype/truetype/Zone.java243
-rw-r--r--gnu/java/awt/font/opentype/truetype/ZonePathIterator.java391
-rw-r--r--gnu/java/awt/java2d/AbstractGraphics2D.java1585
-rw-r--r--gnu/java/awt/java2d/CubicSegment.java128
-rw-r--r--gnu/java/awt/java2d/LineSegment.java103
-rw-r--r--gnu/java/awt/java2d/PolyEdge.java117
-rw-r--r--gnu/java/awt/java2d/PolyEdgeComparator.java70
-rw-r--r--gnu/java/awt/java2d/QuadSegment.java213
-rw-r--r--gnu/java/awt/java2d/Segment.java131
-rw-r--r--gnu/java/awt/peer/swing/SwingComponentPeer.java3
-rw-r--r--gnu/java/awt/peer/swing/SwingContainerPeer.java33
-rw-r--r--gnu/java/net/local/LocalServerSocket.java172
-rw-r--r--gnu/java/net/local/LocalSocket.java312
-rw-r--r--gnu/java/net/local/LocalSocketAddress.java100
-rw-r--r--gnu/java/net/local/LocalSocketImpl.java322
-rw-r--r--gnu/java/net/protocol/ftp/FTPConnection.java3
-rw-r--r--gnu/java/net/protocol/http/HTTPURLConnection.java4
-rw-r--r--gnu/java/security/Properties.java6
-rw-r--r--gnu/java/security/hash/Haval.java2
-rw-r--r--gnu/java/security/hash/MD2.java2
-rw-r--r--gnu/java/security/hash/MD4.java2
-rw-r--r--gnu/java/security/hash/MD5.java2
-rw-r--r--gnu/java/security/hash/RipeMD128.java2
-rw-r--r--gnu/java/security/hash/RipeMD160.java2
-rw-r--r--gnu/java/security/hash/Sha160.java2
-rw-r--r--gnu/java/security/hash/Sha256.java2
-rw-r--r--gnu/java/security/hash/Sha384.java2
-rw-r--r--gnu/java/security/hash/Sha512.java2
-rw-r--r--gnu/java/security/hash/Tiger.java2
-rw-r--r--gnu/java/security/hash/Whirlpool.java2
-rw-r--r--gnu/java/security/jce/sig/RSAKeyFactory.java4
-rw-r--r--gnu/java/security/key/dss/DSSKey.java1
-rw-r--r--gnu/java/security/key/rsa/GnuRSAKey.java21
-rw-r--r--gnu/java/security/key/rsa/GnuRSAPrivateKey.java25
-rw-r--r--gnu/java/security/key/rsa/GnuRSAPublicKey.java17
-rw-r--r--gnu/java/security/key/rsa/RSAKeyPairGenerator.java14
-rw-r--r--gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java13
-rw-r--r--gnu/java/security/key/rsa/RSAKeyPairX509Codec.java3
-rw-r--r--gnu/java/security/provider/Gnu.java1
-rw-r--r--gnu/java/security/x509/X500DistinguishedName.java14
-rw-r--r--gnu/javax/crypto/cipher/Anubis.java2
-rw-r--r--gnu/javax/crypto/cipher/Blowfish.java2
-rw-r--r--gnu/javax/crypto/cipher/Cast5.java2
-rw-r--r--gnu/javax/crypto/cipher/Khazad.java2
-rw-r--r--gnu/javax/crypto/cipher/Rijndael.java2
-rw-r--r--gnu/javax/crypto/cipher/Serpent.java2
-rw-r--r--gnu/javax/crypto/cipher/Square.java2
-rw-r--r--gnu/javax/crypto/cipher/Twofish.java2
-rw-r--r--gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java4
-rw-r--r--gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java21
-rw-r--r--gnu/javax/crypto/mac/UMac32.java2
-rw-r--r--gnu/javax/crypto/prng/CSPRNG.java2
-rw-r--r--gnu/javax/crypto/prng/IPBE.java30
-rw-r--r--gnu/javax/crypto/prng/PBKDF2.java23
-rw-r--r--gnu/javax/security/auth/callback/ConsoleCallbackHandler.java34
-rw-r--r--gnu/javax/swing/text/html/parser/support/Parser.java121
-rw-r--r--gnu/xml/dom/DomDocument.java37
-rw-r--r--gnu/xml/dom/html2/DomHTMLParser.java1
-rw-r--r--include/gnu_java_net_local_LocalSocketImpl.h31
-rw-r--r--java/awt/BasicStroke.java371
-rw-r--r--java/awt/LightweightDispatcher.java66
-rw-r--r--java/awt/Toolkit.java17
-rw-r--r--java/awt/image/ReplicateScaleFilter.java1
-rw-r--r--java/awt/image/renderable/RenderableImageProducer.java72
-rw-r--r--java/beans/beancontext/BeanContextSupport.java2
-rw-r--r--java/lang/Boolean.java2
-rw-r--r--java/lang/Class.java28
-rw-r--r--java/lang/ClassLoader.java2
-rw-r--r--java/lang/Package.java3
-rw-r--r--java/lang/StringBuilder.java2
-rw-r--r--java/lang/Thread.java6
-rw-r--r--java/security/KeyStore.java4
-rw-r--r--java/security/SecureRandom.java78
-rw-r--r--java/security/Security.java5
-rw-r--r--java/sql/Array.java26
-rw-r--r--java/sql/Blob.java96
-rw-r--r--java/sql/CallableStatement.java501
-rw-r--r--java/sql/Clob.java147
-rw-r--r--java/sql/Connection.java136
-rw-r--r--java/sql/DatabaseMetaData.java166
-rw-r--r--java/sql/Date.java6
-rw-r--r--java/sql/Driver.java6
-rw-r--r--java/sql/DriverManager.java17
-rw-r--r--java/sql/PreparedStatement.java124
-rw-r--r--java/sql/ResultSet.java423
-rw-r--r--java/sql/ResultSetMetaData.java86
-rw-r--r--java/sql/SQLData.java4
-rw-r--r--java/sql/SQLOutput.java72
-rw-r--r--java/sql/SQLWarning.java6
-rw-r--r--java/sql/Statement.java37
-rw-r--r--java/sql/Time.java7
-rw-r--r--java/sql/Timestamp.java32
-rw-r--r--java/text/SimpleDateFormat.java3
-rw-r--r--java/util/Locale.java57
-rw-r--r--java/util/jar/JarFile.java3
-rw-r--r--javax/accessibility/AccessibleAction.java22
-rw-r--r--javax/accessibility/AccessibleRole.java50
-rw-r--r--javax/accessibility/AccessibleState.java31
-rw-r--r--javax/net/ssl/HttpsURLConnection.java8
-rw-r--r--javax/swing/ActionMap.java5
-rw-r--r--javax/swing/DefaultListSelectionModel.java13
-rw-r--r--javax/swing/ImageIcon.java94
-rw-r--r--javax/swing/JButton.java66
-rw-r--r--javax/swing/JComboBox.java35
-rw-r--r--javax/swing/JComponent.java45
-rw-r--r--javax/swing/JDesktopPane.java32
-rw-r--r--javax/swing/JInternalFrame.java49
-rw-r--r--javax/swing/JLabel.java1
-rw-r--r--javax/swing/JList.java180
-rw-r--r--javax/swing/JMenu.java14
-rw-r--r--javax/swing/JMenuItem.java34
-rw-r--r--javax/swing/JPanel.java83
-rw-r--r--javax/swing/JProgressBar.java23
-rw-r--r--javax/swing/JRadioButtonMenuItem.java35
-rw-r--r--javax/swing/JScrollPane.java1
-rw-r--r--javax/swing/JSeparator.java83
-rw-r--r--javax/swing/JSlider.java30
-rw-r--r--javax/swing/JSpinner.java4
-rw-r--r--javax/swing/JSplitPane.java130
-rw-r--r--javax/swing/JTabbedPane.java16
-rw-r--r--javax/swing/JTable.java28
-rw-r--r--javax/swing/JToolBar.java30
-rw-r--r--javax/swing/JToolTip.java2
-rw-r--r--javax/swing/JTree.java113
-rw-r--r--javax/swing/ProgressMonitor.java6
-rw-r--r--javax/swing/RepaintManager.java60
-rw-r--r--javax/swing/ScrollPaneLayout.java2
-rw-r--r--javax/swing/SpinnerDateModel.java96
-rw-r--r--javax/swing/SpinnerNumberModel.java30
-rw-r--r--javax/swing/UIManager.java4
-rw-r--r--javax/swing/ViewportLayout.java14
-rw-r--r--javax/swing/border/AbstractBorder.java55
-rw-r--r--javax/swing/border/BevelBorder.java18
-rw-r--r--javax/swing/border/CompoundBorder.java4
-rw-r--r--javax/swing/border/EtchedBorder.java10
-rw-r--r--javax/swing/border/LineBorder.java16
-rw-r--r--javax/swing/border/MatteBorder.java4
-rw-r--r--javax/swing/border/TitledBorder.java10
-rw-r--r--javax/swing/event/ChangeEvent.java33
-rw-r--r--javax/swing/event/ChangeListener.java32
-rw-r--r--javax/swing/event/TableColumnModelListener.java88
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicComboPopup.java4
-rw-r--r--javax/swing/plaf/basic/BasicInternalFrameUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicLabelUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicListUI.java3
-rw-r--r--javax/swing/plaf/basic/BasicMenuBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicMenuUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicOptionPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicPopupMenuUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicScrollBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicScrollPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicSliderUI.java169
-rw-r--r--javax/swing/plaf/basic/BasicSpinnerUI.java9
-rw-r--r--javax/swing/plaf/basic/BasicSplitPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java40
-rw-r--r--javax/swing/plaf/basic/BasicTableHeaderUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTableUI.java3
-rw-r--r--javax/swing/plaf/basic/BasicTextAreaUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTextFieldUI.java15
-rw-r--r--javax/swing/plaf/basic/BasicTextUI.java12
-rw-r--r--javax/swing/plaf/basic/BasicToolBarUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTreeUI.java319
-rw-r--r--javax/swing/table/DefaultTableCellRenderer.java3
-rw-r--r--javax/swing/table/DefaultTableColumnModel.java346
-rw-r--r--javax/swing/table/TableColumnModel.java95
-rw-r--r--javax/swing/text/AbstractDocument.java92
-rw-r--r--javax/swing/text/AsyncBoxView.java2
-rw-r--r--javax/swing/text/CompositeView.java98
-rw-r--r--javax/swing/text/DefaultCaret.java68
-rw-r--r--javax/swing/text/DefaultHighlighter.java22
-rw-r--r--javax/swing/text/FieldView.java7
-rw-r--r--javax/swing/text/FlowView.java2
-rw-r--r--javax/swing/text/Utilities.java74
-rw-r--r--javax/swing/text/View.java29
-rw-r--r--javax/swing/text/WrappedPlainView.java76
-rw-r--r--javax/swing/tree/AbstractLayoutCache.java89
-rw-r--r--javax/swing/tree/DefaultMutableTreeNode.java2
-rw-r--r--javax/swing/tree/DefaultTreeCellEditor.java20
-rw-r--r--javax/swing/tree/DefaultTreeCellRenderer.java29
-rw-r--r--javax/swing/tree/DefaultTreeModel.java68
-rw-r--r--javax/swing/tree/DefaultTreeSelectionModel.java366
-rw-r--r--javax/swing/tree/FixedHeightLayoutCache.java239
-rw-r--r--javax/swing/tree/TreePath.java14
-rw-r--r--javax/swing/tree/VariableHeightLayoutCache.java48
-rw-r--r--javax/xml/datatype/DatatypeFactory.java37
-rw-r--r--lib/.cvsignore1
-rw-r--r--native/fdlibm/Makefile.am2
-rw-r--r--native/fdlibm/ieeefp.h2
-rw-r--r--native/jni/classpath/Makefile.am2
-rw-r--r--native/jni/java-lang/java_lang_VMProcess.c3
-rw-r--r--native/jni/java-net/Makefile.am11
-rw-r--r--native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c538
-rw-r--r--native/jni/java-net/local.c193
-rw-r--r--native/jni/java-net/local.h28
-rw-r--r--resource/java/security/classpath.security3
-rw-r--r--tools/gnu/classpath/tools/HelpPrinter.java41
-rw-r--r--tools/gnu/classpath/tools/jarsigner/HashUtils.java19
-rw-r--r--tools/gnu/classpath/tools/jarsigner/JarSigner.java19
-rw-r--r--tools/gnu/classpath/tools/jarsigner/JarVerifier.java19
-rw-r--r--tools/gnu/classpath/tools/jarsigner/Main.java97
-rw-r--r--tools/gnu/classpath/tools/jarsigner/SFHelper.java19
-rw-r--r--tools/gnu/classpath/tools/jarsigner/jarsigner.txt2
-rw-r--r--tools/jarsigner.sh.in21
-rw-r--r--vm/reference/java/lang/VMClass.java27
-rw-r--r--vm/reference/java/lang/VMClassLoader.java49
-rw-r--r--vm/reference/java/lang/VMProcess.java13
-rw-r--r--vm/reference/java/lang/VMSystem.java51
-rw-r--r--vm/reference/java/lang/VMThread.java7
-rw-r--r--vm/reference/java/security/VMSecureRandom.java134
237 files changed, 21230 insertions, 2072 deletions
diff --git a/ChangeLog b/ChangeLog
index 215cfb7c8..4cf4f88d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,456 @@
+2006-05-01 Tom Tromey <tromey@redhat.com>
+
+ * lib/.cvsignore: Added classes.2.
+
+2006-05-01 Tom Tromey <tromey@redhat.com>
+
+ * java/util/jar/JarFile.java (provider): Now package-private.
+ * java/lang/Enum.java (compareTo): Javadoc fix.
+ * java/lang/Boolean.java (compareTo): Javadoc fix.
+
+2006-05-01 Lillian Angel <langel@redhat.com>
+
+ * gnu/javax/swing/text/html/parser/support/Parser.java
+ (readAttributes): Formatted function. Added handling for
+ SLASH token. The value of an attribute may start with a slash
+ (i.e. a path). I added handling similar to to the NUMTOKEN code.
+ We should not be skipping over these type of attributes.
+
+2006-04-30 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * include/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h,
+ * include/gnu_java_awt_peer_gtk_GdkFontPeer.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphics.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphics2D.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h,
+ * include/gnu_java_awt_peer_gtk_GdkPixbufDecoder.h,
+ * include/gnu_java_awt_peer_gtk_GdkRobotPeer.h,
+ * include/gnu_java_awt_peer_gtk_GdkTextLayout.h,
+ * include/gnu_java_awt_peer_gtk_GtkButtonPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkChoicePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkClipboard.h,
+ * include/gnu_java_awt_peer_gtk_GtkComponentPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkFileDialogPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkFramePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkGenericPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkImage.h,
+ * include/gnu_java_awt_peer_gtk_GtkLabelPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkListPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuBarPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuItemPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkPanelPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkScrollPanePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkScrollbarPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkSelection.h,
+ * include/gnu_java_awt_peer_gtk_GtkTextAreaPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkTextFieldPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkToolkit.h,
+ * include/gnu_java_awt_peer_gtk_GtkWindowPeer.h,
+ * include/gnu_java_awt_peer_qt_MainQtThread.h,
+ * include/gnu_java_awt_peer_qt_QMatrix.h,
+ * include/gnu_java_awt_peer_qt_QPainterPath.h,
+ * include/gnu_java_awt_peer_qt_QPen.h,
+ * include/gnu_java_awt_peer_qt_QtAudioClip.h,
+ * include/gnu_java_awt_peer_qt_QtButtonPeer.h,
+ * include/gnu_java_awt_peer_qt_QtCanvasPeer.h,
+ * include/gnu_java_awt_peer_qt_QtCheckboxPeer.h,
+ * include/gnu_java_awt_peer_qt_QtChoicePeer.h,
+ * include/gnu_java_awt_peer_qt_QtComponentPeer.h,
+ * include/gnu_java_awt_peer_qt_QtContainerPeer.h,
+ * include/gnu_java_awt_peer_qt_QtDialogPeer.h,
+ * include/gnu_java_awt_peer_qt_QtEmbeddedWindowPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFileDialogPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFontMetrics.h,
+ * include/gnu_java_awt_peer_qt_QtFontPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFramePeer.h,
+ * include/gnu_java_awt_peer_qt_QtGraphics.h,
+ * include/gnu_java_awt_peer_qt_QtGraphicsEnvironment.h,
+ * include/gnu_java_awt_peer_qt_QtImage.h,
+ * include/gnu_java_awt_peer_qt_QtLabelPeer.h,
+ * include/gnu_java_awt_peer_qt_QtListPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuBarPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuComponentPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuItemPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuPeer.h,
+ * include/gnu_java_awt_peer_qt_QtPanelPeer.h,
+ * include/gnu_java_awt_peer_qt_QtPopupMenuPeer.h,
+ * include/gnu_java_awt_peer_qt_QtScreenDevice.h,
+ * include/gnu_java_awt_peer_qt_QtScrollPanePeer.h,
+ * include/gnu_java_awt_peer_qt_QtScrollbarPeer.h,
+ * include/gnu_java_awt_peer_qt_QtTextAreaPeer.h,
+ * include/gnu_java_awt_peer_qt_QtTextFieldPeer.h,
+ * include/gnu_java_awt_peer_qt_QtToolkit.h,
+ * include/gnu_java_awt_peer_qt_QtVolatileImage.h,
+ * include/gnu_java_awt_peer_qt_QtWindowPeer.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaMidiDeviceProvider.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaMidiSequencerDevice.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaPortDevice.h,
+ * include/gnu_javax_sound_midi_dssi_DSSIMidiDeviceProvider.h,
+ * include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h,
+ * include/gnu_xml_libxmlj_dom_GnomeAttr.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocument.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocumentBuilder.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocumentType.h,
+ * include/gnu_xml_libxmlj_dom_GnomeElement.h,
+ * include/gnu_xml_libxmlj_dom_GnomeEntity.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNamedNodeMap.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNode.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNodeList.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNotation.h,
+ * include/gnu_xml_libxmlj_dom_GnomeProcessingInstruction.h,
+ * include/gnu_xml_libxmlj_dom_GnomeTypeInfo.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathExpression.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathNSResolver.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathNodeList.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathResult.h,
+ * include/gnu_xml_libxmlj_sax_GnomeLocator.h,
+ * include/gnu_xml_libxmlj_sax_GnomeXMLReader.h,
+ * include/gnu_xml_libxmlj_transform_GnomeTransformer.h,
+ * include/gnu_xml_libxmlj_transform_GnomeTransformerFactory.h,
+ * include/java_lang_VMProcess.h:
+ Regenerated.
+ * native/jni/java-lang/java_lang_VMProcess.c:
+ Redirect when pipe_count is 2 not 3.
+
+2006-04-30 Sascha Brawer <sascha@brawer.ch>
+
+ * gnu/java/awt/font/FontDelegate.java,
+ * gnu/java/awt/font/FontFactory.java,
+ * gnu/java/awt/font/GNUGlyphVector.java,
+ * gnu/java/awt/font/opentype/CharGlyphMap.java,
+ * gnu/java/awt/font/opentype/GlyphNamer.java,
+ * gnu/java/awt/font/opentype/MacResourceFork.java,
+ * gnu/java/awt/font/opentype/NameDecoder.java,
+ * gnu/java/awt/font/opentype/OpenTypeFont.java,
+ * gnu/java/awt/font/opentype/OpenTypeFontFactory.java,
+ * gnu/java/awt/font/opentype/Scaler.java,
+ * gnu/java/awt/font/opentype/truetype/Fixed.java,
+ * gnu/java/awt/font/opentype/truetype/GlyphLoader.java,
+ * gnu/java/awt/font/opentype/truetype/GlyphLocator.java,
+ * gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java,
+ * gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java,
+ * gnu/java/awt/font/opentype/truetype/VirtualMachine.java,
+ * gnu/java/awt/font/opentype/truetype/Zone.java,
+ * gnu/java/awt/font/opentype/truetype/ZonePathIterator.java,
+ * gnu/java/awt/font/opentype/truetype/doc-files/ZonePathIterator-1.dia,
+ * gnu/java/awt/font/opentype/truetype/doc-files/ZonePathIterator-1.png:
+ New files. Imported font framework from:
+ http://www.brawer.ch/software/fonts/
+
+2006-04-30 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java
+ (lastTabInRun): Fix calculation of the last tab in a run. This
+ has caused painting problems sometimes, making the
+ last tab painted incorrectly.
+
+2006-04-30 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27297
+ * javax/swing/JComponent.java (paintChildrenWithOverlap):
+ Use for and not while to prevent the endless loop.
+
+2006-04-29 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JList.java
+ (paramString): Changed from public to protected.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/HelpPrinter.java (printHelp): New method.
+ (printHelpAndExit): Re-factored to use the above method.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/jarsigner.sh.in: Changed license to GPL + Exception.
+ Use -Xbootclasspath/p instead of -cp when invoking the main class.
+ * tools/gnu/classpath/tools/jarsigner/Main.java:
+ Changed license to GPL + Exception.
+ (handler): New field.
+ (getCallbackHandler): New method.
+ (setupSigningParams): Use above method.
+ * tools/gnu/classpath/tools/jarsigner/HashUtils.java:
+ Changed license to GPL + Exception.
+ * tools/gnu/classpath/tools/jarsigner/SFHelper.java: Likewise.
+ * tools/gnu/classpath/tools/jarsigner/JarVerifier.java: Likewise.
+ * tools/gnu/classpath/tools/jarsigner/JarSigner.java: Likewise.
+ * tools/gnu/classpath/tools/jarsigner/jarsigner.txt: Updated copyright.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/javax/security/auth/callback/ConsoleCallbackHandler.java
+ (handleConfirmation): Use print instead of println.
+ (handleConfirmation): When case is YES_NO_OPTION, print default option
+ if one was set.
+ (handleLanguage): Use print instead of println.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/java/security/x509/X500DistinguishedName.java: Updated copyright.
+ (putComponent): Handle O and OU components.
+ (getDer): Use correct (it2) iterator.
+ (readAttributeValue): Read next character and break if end-of-stream.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/java/security/provider/Gnu.java (run):
+ Add "RSA" as an alias to MD5withRSA.
+ * gnu/java/security/key/rsa/RSAKeyPairX509Codec.java (encodePublicKey):
+ Always encode a NULL as the value of an algorithm parameters field.
+ * gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java (log): New field.
+ (encodePrivateKey): Added trace/log statements.
+ (decodePrivateKey): Likewise.
+ * gnu/java/security/key/rsa/RSAKeyPairGenerator.java (log): New field.
+ (setup): Added trace/log statements.
+ (generate): Likewise.
+ * gnu/java/security/key/rsa/GnuRSAPublicKey.java (str): New field.
+ (toString): New method.
+ * gnu/java/security/key/rsa/GnuRSAPrivateKey.java (DEBUG): New constant.
+ (str): New field.
+ (toString): New method.
+ * gnu/java/security/key/rsa/GnuRSAKey.java (str): New field.
+ (getEncoded): Use defaultFormat.
+ (toString): New method.
+ * gnu/java/security/key/dss/DSSKey.java (toString):
+ Include defaultFormat in string.
+ * gnu/java/security/jce/sig/RSAKeyFactory.java (engineGeneratePublic):
+ Break if successfully decoded public key.
+ (engineGeneratePrivate): Break if successfully decoded private key.
+
+2006-04-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * java/security/Security.java <clinit>: Add our Callback provider.
+ * resource/java/security/classpath.security: Likewise
+
+2006-04-28 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27296
+ * javax/swing/ScrollPaneLayout.java (layoutContainer):
+ Decide about scroll bars from the preferred view size, not
+ the current size.
+ * javax/swing/ViewportLayout.java (layoutContainer):
+ Do not change returned preferred size. Do not treat JScrollPane
+ specially.
+
+2006-04-28 Sven de Marothy <sven@physto.se>
+
+ * java/awt/image/ReplicateScaleFilter.java: Fix comment.
+ * javax/swing/ProgressMonitor.java (actionPerformed):
+ Avoid divide-by-zero.
+
+2006-04-28 Sven de Marothy <sven@physto.se>
+
+ * javax/swing/JSpinner.java: Fix default text justification.
+ * javax/swing/plaf/basic/BasicSpinnerUI.java: Fix spinner layout size.
+
+2006-04-28 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JList.java
+ (getMinSelectionIndex): Return correct value, added API docs,
+ (getMaxSelectionIndex): Added API docs.
+
+2006-04-28 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JList.java
+ (JList(Object[])): Pass new model directly to init(),
+ (JList(Vector)): Likewise,
+ (JList(ListModel)): Renamed argument and updated API docs,
+ (init): Throw IllegalArgumentException for null argument,
+ (setListData(Object[])): Delegate model creation,
+ (setListData(Vector)): Likewise,
+ (createListModel(Object[])): New private method,
+ (createListModel(Vector)): New private method,
+ (paramString): Implemented.
+
+2006-04-28 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/Class.java (SYNTHETIC, ENUM, ANNOTATION): New fields.
+ (isEnum): Rewrote.
+ (isSynthetic): Likewise.
+ (isAnnotation): Likewise.
+ * vm/reference/java/lang/VMClass.java (isSynthetic): Removed.
+ (isAnnotation): Likewise.
+ (isEnum): Likewise.
+
+2006-04-28 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/View.java:
+ (getNextVisualPositionFrom): Call modelToView and viewToModel on parent
+ view.
+
+2006-04-28 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/View.java:
+ (getNextVisualPositionFrom): Rewritten.
+ * javax/swing/text/CompositeView.java:
+ (getNextEastWestVisualPositionFrom): Partly implemented.
+ (getNextNorthSouthVisualPositionFrom): Partly implemented.
+
+2006-04-28 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JList.java
+ (setFixedCellHeight): Use correct property name for event.
+
+2006-04-28 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/Utilities.java:
+ (getNextWord): Use codePointAt instead of charAt, added note, changed
+ if-expression, added throwing of exception.
+ (getPreviousWord): Use codePointAt instead of charAt.
+
+2006-04-28 Jeroen Frijters <jeroen@frijters.net>
+
+ * java/lang/StringBuilder.java
+ (ensureCapacity, getChars, append(StringBuffer),
+ append(char[],int,int), delete, replace, insert(int,char[],int,int),
+ insert(int,String), insert(int,char), trimToSize): Replaced
+ System.arraycopy calls with VMSystem.arraycopy.
+
+2006-04-27 Tom Tromey <tromey@redhat.com>
+
+ * java/awt/image/renderable/RenderableImageProducer.java
+ (requestTopDownLeftRightResend): Implemented.
+ (run): Likewise.
+ (startProduction): Add new consumer.
+
+2006-04-27 Sven de Marothy <sven@physto.se>
+
+ * javax/swing/JLabel.java (setIcon): Repaint on setting the icon.
+
+2006-04-27 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/LightweightDispatcher.java
+ Dispatch events only to targets that have a mouselistener
+ attached. Changed to also handle null targets.
+
+2006-04-27 Roman Kennke <kennke@aicas.com>
+
+ * NEWS: Added entries about accessibility support and L&F
+ window decorations.
+
+2006-04-27 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/Utilities.java:
+ (getTabbedTextOffset): Introduced width variable, rewritten the check
+ which ends the loop.
+ (getBreakLocation): Call getTabbedTextOffset with rounding argument set
+ to false.
+
+2006-04-27 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/TreeDemo.java
+ (createContent): Added root visibility and selection listener demos.
+ * javax/swing/JTree.java (setRootVisible): If false, unselect
+ the root node, if it is selected.
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (TreeTraverseAction.actionPerformed): Do not select the root if it
+ is not visible.
+ * javax/swing/tree/DefaultTreeSelectionModel.java (removeSelectionPath,
+ removeSelectionPaths): Reset lead to null if the current lead path is
+ removed from selection.
+ * javax/swing/tree/TreePath.java (getParentPath): Cache the parent path.
+ * javax/swing/tree/FixedHeightLayoutCache.java (NodeRecord.getPath):
+ Return the same path regardless is root visible or not. (update):
+ Reduce the identation if the root is not visible.
+ * javax/swing/tree/VariableHeightLayoutCache.java (NodeRecord.getPath):
+ Return the same path regardless is root visible or not. (update):
+ Reduce the identation if the root is not visible.
+
+2006-04-26 Audrius Meskauskas <AudriusA@Bioinformatics.org
+
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (TreeAction.actionPerformed):Newly obtain the current lead
+ path that must stay visible.
+ (TreeTraverseAction.actionPerformed):Rewritten.
+ * javax/swing/tree/FixedHeightLayoutCache.java (countRows):
+ Do not treat root specially. (setModel): Assume the root node
+ initially expanded.
+ * javax/swing/tree/VariableHeightLayoutCache.java:(countRows):
+ Do not treat root specially. (setModel): Assume the root node
+ initially expanded.
+
+2006-04-26 Chris Burdess <dog@gnu.org>
+
+ Fixes PR 27290
+ * javax/xml/datatype/DatatypeFactory.java: Use complete
+ implementation resolution mechanism.
+
+2006-04-26 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/tree/DefaultTreeModel.java (nodeStructureChanged):
+ Implemented.
+ * javax/swing/tree/DefaultTreeSelectionModel.java (toString):
+ Removed NoImplementException form the implemented method.
+
+2006-04-26 Tom Tromey <tromey@redhat.com>
+
+ * javax/net/ssl/HttpsURLConnection.java (HttpsURLConnection): Doesn't
+ throw IOException.
+
+2006-04-26 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/DefaultListSelectionModel.java
+ (clone): Initialise empty listener list,
+ (setSelectionMode): Throw IllegalArgumentException for bad input.
+
+2006-04-26 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/DefaultListSelectionModel.java
+ (clearSelection): Clear the Bitset.
+
+2006-04-26 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTree.java (setLeadSelectionPath):
+ Repaint the new and old lead pathes.
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (FocusHandler): Repaint the lead row when focus changes.
+ (PropertyChangeHandler): Use existing constants, not the
+ string literals for the property names.
+ (TreeIncrementAction): Shrink the selection when moving
+ from the selection edge to the selection anchor.
+ (TreeSelectionHandler.valueChanged): Repaint the
+ new and old lead pathes.
+ (paintRow): Treat row as focused only if it is the lead row.
+ * javax/swing/tree/DefaultTreeCellRenderer.java
+ (getTreeCellRendererComponent): Set the vertical alignment to CENTER.
+ (paint): Rewritten.
+ * javax/swing/tree/DefaultTreeSelectionModel.java
+ (addSelectionPath): Event construction fix (old and new lead were
+ always the same).
+ (addSelectionPaths): Likewise.
+ * javax/swing/JComponent.java (setOpaque): Explained.
+ * javax/swing/tree/FixedHeightLayoutCache.java (getBounds):
+ Accept null.
+ * javax/swing/tree/VariableHeightLayoutCache.java (getBounds):
+ Accept null.
+
+2006-04-26 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/TreeDemo.java
+ (createContent): Call DefaultTreeModel.reload(), not the
+ tree.repaint(). Expand the parent of the added node.
+ * javax/swing/JTree.java (constructor): Do not call
+ UpdateUI (and documented why). (treeDidChange):
+ Added comment, excluding the misinterpretation of this method.
+ * javax/swing/plaf/basic/BasicTreeUI.java (componentListener,
+ focusListener, keyListener, mouseListener, propertyListener,
+ selectionModelPropertyChangeListener, treeModelListener,
+ treeSelectionListener): Made package private.
+ (PropertyChangeHandler): If the model changes, install the
+ listener on it. (installUI): Assign treeModel.
+ * javax/swing/tree/DefaultMutableTreeNode.java (add): Added
+ comment, excluding misinterpretation.
+ * javax/swing/tree/DefaultTreeModel.java (reload): Implemented.
+ (reload(TreeNode)): Implemented.
+
2006-04-25 Tom Tromey <tromey@redhat.com>
* javax/swing/JComboBox.java (AccessibleJComboBox): Now public.
@@ -6,6 +459,173 @@
* javax/swing/tree/FixedHeightLayoutCache.java (getVisiblePathsFrom):
Genericized.
+2006-04-25 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java (MouseHandler.mousePressed):
+ If clicked on the other row, cancel the current editing session.
+
+2006-04-25 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (NodeDimensionsHandler.getRowX): Add half of the icon width.
+ (paintExpandControl): Always paint in one gap distance from the left
+ border of the path bounds.
+ (paintHorizontalPartOfLeg): Rewritted, taking the icon width
+ into consideration.
+ (paintVerticalPartOfLeg): Paint two gaps from the parent's bounds
+ left edge.
+
+2006-04-25 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java (paint): Rewritten.
+
+2006-04-25 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/javax/swing/text/html/parser/support/Parser.java (readAttributes):
+ Allow slashes (/) in the unquoted parameter value.
+
+2006-04-25 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AbstractGraphics2D.java
+ (drawString(String,int,int)): Implemented.
+ (drawString(String,float,float)): Implemented.
+ (drawString(AttributedCharacterIterator,int,int)): Implemented.
+ (drawString(AttributedCharacterIterator,float,float)): Implemented.
+ (getFontRenderContext): Implemented.
+ (drawGlyphVector): Implemented.
+ (getFont): Implemented.
+ (setFont): Don't change font setting when null.
+ (getFontMetrics): Implemented.
+ (fillShape): Re-written to fill call rawFillShape() with a list
+ of the edges instead of double arrays.
+ (rawFillShape): Implemented using a polygon scanline conversion.
+ (fillScanline): New helper method.
+ (init): Initialize foreground black. Set font.
+ * gnu/java/awt/java2d/PolyEdge.java: New file.
+ * gnu/java/awt/java2d/PolyEdgeComparator.java: New file.
+
+2006-04-25 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/table/DefaultTableColumnModel.java: More API doc updates.
+
+2006-04-25 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTable.java: Fixed API doc tags,
+ * javax/swing/text/AsyncBoxView.java: Likewise,
+ * javax/swing/text/FlowView.java: Likewise.
+
+2006-04-25 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/table/DefaultTableColumnModel.java
+ (moveColumn): Call fireColumnMoved() not fireColumnAdded.
+
+2006-04-24 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/table/DefaultTableColumnModel.java
+ (DefaultTableColumnModel): Set selection model field and add 'this' as
+ listener directly,
+ (addColumn): Add 'this' as a PropertyChangeListener,
+ (removeColumn): Remove column before firing event, and remove 'this' as
+ a PropertyChangeListener,
+ (setSelectionModel): Remove 'this' as a listener from old model,
+ (propertyChange): Check for 'width' property rather than
+ TableColumn.COLUMN_WIDTH_PROPERTY.
+
+2006-04-24 Chris Burdess <dog@gnu.org>
+
+ Fixes PR 27262
+ * gnu/xml/dom/DomDocument.java: getElementById returns user-defined ID
+ attributes when no doctype exists.
+
+2006-04-24 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/event/ChangeEvent.java: Updated API docs,
+ * javax/swing/event/ChangeListener.java: Likewise,
+ * javax/swing/event/TableColumnModelEventListener.java: Likewise,
+ * javax/swing/table/DefaultTableColumnModel.java: Likewise,
+ * javax/swing/table/TableColumnModel.java: Likewise.
+
+2006-04-24 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/Utilities.java:
+ (getBreakLocation): Introduced shift variable, added notes.
+ * javax/swing/text/WrappedPlainView.java:
+ (calculateBreakPosition): Decrease allocation area bounds by insets,
+ added early return when allocation area is empty, provide start offset
+ as argument.
+ (WrappedPlainView.WrappedLine): Change default value for numLines to 1.
+ (WrappedPlainView.WrappedLine.paint): Added count variable, update
+ numLines after loop.
+ (WrappedPlainView.WrappedLine.determineNumLines): Added early return.
+ (WrappedPlainView.WrappedLine.getPreferredSpan): Removed if-statement.
+ (WrappedPlainView.WrappedLine.viewToModel): Changed note, removed
+ decreasing variable end by one, changed break condition in while-loop,
+ added check for return value.
+ (WrappedPlainView.WrappedLine.updateDamage): Set numLines to one if
+ allocation area is empty.
+
+2006-04-24 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/java2d/Segment.java: New file.
+ * gnu/java/awt/java2d/CubicSegment.java: New file.
+ * gnu/java/awt/java2d/QuadSegment.java: New file.
+ * gnu/java/awt/java2d/LineSegment.java: New file.
+ * java/awt/BasicStroke.java
+ (start): New field.
+ (end): New field.
+ (createStrokedShape): Implemented.
+ (solidStroke): New method.
+ (dashedStroke): New method.
+ (capEnds): New method.
+ (convertPath): New method.
+ (addSegments): New method.
+ (capEnd): New method.
+ (lineIntersection): New method.
+ (joinSegments): New method.
+
+2006-04-24 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AbstractGraphics2D.java: Made implements
+ Cloneable.
+ (font): New field.
+ (clip): Changed clip to be in user space not in target space.
+ (isOptimized): Added flag to allow optimized drawing for
+ primitive operations (e.g. for Swing).
+ (AbstractGraphics2D()): Set foreground in init() to avoid trouble
+ with the paint context etc.
+ (draw): Clip the shape before drawing it.
+ (fill): Clip the shape before drawing it.
+ (setComposite): Update isOptimized flag.
+ (setPaint): Likewise.
+ (setStroke): Likewise.
+ (translate): Update the clip.
+ (rotate): Likewise.
+ (scale): Likewise.
+ (shear): Likewise.
+ (transform): Likewise.
+ (setTransform): Likewise.
+ (clip): Added optimization for rectangle clips.
+ (create): Implemented.
+ (clone): New method.
+ (setFont): Basic implementation.
+ (setClip): Update opimization flag.
+ (drawLine): Added possible optimization.
+ (fillRect): Added possible optimization.
+ (fillShape): Implemented shape-filling by filling the flattended
+ shape using polygon fill.
+ (drawPixel): Added basic painting.
+ (rawSetPixel): Changed signature to only take coordinates.
+ (rawSetForeground): New abstract method.
+ (getUserBounds): Implemented default for this method.
+ (rawDrawLine): New method.
+ (rawFillRect): New method.
+ (rawFillPolygon): New method.
+ (init): New method.
+ (updateOptimization): New method.
+ (computeIntersection): New method.
+ (updateClip): New method.
+ (clipShape): New method.
+
2006-04-23 Jeroen Frijters <jeroen@frijters.net>
* java/lang/Package.java: Added compatibility constructor to ease
@@ -28,6 +648,200 @@
to Package constructor.
* vm/reference/java/lang/VMPackage.java: Removed.
+2006-04-23 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/TreeDemo.java:
+ (createContent): Added check box to swith between single and
+ multiple selection.
+ * javax/swing/JTree.java (leadSelectionPath): Removed.
+ (addSelectionInterval): Explained. (getLeadSelectionPath):
+ Request the path from model. (getPathsBetweenRows): Explained.
+ (setLeadSelectionPath): Set the path in model.
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (TreeIncrementAction.actionPerformed, isMultiSelectionEvent,
+ isToggleSelectionEvent, selectPath, selectPathForEvent): Rewritten.
+ (MouseHandler.mousePressed): Call selectPathForEvent.
+
+2006-04-23 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AbstractGraphics2D.java: New file.
+
+2006-04-22 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * NEWS:
+ Mention changes to VMProcess and VMSystem.
+ * doc/vmintegration.texinfo:
+ Change documentation on VMProcess and VMSystem.
+ * include/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h,
+ * include/gnu_java_awt_peer_gtk_GdkFontPeer.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphics.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphics2D.h,
+ * include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h,
+ * include/gnu_java_awt_peer_gtk_GdkPixbufDecoder.h,
+ * include/gnu_java_awt_peer_gtk_GdkRobotPeer.h,
+ * include/gnu_java_awt_peer_gtk_GdkTextLayout.h,
+ * include/gnu_java_awt_peer_gtk_GtkButtonPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkCheckboxPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkChoicePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkClipboard.h,
+ * include/gnu_java_awt_peer_gtk_GtkComponentPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkFileDialogPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkFramePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkGenericPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkImage.h,
+ * include/gnu_java_awt_peer_gtk_GtkLabelPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkListPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuBarPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuItemPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkMenuPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkPanelPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkScrollPanePeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkScrollbarPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkSelection.h,
+ * include/gnu_java_awt_peer_gtk_GtkTextAreaPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkTextFieldPeer.h,
+ * include/gnu_java_awt_peer_gtk_GtkToolkit.h,
+ * include/gnu_java_awt_peer_gtk_GtkWindowPeer.h,
+ * include/gnu_java_awt_peer_qt_MainQtThread.h,
+ * include/gnu_java_awt_peer_qt_QMatrix.h,
+ * include/gnu_java_awt_peer_qt_QPainterPath.h,
+ * include/gnu_java_awt_peer_qt_QPen.h,
+ * include/gnu_java_awt_peer_qt_QtAudioClip.h,
+ * include/gnu_java_awt_peer_qt_QtButtonPeer.h,
+ * include/gnu_java_awt_peer_qt_QtCanvasPeer.h,
+ * include/gnu_java_awt_peer_qt_QtCheckboxPeer.h,
+ * include/gnu_java_awt_peer_qt_QtChoicePeer.h,
+ * include/gnu_java_awt_peer_qt_QtComponentPeer.h,
+ * include/gnu_java_awt_peer_qt_QtContainerPeer.h,
+ * include/gnu_java_awt_peer_qt_QtDialogPeer.h,
+ * include/gnu_java_awt_peer_qt_QtEmbeddedWindowPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFileDialogPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFontMetrics.h,
+ * include/gnu_java_awt_peer_qt_QtFontPeer.h,
+ * include/gnu_java_awt_peer_qt_QtFramePeer.h,
+ * include/gnu_java_awt_peer_qt_QtGraphics.h,
+ * include/gnu_java_awt_peer_qt_QtGraphicsEnvironment.h,
+ * include/gnu_java_awt_peer_qt_QtImage.h,
+ * include/gnu_java_awt_peer_qt_QtLabelPeer.h,
+ * include/gnu_java_awt_peer_qt_QtListPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuBarPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuComponentPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuItemPeer.h,
+ * include/gnu_java_awt_peer_qt_QtMenuPeer.h,
+ * include/gnu_java_awt_peer_qt_QtPanelPeer.h,
+ * include/gnu_java_awt_peer_qt_QtPopupMenuPeer.h,
+ * include/gnu_java_awt_peer_qt_QtScreenDevice.h,
+ * include/gnu_java_awt_peer_qt_QtScrollPanePeer.h,
+ * include/gnu_java_awt_peer_qt_QtScrollbarPeer.h,
+ * include/gnu_java_awt_peer_qt_QtTextAreaPeer.h,
+ * include/gnu_java_awt_peer_qt_QtTextFieldPeer.h,
+ * include/gnu_java_awt_peer_qt_QtToolkit.h,
+ * include/gnu_java_awt_peer_qt_QtVolatileImage.h,
+ * include/gnu_java_awt_peer_qt_QtWindowPeer.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaMidiDeviceProvider.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaMidiSequencerDevice.h,
+ * include/gnu_javax_sound_midi_alsa_AlsaPortDevice.h,
+ * include/gnu_javax_sound_midi_dssi_DSSIMidiDeviceProvider.h,
+ * include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h,
+ * include/gnu_xml_libxmlj_dom_GnomeAttr.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocument.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocumentBuilder.h,
+ * include/gnu_xml_libxmlj_dom_GnomeDocumentType.h,
+ * include/gnu_xml_libxmlj_dom_GnomeElement.h,
+ * include/gnu_xml_libxmlj_dom_GnomeEntity.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNamedNodeMap.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNode.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNodeList.h,
+ * include/gnu_xml_libxmlj_dom_GnomeNotation.h,
+ * include/gnu_xml_libxmlj_dom_GnomeProcessingInstruction.h,
+ * include/gnu_xml_libxmlj_dom_GnomeTypeInfo.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathExpression.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathNSResolver.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathNodeList.h,
+ * include/gnu_xml_libxmlj_dom_GnomeXPathResult.h,
+ * include/gnu_xml_libxmlj_sax_GnomeLocator.h,
+ * include/gnu_xml_libxmlj_sax_GnomeXMLReader.h,
+ * include/gnu_xml_libxmlj_transform_GnomeTransformer.h,
+ * include/gnu_xml_libxmlj_transform_GnomeTransformerFactory.h,
+ * include/java_lang_VMProcess.h,
+ * include/java_lang_VMSystem.h:
+ Regenerated with GCJ 4.1.
+
+2006-04-22 Casey Marshall <csm@gnu.org>
+
+ Fixes PR classpath/27228.
+ * gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java
+ (initialize): also accept `DHParameterSpec.'
+ * gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java (setup):
+ handle a passed-in `DHParameterSpec' properly.
+ (generate): don't check if the random exponent is less than `q -
+ 1' if no `q' was specified.
+
+2006-04-22 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTree.java (TreeSelectionRedirector.valueChanged):
+ Only repaint the patches, speficied in the passed event.
+ (expandPath): Do nothing if the path is already expanded.
+ (scrollPathToVisible): Only scroll to visible, do nothing else.
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (TreeExpansionHandler.treeColapsed): Revalidate and repaint.
+ (TreeExpansionHandler.treeExpanded): Revalidate and repaint.
+ (TreeTraverseAction.actionPerformed): Collapse the node on the
+ action "selectParent". (selectPath): Rewritten.
+ * javax/swing/tree/DefaultTreeSelectionModel.java (clearSelection):
+ Fire change event. (notifyPathChange): Implemented. (setSelectionPath):
+ Do not reuse selection array.
+ * javax/swing/tree/FixedHeightLayoutCache.java (getRowForPath):
+ Accept null.
+ * javax/swing/tree/VariableHeightLayoutCache.java (getRowForPath):
+ Accept null.
+
+2006-04-22 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/tree/DefaultTreeSelectionModel.java
+ (addSelectionPath): If the path cannot be added, set it.
+ (addSelectionPaths): Call insureRowContinuity.
+ (arePathsContiguous): Implemented.
+ (canPathBeAdded): New private method.
+ (canPathsBeAdded): Implemented.
+ (canPathsBeRemoved): Implemented.
+ (getPath): New private method.
+ (insureRowContinuity): Implemented.
+ (removeSelectionPath): Call insureRowContinuity.
+ (removeSelectionPaths): Call insureRowContinuity.
+ (resetRowSelection): Removed stub marking, not used in implementation
+ (nothing to do there).
+ (selectOne): New private method.
+ (setSelectionMode) Call insureRowContinuity.
+ (setSelectionPaths) Remove the current selection by clearing it.
+
+2006-04-22 Carsten Neumann <cn-develop@gmx.net>
+
+ * javax/sql/Array.java: Fixed eclipse API doc warnings, named method
+ parameters consistendly, documented some methods.
+ * java/sql/Blob.java: Likewise.
+ * java/sql/CallableStatement.java: Likewise.
+ * java/sql/Clob.java: Likewise.
+ * java/sql/Connection.java: Likewise.
+ * java/sql/DatabaseMetaData.java: Likewise.
+ * java/sql/Date.java: Likewise.
+ * java/sql/Driver.java: Likewise.
+ * java/sql/PreparedStatement.java: Likewise.
+ * java/sql/ResultSet.java: Likewise.
+ * java/sql/ResultSetMetaData.java: Likewise.
+ * java/sql/SQLData.java: Likewise.
+ * java/sql/SQLOutput.java: Likewise.
+ * java/sql/SQLWarning.java: Likewise.
+ * java/sql/Statement.java: Likewise.
+ * java/sql/Time.java: Likewise.
+ * java/sql/Timestamp.java: Likewise.
+
2006-04-21 Jeroen Frijters <jeroen@frijters.net>
* java/lang/reflect/AccessibleObject.java:
@@ -35,6 +849,481 @@
(getAnnotation, getAnnotations, getDeclaredAnnotations,
isAnnotationPresent): New methods.
+2006-04-21 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27163:
+ * gnu/java/net/protocol/ftp/FTPConnection.java
+ (changeWorkingDirectory): Do nothing if path is empty.
+
+2006-04-21 Tom Tromey <tromey@redhat.com>
+
+ PR libgcj/27231:
+ * gnu/java/net/protocol/http/HTTPURLConnection.java (connect): Handle
+ case where no '/' appears in 'location'.
+
+2006-04-21 Tom Tromey <tromey@redhat.com>
+
+ * java/security/Security.java (<clinit>): Add all default providers.
+ * resource/java/security/classpath.security: Added comment.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/SpinnerDateModel.java: Updated API docs all over,
+ * javax/swing/SpinnerNumberModel.java: Likewise.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/SpinnerDateModel.java
+ (SpinnerDateModel(Date, Comparable, Comparable, int)): Fix argument
+ checking to call compareTo() on start and end.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/border/AbstractBorder.java: API doc updates,
+ * javax/swing/border/BevelBorder.java: Likewise,
+ * javax/swing/border/CompoundBorder.java: Likewise,
+ * javax/swing/border/EtchedBorder.java: Likewise,
+ * javax/swing/border/LineBorder.java: Likewise,
+ * javax/swing/border/MatteBorder.java: Likewise,
+ * javax/swing/border/TitledBorder.java: Likewise.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * gnu/javax/crypto/cipher/Anubis.java:
+ (selfTest): Use Boolean.valueOf() to avoid creating a new Boolean
+ instance,
+ * gnu/javax/crypto/cipher/Blowfish.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Cast5.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Khazad.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Rijndael.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Serpent.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Square.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/cipher/Twofish.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/mac/UMac32.java:
+ (selfTest): Likewise,
+ * gnu/javax/crypto/prng/CSPRNG.java:
+ (getSystemInstance): Likewise.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * gnu/java/security/hash/Haval.java:
+ (selfTest): Use Boolean.valueOf() to avoid creating new Boolean
+ instance,
+ * gnu/java/security/hash/MD2.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/MD4.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/MD5.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/RipeMD128.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/RipeMD160.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Sha160.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Sha256.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Sha384.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Sha512.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Tiger.java:
+ (selfTest): Likewise,
+ * gnu/java/security/hash/Whirlpool.java:
+ (selfTest): Likewise.
+
+2006-04-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (PropertyChangeHandler.propertyChange): Set the row mapper
+ for the selection model.
+ * javax/swing/tree/AbstractLayoutCache.java
+ (NodeDimensions.getNodeDimensions): Explained.
+ (getPreferredHeight, getPreferredWidth, isFixedRowHeight):
+ Implemented. (setRowHeight): Invalidate sizes.
+ * javax/swing/tree/DefaultTreeSelectionModel.java
+ (addSelectionPath, addSelectionPaths): Update lead row.
+ (removeSelectionPath, removeSelectionPaths): Do nothing if
+ selection is empty.
+ (clone): Only clone list selection model if it is not null.
+ (getRow): New method. (isRowSelected, getLeadSelectionRow,
+ setSelectionPath, setSelectionPaths, toString): Implemented.
+ * javax/swing/tree/FixedHeightLayoutCache.java (NodeRecord.getBounds):
+ Pass the empty rectangle. (isFixedRowHeight): New method.
+ * javax/swing/tree/VariableHeightLayoutCache.java
+ (NodeRecord.getBounds): Pass the empty rectangle.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * gnu/java/security/Properties.java
+ (init): Use Boolean.valueOf() to avoid creating new Boolean instances.
+
+2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
+
+ * gnu/classpath/jdwp/util/Value.java
+ (getUntaggedObj(ByteBuffer, Class)): Use Boolean.valueOf() to avoid
+ creating new Boolean instances.
+
+2006-04-20 Mark Wielaard <mark@klomp.org>
+
+ * java/awt/Toolkit.java (getDefaultToolkit): Get classloader in
+ PrivilegedAction. Access awt.toolkit through SystemProperties.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/ActionMap.java: Removed unused imports,
+ * javax/swing/DefaultListSelectionModel.java
+ (clearSelection): Removed unused label,
+ * javax/swing/JScrollPane.java: Removed unused imports,
+ * javax/swing/UIManager.java: Likewise,
+ * javax/swing/table/DefaultTableCellRenderer.java: Likewise.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicSpinnerUI.java: Removed unused imports,
+ * javax/swing/plaf/basic/BasicTextAreaUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicTextFieldUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicTextUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicTreeUI.java: Likewise.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * java/sql/Array.java: Fixed Eclipse API doc warnings,
+ * java/sql/Blob.java: Likewise,
+ * java/sql/CallableStatement.java: Likewise,
+ * java/sql/Clob.java: Likewise,
+ * java/sql/Connection.java: Likewise,
+ * java/sql/DatabaseMetaData.java: Likewise,
+ * java/sql/Date.java: Likewise,
+ * java/sql/Driver.java: Likewise,
+ * java/sql/PreparedStatement.java: Likewise,
+ * java/sql/ResultSet.java: Likewise,
+ * java/sql/ResultSetMetaData.java: Likewise,
+ * java/sql/SQLData.java: Likewise,
+ * java/sql/SQLOutput.java: Likewise,
+ * java/sql/SQLWarning.java: Likewise,
+ * java/sql/Statement.java: Likewise,
+ * java/sql/Time.java: Likewise,
+ * java/sql/Timestamp.java: Likewise.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * java/sql/DriverManager.java
+ (setLoginTimeout): Use incoming argument,
+ (setLogStream): Likewise,
+ (println): Fix API doc comment.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JMenuItem.java
+ (paramString): Updated API docs,
+ (getAccessibleContext): Added API docs,
+ (AccessibleJMenuItem.stateChanged): Marked as stub,
+ (AccessibleJMenuItem.getAccessibleRole): Added API docs,
+ * javax/swing/JSlider.java
+ (paramString): Fix for API docs,
+ * javax/swing/JToolTip.java
+ (getAccessibleContext): Fix for API docs.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JRadioButtonMenuItem.java
+ (paramString): Reimplemented,
+ (getAccessibleContext): API docs added,
+ (AccessibleJRadioButtonMenuItem.AccessibleJRadioButtonMenuItem()):
+ Likewise,
+ (AccessibleJRadioButtonMenuItem.getAccessibleRole): Likewise.
+
+2006-04-20 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java
+ (finish): Invalidate path bounds.
+ (getMaxHeight): Set the row height to the layout cache.
+ (startEditing): Do not request to recalculated
+ row height and preferred size.
+ * javax/swing/tree/DefaultTreeCellEditor.java
+ (ICON_TEXT_GAP, ICON_TREE_GAP): Removed, replacing
+ with 0.
+ * javax/swing/tree/FixedHeightLayoutCache.java:
+ Rewritten.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JDesktopPane.java
+ (paramString): Reimplemented,
+ plus API doc updates in AccessibleJDesktopPane.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/ImageIcon.java:
+ (AccessibleImageIcon.getAccessibleStateSet): Return null always,
+ (AccessibleImageIcon.getLocale): Declared exception and always return
+ null,
+ (getAccessibleContext): Updated API docs,
+ plus updated API docs all over AccessibleImageIcon.
+
+2006-04-20 Roman Kennke <kennke@aicas.com>
+
+ PR 27196
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java
+ (paintText): Fetch the ascent only once. Add the ascent to
+ the text rect also when tabs are disabled.
+
+2006-04-20 Christian Thalinger <twisti@complang.tuwien.ac.at>
+
+ * java/util/Locale.java (defaultLocale): Set to en_US per
+ default and use user.country but prioritize user.region if
+ defined.
+ (getLocale(String language, String country)): Renamed region to
+ country.
+ (getLocale(String language, String region, String variant)):
+ Likewise.
+ (getAvailableLocales): Likewise.
+
+2006-04-20 Roman Kennke <kennke@aicas.com>
+
+ PR 27222
+ * javax/swing/JList.java
+ (JList()): Call init() with DefaultListModel instance.
+ (JList(Object[])): Call init() with null.
+ (JList(Vector)): Call init() with null.
+ (JList(ListModel)): Call init() with model.
+ (init): Changed to take the model as argument. Don't call
+ setter methods and initialize stuff directly instead.
+ (getCellBounds): Check if UI is null.
+
+2006-04-20 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/WrappedPlainView.java: Initialize
+ WrappedLine.numLines with -1.
+ (WrappedPlainView.WrappedLine.getPreferredSpan): Check whether
+ numLines is -1 and reculcalate the value appropriately.
+ (WrappedPlainView.WrappedLine.updateDamage): Set numLines to -1 if
+ allocation area is empty.
+
+2006-04-20 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTabbedPane.java
+ (AccessibleJTabbedPane.stateChanged): Marked as stub,
+ (AccessibleJTabbedPane.getAccessibleRole): Likewise,
+ (AccessibleJTabbedPane.getAccessibleChildrenCount): Likewise,
+ (AccessibleJTabbedPane.getAccessibleSelection): Likewise,
+ (AccessibleJTabbedPane.getAccessibleAt): Likewise,
+ (AccessibleJTabbedPane.getAccessibleSelectionCount): Likewise,
+ (AccessibleJTabbedPane.getAccessibleSelection(int)): Likewise,
+ (AccessibleJTabbedPane.isAccessibleChildSelected): Likewise,
+ (AccessibleJTabbedPane.addAccessibleSelection): Likewise,
+ (AccessibleJTabbedPane.removeAccessibleSelection): Likewise,
+ (AccessibleJTabbedPane.clearAccessibleSelection): Likewise,
+ (AccessibleJTabbedPane.selectAllAccessibleSelection): Likewise,
+ (Page.getAccessibleStateSet): Likewise,
+ (Page.getAccessibleIndexInParent): Likewise.
+
+2006-04-19 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JProgressBar.java
+ (paramString): Reimplemented.
+
+2006-04-19 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JButton.java: Updated API docs all over.
+
+2006-04-19 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/Toolkit.java
+ (getDefaultToolkit): Use system classloader to load the
+ toolkit.
+
+2006-04-19 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/DefaultCaret.java:
+ (DefaultCaret.Bypass.setDot): Call DefaultCaret.setDotImpl
+ instead of DefaultCaret.setDot.
+
+2006-04-19 Roman Kennke <kennke@aicas.com>
+
+ * native/jni/java-net/local.c
+ (local_read): Handle EINTR correctly.
+ (local_write): Likewise.
+
+2006-04-19 Riccardo Mottola <multix@gmail.com>
+
+ PR classpath/27062, PR classpath/25650:
+ * native/fdlibm/ieeefp.h: Check for _POWER and _IBMR2.
+
+2006-04-19 Tom Tromey <tromey@redhat.com>
+
+ * java/text/SimpleDateFormat.java (formatWithAttribute): Take absolute
+ value of 'pureMinutes'. PR classpath/27189.
+
+2006-04-19 Olivier Jolly <olivier.jolly@pcedev.com>
+
+ * vm/reference/java/lang/VMClassLoader.java (getBootPackages): Loads
+ boot packages list from the META-INF/INDEX.LIST file if it exists.
+
+2006-04-19 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ Suggested by Stephen White <stephen-gnu-crypto@randomstuff.org.uk>
+ * gnu/javax/crypto/prng/IPBE.java: Updated documentation.
+ (ITERATION_COUNT): Removed modifiers.
+ (PASSWORD): Likewise.
+ (SALT): Likewise.
+ (PASSWORD_ENCODING): New property.
+ (DEFAULT_PASSWORD_ENCODING): New constant.
+ * gnu/javax/crypto/prng/PBKDF2.java (setup): Check for MAC's raw key
+ material (bytes) before a password (chars).
+
+2006-04-19 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JMenu.java
+ (getAccessibleChildrenCount): Marked as stub,
+ (getAccessibleChild): Likewise,
+ (getAccessibleSelection): Likewise,
+ (getAccessibleSelection(int)): Likewise,
+ (isAccessibleChildSelected): Likewise,
+ (getAccessibleSelectionCount): Likewise,
+ (addAccessibleSelection): Likewise,
+ (removeAccessibleSelection): Likewise,
+ (clearAccessibleSelection): Likewise,
+ (selectAllAccessibleSelection): Likewise.
+
+2006-04-19 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JSplitPane.java
+ (getAccessibleContext): Added API docs,
+ (paramString): Reimplemented,
+ (setOrientation): Updated API docs,
+ (setResizeWeight): Added argument checking and event notification.
+
+2006-04-18 Casey Marshall <csm@gnu.org>
+
+ Fixes PR classpath/25673
+ * java/security/KeyStore.java (getDefaultType): return "gkr" if no
+ property is set. Update JavaDoc to reflect this.
+
+2006-04-18 Lillian Angel <langel@redhat.com>
+
+ * gnu/xml/dom/DomDocument.java
+ (setCheckingCharacters): New function used to set
+ checkingCharacters flag.
+ * gnu/xml/dom/html2/DomHTMLParser.java
+ (parseDocument): Added call to set checkingCharacters flag
+ to false.
+
+2006-04-18 Lillian Angel <langel@redhat.com>
+
+ * gnu/xml/dom/DomDocument.java
+ (checkNCName): Reverted last patch. Added check for colon at
+ last position back in.
+
+2006-04-18 Robert Schuster <robertschuster@fsfe.org>
+
+ * examples/gnu/classpath/examples/swing/NavigationFilterDemo.java:
+ New file.
+ * examples/gnu/classpath/examples/swing/Demo.java:
+ (mkMenuBar): Added NavigationFilter demo.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JSeparator.java: Updated API docs all over, plus
+ (setOrientation): Fire PropertyChangeEvent,
+ (paramString): Reimplemented.
+
+2006-04-18 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/plaf/basic/BasicTextUI.java: Implemented.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JPanel.java: Updated API docs all over, plus
+ (JPanel(LayoutManager, boolean)): Pass on null layout, set
+ double-buffer flag.
+
+2006-04-18 Robert Schuster <robertschuster@fsfe.org>
+
+ * examples/gnu/classpath/examples/swing/DocumentFilterDemo.java:
+ New file.
+ * examples/gnu/classpath/examples/swing/Demo.java:
+ (mkMenuBar): Added DocumenFilter demo.
+
+2006-04-18 Tom Tromey <tromey@redhat.com>
+
+ * doc/www.gnu.org/include/layout.wml: Add FMJ.
+
+2006-04-18 Mark Wielaard <mark@klomp.org>
+
+ Reported by John Sullivan (johns@fsf.org)
+ * doc/www.gnu.org/stories.wml: Update JikesRVM location.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JInternalFrame.java
+ (JDesktopIcon.getAccessibleContext): Added API docs,
+ (getDefaultCloseOperation): Likewise,
+ (paramString): Added 'title' attribute,
+ (setDefaultCloseOperation): Added API docs.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JSlider.java
+ (paramString): Reimplemented.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JComboBox.java
+ (paramString): Reimplemented,
+ (getAccessibleContext): Added API docs,
+ (AccessibleJComboBox.getAccessibleRole): Likewise.
+
+2006-04-18 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/RepaintManager.java
+ (dirtyComponentsWork): New field.
+ (ComponentComparator): Use dirtyComponentsWork instead of
+ dirtyComponents.
+ (RepaintManager): Initialize new field.
+ (paintDirtyRegions): Swap dirtyComponents with dirtyComponentsWork
+ and work on the copy.
+
+2006-04-18 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/peer/swing/SwingComponentPeer.java
+ (setBounds): Call reshape().
+ * gnu/java/awt/peer/swing/SwingContainerPeer.java
+ (SwingContainerPeer): Changed argument to be a Component
+ instead a Container.
+ (getInsets): Call insets().
+ (handleMouseEvent): Added null check to avoid NPE.
+ (handleMouseMotionEvent): Added null check to avoid NPE.
+
+2006-04-18 Roman Kennke <kennke@aicas.com>
+
+ PR 27185
+ * javax/swing/JComponent.java
+ (paintChildrenWithOverlap): When one child is not opaque, propagate
+ the dirty rectangles to the next child.
+ (paintChildrenOptimized): Removed unnecessary 'optimization'.
+ This actually didn't work right and probably gained nothing.
+
+2006-04-18 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTable.java (getCallRect): Do not cache rectangles.
+ (moveToCellBeingEdited): Do not clone the rectangle here.
+
+2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicSliderUI.java
+ (getActionMap): Fixed lookup key,
+ (createActionMap): Modified actions to fetch slider/ui from the event
+ source.
+
2006-04-17 Andrew John Hughes <gnu_andrew@member.fsf.org>
* java/lang/Enum.java: Documented.
@@ -57,6 +1346,144 @@
* java/lang/annotation/Annotation.java:
Documented.
+2006-04-17 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JToolBar.java
+ (AccessibleJToolBar.AccessibleJToolBar()): Updated API docs,
+ (AccessibleJToolBar.getAccessibleStateSet): Implemented,
+ (AccessibleJToolBar.getAccessibleRole): Updated API docs,
+ (getAccessibleContext): Likewise.
+
+2006-04-17 Dalibor Topic <robilad@kaffe.org>
+
+ * configure.ac:
+ Added CLASSPATH_CONVENIENCE substitution for convenience library LDFLAGS.
+
+ * native/fdlibm/Makefile.am,
+ native/jni/classpath/Makefile.am:
+ Don't use -module and -version-info for convenience libraries LDFLAGS.
+ Fixes libtool warnings.
+
+2006-04-17 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicComboBoxUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicComboPopup.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicInternalFrameUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicLabelUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicListUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicMenuBarUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicMenuUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicOptionPaneUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicPopupMenuUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicScrollBarUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicScrollPaneUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicSplitPaneUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicTableHeaderUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicTableUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicTextUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise,
+ * javax/swing/plaf/basic/BasicToolBarUI.java:
+ (installKeyboardActions): Marked as stub,
+ (uninstallKeyboardActions): Likewise.
+
+2006-04-17 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicSliderUI.java
+ (installKeyboardActions): Implemented,
+ (uninstallKeyboardActions): Implemented,
+ (scrollByBlock): Accept any value for direction,
+ (scrollByUnit): Likewise,
+ (getInputMap): New method,
+ (getActionMap): New method,
+ (createActionMap): New method.
+
+
+2006-04-16 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * doc/vmintegration.texinfo:
+ Fix sectioning.
+
+2006-04-16 Tom Tromey <tromey@redhat.com>
+
+ * native/jni/java-net/Makefile.am (AM_CFLAGS): Removed --save-temps.
+
+2006-04-16 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * NEWS:
+ Mention generics additions to the VM interface.
+ * doc/vmintegration.texinfo:
+ Added information on VMClass 1.5 additions and
+ VMSecureRandom.
+
+2006-04-16 Casey Marshall <csm@gnu.org>
+
+ * NEWS: add an entry mentioning local socket support.
+
+2006-04-16 Casey Marshall <csm@gnu.org>
+
+ * configure.ac (--enable-local-sockets): new enable argument.
+ (ENABLE_LOCAL_SOCKETS): new define.
+ * native/jni/java-net/Makefile.am (local_sources): new variable.
+ (lib_javanet_la_SOURCES): append `local_sources.'
+ * native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c,
+ * native/jni/java-net/local.c,
+ * native/jni/java-net/local.h,
+ * include/gnu_java_net_local_LocalSocketImpl.h,
+ * gnu/java/net/local/LocalServerSocket.java,
+ * gnu/java/net/local/LocalSocket.java,
+ * gnu/java/net/local/LocalSocketAddress.java,
+ * gnu/java/net/local/LocalSocketImpl.java: new files.
+
+2006-04-15 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * javax/accessibility/AccessibleAction.java:
+ (DECREMENT): Added field.
+ (INCREMENT): Likewise.
+ (TOGGLE_EXPAND): Likewise.
+ * javax/accessibility/AccessibleRole.java:
+ (EDITBAR): Added field.
+ (FOOTER): Likewise.
+ (HEADER): Likewise.
+ (PARAGRAPH): Likewise.
+ (PROGRESS_MONITOR): Likewise.
+ (RULER): Likewise.
+ * javax/accessibility/AccessibleState.java:
+ (INDETERMINATE): Added field.
+ (MANAGES_DESCENDANTS): Likewise.
+ (TRUNCATED): Likewise.
+
2006-04-14 Tom Tromey <tromey@redhat.com>
* javax/swing/tree/DefaultTreeSelectionModel.java (getListeners):
@@ -64,6 +1491,91 @@
* javax/swing/tree/AbstractLayoutCache.java (getVisiblePathsFrom):
Genericized.
+2006-04-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/DefaultCaret.java:
+ (getBypass): New method.
+ (moveDot): Rewritten.
+ (moveDotImpl): New method.
+ (setDot): Rewritten.
+ (setDotImpl): New method.
+ (DefaultCaret.Bypass): New class.
+
+2006-04-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/AbstractDocument.java:
+ (getBypass): New method.
+ (insertString): Rewritten.
+ (remove): Rewritten.
+ (replace): Rewritten.
+ (insertStringImpl): New method.
+ (removeImpl): New method.
+ (replaceImpl): New method.
+ (AbstractDocument.Bypass): New class.
+
+2006-04-14 Casey Marshall <csm@gnu.org>
+
+ Fixes PR classpath/24642
+ * NEWS: add note about SecureRandom changes, and addition of
+ VMSecureRandom.
+ * java/security/SecureRandom.java (isSeeded): new field.
+ (setSeed, setSeed): set `isSeeded' to `true.'
+ (nextBytes): seed this instance if `isSeeded' is false.
+ (getSeed): call `generateSeed.'
+ (SECURERANDOM_SOURCE, JAVA_SECURITY_EGD, logger): new constants.
+ (generateSeed, generateSeed): new methods.
+ * vm/reference/java/security/VMSecureRandom.java: new file.
+
+2006-04-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/FieldView.java:
+ (paint): Apply clipping rectangle of the allocation area
+ before painting the text.
+ * javax/swing/text/DefaultHighlighter.java:
+ (DefaultHighlighter.DefaultHighlightPainter): Use SwingUtilities to
+ compute union and intersection, calculate intersection with allocation
+ area before painting, adjust x and width when painting multiple lines
+ by the range of the allocation area.
+
+2006-04-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/DefaultHighlighter.java:
+ (paintLayeredHighlights): Marked as stub.
+
+2006-04-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/plaf/basic/BasicTextFieldUI.java:
+ (propertyChanged): Added note, change color only if current background
+ is a ColorUIResource instance.
+
+2006-04-14 Tom Tromey <tromey@redhat.com>
+
+ * java/beans/beancontext/BeanContextSupport.java (hasNext): No longer
+ a stub.
+ (next): Likewise.
+
+2006-04-14 Tom Tromey <tromey@redhat.com>
+
+ * javax/swing/JComboBox.java (AccessibleJComboBox): Now public.
+
+2006-04-14 Mark Wielaard <mark@klomp.org>
+
+ * java/lang/Thread.java (getUncaughtExceptionHandler): Return
+ thread group when exceptionHandler isn't set.
+ * vm/reference/java/lang/VMThread.java (run): Use result of
+ thread.getUncaughtExceptionHandler directly.
+
+2006-04-14 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JSplitPane.java
+ (AccessibleJSplitPane.getAccessibleStateSet): Implemented,
+ (AccessibleJSplitPane.getAccessibleRole): Implemented,
+ (AccessibleJSplitPane.getAccessibleValue): Implemented,
+ (AccessibleJSplitPane.getCurrentAccessibleValue): Implemented,
+ (AccessibleJSplitPane.setCurrentAccessibleValue): Implemented,
+ (AccessibleJSplitPane.getMinimumAccessibleValue): Implemented,
+ (AccessibleJSplitPane.getMaximumAccessibleValue): Implemented.
+
2006-04-10 Tom Tromey <tromey@redhat.com>
* javax/imageio/metadata/IIOMetadataFormatImpl.java (addObjectValue):
@@ -3417,6 +4929,21 @@
* vm/reference/gnu/classpath/Unsafe.java:
New class to handle low-level facilities for concurrency.
+2006-03-19 Michael Barker <mike@middlesoft.co.uk>
+
+ * vm/reference/gnu/java/nio/VMChannel.java: Added, supports setting
+ non-blocking and scatter-gather io operations.
+ * gnu/java/nio/PipeImpl.java: Retrofitted to use VMChannel
+ * gnu/java/nio/SelectorImpl.java
+ (register) Added condition for gnu.java.nio.SocketChannelSelectionKeyImpl
+ * gnu/java/nio/SocketChannelSelectionKeyImpl.java Added.
+ * gnu/java/nio/channels/FileChannelImpl.java: Retrofitted to use VMChannel
+ * java/nio/FileChannel.java
+ (read (ByteBuffer)) Changed to call abstract method.
+ (write (ByteBuffer)) Changed to call abstract method.
+ * include/gnu_java_nio_VMChannel.h: Added.
+ * native/jni/java-nio/gnu_java_nio_VMChannel.c: Added.
+
2006-03-19 Mark Wielaard <mark@klomp.org>
* include/Makefile.am: Rename PlainDatagramSocketImpl to
@@ -12164,7 +13691,7 @@
Added deprecated tag.
* javax/swing/text/JTextComponent.java
(AccessibleJTextComponent): Fixed API doc and
- partially implemented.
+ partiall9 implemented.
(getCaretPosition): Fixed API doc and implemented.
(getSelectedText): Fixed API doc.
(getSelectionStart): Likewise.
diff --git a/NEWS b/NEWS
index 1bc11e6ed..7474267cf 100644
--- a/NEWS
+++ b/NEWS
@@ -16,8 +16,13 @@ New in release 0.91 (UNRELEASED)
* Free Swing improvements: Support for OceanTheme has been mostly completed
and turned on as default Metal theme. X11-style Copy and Paste behavior in
text components with the middle mouse button. Support cursor changes on
- various components when resizing.
+ various components when resizing. Support for Look and Feel window
+ decorations has been added.
* Updated locale data information to CLDR 1.3.
+* Various bugs in Classpath's SecureRandom implementations have been
+ fixed; that class now respects the "securerandom.source" security
+ property and the "java.security.egd" system property.
+* Support for assistive technologies has been added to AWT and Swing.
Runtime interface changes:
@@ -31,6 +36,28 @@ Runtime interface changes:
this method.
* The reference implementation of VMThread has been updated to handle
the new Thread.UncaughtExceptionHandler support.
+* A new class, java.security.VMSecureRandom, is now available that is
+ used to generate random numbers for seeding cryptographically-secure
+ pseudo-random number generators.
+* VMClass and the reference implementations of Method, Constructor and Field
+ now include a number of 1.5 methods imported from the generics branch.
+ These are all optional (in the sense that the methods associated with them
+ merely fail on use if the VM doesn't provide them, rather than the
+ VM failing altogether), but VMs should aim to support them where possible.
+* The implementation of java.lang.instrument has been merged to the main
+ branch from the generics branch.
+* The VM interfaces of the main branch and the generics branch are now
+ consistent with one another. As a result, the main branch includes an
+ additional environ() function in VMSystem and an additional argument has
+ been added to nativeSpawn() in VMProcess.
+* Annotation support is now available in the main branch, if the VM supports
+ it. The VM should implement VMClass.getDeclaredAnnotations,
+ Constructor.getAnnotation, Constructor.getDeclaredAnnotations,
+ Field.getAnnotation, Field.getDeclaredAnnotations, Method.getAnnotation and
+ Method.getDeclaredAnnotations.
+* java.lang.Package now has a new constructor that takes the defining
+ ClassLoader as an extra argument. If you use a custom version of
+ VMClassLoader, please switch it to use this constructor.
New in release 0.90 (March 6, 2006)
diff --git a/configure.ac b/configure.ac
index 1731b9955..af4963067 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,6 +33,9 @@ esac
CLASSPATH_MODULE="${cp_module} -version-info ${LIBVERSION} -no-undefined"
AC_SUBST(CLASSPATH_MODULE)
+CLASSPATH_CONVENIENCE="-no-undefined"
+AC_SUBST(CLASSPATH_CONVENIENCE)
+
AC_PREREQ(2.59)
AM_INIT_AUTOMAKE([1.9.0 gnu std-options tar-ustar])
AC_CONFIG_HEADERS([include/config.h])
@@ -612,6 +615,30 @@ AC_SUBST(PATH_TO_GLIBJ_ZIP)
dnl -----------------------------------------------------------
+dnl Check if local socket support should be included.
+dnl -----------------------------------------------------------
+AC_ARG_ENABLE([local-sockets],
+ [AS_HELP_STRING(--enable-local-sockets,enables local (AF_LOCAL) socket API [default: no])],
+ [case "${enableval}" in
+ yes)
+ ENABLE_LOCAL_SOCKETS=yes
+ ;;
+ *)
+ ENABLE_LOCAL_SOCKETS=no
+ ;;
+ esac],
+ [])
+if test "x$ENABLE_LOCAL_SOCKETS" = "xyes"
+then
+ AC_CHECK_HEADER([sys/un.h])
+ AC_CHECK_FUNCS([read write bind listen accept shutdown], [],
+ AC_MSG_ERROR([networking support not available]))
+ AC_DEFINE(ENABLE_LOCAL_SOCKETS, [1], [Define to enable support for local sockets.])
+fi
+AM_CONDITIONAL(ENABLE_LOCAL_SOCKETS, test "x$ENABLE_LOCAL_SOCKETS" = "xyes")
+
+
+dnl -----------------------------------------------------------
dnl output files
dnl -----------------------------------------------------------
AC_CONFIG_FILES([Makefile
diff --git a/doc/vmintegration.texinfo b/doc/vmintegration.texinfo
index 0164f7c83..a784e6fad 100644
--- a/doc/vmintegration.texinfo
+++ b/doc/vmintegration.texinfo
@@ -201,6 +201,7 @@ implementation.
* java.nio.channels::
* gnu.java.nio::
* java.lang.reflect::
+* gnu.java.lang::
* Classpath Callbacks::
@end menu
@@ -227,7 +228,6 @@ become operable.
* java.lang.VMRuntime::
* java.lang.VMString::
* java.lang.VMThread::
-* java.lang.VMInstrumentationImpl::
* java.lang.VMMath::
@end menu
@@ -275,9 +275,12 @@ VM should filter out non-public classes.
@item @code{getDeclaredConstructors(Class,boolean)} -- And constructors.
@item @code{getClassLoader(Class)} -- Returns the @code{ClassLoader} instance
which is responsible for the specified class.
-@item @code{forName(String)} -- The VM should create a @code{Class} instance
-corresponding to the named class. As noted in @ref{VM Hooks}, the internal
-content of the instance is the responsibility of the VM.
+@item @code{forName(String, boolean, ClassLoader)} -- The VM should create a
+@code{Class} instance corresponding to the named class. As noted in
+@ref{VM Hooks}, the internal content of the instance is the
+responsibility of the VM. The supplied class loader is recorded as that
+which loaded the class, and the boolean specifies whether or not to
+run the class initializer.
@item @code{isArray(Class)} -- Another property test, corresponding to a
class file flag.
@item @code{initialize(Class)} -- The VM should initialize the class fully,
@@ -308,15 +311,44 @@ information stored in the class file.
an inner or member class, or @code{null} if the instance refers to a top-level
class.
@end itemize
+@item 1.5
+@itemize @bullet
+@item @code{isSynthetic(Class)} -- Returns true if the flags for this class
+mark it as synthetic.
+@item @code{isAnnotation(Class)} -- Returns true if the flags for this class
+mark it as an annotation.
+@item @code{isEnum(Class)} -- Returns true if the flags for this class
+mark it as an enumeration.
+@item @code{getSimpleName(Class)} -- Returns the simple name of the class.
+A default implementation is provided, but a more efficient version may instead
+be provided by the VM.
+@item @code{getCanonicalName(Class)} -- Returns the canonical name of the
+class. A default implementation is provided, but a more efficient
+version may instead be provided by the VM.
+@item @code{getEnclosingClass(Class)} -- Returns the immediately enclosing
+class (null for a top-level class).
+@item @code{getEnclosingConstructor(Class)} -- Returns the constructor
+which immediately encloses the supplied class.
+@item @code{getEnclosingMethod(Class)} -- Returns the method
+which immediately encloses the supplied class.
+@item @code{getClassSignature(Class)} -- Returns the generic signature of
+the class or null if there isn't one.
+@item @code{isAnonymousClass(Class)} -- Returns true if the class is an
+anonymous class.
+@item @code{isLocalClass(Class)} -- Returns true if the class is an
+local class.
+@item @code{isMemberClass(Class)} -- Returns true if the class is an
+member class.
+@end itemize
@end itemize
@node java.lang.VMObject, java.lang.VMClassLoader, java.lang.VMClass, java.lang
@subsection @code{java.lang.VMObject}
-@code{VMObject} is the bridge between the low level @code{Object} facilities
-such as making a clone, getting the class of the object and the wait/notify
-semantics. This is accomplished using the following @code{native}
-methods.
+@code{VMObject} is the bridge between the low level @code{Object}
+facilities such as making a clone, getting the class of the object and
+the wait/notify semantics. This is accomplished using the following
+@code{native} methods.
@itemize @bullet
@item @code{getClass(Object)} -- Returns the @code{Class} instance for the
@@ -414,13 +446,15 @@ and direct memory manipulation than would have been achieved by using Java.
@item @code{currentTimeMillis()} -- Gets the system time in milliseconds.
@item @code{getenv(String)} -- Returns the value of the specified environment
variable.
+@item @code{getenv()} -- Returns a list of `name=value' pairs which correspond
+to the environment variables.
@end itemize
@item Java Methods
@itemize @bullet
@item @code{makeStandardInputStream()} -- Helps provide the functionality of
-@code{System.in} by wrapping the appropriate file descriptor in a buffered
-file input stream. VMs may choose to create the stream from the descriptor
-differently rather than using this method.
+@code{System.in} by wrapping the appropriate file descriptor in a
+buffered file input stream. VMs may choose to create the stream from
+the descriptor differently rather than using this method.
@item @code{makeStandardOutputStream()} -- Helps provide the functionality of
@code{System.out} by wrapping the appropriate file descriptor in a buffered
file output stream. VMs may choose to create the stream from the descriptor
@@ -541,11 +575,14 @@ for all three by Classpath, making VM implementation optional. These use
the POSIX functions, @code{fork()}, @code{waitpid()} and @code{kill()}.
@itemize @bullet
-@item @code{nativeSpawn(String[],String[],File)} -- The VM should create a
-new process which uses the specified command-line arguments, environment
-variables and working directory. Unlike the other two methods, this
-method is linked to an instance, and must call @code{setProcessInfo()} with
-the results before returning.
+@item @code{nativeSpawn(String[],String[],File,boolean)} -- The VM should
+create a new process which uses the specified command-line arguments,
+environment variables and working directory. Unlike the other two
+methods, this method is linked to an instance, and must call
+@code{setProcessInfo()} with the results before returning. The
+boolean argument maps to the @code{redirectErrorStream} property of
+@code{java.lang.ProcessBuilder}. When true, the output and error streams
+are merged.
@item @code{nativeReap()} -- This is called to perform a reap of any
zombie processes, and should not block, instead returning a boolean as to
whether reaping actually took place.
@@ -610,7 +647,7 @@ A new mapping is created for each new string being @code{intern}ed.
A VM may implement this differently by implementing this method,
which is @code{static} and the only one in @code{VMString}.
-@node java.lang.VMThread,java.lang.VMInstrumentationImpl, java.lang.VMString, java.lang
+@node java.lang.VMThread, java.lang.VMMath, java.lang.VMString, java.lang
@subsection @code{java.lang.VMThread}
@code{VMThread} provides the link between Java's threads and the platform
@@ -686,49 +723,7 @@ having returned true, and is thus deprecated as a result.
@end itemize
@end itemize
-@node java.lang.VMInstrumentationImpl, java.lang.VMMath, java.lang.VMThread, java.lang
-@subsection @code{java.lang.VMInstrumentationImpl}
-
-The @code{java.lang.VMInstrumentationImpl} and
-@code{java.lang.InstrumentationImpl} classes provide an implementation of the
-@code{java.lang.instrument.Instrument} interface. This interface is for java
-1.5 and is only in the generics branch.
-A @code{InstrumentationImpl} object should be created by the VM when agents
-are given in the command line (see the @code{java.lang.instrument} package
-documentation). The VM has to set the static field
-@code{VMClassLoader.instrumenter} to this object. The VM should implement the
-static native methods of the @code{VMInstrumentationImpl} class.
-
-@itemize @bullet
-@item @code{isRedefineClassesSupported()} -- Returns true if the JVM supports
-class redefinition.
-@item @code{redefineClasses()} -- Gives a set of classes with new bytecodes.
-The VM must redefine the classes by reading the new bytecodes.
-@item @code{getAllLoadedClass()} -- Returns an array of all loaded classes.
-@item @code{getInitiatedClass()} -- Returns an array of all classes loaded
-by a specific class loader.
-@item @code{getObjectSize()} -- Gives the size of an object.
-@end itemize
-
-Instrumentation allows to modify the bytecode of a class before it gets read
-by the VM. In GNU Classpath, the @code{ClassLoader.defineClass} method calls
-the @code{VMClassLoader.defineClassWithTransformers} method which first checks
-if @code{VMClassLoader.instrumenter} is @code{null}. If it's the case, it
-directly calls @code{VMClassLoader.defineClass}. If it's not the case, the
-method calls at first the @code{InstrumentationImpl.callTransformers} method,
-which calls each transformer registered to the @code{InstrumentationImpl}
-object and returns a new bytecode array. Then, it calls the
-@code{VMClassLoader.defineClass} method with this new bytecode array.
-
-The second use of instrumentation is to redefine a class after it has been
-loaded by the VM. This is done in the Java application by calling the
-@code{Instrumentation.redefineClasses} method of the standard interface on
-a @code{Instrumentation} object. The @code{InstrumentationImpl.redefineClasses}
-method calls the @code{VMInstrumentationImpl.redefineClasses} native method
-which must be implemented by the VM. The implementation should call the
-@code{InstrumentationImpl.callTransformers} method.
-
-@node java.lang.VMMath, , java.lang.VMInstrumentationImpl, java.lang
+@node java.lang.VMMath,, java.lang.VMThread, java.lang
@subsection @code{java.lang.VMMath}
The @code{VMMath} class provides a series of native methods
@@ -1004,14 +999,14 @@ is optional.
@section java.security
The @code{java.security} package provides support for Java's security
-architecture. At present, @code{VMAccessController} represents the sole
-VM hook for this.
+architecture.
@menu
* java.security.VMAccessController::
+* java.security.VMSecureRandom::
@end menu
-@node java.security.VMAccessController,,java.security,java.security
+@node java.security.VMAccessController,java.security.VMSecureRandom,java.security,java.security
@subsection @code{java.security.VMAccessController}
The @code{AccessController} is used to perform privileged actions. Its
@@ -1034,6 +1029,23 @@ arrays of classes and method names. The actual implementation returns
an empty array, indicating that there are no permissions.
@end itemize
+@node java.security.VMSecureRandom,,java.security.VMAccessController,java.security
+@subsection @code{java.security.VMSecureRandom}
+
+The @code{VMSecureRandom} class is used to provide access to
+cryptographically secure random numbers. The default implementation
+of the class runs eight threads that increment counters in a tight
+loop, and XORs each counter to produce one byte of seed data. This is
+not very efficient, and is not guaranteed to be random (the thread
+scheduler is probably deterministic, after all). VM implementors
+should provide a version of this class, which implements the method
+@code{generateSeed(byte[],int,int)}, so that it fills the buffer using
+a random seed from a system facility, such as a system entropy
+gathering device or hardware random number generator. The parameters
+are the usual set of buffer, offset and length and the method returns
+the number of bytes actually generated, which may be less than that
+requested.
+
@node java.net, java.nio, java.security, Classpath Hooks
@section java.net
@@ -1176,7 +1188,7 @@ operation to be performed. This is represented by the @code{static}
@code{native} method, @code{select(int[],int[],int[],long)}, and a default
implementation of this is provided.
-@node java.lang.reflect, Classpath Callbacks, gnu.java.nio, Classpath Hooks
+@node java.lang.reflect, gnu.java.lang, gnu.java.nio, Classpath Hooks
@section @code{java.lang.reflect}
@code{java.lang.reflect} provides the interface to Java's reflection
facilities. Via reflection, programmers can obtain type information about
@@ -1194,7 +1206,59 @@ which the VM uses to generate a new non-primitive array of a
particular class and size. The default implementation simply passes
the job down to the standard JNI function, @code{NewObjectArray}.
-@node Classpath Callbacks, , java.lang.reflect, Classpath Hooks
+@node gnu.java.lang, Classpath Callbacks, java.lang.reflect, Classpath Hooks
+@section @code{gnu.java.lang}
+
+@code{gnu.java.lang} provides VM interfaces for the GNU
+implementations of features in java.lang. Currently, this includes the
+implementation of instrumentation.
+
+@menu
+* gnu.java.lang.VMInstrumentationImpl::
+@end menu
+
+@node gnu.java.lang.VMInstrumentationImpl,,,gnu.java.lang
+@subsection @code{gnu.java.lang.VMInstrumentationImpl}
+
+The @code{gnu.java.lang.VMInstrumentationImpl} and
+@code{gnu.java.lang.InstrumentationImpl} classes provide an implementation of the
+@code{java.lang.instrument.Instrument} interface.
+A @code{InstrumentationImpl} object should be created by the VM when agents
+are given in the command line (see the @code{java.lang.instrument} package
+documentation). The VM has to set the static field
+@code{VMClassLoader.instrumenter} to this object. The VM should implement the
+static native methods of the @code{VMInstrumentationImpl} class.
+
+@itemize @bullet
+@item @code{isRedefineClassesSupported()} -- Returns true if the JVM supports
+class redefinition.
+@item @code{redefineClasses()} -- Gives a set of classes with new bytecodes.
+The VM must redefine the classes by reading the new bytecodes.
+@item @code{getAllLoadedClass()} -- Returns an array of all loaded classes.
+@item @code{getInitiatedClass()} -- Returns an array of all classes loaded
+by a specific class loader.
+@item @code{getObjectSize()} -- Gives the size of an object.
+@end itemize
+
+Instrumentation allows to modify the bytecode of a class before it gets read
+by the VM. In GNU Classpath, the @code{ClassLoader.defineClass} method calls
+the @code{VMClassLoader.defineClassWithTransformers} method which first checks
+if @code{VMClassLoader.instrumenter} is @code{null}. If it's the case, it
+directly calls @code{VMClassLoader.defineClass}. If it's not the case, the
+method calls at first the @code{InstrumentationImpl.callTransformers} method,
+which calls each transformer registered to the @code{InstrumentationImpl}
+object and returns a new bytecode array. Then, it calls the
+@code{VMClassLoader.defineClass} method with this new bytecode array.
+
+The second use of instrumentation is to redefine a class after it has been
+loaded by the VM. This is done in the Java application by calling the
+@code{Instrumentation.redefineClasses} method of the standard interface on
+a @code{Instrumentation} object. The @code{InstrumentationImpl.redefineClasses}
+method calls the @code{VMInstrumentationImpl.redefineClasses} native method
+which must be implemented by the VM. The implementation should call the
+@code{InstrumentationImpl.callTransformers} method.
+
+@node Classpath Callbacks, , gnu.java.lang, Classpath Hooks
Some of the classes you implement for the VM will need to call back to
package-private methods in Classpath:
diff --git a/doc/www.gnu.org/include/layout.wml b/doc/www.gnu.org/include/layout.wml
index 485b98601..fda795098 100644
--- a/doc/www.gnu.org/include/layout.wml
+++ b/doc/www.gnu.org/include/layout.wml
@@ -128,6 +128,7 @@
<menutitle>External Tools</menutitle>
<menuitem><createlink name="External Packages" url="external.html#packages"></menuitem>
<menuitem><createlink name="ClasspathX" url="http://www.gnu.org/software/classpathx/"></menuitem>
+<menuitem><createlink name="Free Media Project" url="http://fmj.sourceforge.net/"></menuitem>
<menuitem><createlink name="Mauve" url="http://sources.redhat.com/mauve/"></menuitem>
<menuitem><createlink name="Jessie" url="http://www.nongnu.org/jessie/"></menuitem>
<menuitem><createlink name="Jalopy" url="external.html#jalopy"></menuitem>
diff --git a/doc/www.gnu.org/stories.wml b/doc/www.gnu.org/stories.wml
index c01ac1937..e13a95ee1 100644
--- a/doc/www.gnu.org/stories.wml
+++ b/doc/www.gnu.org/stories.wml
@@ -67,7 +67,7 @@ framework, compiles them with GCC, and loads them using a built-in
ELF object file loader.
</project>
-<project url="http://www.ibm.com/developerworks/oss/jikesrvm/" name="Jikes RVM">
+<project url="http://jikesrvm.sourceforge.net/" name="Jikes RVM">
Jikes RVM uses GNU Classpath for all of its libraries. Instructions for using
Classpath are provided in the Jikes RVM user's guide as of the Jikes RVM
release 2.2.1 (4/7/03). Nightly regression tests are run against the latest
@@ -185,9 +185,9 @@ analyze, and change the code for one's purposes.</p>
</entry>
<entry name="IBM's Jikes RVM">
-<createlink url="http://www-124.ibm.com/developerworks/oss/jikesrvm/" name="Jikes RVM"> (the Jikes Research Virtual Machine) provides the research community with a flexible open testbed to prototype virtual machine technologies and experiment with a large variety of design alternatives. The virtual machine infrastructure in the Jikes RVM release was independently developed as part of the Jalapeño research project at the IBM T.J. Watson Research Center.
+<createlink url="http://jikesrvm.sourceforge.net/" name="Jikes RVM"> (the Jikes Research Virtual Machine) provides the research community with a flexible open testbed to prototype virtual machine technologies and experiment with a large variety of design alternatives. The virtual machine infrastructure in the Jikes RVM release was independently developed as part of the Jalapeño research project at the IBM T.J. Watson Research Center.
-<p>[<createlink name="Publications" url="http://www-124.ibm.com/developerworks/oss/jikesrvm/info/papers.shtml">]
+<p>[<createlink name="Publications" url="http://jikesrvm.sourceforge.net/info/papers.shtml">]
</entry>
<entry name="SableVM">
diff --git a/examples/gnu/classpath/examples/swing/Demo.java b/examples/gnu/classpath/examples/swing/Demo.java
index 3a47e0609..0f0b3555e 100644
--- a/examples/gnu/classpath/examples/swing/Demo.java
+++ b/examples/gnu/classpath/examples/swing/Demo.java
@@ -151,6 +151,12 @@ public class Demo
examples.add(new JMenuItem(new PopupAction("Theme Editor",
MetalThemeEditor.createDemoFactory())));
+ examples.add(new JMenuItem(new PopupAction("DocumentFilter",
+ DocumentFilterDemo.createDemoFactory())));
+
+ examples.add(new JMenuItem(new PopupAction("NavigationFilter",
+ NavigationFilterDemo.createDemoFactory())));
+
final JMenuItem vmMenu;
help.add(new JMenuItem("just play with the widgets"));
diff --git a/examples/gnu/classpath/examples/swing/DocumentFilterDemo.java b/examples/gnu/classpath/examples/swing/DocumentFilterDemo.java
new file mode 100644
index 000000000..28dce1c34
--- /dev/null
+++ b/examples/gnu/classpath/examples/swing/DocumentFilterDemo.java
@@ -0,0 +1,289 @@
+/* DpocumentFilterDemo.java -- An example for the DocumentFilter class.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath examples.
+
+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.
+*/
+
+
+package gnu.classpath.examples.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridLayout;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DocumentFilter;
+import javax.swing.text.TextAction;
+
+/**
+ * A demonstration of the <code>javax.swing.text.DocumentFilter</code> class.
+ *
+ * <p>Similar to a dialog in a popular programming IDE the user can insert
+ * a CVS URL into a textfield and the filter will split the components apart
+ * and will put them into the right textfields saving the user a lot of
+ * typing time.</p>
+ *
+ * @author Robert Schuster
+ */
+public class DocumentFilterDemo
+ extends JPanel
+ implements ActionListener
+{
+ JTextField target;
+
+ JTextField host;
+ JTextField repositoryPath;
+ JTextField user;
+ JTextField password;
+ JComboBox connectionType;
+
+ /**
+ * Creates a new demo instance.
+ */
+ public DocumentFilterDemo()
+ {
+ createContent();
+ // initFrameContent() is only called (from main) when running this app
+ // standalone
+ }
+
+ /**
+ * When the demo is run independently, the frame is displayed, so we should
+ * initialise the content panel (including the demo content and a close
+ * button). But when the demo is run as part of the Swing activity board,
+ * only the demo content panel is used, the frame itself is never displayed,
+ * so we can avoid this step.
+ */
+ void initFrameContent()
+ {
+ JPanel closePanel = new JPanel();
+ JButton closeButton = new JButton("Close");
+ closeButton.setActionCommand("CLOSE");
+ closeButton.addActionListener(this);
+ closePanel.add(closeButton);
+ add(closePanel, BorderLayout.SOUTH);
+ }
+
+ private void createContent()
+ {
+ setLayout(new BorderLayout());
+
+ JPanel panel = new JPanel(new GridLayout(7, 2));
+ panel.add(new JLabel("CVS URL:"));
+ panel.add(target = new JTextField(20));
+ target.setBackground(Color.RED);
+
+ panel.add(new JLabel("Host:"));
+ panel.add(host = new JTextField(20));
+
+ panel.add(new JLabel("Repository Path:"));
+ panel.add(repositoryPath = new JTextField(20));
+
+ panel.add(new JLabel("Username:"));
+ panel.add(user = new JTextField(20));
+
+ panel.add(new JLabel("Password:"));
+ panel.add(password = new JTextField(20));
+
+ panel.add(new JLabel("Connection Type:"));
+ panel.add(connectionType = new JComboBox());
+
+ JButton helpButton = new JButton("Help");
+ panel.add(helpButton);
+
+ helpButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ae)
+ {
+ JOptionPane.showMessageDialog(DocumentFilterDemo.this,
+ "Paste a CVS URL into the red " +
+ "textfield.\nIf you do not want to " +
+ "look up a CVS URL yourself click " +
+ "on the 'provide me an example' " +
+ "button.\nThis will paste a proper " +
+ "string into your clipboard.");
+ }
+ });
+
+ JButton exampleButton = new JButton("Provide me an example!");
+ panel.add(exampleButton);
+ exampleButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ae)
+ {
+ try
+ {
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ Clipboard cb = tk.getSystemSelection();
+ StringSelection selection
+ = new StringSelection(":extssh:gnu@cvs.savannah.gnu.org:" +
+ "/cvs/example/project");
+
+ cb.setContents(selection, selection);
+
+ // Confirm success with a beep.
+ tk.beep();
+ }
+ catch (IllegalStateException ise)
+ {
+ JOptionPane.showMessageDialog(DocumentFilterDemo.this,
+ "Clipboard is currently" +
+ " unavailable.",
+ "Error",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+
+ connectionType.addItem("pserver");
+ connectionType.addItem("ext");
+ connectionType.addItem("extssh");
+
+ add(panel);
+
+ AbstractDocument doc = (AbstractDocument) target.getDocument();
+ doc.setDocumentFilter(new CVSFilter());
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getActionCommand().equals("CLOSE"))
+ System.exit(0);
+
+ }
+
+ public static void main(String[] args)
+ {
+ SwingUtilities.invokeLater
+ (new Runnable()
+ {
+ public void run()
+ {
+ DocumentFilterDemo app = new DocumentFilterDemo();
+ app.initFrameContent();
+ JFrame frame = new JFrame("DocumentFilterDemo");
+ frame.getContentPane().add(app);
+ frame.pack();
+ frame.setVisible(true);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+ });
+ }
+
+ /**
+ * Returns a DemoFactory that creates a DocumentFilterDemo.
+ *
+ * @return a DemoFactory that creates a DocumentFilterDemo
+ */
+ public static DemoFactory createDemoFactory()
+ {
+ return new DemoFactory()
+ {
+ public JComponent createDemo()
+ {
+ return new DocumentFilterDemo();
+ }
+ };
+ }
+
+ class CVSFilter extends DocumentFilter
+ {
+ // example: pserver:anonymous@cvs.sourceforge.net:/cvsroot/fmj
+ String cvsPattern = ":?(pserver|ext|extssh):(\\w)+(:(\\w)+)?@(\\w|\\.)+:/(\\w|/)*";
+
+ public void insertString(DocumentFilter.FilterBypass fb,
+ int offset, String string,
+ AttributeSet attr)
+ throws BadLocationException
+ {
+ filterString(fb, offset, 0, string, attr, true);
+ }
+
+ public void replace(DocumentFilter.FilterBypass fb,
+ int offset, int length,
+ String string,
+ AttributeSet attr)
+ throws BadLocationException
+ {
+ filterString(fb, offset, length, string, attr, false);
+ }
+
+ public void filterString(DocumentFilter.FilterBypass fb,
+ int offset, int length, String string,
+ AttributeSet attr, boolean insertion)
+ throws BadLocationException
+ {
+ if(string.matches(cvsPattern))
+ {
+ // Split off the connection type part.
+ String[] result = string.split(":", 2);
+
+ // If the string contained a leading colon, result[0]
+ // will be empty at that point. We simply repeat the split
+ // operation on the remaining string and continue.
+ if(result[0].equals(""))
+ result = result[1].split(":", 2);
+
+ connectionType.setSelectedItem(result[0]);
+
+ // Split off the username and password part
+ result = result[1].split("@", 2);
+
+ // Break username and password in half
+ String[] userCredentials = result[0].split(":");
+ user.setText(userCredentials[0]);
+
+ // If the result has two entries the second one will
+ // be the password.
+ if (userCredentials.length == 2)
+ password.setText(userCredentials[1]);
+
+ // Now break the host part apart.
+ result = result[1].split(":");
+
+ host.setText(result[0]);
+
+ repositoryPath.setText(result[1]);
+ }
+
+ // The unmodified string is put into the document.
+ if (insertion)
+ fb.insertString(offset, string, attr);
+ else
+ fb.replace(offset, length, string, attr);
+ }
+
+ }
+
+}
diff --git a/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java b/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java
new file mode 100644
index 000000000..6c1be74cc
--- /dev/null
+++ b/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java
@@ -0,0 +1,206 @@
+/* NavigationFilterDemo.java -- An example for the NavigationFilter class.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath examples.
+
+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.
+*/
+
+
+package gnu.classpath.examples.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.NavigationFilter;
+import javax.swing.text.Position;
+import javax.swing.text.Utilities;
+
+/**
+ * A demonstration of the <code>javax.swing.text.NavigationFilter</code> class.
+ *
+ * <p>It shows a NavigationFilter which lets you walk word-wise
+ * through a text.</p>
+ *
+ * @author Robert Schuster
+ */
+public class NavigationFilterDemo
+ extends JPanel
+ implements ActionListener
+{
+
+ JTextArea textArea;
+
+ /**
+ * Creates a new demo instance.
+ */
+ public NavigationFilterDemo()
+ {
+ createContent();
+ // initFrameContent() is only called (from main) when running this app
+ // standalone
+ }
+
+ /**
+ * When the demo is run independently, the frame is displayed, so we should
+ * initialise the content panel (including the demo content and a close
+ * button). But when the demo is run as part of the Swing activity board,
+ * only the demo content panel is used, the frame itself is never displayed,
+ * so we can avoid this step.
+ */
+ void initFrameContent()
+ {
+ JPanel closePanel = new JPanel();
+ JButton closeButton = new JButton("Close");
+ closeButton.setActionCommand("CLOSE");
+ closeButton.addActionListener(this);
+ closePanel.add(closeButton);
+ add(closePanel, BorderLayout.SOUTH);
+ }
+
+ private void createContent()
+ {
+ setLayout(new BorderLayout());
+
+ add(textArea = new JTextArea(10, 20));
+
+ textArea.setWrapStyleWord(true);
+
+ textArea.setLineWrap(true);
+
+ textArea.setNavigationFilter(new WordFilter());
+
+ textArea.setText("GNU Classpath, Essential Libraries for Java, " +
+ "is a GNU project to create free core class " +
+ "libraries for use with virtual machines and " +
+ "compilers for the java programming language.");
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getActionCommand().equals("CLOSE"))
+ System.exit(0);
+
+ }
+
+ public static void main(String[] args)
+ {
+ SwingUtilities.invokeLater
+ (new Runnable()
+ {
+ public void run()
+ {
+ NavigationFilterDemo app = new NavigationFilterDemo();
+ app.initFrameContent();
+ JFrame frame = new JFrame("NavigationFilterDemo");
+ frame.getContentPane().add(app);
+ frame.pack();
+ frame.setVisible(true);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+ });
+ }
+
+ /**
+ * Returns a DemoFactory that creates a NavigationFilterDemo.
+ *
+ * @return a DemoFactory that creates a NavigationFilterDemo
+ */
+ public static DemoFactory createDemoFactory()
+ {
+ return new DemoFactory()
+ {
+ public JComponent createDemo()
+ {
+ return new NavigationFilterDemo();
+ }
+ };
+ }
+
+ class WordFilter extends NavigationFilter
+ {
+ public int getNextVisualPositionFrom(JTextComponent text,
+ int pos,
+ Position.Bias bias,
+ int direction,
+ Position.Bias[] biasRet)
+ throws BadLocationException
+ {
+ Point pt;
+
+ int newpos = pos;
+ switch (direction)
+ {
+ case SwingConstants.NORTH:
+ // Find out where the caret want to be positioned ideally.
+ pt = text.getCaret().getMagicCaretPosition();
+
+ // Calculate its position above.
+ newpos = Utilities.getPositionAbove(text, pos, pt.x);
+
+ // If we have a valid position, then calculate the next word start
+ // from there.
+ if (newpos != -1)
+ return Utilities.getWordStart(text, newpos);
+ else
+ return pos;
+ case SwingConstants.SOUTH:
+ // Find out where the caret want to be positioned ideally.
+ pt = text.getCaret().getMagicCaretPosition();
+
+ // Calculate its position below.
+ newpos = Utilities.getPositionBelow(text, pos, pt.x);
+
+ // If we have a valid position, then calculate the next word start
+ // from there.
+ if (newpos != -1)
+ return Utilities.getWordStart(text, newpos);
+ else
+ return pos;
+ case SwingConstants.WEST:
+ // Calculate the next word start.
+ newpos = Utilities.getWordStart(text, newpos);;
+
+ // If that means that the caret will not move, return
+ // the start of the previous word.
+ if (newpos != pos)
+ return newpos;
+ else
+ return Utilities.getPreviousWord(text, newpos);
+ case SwingConstants.EAST:
+ // Simply calculate the next word's start offset.
+ return Utilities.getNextWord(text, newpos);
+ default:
+ // Do whatever the super implementation did.
+ return super.getNextVisualPositionFrom(text, pos, bias,
+ direction, biasRet);
+ }
+ }
+
+ }
+
+}
diff --git a/examples/gnu/classpath/examples/swing/TreeDemo.java b/examples/gnu/classpath/examples/swing/TreeDemo.java
index 9c6c3b87e..32f765f73 100644
--- a/examples/gnu/classpath/examples/swing/TreeDemo.java
+++ b/examples/gnu/classpath/examples/swing/TreeDemo.java
@@ -39,19 +39,27 @@ exception statement from your version. */
package gnu.classpath.examples.swing;
import java.awt.BorderLayout;
+import java.awt.JobAttributes.DefaultSelectionType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import javax.swing.DebugGraphics;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
+import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
public class TreeDemo
extends JPanel
@@ -129,9 +137,10 @@ public class TreeDemo
final JTree tree = new JTree(root);
tree.setLargeModel(true);
tree.setEditable(true);
- DefaultTreeSelectionModel dtsm = new DefaultTreeSelectionModel();
- dtsm.setSelectionMode(DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
- tree.setSelectionModel(dtsm);
+ final DefaultTreeSelectionModel selModel = new DefaultTreeSelectionModel();
+ selModel.setSelectionMode(
+ DefaultTreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+ tree.setSelectionModel(selModel);
// buttons to add and delete
JButton add = new JButton("add element");
@@ -147,21 +156,79 @@ public class TreeDemo
DefaultMutableTreeNode n = (DefaultMutableTreeNode) p.
getLastPathComponent();
n.add(new DefaultMutableTreeNode("New Element"));
- tree.repaint();
+
+ // The expansion state of the parent node does not change
+ // by default. We will expand it manually, to ensure that the
+ // added node is immediately visible.
+ tree.expandPath(p);
+
+ // Refresh the tree (.repaint would be not enough both in
+ // Classpath and Sun implementations).
+ DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
+ model.reload(n);
break;
}
}
}
});
-
-
+
+ // Demonstration of the various selection modes
+ final JCheckBox cbSingle = new JCheckBox("single selection");
+ cbSingle.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ if (cbSingle.isSelected())
+ selModel.setSelectionMode(
+ DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
+ else
+ selModel.setSelectionMode(
+ DefaultTreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+ }
+ });
+
+ // Demonstration of the root visibility changes
+ final JCheckBox cbRoot = new JCheckBox("root");
+ cbRoot.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ tree.setRootVisible(cbRoot.isSelected());
+ }
+ });
+ cbRoot.setSelected(true);
+
+ // Demonstration of the tree selection listener.
+ final JLabel choice = new JLabel("Make a choice");
+ tree.getSelectionModel().addTreeSelectionListener(
+ new TreeSelectionListener()
+ {
+ public void valueChanged(TreeSelectionEvent event)
+ {
+ TreePath was = event.getOldLeadSelectionPath();
+ TreePath now = event.getNewLeadSelectionPath();
+ String swas =
+ was == null ? "none":was.getLastPathComponent().toString();
+ String snow =
+ now == null ? "none":now.getLastPathComponent().toString();
+ choice.setText("From "+swas+" to "+snow);
+ }
+ }
+ );
+
setLayout(new BorderLayout());
JPanel p2 = new JPanel();
p2.add(add);
+ p2.add(cbSingle);
+ p2.add(cbRoot);
+
+ tree.getSelectionModel().
+ setSelectionMode(DefaultTreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
add(p2, BorderLayout.NORTH);
add(new JScrollPane(tree), BorderLayout.CENTER);
+ add(choice, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e)
diff --git a/gnu/classpath/jdwp/util/Value.java b/gnu/classpath/jdwp/util/Value.java
index c73ffef80..414c4a33b 100644
--- a/gnu/classpath/jdwp/util/Value.java
+++ b/gnu/classpath/jdwp/util/Value.java
@@ -1,5 +1,5 @@
/* Value.java -- class to read/write JDWP tagged and untagged values
- Copyright (C) 2005 Free Software Foundation
+ Copyright (C) 2005, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -232,7 +232,7 @@ public class Value
else if (type == short.class)
return new Short(bb.getShort());
else if (type == boolean.class)
- return (bb.get() == 0) ? new Boolean(false) : new Boolean(true);
+ return Boolean.valueOf(bb.get() != 0);
else if (type == void.class)
return new byte[0];
else
diff --git a/gnu/java/awt/font/FontDelegate.java b/gnu/java/awt/font/FontDelegate.java
new file mode 100644
index 000000000..a26510ee2
--- /dev/null
+++ b/gnu/java/awt/font/FontDelegate.java
@@ -0,0 +1,313 @@
+/* FontDelegate.java -- Interface implemented by all font delegates.
+ 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;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
+import java.util.Locale;
+
+
+/**
+ * The interface that all font delegate objects implement,
+ * irrespective of where they get their information from.
+ *
+ * <p><b>Thread Safety:</b> All classes that implement the
+ * <code>FontDelegate</code> interface must allow calling these
+ * methods from multiple concurrent threads. The delegates are
+ * responsible for performing the necessary synchronization.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public interface FontDelegate
+{
+ /**
+ * Returns the full name of this font face in the specified
+ * locale, for example <i>&#x201c;Univers Light&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the face name.
+ */
+ public String getFullName(Locale locale);
+
+
+ /**
+ * Returns the name of the family to which this font face belongs,
+ * for example <i>&#x201c;Univers&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the family name.
+ */
+ public String getFamilyName(Locale locale);
+
+
+ /**
+ * Returns the name of this font face inside the family, for example
+ * <i>&#x201c;Light&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the name of the face inside its family.
+ */
+ public String getSubFamilyName(Locale locale);
+
+
+ /**
+ * Returns the PostScript name of this font face, for example
+ * <i>&#x201c;Helvetica-Bold&#x201d;</i>.
+ *
+ * @return the PostScript name, or <code>null</code> if the font
+ * does not provide a PostScript name.
+ */
+ public String getPostScriptName();
+
+
+ /**
+ * Returns the number of glyphs in this font face.
+ */
+ public int getNumGlyphs();
+
+
+ /**
+ * Returns the index of the glyph which gets displayed if the font
+ * cannot map a Unicode code point to a glyph. Many fonts show this
+ * glyph as an empty box.
+ */
+ public int getMissingGlyphCode();
+
+
+ /**
+ * Creates a GlyphVector by mapping each character in a
+ * CharacterIterator to the corresponding glyph.
+ *
+ * <p>The mapping takes only the font&#x2019;s <code>cmap</code>
+ * tables into consideration. No other operations (such as glyph
+ * re-ordering, composition, or ligature substitution) are
+ * performed. This means that the resulting GlyphVector will not be
+ * correct for text in languages that have complex
+ * character-to-glyph mappings, such as Arabic, Hebrew, Hindi, or
+ * Thai.
+ *
+ * @param font the font object that the created GlyphVector
+ * will return when it gets asked for its font. This argument is
+ * needed because the public API works with java.awt.Font,
+ * not with some private delegate like OpenTypeFont.
+ *
+ * @param frc the font rendering parameters that are used for
+ * measuring glyphs. The exact placement of text slightly depends on
+ * device-specific characteristics, for instance the device
+ * resolution or anti-aliasing. For this reason, any measurements
+ * will only be accurate if the passed
+ * <code>FontRenderContext</code> correctly reflects the relevant
+ * parameters. Hence, <code>frc</code> should be obtained from the
+ * same <code>Graphics2D</code> that will be used for drawing, and
+ * any rendering hints should be set to the desired values before
+ * obtaining <code>frc</code>.
+ *
+ * @param ci a CharacterIterator for iterating over the
+ * characters to be displayed.
+ */
+ public GlyphVector createGlyphVector(Font font,
+ FontRenderContext frc,
+ CharacterIterator ci);
+
+
+ /**
+ * Determines the advance width and height for a glyph.
+ *
+ * @param glyphIndex the glyph whose advance width is to be
+ * determined.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @param advance a point whose <code>x</code> and <code>y</code>
+ * fields will hold the advance in each direction. It is well
+ * possible that both values are non-zero, for example for rotated
+ * text or for Urdu fonts.
+ */
+ public void getAdvance(int glyphIndex,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal,
+ Point2D advance);
+
+
+ /**
+ * Returns the shape of a glyph.
+ *
+ * @param glyphIndex the glyph whose advance width is to be
+ * determined.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts, this
+ * parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional
+ * metrics, <code>false</code> for rounding the result to a pixel
+ * boundary.
+ *
+ * @return the scaled and grid-fitted outline of the specified
+ * glyph, or <code>null</code> for bitmap fonts.
+ */
+ public GeneralPath getGlyphOutline(int glyphIndex,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics);
+
+
+ /**
+ * Returns a name for the specified glyph. This is useful for
+ * generating PostScript or PDF files that embed some glyphs of a
+ * font.
+ *
+ * <p><b>Names are not unique:</b> Under some rare circumstances,
+ * the same name can be returned for different glyphs. It is
+ * therefore recommended that printer drivers check whether the same
+ * name has already been returned for antoher glyph, and make the
+ * name unique by adding the string ".alt" followed by the glyph
+ * index.</p>
+ *
+ * <p>This situation would occur for an OpenType or TrueType font
+ * that has a <code>post</code> table of format 3 and provides a
+ * mapping from glyph IDs to Unicode sequences through a
+ * <code>Zapf</code> table. If the same sequence of Unicode
+ * codepoints leads to different glyphs (depending on contextual
+ * position, for example, or on typographic sophistication level),
+ * the same name would get synthesized for those glyphs.
+ *
+ * @param glyphIndex the glyph whose name the caller wants to
+ * retrieve.
+ */
+ public String getGlyphName(int glyphIndex);
+
+
+ /**
+ * Determines the distance between the base line and the highest
+ * ascender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the ascent, which usually is a positive number.
+ */
+ public float getAscent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal);
+
+
+ /**
+ * Determines the distance between the base line and the lowest
+ * descender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the descent, which usually is a nagative number.
+ */
+ public float getDescent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal);
+}
diff --git a/gnu/java/awt/font/FontFactory.java b/gnu/java/awt/font/FontFactory.java
new file mode 100644
index 000000000..6c1084eef
--- /dev/null
+++ b/gnu/java/awt/font/FontFactory.java
@@ -0,0 +1,90 @@
+/* FontFactory.java -- Factory for font delegates.
+ 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;
+
+import java.nio.ByteBuffer;
+
+import java.awt.FontFormatException;
+import gnu.java.awt.font.opentype.OpenTypeFontFactory;
+
+
+/**
+ * A factory for creating font delegate objects.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class FontFactory
+{
+ /**
+ * The constructor is private so nobody can construct an instance
+ */
+ private FontFactory()
+ {
+ }
+
+
+ /**
+ * Creates FontDelegate objects for the fonts in the specified buffer.
+ * The following font formats are currently recognized:
+ * recognized font formats are:
+ *
+ * <p><ul>
+ * <li>OpenType (*.otf);</li>
+ * <li>TrueType (*.ttf);</li>
+ * <li>TrueType Collections (*.ttc);</li>
+ * <li>Apple MacOS X data-fork font (*.dfont).</li></ul>
+ *
+ * <p>Some formats may contain more than a single font, for example
+ * *.ttc and *.dfont files. This is the reason why this function
+ * returns an array.
+ *
+ * <p>The implementation reads data from the buffer only when
+ * needed. Therefore, it greatly increases efficiency if
+ * <code>buf</code> has been obtained through mapping a file into
+ * the virtual address space.
+ *
+ * @throws FontFormatException if the font data is not in one of the
+ * known formats.
+ */
+ public static FontDelegate[] createFonts(ByteBuffer buf)
+ throws FontFormatException
+ {
+ return OpenTypeFontFactory.createFonts(buf);
+ }
+}
diff --git a/gnu/java/awt/font/GNUGlyphVector.java b/gnu/java/awt/font/GNUGlyphVector.java
new file mode 100644
index 000000000..9688698de
--- /dev/null
+++ b/gnu/java/awt/font/GNUGlyphVector.java
@@ -0,0 +1,596 @@
+/* GNUGlyphVector.java -- The GNU implementation of GlyphVector.
+ 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;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphVector;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+
+/**
+ * The GNU implementation of the abstract GlyphVector class, which
+ * uses the services provided by a FontDelegate for its functionality.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public class GNUGlyphVector
+ extends GlyphVector
+{
+ private FontDelegate fontDelegate;
+ private Font font;
+ private FontRenderContext renderContext;
+ private int[] glyphs;
+ private float fontSize;
+ private AffineTransform transform;
+ private boolean valid;
+
+
+ /**
+ * The position of each glyph. The horizontal position of the
+ * <code>i</code>-th glyph is at <code>pos[i * 2]</code>, its
+ * vertical position at <code>pos[i * 2 + 1]</code>. The total
+ * advance width of the entire vector is stored at
+ * <code>pos[numGlyphs]</code>, the total advance height at
+ * <code>pos[numGlyphs + 1]</code>.
+ */
+ private float[] pos;
+
+
+ private AffineTransform[] transforms;
+ private int layoutFlags;
+
+
+ /**
+ * Constructs a new GNUGlyphVector.
+ *
+ * @param fontDelegate the FontDelegate that creates this vector.
+ *
+ * @param font the Font that this GlyphVector will return for {@link
+ * #getFont()}. That object is also used to determine the point
+ * size, which affects the affine transformation used by the font
+ * scaler.
+ *
+ * @param renderContext an object with parameters for font
+ * rendering, such as whether anti-aliasing is enabled.
+ *
+ * @param glyphs the glyphs in this vector.
+ */
+ public GNUGlyphVector(FontDelegate fontDelegate,
+ Font font,
+ FontRenderContext renderContext,
+ int[] glyphs)
+ {
+ this.fontDelegate = fontDelegate;
+ this.font = font;
+ this.renderContext = renderContext;
+ this.glyphs = glyphs;
+
+ fontSize = font.getSize2D();
+ transform = font.getTransform(); // returns a modifiable copy
+ transform.concatenate(renderContext.getTransform());
+ }
+
+
+
+ /**
+ * Returns the font of the glyphs in this GlyphVector.
+ */
+ public Font getFont()
+ {
+ return font;
+ }
+
+
+ /**
+ * Returns the FontRenderContext that is used to calculate the
+ * extent and position of the glyphs.
+ */
+ public FontRenderContext getFontRenderContext()
+ {
+ return renderContext;
+ }
+
+
+ /**
+ * Moves each glyph in the vector to its default position.
+ */
+ public void performDefaultLayout()
+ {
+ float x, y, advanceWidth, advanceHeight;
+ int i, p;
+ AffineTransform tx;
+ Point2D.Float advance = new Point2D.Float();
+
+ pos = new float[(glyphs.length + 1) * 2];
+ x = y = 0.0f;
+ p = 0;
+ for (i = p = 0; i < glyphs.length; i++)
+ {
+ p += 2;
+
+ if ((transforms == null) || (tx = transforms[i]) == null)
+ tx = this.transform;
+ else
+ {
+ tx = new AffineTransform(tx);
+ tx.concatenate(this.transform);
+ }
+
+ fontDelegate.getAdvance(glyphs[i], fontSize, tx,
+ renderContext.isAntiAliased(),
+ renderContext.usesFractionalMetrics(),
+ /* horizontal */ true,
+ advance);
+ pos[p] = x += advance.x;
+ pos[p + 1] = y += advance.y;
+ }
+ valid = true;
+ }
+
+
+ /**
+ * Determines the number of glyphs in this GlyphVector.
+ */
+ public int getNumGlyphs()
+ {
+ return glyphs.length;
+ }
+
+
+ /**
+ * Determines the glyph number by index in this vector.
+ * Glyph numbers are specific to each font, so two fonts
+ * will likely assign different numbers to the same glyph.
+ *
+ * @param glyphIndex the index of the glyph whose glyph number is to
+ * be retrieved.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code>
+ * is not in the range <code[0 .. getNumGlyphs() - 1]</code>.
+ */
+ public int getGlyphCode(int glyphIndex)
+ {
+ /* The exception is thrown automatically if the index is out
+ * of the valid bounds.
+ */
+ return glyphs[glyphIndex];
+ }
+
+
+ /**
+ * Returns a slice of this GlyphVector.
+ *
+ * @param firstGlyphIndex the index of the first glyph in the
+ * returned slice.
+ *
+ * @param numEntries the size of the returned slice.
+ *
+ * @param outCodes a pre-allocated array for storing the slice,
+ * or <code>null</code> to cause allocation of a new array.
+ *
+ * @return a slice of this GlyphVector. If <code>outCodes</code>
+ * is <code>null</code>, the slice will be stored into a freshly
+ * allocated array; otherwise, the result will be stored into
+ * <code>outCodes</code>.
+ */
+ public int[] getGlyphCodes(int firstGlyphIndex,
+ int numEntries,
+ int[] outCodes)
+ {
+ if (numEntries < 0)
+ throw new IllegalArgumentException();
+ if (outCodes == null)
+ outCodes = new int[numEntries];
+ System.arraycopy(glyphs, firstGlyphIndex, outCodes, 0, numEntries);
+ return outCodes;
+ }
+
+
+ public Rectangle2D getLogicalBounds()
+ {
+ float ascent, descent;
+
+ validate();
+
+ return new Rectangle2D.Float(0, 0,
+ pos[pos.length - 2],
+ getAscent() - getDescent());
+ }
+
+
+ public Rectangle2D getVisualBounds()
+ {
+ validate();
+
+ // FIXME: Not yet implemented.
+ return getLogicalBounds();
+ }
+
+
+ /**
+ * Returns the shape of this GlyphVector.
+ */
+ public Shape getOutline()
+ {
+ validate();
+ return getOutline(0.0f, 0.0f);
+ }
+
+
+ /**
+ * Returns the shape of this GlyphVector, translated to the
+ * specified position.
+ *
+ * @param x the horizontal position for rendering this vector.
+ * @param y the vertical position for rendering this vector.
+ */
+ public Shape getOutline(float x, float y)
+ {
+ validate();
+
+ GeneralPath outline = new GeneralPath();
+ int len = glyphs.length;
+ for (int i = 0; i < len; i++)
+ {
+ GeneralPath p = new GeneralPath(getGlyphOutline(i));
+ outline.append(p, false);
+ }
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ outline.transform(t);
+ return outline;
+ }
+
+
+ /**
+ * Determines the shape of the specified glyph.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs()]</code>.
+ */
+ public Shape getGlyphOutline(int glyphIndex)
+ {
+ 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());
+
+ 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
+ * total advance width and height of the vector.
+ *
+ * @param glyphIndex the index of the glyph in question.
+ * If this value equals <code>getNumGlyphs()</code>, the
+ * position <i>after</i> the last glyph will be returned,
+ * which is the total advance width and height of the vector.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs()]</code>.
+ */
+ public Point2D getGlyphPosition(int glyphIndex)
+ {
+ validate();
+ return new Point2D.Float(pos[glyphIndex * 2],
+ pos[glyphIndex * 2 + 1]);
+ }
+
+
+ /**
+ * Moves the specified glyph to a new position, or changes the
+ * advance width and height of the entire glyph vector.
+ *
+ * <p>Note that the position of an individual glyph may also
+ * affected by its affine transformation.
+ *
+ * @param glyphIndex the index of the moved glyph. If
+ * <code>glyphIndex</code> equals the total number of glyphs in this
+ * vector, the advance width and height of the vector is changed.
+ *
+ * @param position the new position of the glyph.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs()]</code>.
+ */
+ public void setGlyphPosition(int glyphIndex, Point2D position)
+ {
+ validate();
+ pos[glyphIndex * 2] = (float) position.getX();
+ pos[glyphIndex * 2 + 1] = (float) position.getY();
+ }
+
+
+ /**
+ * Returns the affine transformation that is applied to the
+ * glyph at the specified index.
+ *
+ * @param glyphIndex the index of the glyph whose transformation
+ * is to be retrieved.
+ *
+ * @return an affine transformation, or <code>null</code>
+ * for the identity transformation.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
+ */
+ public AffineTransform getGlyphTransform(int glyphIndex)
+ {
+ if (transforms == null)
+ return null;
+ else
+ return transforms[glyphIndex];
+ }
+
+
+ /**
+ * Applies an affine transformation to the glyph at the specified
+ * index.
+ *
+ * @param glyphIndex the index of the glyph to which the
+ * transformation is applied.
+ *
+ * @param transform the affine transformation for the glyph, or
+ * <code>null</code> for an identity transformation.
+ */
+ public void setGlyphTransform(int glyphIndex,
+ AffineTransform transform)
+ {
+ if (transforms == null)
+ transforms = new AffineTransform[glyphs.length];
+ transforms[glyphIndex] = transform;
+
+ /* If the GlyphVector has only a transform for a single glyph, and
+ * the caller clears its transform, the FLAG_HAS_TRANSFORMS bit
+ * should be cleared in layoutFlags. However, this would require
+ * that we keep track of the number of transformed glyphs, or that
+ * we count them when a transform is cleared. This would
+ * complicate the code quite a bit. Note that the only drawback of
+ * wrongly setting FLAG_HAS_TRANSFORMS is that a slower code path
+ * might be taken for rendering the vector. Right now, we never
+ * really look at the flag, so it does not make any difference.
+ */
+ if (transform != null)
+ layoutFlags |= FLAG_HAS_TRANSFORMS;
+ valid = false;
+ }
+
+
+ /**
+ * Returns flags that can be used for optimizing the rendering
+ * of this GlyphVector.
+ *
+ * @return a bit mask with the applicable flags set.
+ *
+ * @since 1.4
+ *
+ * @see GlyphVector#FLAG_HAS_POSITION_ADJUSTMENTS
+ * @see GlyphVector#FLAG_HAS_TRANSFORMS
+ * @see GlyphVector#FLAG_RUN_RTL
+ * @see GlyphVector#FLAG_COMPLEX_GLYPHS
+ * @see GlyphVector#FLAG_MASK
+ */
+ public int getLayoutFlags()
+ {
+ return layoutFlags;
+ }
+
+
+ /**
+ * Returns the positions of a range of glyphs in this vector.
+ *
+ * @param firstGlyphIndex the index of the first glyph whose
+ * position is retrieved.
+ *
+ * @param numGlyphs the number of glyphs whose positions
+ * are retrieved.
+ *
+ * @param outPositions an array for storing the results
+ * (the length must be at least twice <code>numGlyphs</code>),
+ * or <code>null</code> for freshly allocating an array.
+ *
+ * @return an array with the glyph positions. The horizontal
+ * position of the <code>i</code>-th glyph is at index <code>2 *
+ * i</code>, the vertical position at index <code>2 * i + 1</code>.
+ *
+ * @throws IllegalArgumentException if <code>numGlyphs</code>
+ * is less than zero.
+ *
+ * @throws IndexOutOfBoundsException if either
+ * <code>firstGlyphIndex</code> or <code>(firstGlyphIndex +
+ * numGlyphs)</code> is not in the range <code>[0 .. getNumGlyphs() -
+ * 1]</code>.
+ */
+ public float[] getGlyphPositions(int firstGlyphIndex,
+ int numGlyphs,
+ float[] outPositions)
+ {
+ if (numGlyphs < 0)
+ throw new IllegalArgumentException();
+
+ validate();
+ if (outPositions == null)
+ outPositions = new float[numGlyphs * 2];
+
+ System.arraycopy(/*src */ pos, /* srcStart */ firstGlyphIndex * 2,
+ /* dest */ outPositions, /* destStart */ 0,
+ /* length */ numGlyphs * 2);
+ return outPositions;
+ }
+
+
+ private float getAscent()
+ {
+ return fontDelegate.getAscent(fontSize, transform,
+ renderContext.isAntiAliased(),
+ renderContext.usesFractionalMetrics(),
+ /* horizontal */ true);
+ }
+
+
+ private float getDescent()
+ {
+ return fontDelegate.getDescent(fontSize, transform,
+ renderContext.isAntiAliased(),
+ renderContext.usesFractionalMetrics(),
+ /* horizontal */ true);
+ }
+
+
+ public Shape getGlyphLogicalBounds(int glyphIndex)
+ {
+ float x, y, ascent;
+
+ validate();
+ ascent = getAscent();
+ x = pos[glyphIndex * 2];
+ y = pos[glyphIndex * 2 + 1];
+
+ return new Rectangle2D.Float(x, y - ascent,
+ pos[(glyphIndex + 1) * 2] - x,
+ ascent - getDescent());
+ }
+
+
+ public Shape getGlyphVisualBounds(int glyphIndex)
+ {
+ return getGlyphOutline(glyphIndex).getBounds2D();
+ }
+
+
+ /**
+ * Determines the metrics of the glyph at the specified index.
+ *
+ * @param glyphIndex the index of the glyph whose metrics is to be
+ * retrieved.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
+ */
+ public GlyphMetrics getGlyphMetrics(int glyphIndex)
+ {
+ // FIXME: Not yet implemented.
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
+ * Determines the justification information for the glyph at the
+ * specified index.
+ *
+ * @param glyphIndex the index of the glyph whose justification
+ * information is to be retrieved.
+ *
+ * @throws IndexOutOfBoundsException if <code>glyphIndex</code> is
+ * not in the range <code[0 .. getNumGlyphs() - 1]</code>.
+ */
+ public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex)
+ {
+ // FIXME: Not yet implemented.
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
+ * Determines whether another GlyphVector is for the same font and
+ * rendering context, uses the same glyphs and positions them to the
+ * same location.
+ *
+ * @param other the GlyphVector to compare with.
+ *
+ * @return <code>true</code> if the two vectors are equal,
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(GlyphVector other)
+ {
+ GNUGlyphVector o;
+ if (!(other instanceof GNUGlyphVector))
+ return false;
+
+ o = (GNUGlyphVector) other;
+ if ((this.font != o.font)
+ || (this.fontDelegate != o.fontDelegate)
+ || (this.renderContext != o.renderContext)
+ || (this.glyphs.length != o.glyphs.length))
+ return false;
+
+ for (int i = 0; i < glyphs.length; i++)
+ if (this.glyphs[i] != o.glyphs[i])
+ return false;
+
+ validate();
+ o.validate();
+ for (int i = 0; i < pos.length; i++)
+ if (this.pos[i] != o.pos[i])
+ return false;
+
+ return true;
+ }
+
+ private void validate()
+ {
+ if (!valid)
+ performDefaultLayout();
+ }
+}
diff --git a/gnu/java/awt/font/opentype/CharGlyphMap.java b/gnu/java/awt/font/opentype/CharGlyphMap.java
new file mode 100644
index 000000000..6ada3b147
--- /dev/null
+++ b/gnu/java/awt/font/opentype/CharGlyphMap.java
@@ -0,0 +1,1027 @@
+/* CharGlyphMap.java -- Manages the 'cmap' table of TrueType fonts
+ 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 java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.ShortBuffer;
+import java.nio.IntBuffer;
+
+
+/**
+ * A mapping from Unicode codepoints to glyphs. This mapping
+ * does not perform any re-ordering or decomposition, so it
+ * is not everything that is needed to support Unicode.
+ *
+ * <p>This class manages the <code>cmap</code> table of
+ * OpenType and TrueType fonts.
+ *
+ * @see <a href="http://partners.adobe.com/asn/tech/type/opentype/cmap.jsp">
+ * the <code>cmap</code> part of Adobe&#x2019; OpenType Specification</a>
+ *
+ * @see <a href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html">
+ * the <code>cmap</code> section of Apple&#x2019;s TrueType Reference
+ * Manual</a>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+abstract class CharGlyphMap
+{
+ private static final int PLATFORM_UNICODE = 0;
+ private static final int PLATFORM_MACINTOSH = 1;
+ private static final int PLATFORM_MICROSOFT = 3;
+
+
+ /**
+ * Determines the glyph index for a given Unicode codepoint. Users
+ * should be aware that the character-to-glyph mapping not not
+ * everything that is needed for full Unicode support. For example,
+ * the <code>cmap</code> table is not able to synthesize accented
+ * glyphs from the canonical decomposition sequence, even if the
+ * font would contain a glyph for the composed form.
+ *
+ * @param ucs4 the Unicode codepoint in UCS-4 encoding. Surrogates
+ * (U+D800 to U+DFFF) cannot be passed, they must be mapped to
+ * UCS-4 first.
+ *
+ * @return the glyph index, or 0 if the font does not contain
+ * a glyph for this codepoint.
+ */
+ public abstract int getGlyph(int ucs4);
+
+
+ /**
+ * Reads a CharGlyphMap from an OpenType or TrueType <code>cmap</code>
+ * table. The current implementation works as follows:
+ *
+ * <p><ol><li>If the font has a type 4 cmap for the Unicode platform
+ * (encoding 0, 1, 2, 3 or 4), or a type 4 cmap for the Microsoft
+ * platform (encodings 1 or 10), that table is used to map Unicode
+ * codepoints to glyphs. Most recent fonts, both for Macintosh and
+ * Windows, should provide such a table.</li>
+ *
+ * <li>Otherwise, if the font has any type 0 cmap for the Macintosh
+ * platform, a Unicode-to-glyph mapping is synthesized from certain
+ * type 0 cmaps. The current implementation collects mappings from
+ * Roman, Icelandic, Turkish, Croatian, Romanian, Eastern European,
+ * Cyrillic, Greek, Hebrew, Arabic and Farsi cmaps.</li>.</ol>
+ *
+ * @param buf a buffer whose position is right at the start
+ * of the entire <code>cmap</code> table, and whose limit
+ * is at its end.
+ *
+ * @return a concrete subclass of <code>CharGlyphMap</code>
+ * that performs the mapping.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/opentype/cmap.jsp"
+ * >the <code>cmap</code> part of Adobe&#x2019; OpenType Specification</a>
+ *
+ * @see <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html"
+ * >the <code>cmap</code> section of Apple&#x2019;s TrueType Reference
+ * Manual</a>
+ */
+ public static CharGlyphMap forTable(ByteBuffer buf)
+ {
+ boolean hasType0 = false;
+ int start4 = -1, platform4 = 0, encoding4 = 0;
+ int start12 = -1, platform12 = 0, encoding12 = 0;
+ int version;
+ int numTables;
+ int tableStart = buf.position();
+ int limit = buf.limit();
+ int format, platform, language, encoding, length, offset;
+
+ version = buf.getChar();
+ if (version != 0)
+ return null;
+
+ numTables = buf.getChar();
+ for (int i = 0; i < numTables; i++)
+ {
+ buf.limit(limit).position(tableStart + 4 + i * 8);
+ platform = buf.getChar();
+ encoding = buf.getChar();
+ offset = tableStart + buf.getInt();
+
+ buf.position(offset);
+ format = buf.getChar();
+
+ switch (format)
+ {
+ case 0:
+ hasType0 = true;
+ break;
+
+ case 4:
+ length = buf.getChar();
+ language = buf.getChar();
+ if ((start4 == -1)
+ && Type4.isSupported(platform, language, encoding))
+ {
+ start4 = offset;
+ platform4 = platform;
+ encoding4 = encoding;
+ }
+ break;
+
+ case 12:
+ if ((start12 == -1) && Type12.isSupported(platform, encoding))
+ {
+ start12 = offset;
+ platform12 = platform;
+ encoding12 = encoding;
+ }
+ break;
+ }
+ }
+
+
+ if (start12 >= 0)
+ {
+ try
+ {
+ buf.limit(limit).position(start12);
+ return new Type12(buf, platform12, encoding12);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ if (start4 >= 0)
+ {
+ try
+ {
+ buf.limit(limit).position(start4);
+ return Type4.readTable(buf, platform4, encoding4);
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ if (hasType0)
+ {
+ try
+ {
+ buf.limit(limit).position(tableStart);
+ return new Type0(buf);
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ return new Dummy();
+ }
+
+
+ /**
+ * A dummy mapping that maps anything to the undefined glyph.
+ * Used if no other cmap is understood in a font.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static final class Dummy
+ extends CharGlyphMap
+ {
+ public int getGlyph(int ucs4)
+ {
+ return 0;
+ }
+ }
+
+
+ /**
+ * A mapping from Unicode code points to glyph IDs through CMAP Type
+ * 0 tables. These tables have serious limitations: Only the first
+ * 256 glyphs can be addressed, and the source of the mapping is not
+ * Unicode, but an encoding used on the Macintosh.
+ *
+ * <p>However, some fonts have only a Type 0 cmap. In this case, we
+ * process all the Type 0 tables we understand, and establish
+ * a reversed glyph-to-Unicode mapping. When a glyph is requested
+ * for a given Unicode character, we perform a linear search on the
+ * reversed table to find the glyph which maps to the requested
+ * character. While not blazingly fast, this gives a reasonable
+ * fallback for old fonts.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static final class Type0
+ extends CharGlyphMap
+ {
+ /**
+ * An array whose <code>i</code>-th element indicates the
+ * Unicode code point of glyph <code>i</code> in the font.
+ */
+ private char[] glyphToUCS2 = new char[256];
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Arabic encoding.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ARABIC.TXT"
+ * >the Unicode mapping table for the MacOS Arabic encoding</a>
+ */
+ private static final String UPPER_ARABIC
+ = "\u007e\u0000\u00c4\u00a0\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u06ba\u00ab\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u2026\u00ee\u00ef\u00f1\u00f3\u00bb\u00f4\u00f6\u00f7"
+ + "\u00fa\u00f9\u00fb\u00fc\u0020\u0021\"\u0023\u0024\u066a"
+ + "\u0026\u0027\u0028\u0029\u002a\u002b\u060c\u002d\u002e\u002f"
+ + "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669"
+ + "\u003a\u061b\u003c\u003d\u003e\u061f\u274a\u0621\u0622\u0623"
+ + "\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d"
+ + "\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637"
+ + "\u0638\u0639\u063a\u005b\\\u005d\u005e\u005f\u0640\u0641"
+ + "\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b"
+ + "\u064c\u064d\u064e\u064f\u0650\u0651\u0652\u067e\u0679\u0686"
+ + "\u06d5\u06a4\u06af\u0688\u0691\u007b\u007c\u007d\u0698\u06d2";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS East European Roman encoding.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CENTEURO.TXT"
+ * >the Unicode mapping table for the MacOS Central European
+ * encoding</a>
+ */
+ private static final String UPPER_EAST_EUROPEAN_ROMAN
+ = "\u007e\u0000\u00c4\u0100\u0101\u00c9\u0104\u00d6\u00dc\u00e1"
+ + "\u0105\u010c\u00e4\u010d\u0106\u0107\u00e9\u0179\u017a\u010e"
+ + "\u00ed\u010f\u0112\u0113\u0116\u00f3\u0117\u00f4\u00f6\u00f5"
+ + "\u00fa\u011a\u011b\u00fc\u2020\u00b0\u0118\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u00a9\u2122\u0119\u00a8\u2260\u0123\u012e"
+ + "\u012f\u012a\u2264\u2265\u012b\u0136\u2202\u2211\u0142\u013b"
+ + "\u013c\u013d\u013e\u0139\u013a\u0145\u0146\u0143\u00ac\u221a"
+ + "\u0144\u0147\u2206\u00ab\u00bb\u2026\u00a0\u0148\u0150\u00d5"
+ + "\u0151\u014c\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\u014d\u0154\u0155\u0158\u2039\u203a\u0159\u0156\u0157\u0160"
+ + "\u201a\u201e\u0161\u015a\u015b\u00c1\u0164\u0165\u00cd\u017d"
+ + "\u017e\u016a\u00d3\u00d4\u016b\u016e\u00da\u016f\u0170\u0171"
+ + "\u0172\u0173\u00dd\u00fd\u0137\u017b\u0141\u017c\u0122\u02c7";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Roman encoding for the Croatian language.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CROATIAN.TXT"
+ * >the Unicode mapping table for the MacOS Croatian encoding</a>
+ */
+ private static final String UPPER_CROATIAN
+ = "\u007e\u0000\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u0160\u2122\u00b4\u00a8\u2260\u017d\u00d8"
+ + "\u221e\u00b1\u2264\u2265\u2206\u00b5\u2202\u2211\u220f\u0161"
+ + "\u222b\u00aa\u00ba\u03a9\u017e\u00f8\u00bf\u00a1\u00ac\u221a"
+ + "\u0192\u2248\u0106\u00ab\u010c\u2026\u00a0\u00c0\u00c3\u00d5"
+ + "\u0152\u0153\u0110\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\uf8ff\u00a9\u2044\u20ac\u2039\u203a\u00c6\u00bb\u2013\u00b7"
+ + "\u201a\u201e\u2030\u00c2\u0107\u00c1\u010d\u00c8\u00cd\u00ce"
+ + "\u00cf\u00cc\u00d3\u00d4\u0111\u00d2\u00da\u00db\u00d9\u0131"
+ + "\u02c6\u02dc\u00af\u03c0\u00cb\u02da\u00b8\u00ca\u00e6\u02c7";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Cyrillic encoding.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT"
+ * >the Unicode mapping table for the MacOS Cyrillic encoding</a>
+ */
+ private static final String UPPER_CYRILLIC
+ = "\u007e\u0000\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417"
+ + "\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421"
+ + "\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b"
+ + "\u042c\u042d\u042e\u042f\u2020\u00b0\u0490\u00a3\u00a7\u2022"
+ + "\u00b6\u0406\u00ae\u00a9\u2122\u0402\u0452\u2260\u0403\u0453"
+ + "\u221e\u00b1\u2264\u2265\u0456\u00b5\u0491\u0408\u0404\u0454"
+ + "\u0407\u0457\u0409\u0459\u040a\u045a\u0458\u0405\u00ac\u221a"
+ + "\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u040b\u045b\u040c"
+ + "\u045c\u0455\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u201e"
+ + "\u040e\u045e\u040f\u045f\u2116\u0401\u0451\u044f\u0430\u0431"
+ + "\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b"
+ + "\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445"
+ + "\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u20ac";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Arabic encoding with the Farsi language.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/FARSI.TXT"
+ * >the Unicode mapping table for the MacOS Farsi encoding</a>
+ */
+ private static final String UPPER_FARSI
+ = "\u007e\u0000\u00c4\u00a0\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u06ba\u00ab\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u2026\u00ee\u00ef\u00f1\u00f3\u00bb\u00f4\u00f6\u00f7"
+ + "\u00fa\u00f9\u00fb\u00fc\u0020\u0021\"\u0023\u0024\u066a"
+ + "\u0026\u0027\u0028\u0029\u002a\u002b\u060c\u002d\u002e\u002f"
+ + "\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9"
+ + "\u003a\u061b\u003c\u003d\u003e\u061f\u274a\u0621\u0622\u0623"
+ + "\u0624\u0625\u0626\u0627\u0628\u0629\u062a\u062b\u062c\u062d"
+ + "\u062e\u062f\u0630\u0631\u0632\u0633\u0634\u0635\u0636\u0637"
+ + "\u0638\u0639\u063a\u005b\\\u005d\u005e\u005f\u0640\u0641"
+ + "\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b"
+ + "\u064c\u064d\u064e\u064f\u0650\u0651\u0652\u067e\u0679\u0686"
+ + "\u06d5\u06a4\u06af\u0688\u0691\u007b\u007c\u007d\u0698\u06d2";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Greek encoding.
+ *
+ * @see <a
+ * href="http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/GREEK.TXT"
+ * >the Unicode mapping table for the MacOS Greek encoding</a>
+ */
+ private static final String UPPER_GREEK
+ = "\u007e\u0000\u00c4\u00b9\u00b2\u00c9\u00b3\u00d6\u00dc\u0385"
+ + "\u00e0\u00e2\u00e4\u0384\u00a8\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00a3\u2122\u00ee\u00ef\u2022\u00bd\u2030\u00f4\u00f6\u00a6"
+ + "\u20ac\u00f9\u00fb\u00fc\u2020\u0393\u0394\u0398\u039b\u039e"
+ + "\u03a0\u00df\u00ae\u00a9\u03a3\u03aa\u00a7\u2260\u00b0\u00b7"
+ + "\u0391\u00b1\u2264\u2265\u00a5\u0392\u0395\u0396\u0397\u0399"
+ + "\u039a\u039c\u03a6\u03ab\u03a8\u03a9\u03ac\u039d\u00ac\u039f"
+ + "\u03a1\u2248\u03a4\u00ab\u00bb\u2026\u00a0\u03a5\u03a7\u0386"
+ + "\u0388\u0153\u2013\u2015\u201c\u201d\u2018\u2019\u00f7\u0389"
+ + "\u038a\u038c\u038e\u03ad\u03ae\u03af\u03cc\u038f\u03cd\u03b1"
+ + "\u03b2\u03c8\u03b4\u03b5\u03c6\u03b3\u03b7\u03b9\u03be\u03ba"
+ + "\u03bb\u03bc\u03bd\u03bf\u03c0\u03ce\u03c1\u03c3\u03c4\u03b8"
+ + "\u03c9\u03c2\u03c7\u03c5\u03b6\u03ca\u03cb\u0390\u03b0\u00ad";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Hebrew encoding.
+ *
+ * <p>The codepoint 0x81 (HEBREW LIGATURE YIDDISH YOD YOD PATAH)
+ * has no composed Unicode equivalent, but is expressed as the
+ * sequence U+05F2 U+05B7 in Unicode. A similar situation exists
+ * with the codepoint 0xC0 (HEBREW LIGATURE LAMED HOLAM), which
+ * MacOS converts to U+F86A U+05DC U+05B9. To correctly deal
+ * with these sequences, we probably should synthesize a ligature
+ * table if a Hebrew font only provides a Type 0 CMAP.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/HEBREW.TXT"
+ * >the Unicode mapping table for the MacOS Hebrew encoding</a>
+ */
+ private static final String UPPER_HEBREW
+ = "\u007e\u0000\u00c4\u0000\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u0020\u0021\"\u0023\u0024\u0025"
+ + "\u20aa\u0027\u0029\u0028\u002a\u002b\u002c\u002d\u002e\u002f"
+ + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039"
+ + "\u003a\u003b\u003c\u003d\u003e\u003f\u0000\u201e\uf89b\uf89c"
+ + "\uf89d\uf89e\u05bc\ufb4b\ufb35\u2026\u00a0\u05b8\u05b7\u05b5"
+ + "\u05b6\u05b4\u2013\u2014\u201c\u201d\u2018\u2019\ufb2a\ufb2b"
+ + "\u05bf\u05b0\u05b2\u05b1\u05bb\u05b9\u0000\u05b3\u05d0\u05d1"
+ + "\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da\u05db"
+ + "\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4\u05e5"
+ + "\u05e6\u05e7\u05e8\u05e9\u05ea\u007d\u005d\u007b\u005b\u007c";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Roman encoding with the Icelandic language.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ICELAND.TXT"
+ * >the Unicode mapping table for the MacOS Icelandic encoding</a>
+ */
+ private static final String UPPER_ICELANDIC
+ = "\u007e\u0000\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u00dd\u00b0\u00a2\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8"
+ + "\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0"
+ + "\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a"
+ + "\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5"
+ + "\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\u00ff\u0178\u2044\u20ac\u00d0\u00f0\u00de\u00fe\u00fd\u00b7"
+ + "\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce"
+ + "\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131"
+ + "\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Roman encoding for most languages. Exceptions include
+ * Croatian, Icelandic, Romanian, and Turkish.
+ *
+ * @see <a
+ * href="http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT"
+ * >the Unicode mapping table for the MacOS Roman encoding</a>
+ */
+ private static final String UPPER_ROMAN
+ = "\u007e\u0000\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8"
+ + "\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0"
+ + "\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a"
+ + "\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5"
+ + "\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\u00ff\u0178\u2044\u20ac\u2039\u203a\ufb01\ufb02\u2021\u00b7"
+ + "\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce"
+ + "\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131"
+ + "\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Roman encoding with the Romanian language.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT"
+ * >the Unicode mapping table for the MacOS Romanian encoding</a>
+ */
+ private static final String UPPER_ROMANIAN
+ = "\u007e\u0000\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u0102\u0218"
+ + "\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0"
+ + "\u222b\u00aa\u00ba\u03a9\u0103\u0219\u00bf\u00a1\u00ac\u221a"
+ + "\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5"
+ + "\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\u00ff\u0178\u2044\u20ac\u2039\u203a\u021a\u021b\u2021\u00b7"
+ + "\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce"
+ + "\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\u0131"
+ + "\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7";
+
+
+ /**
+ * A String whose <code>charAt(i)</code> is the Unicode character
+ * that corresponds to the codepoint <code>i + 127</code> in the
+ * MacOS Roman encoding with the Turkish language.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/TURKISH.TXT"
+ * >the Unicode mapping table for the MacOS Turkish encoding</a>
+ */
+ private static final String UPPER_TURKISH
+ = "\u007e\u0000\u00c4\u00c5\u00c7\u00c9\u00d1\u00d6\u00dc\u00e1"
+ + "\u00e0\u00e2\u00e4\u00e3\u00e5\u00e7\u00e9\u00e8\u00ea\u00eb"
+ + "\u00ed\u00ec\u00ee\u00ef\u00f1\u00f3\u00f2\u00f4\u00f6\u00f5"
+ + "\u00fa\u00f9\u00fb\u00fc\u2020\u00b0\u00a2\u00a3\u00a7\u2022"
+ + "\u00b6\u00df\u00ae\u00a9\u2122\u00b4\u00a8\u2260\u00c6\u00d8"
+ + "\u221e\u00b1\u2264\u2265\u00a5\u00b5\u2202\u2211\u220f\u03c0"
+ + "\u222b\u00aa\u00ba\u03a9\u00e6\u00f8\u00bf\u00a1\u00ac\u221a"
+ + "\u0192\u2248\u2206\u00ab\u00bb\u2026\u00a0\u00c0\u00c3\u00d5"
+ + "\u0152\u0153\u2013\u2014\u201c\u201d\u2018\u2019\u00f7\u25ca"
+ + "\u00ff\u0178\u011e\u011f\u0130\u0131\u015e\u015f\u2021\u00b7"
+ + "\u201a\u201e\u2030\u00c2\u00ca\u00c1\u00cb\u00c8\u00cd\u00ce"
+ + "\u00cf\u00cc\u00d3\u00d4\uf8ff\u00d2\u00da\u00db\u00d9\uf8a0"
+ + "\u02c6\u02dc\u00af\u02d8\u02d9\u02da\u00b8\u02dd\u02db\u02c7";
+
+
+ /**
+ * Constructs a CharGlyphMap.Type0 from all type 0 cmaps provided
+ * by the font. The implementation is able to fuse multiple type
+ * 0 cmaps, such as the MacRoman, Turkish, Icelandic and Croatian
+ * encoding, into a single map from Unicode characters to glyph
+ * indices.
+ *
+ * @param buf a ByteBuffer whose position is right at the
+ * beginning of the entire cmap table of the font (<i>not</i>
+ * at some subtable).
+ */
+ public Type0(ByteBuffer buf)
+ {
+ int numTables;
+ int tableStart = buf.position();
+ int limit = buf.limit();
+
+ /* The CMAP version must be 0. */
+ if (buf.getChar() != 0)
+ throw new IllegalStateException();
+
+ numTables = buf.getChar();
+ for (int i = 0; i < numTables; i++)
+ {
+ buf.limit(limit).position(tableStart + 4 + i * 8);
+ int platform = buf.getChar();
+ int encoding = buf.getChar();
+ int offset = tableStart + buf.getInt();
+
+ buf.position(offset);
+ int format = buf.getChar();
+ int length = buf.getChar();
+ buf.limit(offset + length);
+ int language = buf.getChar();
+
+ if (format == 0)
+ readSingleTable(buf, platform, language, encoding);
+ }
+ }
+
+
+ /**
+ * Processes a CMAP Type 0 table whose platform, encoding and
+ * language are already known.
+ *
+ * @param buf the buffer to read the table from, positioned
+ * right after the language tag.
+ */
+ private void readSingleTable(ByteBuffer buf,
+ int platform, int language,
+ int encoding)
+ {
+ String upper = getUpper129(platform, encoding, language);
+ if (upper == null)
+ return;
+
+ /* Skip the MacOS codepoints [0 .. 31] because they do not
+ * correspond to any Unicode codepoint.
+ */
+ buf.position(buf.position() + 32);
+
+ /* Irrespective of script and language, the MacOS codepoints
+ * [32 .. 126] correspond to the same Unicode codepoint.
+ */
+ for (int i = 32; i < 126; i++)
+ glyphToUCS2[buf.get() & 0xff] = (char) i;
+
+ for (int i = 127; i < 256; i++)
+ glyphToUCS2[buf.get() & 0xff] = upper.charAt(i - 127);
+
+ /* Glyph 0 is always the undefined character, which has
+ * no codepoint in Unicode.
+ */
+ glyphToUCS2[0] = 0;
+ }
+
+
+ /**
+ * Determines the glyph index for a given Unicode codepoint.
+ *
+ * @param ucs4 the Unicode codepoint in UCS-4 encoding.
+ *
+ * @return the glyph index, or 0 if the font does not contain
+ * a glyph for this codepoint.
+ */
+ public int getGlyph(int ucs4)
+ {
+ /* This linear search is not exactly super fast. However,
+ * only really ancient fonts have only a type 0 cmap,
+ * so it should not hurt in very many cases. If it shows
+ * to be a performance problem, one could do a binary search
+ * on a 256-entry table sorted by Unicode codepoint. The
+ * matching index of that table could then be used to look
+ * up the glyph ID at that position.
+ */
+ for (int i = 0; i < 256; i++)
+ if (glyphToUCS2[i] == ucs4)
+ return i;
+ return 0;
+ }
+
+
+ /**
+ * Returns a String whose <code>charAt(i)</code> is the Unicode
+ * character that corresponds to the codepoint <code>i +
+ * 127</code> in the encoding specified by the platform, script
+ * and language tag of a Type 0 CMAP.
+ *
+ * @param language the language tag in the cmap subtable. For the
+ * Macintosh platform, this is 0 to indicate language-neutral
+ * encoding, or the MacOS language code <i>plus one.</i> The
+ * Apple documentation does not mention that one needs to be
+ * added, but the Adobe OpenType specification does.
+ *
+ * @return a String for mapping the top 129 characters to
+ * UCS-2. If <code>platform</code> is not <code>1</code>
+ * (indicating Macintosh), or if the combination of
+ * <code>script</code> and <code>language</code> is not
+ * recognized, <code>null</code> will be returned.
+ */
+ private static String getUpper129(int platform, int script, int language)
+ {
+ if (platform != PLATFORM_MACINTOSH)
+ return null;
+
+ switch (script)
+ {
+ case 0: /* smRoman */
+ if (language == /* langIcelandic+1 */ 16)
+ return UPPER_ICELANDIC;
+ else if (language == /* langTurkish+1 */ 18)
+ return UPPER_TURKISH;
+ else if (language == /* langCroatian+1 */ 19)
+ return UPPER_CROATIAN;
+ else if (language == /* langRomanian+1 */ 38)
+ return UPPER_ROMANIAN;
+ else if (language == /* language-neutral */ 0)
+ return UPPER_ROMAN;
+ else
+ return null;
+
+ case 4: /* smArabic */
+ if (language == /* langFarsi+1 */ 32)
+ return UPPER_FARSI;
+ else
+ return UPPER_ARABIC;
+
+ case 5: /* smHebrew */
+ return UPPER_HEBREW;
+
+ case 6: /* smGreek */
+ return UPPER_GREEK;
+
+ case 7: /* smCyrillic */
+ return UPPER_CYRILLIC;
+
+ case 29: /* smSlavic == smEastEurRoman */
+ return UPPER_EAST_EUROPEAN_ROMAN;
+ }
+
+ return null;
+ }
+ }
+
+
+ /**
+ * A mapping from Unicode code points to glyph IDs through CMAP Type
+ * 4 tables. These tables are able to map two-byte encoded text
+ * to glyph IDs, such as Unicode Basic Multilingual Plane which
+ * contains U+0000 .. U+FFFE without surrogates.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static final class Type4
+ extends CharGlyphMap
+ {
+ /**
+ * Determines whether this implementation supports a combination
+ * of platform, language and encoding is supported for a type 4
+ * <code>cmap</code> table.
+ *
+ * <p>Currently, we support the following combinations:
+ *
+ * <ul><li>the Unicode platform in encodings 0, 1, 2, 3 and
+ * 4;</li>
+ *
+ * <li>the Microsoft platform in encodings 1 (Basic Multilingual
+ * Plane) and 10 (full Unicode).</li></ul>
+ *
+ * <p>Most recent Macintosh fonts provide a type 4
+ * <code>cmap</code> for Unicode. Microsoft recommends providing a
+ * type 4 <code>cmap</code> for encoding 1 of the Microsoft
+ * platform. The implementation of GNU Classpath supports both
+ * variants.
+ *
+ * <p>Not supported are ShiftJIS, Big5, Wansung, Johab, and other
+ * non-Unicode encodings. Text can easily be converted to Unicode
+ * using the java.nio.charset package.
+ */
+ static boolean isSupported(int platform, int language, int encoding)
+ {
+ switch (platform)
+ {
+ case PLATFORM_UNICODE:
+ return (encoding >= 0) && (encoding <= 4);
+
+ case PLATFORM_MICROSOFT:
+ return (encoding == /* Basic Multilingual Plane */ 1)
+ || (encoding == /* Full Unicode */ 10);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Processes a CMAP Type 4 table whose platform, encoding and
+ * language are already known. We understand the Unicode platform
+ * with encodings 0, 1, 2, 3 and 4, and the Microsoft platform
+ * with encodings 1 (Unicode BMP) and 10 (UCS-4).
+ *
+ * @param buf the buffer to read the table from, positioned at
+ * its beginning.
+ *
+ * @return a Type4 table, or <code>null</code> if the combination
+ * of platform and encoding is not understood.
+ */
+ static Type4 readTable(ByteBuffer buf,
+ int platform, int encoding)
+ {
+ int tableStart = buf.position();
+ char format = buf.getChar();
+ int length = buf.getChar();
+ int language = buf.getChar();
+
+ if ((format != 4) || !isSupported(platform, language, encoding))
+ throw new IllegalArgumentException();
+
+ buf.limit(tableStart + length);
+
+ int segCountX2 = buf.getChar();
+ int segCount = segCountX2 / 2;
+ int searchRange = buf.getChar();
+ int entrySelector = buf.getChar();
+ int rangeShift = buf.getChar();
+
+ CharBuffer endCode, startCode, idRangeOffset_glyphID;
+ ShortBuffer idDelta;
+
+ int pos = buf.position();
+ endCode = buf.asCharBuffer();
+ pos += segCountX2 + /* reservedPad */ 2;
+
+ buf.position(pos);
+ startCode = buf.asCharBuffer();
+ pos += segCountX2;
+
+ buf.position(pos);
+ idDelta = buf.asShortBuffer();
+ pos += segCountX2;
+
+ buf.position(pos);
+ idRangeOffset_glyphID = buf.asCharBuffer();
+
+ endCode.limit(segCount);
+ startCode.limit(segCount);
+ idDelta.limit(segCount);
+ idRangeOffset_glyphID.limit((buf.limit() - pos) / 2);
+
+ return new Type4(segCount,
+ endCode, startCode, idDelta,
+ idRangeOffset_glyphID);
+ }
+
+
+ private CharBuffer lastChar;
+ private CharBuffer firstChar;
+ private ShortBuffer idDelta;
+ private CharBuffer rangeID;
+ private int numSegments;
+
+ private Type4(int numSegments,
+ CharBuffer lastChar, CharBuffer firstChar,
+ ShortBuffer idDelta, CharBuffer rangeID)
+ {
+ this.numSegments = numSegments;
+ this.lastChar = lastChar;
+ this.firstChar = firstChar;
+ this.idDelta = idDelta;
+ this.rangeID = rangeID;
+ }
+
+
+ /**
+ * Determines the glyph index for a given Unicode codepoint.
+ *
+ * @param ucs4 the Unicode codepoint in UCS-4 encoding.
+ *
+ * @return the glyph index, or 0 if the font does not contain
+ * a glyph for this codepoint.
+ */
+ public int getGlyph(int ucs4)
+ {
+ char c, segStart;
+ int segment, idRangeOffset;
+
+ if (ucs4 > 0xffff)
+ return 0;
+
+ c = (char) ucs4;
+ segment = find(c);
+ segStart = firstChar.get(segment);
+ if ((c < segStart) || (c > lastChar.get(segment)))
+ return 0;
+
+ /*
+ * System.out.println("seg " + segment
+ * + ", range=" + (int) rangeID[segment]
+ * + ", delta=" + delta[segment]);
+ */
+
+ idRangeOffset = rangeID.get(segment);
+ if (idRangeOffset == 0)
+ return (int) (char) (((int) c) + idDelta.get(segment));
+ int result = rangeID.get((idRangeOffset >> 1)
+ + (c - segStart) + segment);
+ if (result == 0)
+ return 0;
+ return (int) (char) (result + idDelta.get(segment));
+ }
+
+
+ private int find(char c)
+ {
+ int min, max, mid;
+
+ min = 0;
+ max = numSegments - 1;
+ mid = max >> 1;
+
+ while (min < max)
+ {
+ // System.out.println("(" + min + "," + max + ") " + mid);
+ char val = lastChar.get(mid);
+ if (val == c)
+ break;
+ else if (val < c)
+ min = mid + 1;
+ else if (val > c)
+ max = mid;
+ mid = (min + max) >> 1;
+ }
+
+ return mid;
+ }
+ }
+
+
+ /**
+ * A mapping from Unicode code points to glyph IDs through CMAP Type
+ * 12 tables. These tables are able to map four-byte encoded text
+ * to glyph IDs, such as Unicode UCS-4.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static final class Type12
+ extends CharGlyphMap
+ {
+ int numGroups;
+ IntBuffer data;
+
+
+ /**
+ * Determines whether this implementation supports a combination
+ * of platform and encoding for a type 12 <code>cmap</code> table.
+ *
+ * <p>Currently, we support the following combinations:
+ *
+ * <ul><li>the Unicode platform in encodings 0, 1, 2, 3 and
+ * 4;</li>
+ *
+ * <li>the Microsoft platform in encodings 1 (Basic Multilingual
+ * Plane) and 10 (full Unicode).</li></ul>
+ */
+ static boolean isSupported(int platform, int encoding)
+ {
+ switch (platform)
+ {
+ case PLATFORM_UNICODE:
+ return (encoding >= 0) && (encoding <= 4);
+
+ case PLATFORM_MICROSOFT:
+ return (encoding == /* Basic Multilingual Plane */ 1)
+ || (encoding == /* Full Unicode */ 10);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Constructs a <code>cmap</code> type 12 table whose platform and
+ * encoding are already known. We understand the Unicode platform
+ * with encodings 0, 1, 2, 3 and 4, and the Microsoft platform
+ * with encodings 1 (Unicode BMP) and 10 (UCS-4).
+ *
+ * @param buf the buffer to read the table from, positioned at
+ * its beginning.
+ */
+ Type12(ByteBuffer buf, int platform, int encoding)
+ {
+ int tableStart = buf.position();
+ int format = buf.getChar();
+ if ((format != 12) || !isSupported(platform, encoding))
+ throw new IllegalStateException();
+
+ buf.getChar(); // skip reserved field
+ buf.limit(tableStart + buf.getInt());
+ int language = buf.getInt();
+ numGroups = buf.getInt();
+ data = buf.asIntBuffer();
+ }
+
+
+ /**
+ * Determines the glyph index for a given Unicode codepoint. Users
+ * should be aware that the character-to-glyph mapping not not
+ * everything that is needed for full Unicode support. For example,
+ * the <code>cmap</code> table is not able to synthesize accented
+ * glyphs from the canonical decomposition sequence, even if the
+ * font would contain a glyph for the composed form.
+ *
+ * @param ucs4 the Unicode codepoint in UCS-4 encoding. Surrogates
+ * (U+D800 to U+DFFF) cannot be passed, they must be mapped to
+ * UCS-4 first.
+ *
+ * @return the glyph index, or 0 if the font does not contain
+ * a glyph for this codepoint.
+ */
+ public int getGlyph(int ucs4)
+ {
+ int min, max, mid, startCharCode, endCharCode;
+
+ min = 0;
+ max = numGroups - 1;
+ mid = max >> 1;
+ do
+ {
+ startCharCode = data.get(3 * mid);
+ endCharCode = data.get(3 * mid + 1);
+
+
+ /*
+ System.out.println("group " + mid + " (U+"
+ + Integer.toHexString(startCharCode)
+ + " .. U+" + Integer.toHexString(endCharCode)
+ + "): glyph " + (int) data.get(mid*3+2));
+ */
+
+ if ((startCharCode <= ucs4) && (ucs4 <= endCharCode))
+ return ucs4
+ - startCharCode
+ + /* startGlyphID */ data.get(mid * 3 + 2);
+
+ if (endCharCode < ucs4)
+ min = mid + 1;
+ else
+ max = mid;
+ mid = (min + max) >> 1;
+ }
+ while (min < max);
+
+ startCharCode = data.get(3 * mid);
+ endCharCode = data.get(3 * mid + 1);
+ if ((startCharCode <= ucs4) && (ucs4 <= endCharCode))
+ return ucs4
+ - startCharCode
+ + /* startGlyphID */ data.get(mid * 3 + 2);
+
+ return 0;
+ }
+ }
+}
diff --git a/gnu/java/awt/font/opentype/GlyphNamer.java b/gnu/java/awt/font/opentype/GlyphNamer.java
new file mode 100644
index 000000000..ea4b8e2a1
--- /dev/null
+++ b/gnu/java/awt/font/opentype/GlyphNamer.java
@@ -0,0 +1,1133 @@
+/* GlyphNamer.java -- Provides glyph names.
+ 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 java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.nio.CharBuffer;
+
+
+/**
+ * Provides names for glyphs, which is useful when embedding fonts
+ * in PostScript or PDF documents.
+ *
+ * <p>If the font has a <code>Zapf</code> table, it is used to map
+ * glyph IDs back to a sequence of Unicode codepoints, which then
+ * makes it possible to look up or synthesize a PostScript glyph name
+ * according to Adobe&#x2019;s conventions. This allows to extract the
+ * original text from the generated PDF or PostScript file, which is
+ * important for indexing, searching and extracting.
+ *
+ * <p>Otherwise, glyph names are taken from the <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM06/Chap6post.html"
+ * ><code>post</code> table</a>. All known formats (1, 2, 2.5, 3 and
+ * 4) are supported.
+ *
+ * <p><b>Open Tasks:</b> The code could be cleaner structured by
+ * having separate sub-classes for each variant of the POST table.
+ * Also, the implementation should not read in all glyph names if a
+ * font provides them in a POST table of type 2. It would be
+ * sufficient to just read in the offsets and delay the String
+ * fetching and conversion to the time when the glyph name is actually
+ * requested.
+ *
+ * <p><b>Lack of Thread Safety:</b> The GlyphNamer class is
+ * intentionally <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font has already obtained a lock before calling the GlyphNamer.
+ * It would thus be wasteful to acquire additional locks for the
+ * GlyphNamer.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class GlyphNamer
+{
+ /**
+ * The 'post' table of the font.
+ */
+ private ByteBuffer postTable;
+
+
+ /**
+ * The 'Zapf' table of the font, or null if the font has no
+ * such table.
+ */
+ private ByteBuffer zapfTable;
+
+
+ /**
+ * The offset of each glyph relative to the Zapf table,
+ * or null if the font does not have a Zapf table.
+ */
+ private IntBuffer zapfOffsets;
+
+
+ /**
+ * The offset from the start of the Zapf table to the start
+ * of the extra info area.
+ */
+ private int zapfExtraInfo;
+
+
+ /**
+ * The format of the post table, a Fixed 16.16 number.
+ */
+ private int postFormat;
+
+
+ /**
+ * An array of glyph names. Used for table formats 1, 2, 2.5.
+ */
+ private String[] glyphNames;
+
+
+ /**
+ * An array from glyph to character codes. Similar to the
+ * workings of a Zapf table, but maps to CID instead of
+ * Unicode. Used for table format 4.
+ */
+ private CharBuffer glyphCharacterCodes;
+
+
+ /**
+ * The PostScript names of the 258 standard Macintosh glyphs. Note
+ * that some of these glyphs are not in the Adobe Standard Glyph
+ * List for New Fonts, namely .notdef, .null, nonmarkingreturn,
+ * nonbreakingspace, apple, onesuperior, twosuperior, and
+ * threesuperior.
+ */
+ private static final String[] STANDARD_POSTSCRIPT_GLYPH_NAMES =
+ {
+ ".notdef", // glyph #0
+ ".null", // glyph #1
+ "nonmarkingreturn", // glyph #2
+ "space", // glyph #3
+ "exclam", // glyph #4
+ "quotedbl", // glyph #5
+ "numbersign", // glyph #6
+ "dollar", // glyph #7
+ "percent", // glyph #8
+ "ampersand", // glyph #9
+ "quotesingle", // glyph #10
+ "parenleft", // glyph #11
+ "parenright", // glyph #12
+ "asterisk", // glyph #13
+ "plus", // glyph #14
+ "comma", // glyph #15
+ "hyphen", // glyph #16
+ "period", // glyph #17
+ "slash", // glyph #18
+ "zero", // glyph #19
+ "one", // glyph #20
+ "two", // glyph #21
+ "three", // glyph #22
+ "four", // glyph #23
+ "five", // glyph #24
+ "six", // glyph #25
+ "seven", // glyph #26
+ "eight", // glyph #27
+ "nine", // glyph #28
+ "colon", // glyph #29
+ "semicolon", // glyph #30
+ "less", // glyph #31
+ "equal", // glyph #32
+ "greater", // glyph #33
+ "question", // glyph #34
+ "at", // glyph #35
+ "A", // glyph #36
+ "B", // glyph #37
+ "C", // glyph #38
+ "D", // glyph #39
+ "E", // glyph #40
+ "F", // glyph #41
+ "G", // glyph #42
+ "H", // glyph #43
+ "I", // glyph #44
+ "J", // glyph #45
+ "K", // glyph #46
+ "L", // glyph #47
+ "M", // glyph #48
+ "N", // glyph #49
+ "O", // glyph #50
+ "P", // glyph #51
+ "Q", // glyph #52
+ "R", // glyph #53
+ "S", // glyph #54
+ "T", // glyph #55
+ "U", // glyph #56
+ "V", // glyph #57
+ "W", // glyph #58
+ "X", // glyph #59
+ "Y", // glyph #60
+ "Z", // glyph #61
+ "bracketleft", // glyph #62
+ "backslash", // glyph #63
+ "bracketright", // glyph #64
+ "asciicircum", // glyph #65
+ "underscore", // glyph #66
+ "grave", // glyph #67
+ "a", // glyph #68
+ "b", // glyph #69
+ "c", // glyph #70
+ "d", // glyph #71
+ "e", // glyph #72
+ "f", // glyph #73
+ "g", // glyph #74
+ "h", // glyph #75
+ "i", // glyph #76
+ "j", // glyph #77
+ "k", // glyph #78
+ "l", // glyph #79
+ "m", // glyph #80
+ "n", // glyph #81
+ "o", // glyph #82
+ "p", // glyph #83
+ "q", // glyph #84
+ "r", // glyph #85
+ "s", // glyph #86
+ "t", // glyph #87
+ "u", // glyph #88
+ "v", // glyph #89
+ "w", // glyph #90
+ "x", // glyph #91
+ "y", // glyph #92
+ "z", // glyph #93
+ "braceleft", // glyph #94
+ "bar", // glyph #95
+ "braceright", // glyph #96
+ "asciitilde", // glyph #97
+ "Adieresis", // glyph #98
+ "Aring", // glyph #99
+ "Ccedilla", // glyph #100
+ "Eacute", // glyph #101
+ "Ntilde", // glyph #102
+ "Odieresis", // glyph #103
+ "Udieresis", // glyph #104
+ "aacute", // glyph #105
+ "agrave", // glyph #106
+ "acircumflex", // glyph #107
+ "adieresis", // glyph #108
+ "atilde", // glyph #109
+ "aring", // glyph #110
+ "ccedilla", // glyph #111
+ "eacute", // glyph #112
+ "egrave", // glyph #113
+ "ecircumflex", // glyph #114
+ "edieresis", // glyph #115
+ "iacute", // glyph #116
+ "igrave", // glyph #117
+ "icircumflex", // glyph #118
+ "idieresis", // glyph #119
+ "ntilde", // glyph #120
+ "oacute", // glyph #121
+ "ograve", // glyph #122
+ "ocircumflex", // glyph #123
+ "odieresis", // glyph #124
+ "otilde", // glyph #125
+ "uacute", // glyph #126
+ "ugrave", // glyph #127
+ "ucircumflex", // glyph #128
+ "udieresis", // glyph #129
+ "dagger", // glyph #130
+ "degree", // glyph #131
+ "cent", // glyph #132
+ "sterling", // glyph #133
+ "section", // glyph #134
+ "bullet", // glyph #135
+ "paragraph", // glyph #136
+ "germandbls", // glyph #137
+ "registered", // glyph #138
+ "copyright", // glyph #139
+ "trademark", // glyph #140
+ "acute", // glyph #141
+ "dieresis", // glyph #142
+ "notequal", // glyph #143
+ "AE", // glyph #144
+ "Oslash", // glyph #145
+ "infinity", // glyph #146
+ "plusminus", // glyph #147
+ "lessequal", // glyph #148
+ "greaterequal", // glyph #149
+ "yen", // glyph #150
+ "mu", // glyph #151
+ "partialdiff", // glyph #152
+ "summation", // glyph #153
+ "product", // glyph #154
+ "pi", // glyph #155
+ "integral", // glyph #156
+ "ordfeminine", // glyph #157
+ "ordmasculine", // glyph #158
+ "Omega", // glyph #159
+ "ae", // glyph #160
+ "oslash", // glyph #161
+ "questiondown", // glyph #162
+ "exclamdown", // glyph #163
+ "logicalnot", // glyph #164
+ "radical", // glyph #165
+ "florin", // glyph #166
+ "approxequal", // glyph #167
+ "Delta", // glyph #168
+ "guillemotleft", // glyph #169
+ "guillemotright", // glyph #170
+ "ellipsis", // glyph #171
+ "nonbreakingspace", // glyph #172
+ "Agrave", // glyph #173
+ "Atilde", // glyph #174
+ "Otilde", // glyph #175
+ "OE", // glyph #176
+ "oe", // glyph #177
+ "endash", // glyph #178
+ "emdash", // glyph #179
+ "quotedblleft", // glyph #180
+ "quotedblright", // glyph #181
+ "quoteleft", // glyph #182
+ "quoteright", // glyph #183
+ "divide", // glyph #184
+ "lozenge", // glyph #185
+ "ydieresis", // glyph #186
+ "Ydieresis", // glyph #187
+ "fraction", // glyph #188
+ "currency", // glyph #189
+ "guilsinglleft", // glyph #190
+ "guilsinglright", // glyph #191
+ "fi", // glyph #192
+ "fl", // glyph #193
+ "daggerdbl", // glyph #194
+ "periodcentered", // glyph #195
+ "quotesinglbase", // glyph #196
+ "quotedblbase", // glyph #197
+ "perthousand", // glyph #198
+ "Acircumflex", // glyph #199
+ "Ecircumflex", // glyph #200
+ "Aacute", // glyph #201
+ "Edieresis", // glyph #202
+ "Egrave", // glyph #203
+ "Iacute", // glyph #204
+ "Icircumflex", // glyph #205
+ "Idieresis", // glyph #206
+ "Igrave", // glyph #207
+ "Oacute", // glyph #208
+ "Ocircumflex", // glyph #209
+ "apple", // glyph #210
+ "Ograve", // glyph #211
+ "Uacute", // glyph #212
+ "Ucircumflex", // glyph #213
+ "Ugrave", // glyph #214
+ "dotlessi", // glyph #215
+ "circumflex", // glyph #216
+ "tilde", // glyph #217
+ "macron", // glyph #218
+ "breve", // glyph #219
+ "dotaccent", // glyph #220
+ "ring", // glyph #221
+ "cedilla", // glyph #222
+ "hungarumlaut", // glyph #223
+ "ogonek", // glyph #224
+ "caron", // glyph #225
+ "Lslash", // glyph #226
+ "lslash", // glyph #227
+ "Scaron", // glyph #228
+ "scaron", // glyph #229
+ "Zcaron", // glyph #230
+ "zcaron", // glyph #231
+ "brokenbar", // glyph #232
+ "Eth", // glyph #233
+ "eth", // glyph #234
+ "Yacute", // glyph #235
+ "yacute", // glyph #236
+ "Thorn", // glyph #237
+ "thorn", // glyph #238
+ "minus", // glyph #239
+ "multiply", // glyph #240
+ "onesuperior", // glyph #241
+ "twosuperior", // glyph #242
+ "threesuperior", // glyph #243
+ "onehalf", // glyph #244
+ "onequarter", // glyph #245
+ "threequarters", // glyph #246
+ "franc", // glyph #247
+ "Gbreve", // glyph #248
+ "gbreve", // glyph #249
+ "Idotaccent", // glyph #250
+ "Scedilla", // glyph #251
+ "scedilla", // glyph #252
+ "Cacute", // glyph #253
+ "cacute", // glyph #254
+ "Ccaron", // glyph #255
+ "ccaron", // glyph #256
+ "dcroat" // glyph #257
+ };
+
+
+ private GlyphNamer(int numGlyphs,
+ ByteBuffer postTable,
+ ByteBuffer zapfTable)
+ {
+ this.postTable = postTable;
+ this.zapfTable = zapfTable;
+
+ if ((zapfTable != null) && (zapfTable.getInt(0) == 0x00010000))
+ {
+ readZapf(numGlyphs);
+ return;
+ }
+
+ readPost();
+ }
+
+
+ /**
+ * Sets up the information which allows to retrieve the information
+ * on demand.
+ *
+ * @param numGlyphs the number of glyphs in the font. This value
+ * comes from the <code>maxp</code> table.
+ */
+ public static GlyphNamer forTables(int numGlyphs,
+ ByteBuffer postTable,
+ ByteBuffer zapfTable)
+ {
+ return new GlyphNamer(numGlyphs, postTable, zapfTable);
+ }
+
+
+ /**
+ * Retrieves or synthesizes a PostScript name for the glyph.
+ * Although the code is reasonably fast, it is recommended
+ * to cache the results in the printer driver.
+ *
+ * <p>If a font provides a 'Zapf' table, the reverse mapping
+ * from glyph to UTF-16 sequence is performed, and a glyph
+ * name is synthesized following the recommendations by Adobe.
+ * This allows to extract the original text from the generated
+ * PostScript or PDF, which is a requirement for indexing
+ * and searching.
+ *
+ * <p>If a font does not provide a 'Zapf' table, the glyph name
+ * is taken from the 'post' table. Note that some fonts have
+ * wrong data in their post data, in which case the resulting
+ * name will be garbage. Usually, this does not hurt, unless
+ * the user wants to extract text from the generated PostScript
+ * or PDF file. The GNU implementation understands all known
+ * formats of the post table (1, 2, 2.5, 3 and 4).
+ *
+ * @param glyph the index of the glyph whose name is to be
+ * retrieved.
+ *
+ * @return the glyph name, such as <code>A</code>,
+ * <code>gcircumflex</code>, <code>z_uni0302</code>, or
+ * <code>u11C42</code>.</li>
+ */
+ String getGlyphName(int glyph)
+ {
+ if (zapfOffsets != null)
+ {
+ zapfTable.position(zapfOffsets.get(glyph) + 8);
+ int numChars = zapfTable.getChar();
+ char[] chars = new char[numChars];
+ for (int i = 0; i < numChars; i++)
+ chars[i] = zapfTable.getChar();
+ return getGlyphName(chars);
+ }
+
+
+ /* Type 1, Type 2, Type 2.5 */
+ if (glyphNames != null)
+ return glyphNames[glyph];
+
+ /* Type 4: Synthesized glyph name. */
+ if (glyphCharacterCodes != null)
+ return "a" + glyphCharacterCodes.get(glyph);
+
+ /* Type 3: Arbitrary, but unique name for the glyph.
+ *
+ * To find out what a good naming scheme would be, we have printed
+ * a document containing the character U+201C in the font
+ * "Hiragino Kaku Gothic Pro W3" (by Dainippon Screen Mfg. Co.,
+ * Ltd.) on Apple MacOS X 10.1.5. This font has a type 3 'post'
+ * table, and its 'cmap' maps U+201C to glyph #108. The generated
+ * PostScript file defined a character whose name was "g108".
+ *
+ * Therefore, we use 'g' as name prefix. According to the
+ * TrueType/OpenType specification, it should not matter what
+ * prefix we use. On the other hand, it does not hurt either to be
+ * compatible with a good printer driver.
+ *
+ * Actually, that specific font also contains a 'Zapf' table,
+ * which allows to generate glyph names according to Adobe's
+ * conventions, so that extracting text from and searching in the
+ * generated PostScript or PDF becomes possible. While the Apple
+ * PostScript printer driver does not seem to use the 'Zapf' table
+ * for this purpose, we do.
+ */
+ return "g" + glyph;
+ }
+
+
+ /**
+ * Sets up some buffers which allow to quickly read information from
+ * the Zapf table.
+ *
+ * @see <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM06/Chap6Zapf.html">
+ * Apple&#x2019;s documentation of the <code>Zapf</code> table</a>
+ */
+ private void readZapf(int numGlyphs)
+ {
+ zapfExtraInfo = zapfTable.getInt(4);
+ zapfTable.position(8);
+ zapfOffsets = zapfTable.asIntBuffer();
+ zapfOffsets.limit(numGlyphs);
+ }
+
+
+ /**
+ * Reads in the PostScript data from a <code>post</code> table of a
+ * TrueType or OpenType font. The implementation currently
+ * understands the table formats 1, 2, 2.5, 3, and 4.
+ */
+ private void readPost()
+ {
+ int numGlyphs, nameIndex, maxNameIndex;
+ char[] nameIndices;
+ String[] names;
+ byte[] pascalName;
+
+ postTable.position(0);
+ postFormat = postTable.getInt();
+ switch (postFormat)
+ {
+ case 0x00010000:
+ glyphNames = STANDARD_POSTSCRIPT_GLYPH_NAMES;
+ return;
+
+ case 0x00020000:
+ postTable.position(32);
+ numGlyphs = postTable.getChar();
+ glyphNames = new String[numGlyphs];
+ pascalName = new byte[255];
+ nameIndices = new char[numGlyphs];
+ maxNameIndex = 0;
+ for (int i = 0; i < numGlyphs; i++)
+ maxNameIndex = Math.max(maxNameIndex,
+ nameIndices[i] = postTable.getChar());
+
+ names = new String[Math.max(maxNameIndex - 258 + 1, 0)];
+ for (int i = 258; i <= maxNameIndex; i++)
+ {
+ int nameLen = (postTable.get() & 0xff);
+ postTable.get(pascalName, 0, nameLen);
+ names[i - 258] = new String(pascalName, 0, nameLen);
+ }
+ for (int i = 0; i < numGlyphs; i++)
+ {
+ nameIndex = nameIndices[i];
+ if (nameIndex < 258)
+ glyphNames[i] = STANDARD_POSTSCRIPT_GLYPH_NAMES[nameIndex];
+ else
+ glyphNames[i] = names[nameIndex - 258];
+ }
+ return;
+
+ case 0x00025000: // in case some font has a wrong representation of 2.5
+ case 0x00028000:
+ /* Format 2.5 is a re-ordering of the standard names. It has
+ * been deprecated in February 2000, but might still occasionally
+ * float around. Since it can be supported with so little code,
+ * we do so.
+ */
+ postTable.position(32);
+ numGlyphs = postTable.getChar();
+ glyphNames = new String[numGlyphs];
+ for (int i = 0; i < numGlyphs; i++)
+ glyphNames[i] = STANDARD_POSTSCRIPT_GLYPH_NAMES[i + postTable.get()];
+ return;
+
+ case 0x00030000:
+ /* Format 3 leaves it to the printer driver to choose whatever
+ * name it wants to.
+ */
+ return;
+
+ case 0x00040000:
+ /* Format 4 is used by Apple for composite fonts that have
+ * synthetic glyph names. The name of a glyph is "a" plus
+ * the integer (in decimal notation) that follows the table
+ * after numGlyphs.
+ */
+ postTable.position(32);
+ numGlyphs = postTable.getChar();
+ glyphCharacterCodes = postTable.asCharBuffer();
+ glyphCharacterCodes.limit(numGlyphs);
+ return;
+ }
+ }
+
+
+
+ /* For generating the following tables, a quick-and-dirty Python
+ * script was used. It is unlikely that we ever need to run it
+ * again, but for information and convenient access, it is included
+ * below. Initial '#' characters need to be removed from the generated
+ * strings, they are present so that the lines not break in the middle
+ * of Java escape sequences (no, this is not very clean).
+ *
+ * import string
+ *
+ * javaEscapes = {0x22:'\\"', 0x5c:'\\\\'}
+ * def escape(c):
+ * if javaEscapes.has_key(c):
+ * return javaEscapes[c]
+ * elif 0x20 <= c <= 0x7e:
+ * return chr(c)
+ * else:
+ * return '\\u%04x' % c
+ *
+ * def dump(name, s, stride):
+ * s = ('#' * stride) + s
+ * print " private static final String %s" % name
+ * for i in range(0, len(s), 60):
+ * print ' + "%s"' % s[i:i+60]
+ *
+ * glyphs = {}
+ * for line in open('aglfn13.txt', 'r').readlines():
+ * if line[0] == '#': continue
+ * [ucs, glyphName, desc] = line.split(';')
+ * glyph = int('0x' + ucs, 0)
+ * assert (not glyphs.has_key(glyph)) or (glyphs[glyph] == glyphName)
+ * glyphs[glyph] = glyphName
+ * del glyphs[0] # arrowvertex
+ * k = glyphs.keys()
+ * k.sort()
+ * numGlyphs = len(k)
+ * names = ''
+ * pos = []
+ * for glyph in k:
+ * pos.append(len(names) + 1)
+ * names = names + '/' + glyphs[glyph]
+ * dump('AGLFN_GLYPHS', string.join(map(escape, k), ''), 5)
+ * dump('AGLFN_NAME_OFFSET', string.join(map(escape, pos), ''), 4)
+ * dump('AGLFN_NAMES', names + '/', 0)
+ */
+
+
+ /**
+ * A String that contains the Unicode codepoint for each glyph
+ * in the Adobe Glyph List. The characters are in sorted order.
+ *
+ * Generated from the Adobe Glyph List for New Fonts, version 1.1
+ * of 17 April 2003.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
+ * Glyph List for New Fonts</a>
+ */
+ private static final String AGLFN_GLYPHS
+ = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU"
+ + "VWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u00a1\u00a2\u00a3"
+ + "\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ae"
+ + "\u00af\u00b0\u00b1\u00b4\u00b5\u00b6\u00b7\u00b8\u00ba\u00bb"
+ + "\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5"
+ + "\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf"
+ + "\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9"
+ + "\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3"
+ + "\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed"
+ + "\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7"
+ + "\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0100\u0101"
+ + "\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b"
+ + "\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115"
+ + "\u0116\u0117\u0118\u0119\u011a\u011b\u011c\u011d\u011e\u011f"
+ + "\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127\u0128\u0129"
+ + "\u012a\u012b\u012c\u012d\u012e\u012f\u0130\u0131\u0132\u0133"
+ + "\u0134\u0135\u0136\u0137\u0138\u0139\u013a\u013b\u013c\u013d"
+ + "\u013e\u013f\u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147"
+ + "\u0148\u0149\u014a\u014b\u014c\u014d\u014e\u014f\u0150\u0151"
+ + "\u0152\u0153\u0154\u0155\u0156\u0157\u0158\u0159\u015a\u015b"
+ + "\u015c\u015d\u015e\u015f\u0160\u0161\u0162\u0163\u0164\u0165"
+ + "\u0166\u0167\u0168\u0169\u016a\u016b\u016c\u016d\u016e\u016f"
+ + "\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0178\u0179"
+ + "\u017a\u017b\u017c\u017d\u017e\u017f\u0192\u01a0\u01a1\u01af"
+ + "\u01b0\u01e6\u01e7\u01fa\u01fb\u01fc\u01fd\u01fe\u01ff\u0218"
+ + "\u0219\u02bc\u02bd\u02c6\u02c7\u02d8\u02d9\u02da\u02db\u02dc"
+ + "\u02dd\u0300\u0301\u0303\u0309\u0323\u0384\u0385\u0386\u0387"
+ + "\u0388\u0389\u038a\u038c\u038e\u038f\u0390\u0391\u0392\u0393"
+ + "\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e"
+ + "\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03aa"
+ + "\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4"
+ + "\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bd\u03be\u03bf"
+ + "\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9"
+ + "\u03ca\u03cb\u03cc\u03cd\u03ce\u03d1\u03d2\u03d5\u03d6\u0401"
+ + "\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b"
+ + "\u040c\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416"
+ + "\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420"
+ + "\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a"
+ + "\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434"
+ + "\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e"
+ + "\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448"
+ + "\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0451\u0452\u0453"
+ + "\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045e"
+ + "\u045f\u0462\u0463\u0472\u0473\u0474\u0475\u0490\u0491\u04d9"
+ + "\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9"
+ + "\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05d0"
+ + "\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da"
+ + "\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4"
+ + "\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05f0\u05f1\u05f2\u060c"
+ + "\u061b\u061f\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628"
+ + "\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632"
+ + "\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\u0640\u0641"
+ + "\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b"
+ + "\u064c\u064d\u064e\u064f\u0650\u0651\u0652\u0660\u0661\u0662"
+ + "\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u066a\u066d\u0679"
+ + "\u067e\u0686\u0688\u0691\u0698\u06a4\u06af\u06ba\u06d2\u06d5"
+ + "\u1e80\u1e81\u1e82\u1e83\u1e84\u1e85\u1ef2\u1ef3\u200c\u200d"
+ + "\u200e\u200f\u2012\u2013\u2014\u2015\u2017\u2018\u2019\u201a"
+ + "\u201b\u201c\u201d\u201e\u2020\u2021\u2022\u2024\u2025\u2026"
+ + "\u202c\u202d\u202e\u2030\u2032\u2033\u2039\u203a\u203c\u2044"
+ + "\u20a1\u20a3\u20a4\u20a7\u20aa\u20ab\u20ac\u2105\u2111\u2113"
+ + "\u2116\u2118\u211c\u211e\u2122\u2126\u212e\u2135\u2153\u2154"
+ + "\u215b\u215c\u215d\u215e\u2190\u2191\u2192\u2193\u2194\u2195"
+ + "\u21a8\u21b5\u21d0\u21d1\u21d2\u21d3\u21d4\u2200\u2202\u2203"
+ + "\u2205\u2206\u2207\u2208\u2209\u220b\u220f\u2211\u2212\u2217"
+ + "\u221a\u221d\u221e\u221f\u2220\u2227\u2228\u2229\u222a\u222b"
+ + "\u2234\u223c\u2245\u2248\u2260\u2261\u2264\u2265\u2282\u2283"
+ + "\u2284\u2286\u2287\u2295\u2297\u22a5\u22c5\u2302\u2310\u2320"
+ + "\u2321\u2329\u232a\u2500\u2502\u250c\u2510\u2514\u2518\u251c"
+ + "\u2524\u252c\u2534\u253c\u2550\u2551\u2552\u2553\u2554\u2555"
+ + "\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f"
+ + "\u2560\u2561\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569"
+ + "\u256a\u256b\u256c\u2580\u2584\u2588\u258c\u2590\u2591\u2592"
+ + "\u2593\u25a0\u25a1\u25aa\u25ab\u25ac\u25b2\u25ba\u25bc\u25c4"
+ + "\u25ca\u25cb\u25cf\u25d8\u25d9\u25e6\u263a\u263b\u263c\u2640"
+ + "\u2642\u2660\u2663\u2665\u2666\u266a\u266b";
+
+
+ /**
+ * The offset of each glyph name in AGLFN_NAMES.
+ *
+ * Generated from the Adobe Glyph List for New Fonts, version 1.1
+ * of 17 April 2003.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
+ * Glyph List for New Fonts</a>
+ */
+ private static final String AGLFN_NAME_OFFSET
+ = "\u0001\u0007\u000e\u0017\")1;GQ\\ejpw~\u0084\u0089\u008d"
+ + "\u0091\u0097\u009c\u00a1\u00a5\u00ab\u00b1\u00b6\u00bc\u00c6"
+ + "\u00cb\u00d1\u00d9\u00e2\u00e5\u00e7\u00e9\u00eb\u00ed\u00ef"
+ + "\u00f1\u00f3\u00f5\u00f7\u00f9\u00fb\u00fd\u00ff\u0101\u0103"
+ + "\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117"
+ + "\u0119\u0125\u012f\u013c\u0148\u0153\u0159\u015b\u015d\u015f"
+ + "\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173"
+ + "\u0175\u0177\u0179\u017b\u017d\u017f\u0181\u0183\u0185\u0187"
+ + "\u0189\u018b\u018d\u0197\u019b\u01a6\u01b1\u01bc\u01c1\u01ca"
+ + "\u01d3\u01d7\u01e1\u01e9\u01f2\u01fc\u0208\u0216\u0221\u022c"
+ + "\u0233\u023a\u0244\u024a\u024d\u0257\u0266\u026e\u027b\u028a"
+ + "\u0295\u029d\u02ab\u02b8\u02bf\u02c6\u02d2\u02d9\u02e3\u02e9"
+ + "\u02ec\u02f5\u02fc\u0303\u030f\u0319\u0320\u0327\u0333\u033d"
+ + "\u0341\u0348\u034f\u0356\u0362\u0369\u0373\u037c\u0383\u038a"
+ + "\u0391\u039d\u03a7\u03ae\u03b4\u03bf\u03c6\u03cd\u03d9\u03e0"
+ + "\u03ea\u03f0\u03f3\u03fc\u0403\u040a\u0416\u0420\u0427\u042e"
+ + "\u043a\u0444\u0448\u044f\u0456\u045d\u0469\u0470\u047a\u0481"
+ + "\u0488\u048f\u0496\u04a2\u04ac\u04b3\u04b9\u04c3\u04cb\u04d3"
+ + "\u04da\u04e1\u04e9\u04f1\u04f8\u04ff\u050b\u0517\u0522\u052d"
+ + "\u0534\u053b\u0542\u0549\u0550\u0557\u055f\u0567\u056e\u0575"
+ + "\u0580\u058b\u0593\u059b\u05a2\u05a9\u05b5\u05c1\u05c8\u05cf"
+ + "\u05da\u05e5\u05f2\u05ff\u060b\u0617\u061c\u0621\u0628\u062f"
+ + "\u0637\u063f\u0646\u064d\u0655\u065d\u0668\u0671\u0674\u0677"
+ + "\u0683\u068f\u069c\u06a9\u06b6\u06bd\u06c4\u06d1\u06de\u06e5"
+ + "\u06ec\u06f1\u06f6\u06fd\u0704\u070b\u0712\u071f\u072c\u0733"
+ + "\u073a\u0746\u074a\u074e\u0756\u075e\u0765\u076c\u077a\u0788"
+ + "\u078b\u078e\u0795\u079c\u07a9\u07b6\u07bd\u07c4\u07cb\u07d2"
+ + "\u07de\u07ea\u07f3\u07fc\u0803\u080a\u0817\u0824\u082b\u0832"
+ + "\u0837\u083c\u0843\u084a\u0852\u085a\u0861\u0868\u086e\u0874"
+ + "\u0882\u0890\u0898\u08a0\u08ac\u08b8\u08c4\u08d0\u08da\u08e1"
+ + "\u08e8\u08f3\u08fe\u0905\u090c\u0912\u0919\u091f\u0925\u092b"
+ + "\u0931\u0938\u093f\u094a\u0955\u095d\u0965\u0971\u097d\u098a"
+ + "\u0997\u09a1\u09ab\u09b6\u09bc\u09c2\u09cc\u09d1\u09d8\u09de"
+ + "\u09eb\u09f5\u09ff\u0a09\u0a17\u0a24\u0a2a\u0a38\u0a43\u0a4d"
+ + "\u0a5a\u0a63\u0a6d\u0a7a\u0a87\u0a92\u0aa4\u0aaa\u0aaf\u0ab5"
+ + "\u0abd\u0ac2\u0ac6\u0acc\u0ad1\u0ad7\u0ade\u0ae1\u0ae4\u0ae7"
+ + "\u0aef\u0af2\u0af6\u0afc\u0b00\u0b08\u0b0c\u0b10\u0b14\u0b21"
+ + "\u0b31\u0b3c\u0b49\u0b52\u0b5c\u0b71\u0b77\u0b7c\u0b82\u0b88"
+ + "\u0b90\u0b95\u0b99\u0b9f\u0ba4\u0baa\u0bb1\u0bb4\u0bb7\u0bbf"
+ + "\u0bc2\u0bc6\u0bcd\u0bd3\u0bd7\u0bdf\u0be3\u0be7\u0beb\u0bf1"
+ + "\u0bfe\u0c0e\u0c1b\u0c28\u0c33\u0c3a\u0c43\u0c48\u0c4f\u0c59"
+ + "\u0c63\u0c6d\u0c77\u0c81\u0c8b\u0c95\u0c9f\u0ca9\u0cb3\u0cbd"
+ + "\u0cc7\u0cd1\u0cdb\u0ce5\u0cef\u0cf9\u0d03\u0d0d\u0d17\u0d21"
+ + "\u0d2b\u0d35\u0d3f\u0d49\u0d53\u0d5d\u0d67\u0d71\u0d7b\u0d85"
+ + "\u0d8f\u0d99\u0da3\u0dad\u0db7\u0dc1\u0dcb\u0dd5\u0ddf\u0de9"
+ + "\u0df3\u0dfd\u0e07\u0e11\u0e1b\u0e25\u0e2f\u0e39\u0e43\u0e4d"
+ + "\u0e57\u0e61\u0e6b\u0e75\u0e7f\u0e89\u0e93\u0e9d\u0ea7\u0eb1"
+ + "\u0ebb\u0ec5\u0ecf\u0ed9\u0ee3\u0eed\u0ef7\u0f01\u0f0b\u0f15"
+ + "\u0f1f\u0f29\u0f33\u0f3d\u0f47\u0f51\u0f5b\u0f65\u0f6f\u0f79"
+ + "\u0f83\u0f8d\u0f97\u0fa1\u0fab\u0fb5\u0fbf\u0fc9\u0fd3\u0fdd"
+ + "\u0fe7\u0ff1\u0ffb\u1005\u100f\u1019\u1023\u102d\u1037\u1041"
+ + "\u104b\u1055\u105f\u1069\u1073\u107d\u1087\u1091\u109b\u10a5"
+ + "\u10af\u10b9\u10c3\u10cd\u10d7\u10e1\u10eb\u10f5\u10ff\u1109"
+ + "\u1113\u111d\u1127\u1131\u113b\u1145\u114f\u1159\u1163\u116d"
+ + "\u1177\u1181\u118b\u1195\u119f\u11a9\u11b3\u11bd\u11c7\u11d1"
+ + "\u11db\u11e5\u11ef\u11f9\u1203\u120d\u1217\u1221\u122b\u1235"
+ + "\u123f\u1249\u1253\u125d\u1267\u1271\u127b\u1285\u128f\u1299"
+ + "\u12a3\u12ad\u12b7\u12c1\u12cb\u12d5\u12df\u12e9\u12f3\u12fd"
+ + "\u1307\u1311\u131b\u1325\u132f\u1339\u1343\u134d\u1357\u1361"
+ + "\u136b\u1375\u137f\u1389\u1393\u139d\u13a7\u13b1\u13bb\u13c5"
+ + "\u13cf\u13d9\u13e3\u13ed\u13f7\u1401\u140b\u1415\u141f\u1429"
+ + "\u1433\u143d\u1447\u1451\u145b\u1465\u146f\u1479\u1483\u148d"
+ + "\u1497\u14a1\u14ab\u14b5\u14bf\u14c9\u14d3\u14dd\u14e7\u14f1"
+ + "\u14f8\u14ff\u1506\u150d\u1517\u1521\u1528\u152f\u1539\u1541"
+ + "\u1549\u1551\u155c\u1563\u156a\u1574\u1582\u158c\u1597\u15a6"
+ + "\u15b4\u15c1\u15cf\u15dc\u15e3\u15ed\u15f4\u1603\u1612\u161b"
+ + "\u1625\u162f\u1639\u1645\u164c\u1653\u1661\u1670\u167a\u1683"
+ + "\u1691\u1697\u169c\u16a3\u16ad\u16b2\u16b7\u16c1\u16ca\u16d4"
+ + "\u16de\u16ea\u16f3\u1700\u170a\u1710\u171a\u1720\u1729\u1733"
+ + "\u173d\u174a\u1756\u1763\u176d\u1775\u1780\u178a\u1794\u179e"
+ + "\u17ab\u17ba\u17c7\u17d2\u17e0\u17ed\u17fa\u1804\u1810\u181c"
+ + "\u1825\u182b\u1834\u183c\u1847\u1850\u1858\u1862\u1868\u1875"
+ + "\u187d\u188a\u1893\u189e\u18a4\u18af\u18b9\u18c6\u18cc\u18d5"
+ + "\u18df\u18e7\u18f1\u18fd\u1906\u1912\u191c\u1929\u1936\u1945"
+ + "\u194f\u195c\u196b\u1976\u1985\u1993\u199b\u19a1\u19af\u19ba"
+ + "\u19c5\u19cf\u19da\u19e3\u19ec\u19f5\u19fe\u1a07\u1a10\u1a19"
+ + "\u1a22\u1a2b\u1a34\u1a3d\u1a46\u1a4f\u1a58\u1a61\u1a6a\u1a73"
+ + "\u1a7c\u1a85\u1a8e\u1a97\u1aa0\u1aa9\u1ab2\u1abb\u1ac4\u1acd"
+ + "\u1ad6\u1adf\u1ae8\u1af1\u1afa\u1b03\u1b0c\u1b15\u1b1e\u1b27"
+ + "\u1b30\u1b39\u1b42\u1b4a\u1b52\u1b58\u1b60\u1b68\u1b70\u1b76"
+ + "\u1b7e\u1b88\u1b8f\u1b96\u1b9d\u1ba8\u1bb0\u1bb8\u1bc0\u1bc8"
+ + "\u1bd0\u1bd7\u1bde\u1be8\u1bf2\u1bfd\u1c07\u1c14\u1c18\u1c1f"
+ + "\u1c24\u1c2a\u1c2f\u1c35\u1c3d\u1c49";
+
+
+ /**
+ * The name of each glyph in the Adobe Glyph List for New Fonts
+ * (AGLFN). The name of the n-th glyph starts at position
+ * AGLFN_NAME_OFFSET.charAt(n). It ends before the following
+ * slash (slashes cannot be part of a PostScript name, which
+ * is why we use it for separation).
+ *
+ * <p>Generated from the Adobe Glyph List for New Fonts, version 1.1
+ * of 17 April 2003.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
+ * Glyph List for New Fonts</a>
+ */
+ private static final String AGLFN_NAMES
+ = "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/q"
+ + "uotesingle/parenleft/parenright/asterisk/plus/comma/hyphen/p"
+ + "eriod/slash/zero/one/two/three/four/five/six/seven/eight/nin"
+ + "e/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F"
+ + "/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backsla"
+ + "sh/bracketright/asciicircum/underscore/grave/a/b/c/d/e/f/g/h"
+ + "/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/bracerigh"
+ + "t/asciitilde/exclamdown/cent/sterling/currency/yen/brokenbar"
+ + "/section/dieresis/copyright/ordfeminine/guillemotleft/logica"
+ + "lnot/registered/macron/degree/plusminus/acute/mu/paragraph/p"
+ + "eriodcentered/cedilla/ordmasculine/guillemotright/onequarter"
+ + "/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumfle"
+ + "x/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumfl"
+ + "ex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/"
+ + "Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/U"
+ + "grave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/a"
+ + "grave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/"
+ + "egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumfle"
+ + "x/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odie"
+ + "resis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacu"
+ + "te/thorn/ydieresis/Amacron/amacron/Abreve/abreve/Aogonek/aog"
+ + "onek/Cacute/cacute/Ccircumflex/ccircumflex/Cdotaccent/cdotac"
+ + "cent/Ccaron/ccaron/Dcaron/dcaron/Dcroat/dcroat/Emacron/emacr"
+ + "on/Ebreve/ebreve/Edotaccent/edotaccent/Eogonek/eogonek/Ecaro"
+ + "n/ecaron/Gcircumflex/gcircumflex/Gbreve/gbreve/Gdotaccent/gd"
+ + "otaccent/Gcommaaccent/gcommaaccent/Hcircumflex/hcircumflex/H"
+ + "bar/hbar/Itilde/itilde/Imacron/imacron/Ibreve/ibreve/Iogonek"
+ + "/iogonek/Idotaccent/dotlessi/IJ/ij/Jcircumflex/jcircumflex/K"
+ + "commaaccent/kcommaaccent/kgreenlandic/Lacute/lacute/Lcommaac"
+ + "cent/lcommaaccent/Lcaron/lcaron/Ldot/ldot/Lslash/lslash/Nacu"
+ + "te/nacute/Ncommaaccent/ncommaaccent/Ncaron/ncaron/napostroph"
+ + "e/Eng/eng/Omacron/omacron/Obreve/obreve/Ohungarumlaut/ohunga"
+ + "rumlaut/OE/oe/Racute/racute/Rcommaaccent/rcommaaccent/Rcaron"
+ + "/rcaron/Sacute/sacute/Scircumflex/scircumflex/Scedilla/scedi"
+ + "lla/Scaron/scaron/Tcommaaccent/tcommaaccent/Tcaron/tcaron/Tb"
+ + "ar/tbar/Utilde/utilde/Umacron/umacron/Ubreve/ubreve/Uring/ur"
+ + "ing/Uhungarumlaut/uhungarumlaut/Uogonek/uogonek/Wcircumflex/"
+ + "wcircumflex/Ycircumflex/ycircumflex/Ydieresis/Zacute/zacute/"
+ + "Zdotaccent/zdotaccent/Zcaron/zcaron/longs/florin/Ohorn/ohorn"
+ + "/Uhorn/uhorn/Gcaron/gcaron/Aringacute/aringacute/AEacute/aea"
+ + "cute/Oslashacute/oslashacute/Scommaaccent/scommaaccent/afii5"
+ + "7929/afii64937/circumflex/caron/breve/dotaccent/ring/ogonek/"
+ + "tilde/hungarumlaut/gravecomb/acutecomb/tildecomb/hookaboveco"
+ + "mb/dotbelowcomb/tonos/dieresistonos/Alphatonos/anoteleia/Eps"
+ + "ilontonos/Etatonos/Iotatonos/Omicrontonos/Upsilontonos/Omega"
+ + "tonos/iotadieresistonos/Alpha/Beta/Gamma/Epsilon/Zeta/Eta/Th"
+ + "eta/Iota/Kappa/Lambda/Mu/Nu/Xi/Omicron/Pi/Rho/Sigma/Tau/Upsi"
+ + "lon/Phi/Chi/Psi/Iotadieresis/Upsilondieresis/alphatonos/epsi"
+ + "lontonos/etatonos/iotatonos/upsilondieresistonos/alpha/beta/"
+ + "gamma/delta/epsilon/zeta/eta/theta/iota/kappa/lambda/nu/xi/o"
+ + "micron/pi/rho/sigma1/sigma/tau/upsilon/phi/chi/psi/omega/iot"
+ + "adieresis/upsilondieresis/omicrontonos/upsilontonos/omegaton"
+ + "os/theta1/Upsilon1/phi1/omega1/afii10023/afii10051/afii10052"
+ + "/afii10053/afii10054/afii10055/afii10056/afii10057/afii10058"
+ + "/afii10059/afii10060/afii10061/afii10062/afii10145/afii10017"
+ + "/afii10018/afii10019/afii10020/afii10021/afii10022/afii10024"
+ + "/afii10025/afii10026/afii10027/afii10028/afii10029/afii10030"
+ + "/afii10031/afii10032/afii10033/afii10034/afii10035/afii10036"
+ + "/afii10037/afii10038/afii10039/afii10040/afii10041/afii10042"
+ + "/afii10043/afii10044/afii10045/afii10046/afii10047/afii10048"
+ + "/afii10049/afii10065/afii10066/afii10067/afii10068/afii10069"
+ + "/afii10070/afii10072/afii10073/afii10074/afii10075/afii10076"
+ + "/afii10077/afii10078/afii10079/afii10080/afii10081/afii10082"
+ + "/afii10083/afii10084/afii10085/afii10086/afii10087/afii10088"
+ + "/afii10089/afii10090/afii10091/afii10092/afii10093/afii10094"
+ + "/afii10095/afii10096/afii10097/afii10071/afii10099/afii10100"
+ + "/afii10101/afii10102/afii10103/afii10104/afii10105/afii10106"
+ + "/afii10107/afii10108/afii10109/afii10110/afii10193/afii10146"
+ + "/afii10194/afii10147/afii10195/afii10148/afii10196/afii10050"
+ + "/afii10098/afii10846/afii57799/afii57801/afii57800/afii57802"
+ + "/afii57793/afii57794/afii57795/afii57798/afii57797/afii57806"
+ + "/afii57796/afii57807/afii57839/afii57645/afii57841/afii57842"
+ + "/afii57804/afii57803/afii57658/afii57664/afii57665/afii57666"
+ + "/afii57667/afii57668/afii57669/afii57670/afii57671/afii57672"
+ + "/afii57673/afii57674/afii57675/afii57676/afii57677/afii57678"
+ + "/afii57679/afii57680/afii57681/afii57682/afii57683/afii57684"
+ + "/afii57685/afii57686/afii57687/afii57688/afii57689/afii57690"
+ + "/afii57716/afii57717/afii57718/afii57388/afii57403/afii57407"
+ + "/afii57409/afii57410/afii57411/afii57412/afii57413/afii57414"
+ + "/afii57415/afii57416/afii57417/afii57418/afii57419/afii57420"
+ + "/afii57421/afii57422/afii57423/afii57424/afii57425/afii57426"
+ + "/afii57427/afii57428/afii57429/afii57430/afii57431/afii57432"
+ + "/afii57433/afii57434/afii57440/afii57441/afii57442/afii57443"
+ + "/afii57444/afii57445/afii57446/afii57470/afii57448/afii57449"
+ + "/afii57450/afii57451/afii57452/afii57453/afii57454/afii57455"
+ + "/afii57456/afii57457/afii57458/afii57392/afii57393/afii57394"
+ + "/afii57395/afii57396/afii57397/afii57398/afii57399/afii57400"
+ + "/afii57401/afii57381/afii63167/afii57511/afii57506/afii57507"
+ + "/afii57512/afii57513/afii57508/afii57505/afii57509/afii57514"
+ + "/afii57519/afii57534/Wgrave/wgrave/Wacute/wacute/Wdieresis/w"
+ + "dieresis/Ygrave/ygrave/afii61664/afii301/afii299/afii300/fig"
+ + "uredash/endash/emdash/afii00208/underscoredbl/quoteleft/quot"
+ + "eright/quotesinglbase/quotereversed/quotedblleft/quotedblrig"
+ + "ht/quotedblbase/dagger/daggerdbl/bullet/onedotenleader/twodo"
+ + "tenleader/ellipsis/afii61573/afii61574/afii61575/perthousand"
+ + "/minute/second/guilsinglleft/guilsinglright/exclamdbl/fracti"
+ + "on/colonmonetary/franc/lira/peseta/afii57636/dong/Euro/afii6"
+ + "1248/Ifraktur/afii61289/afii61352/weierstrass/Rfraktur/presc"
+ + "ription/trademark/Omega/estimated/aleph/onethird/twothirds/o"
+ + "neeighth/threeeighths/fiveeighths/seveneighths/arrowleft/arr"
+ + "owup/arrowright/arrowdown/arrowboth/arrowupdn/arrowupdnbse/c"
+ + "arriagereturn/arrowdblleft/arrowdblup/arrowdblright/arrowdbl"
+ + "down/arrowdblboth/universal/partialdiff/existential/emptyset"
+ + "/Delta/gradient/element/notelement/suchthat/product/summatio"
+ + "n/minus/asteriskmath/radical/proportional/infinity/orthogona"
+ + "l/angle/logicaland/logicalor/intersection/union/integral/the"
+ + "refore/similar/congruent/approxequal/notequal/equivalence/le"
+ + "ssequal/greaterequal/propersubset/propersuperset/notsubset/r"
+ + "eflexsubset/reflexsuperset/circleplus/circlemultiply/perpend"
+ + "icular/dotmath/house/revlogicalnot/integraltp/integralbt/ang"
+ + "leleft/angleright/SF100000/SF110000/SF010000/SF030000/SF0200"
+ + "00/SF040000/SF080000/SF090000/SF060000/SF070000/SF050000/SF4"
+ + "30000/SF240000/SF510000/SF520000/SF390000/SF220000/SF210000/"
+ + "SF250000/SF500000/SF490000/SF380000/SF280000/SF270000/SF2600"
+ + "00/SF360000/SF370000/SF420000/SF190000/SF200000/SF230000/SF4"
+ + "70000/SF480000/SF410000/SF450000/SF460000/SF400000/SF540000/"
+ + "SF530000/SF440000/upblock/dnblock/block/lfblock/rtblock/ltsh"
+ + "ade/shade/dkshade/filledbox/H22073/H18543/H18551/filledrect/"
+ + "triagup/triagrt/triagdn/triaglf/lozenge/circle/H18533/invbul"
+ + "let/invcircle/openbullet/smileface/invsmileface/sun/female/m"
+ + "ale/spade/club/heart/diamond/musicalnote/musicalnotedbl/";
+
+
+ /**
+ * Determines the name of a glyph according to the Adobe Glyph List
+ * for New Fonts (AGLFN). Because all glyphs in AGLFN correspond to
+ * a precomposed Unicode codepoint, the mismatch between characters
+ * and glyphs is not an issue here.
+ *
+ * @param c the Unicode codepoint that corresponds to the glyph, for
+ * example <code>0x010a</code> for <code>LATIN CAPITAL LETTER C WITH
+ * DOT ABOVE</code>.
+ *
+ * @return the glyph name, for example <code>Cdotaccent</code>. If
+ * the glyph is not in the <i>Adobe Glyph List for New Fonts</i>,
+ * <code>null</code> is returned.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
+ * Glyph List for New Fonts (AGLFN), version 1.1 of April 17,
+ * 2003</a>
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/developer/type/unicodegn.html#6"
+ * >Adobe&#x2019;s guidelines related to Unicode</a>
+ */
+ private static String getAGLFNName(char c)
+ {
+ int min, max, mid;
+ char midChar;
+
+ /* Performs a binary search in the sorted array (actually, a
+ * String) of glyphs in the Adobe Glyph List for New Fonts.
+ *
+ * A good compiler might be able to optimize a call to charAt for
+ * a static final String, but this routine is probably not that
+ * critical to performance.
+ */
+ min = 0;
+ max = AGLFN_GLYPHS.length() - 1;
+ mid = max >> 1;
+ midChar = AGLFN_GLYPHS.charAt(mid);
+ do
+ {
+ if (midChar == c)
+ break;
+ else if (midChar < c)
+ min = mid + 1;
+ else
+ max = mid;
+ mid = (min + max) >> 1;
+ midChar = AGLFN_GLYPHS.charAt(mid);
+ }
+ while (min < max);
+
+ if (midChar != c)
+ return null;
+
+ int pos = AGLFN_NAME_OFFSET.charAt(mid);
+ return AGLFN_NAMES.substring(pos, AGLFN_NAMES.indexOf('/', pos));
+ }
+
+
+ /**
+ * Returns the PostScript name of a glyph, given the sequence of
+ * Unicode characters that is required to produce the glyph. The
+ * returned name follows Adobe&#x2019;s glyph naming recommendations
+ * in order to allow searching and indexing of the produced
+ * PostScript and PDF.
+ *
+ * <p>Some examples:
+ * <ul><li><code>U+0041</code> gives <code>A</code>;</li>
+ * <li><code>U+011D</code> gives <code>gcircumflex</code>;</li>
+ * <li><code>U+007A U+0302</code> gives <code>z_uni0302</code>;</li>
+ * <li><code>U+D807 U+DC42</code> (an UTF-16 escape sequence)
+ * gives <code>u11C42</code>;</li>
+ * </ul>.
+ *
+ * <p>The routine does <i>not</i> bring sequences in any canonical
+ * form. Therefore, the result for <code>U+0067 U+0302</code> (the
+ * decomposition of <code>U+011D</code>) will be
+ * <code>g_uni0302</code>, not <code>gcircumflex</code>.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/unicodegn.jsp" >Unicode
+ * and Glyph Names</a> and <a href=
+ * "http://partners.adobe.com/asn/tech/type/glyphnamelimits.jsp"
+ * >Glyph Names and Current Implementations</a>
+ */
+ private static String getGlyphName(char[] chars)
+ {
+ char c;
+ String name;
+ int numChars;
+ boolean hasSurrogates = false;
+
+ if ((chars == null) || ((numChars = chars.length) == 0))
+ return ".notdef";
+
+ /* The vast majority of cases will be just a single character.
+ * Therefore, we have a special code path for this case.
+ */
+ if (numChars == 1)
+ {
+ c = chars[0];
+ name = getAGLFNName(c);
+ if (name != null)
+ return name;
+ }
+
+ StringBuffer buf = new StringBuffer(numChars * 8);
+ for (int i = 0; i < numChars; i++)
+ {
+ if (i > 0)
+ buf.append('_');
+ c = chars[i];
+
+ /* handle surrogate pairs */
+ if (c >> 10 == 0x36) // U+D800 .. U+DBFF: High surrogate
+ {
+ /* Adobe recommends using the 'u' prefix only for
+ * characters outside the Unicode Basic Multilingual Plane,
+ * because Acrobat 4 and 5 understand only the "uni" prefix.
+ * The 'u' prefix will be supported by Acrobat 6 and later.
+ *
+ * For further information, please refer to this page:
+ * http://partners.adobe.com/asn/tech/type/glyphnamelimits.jsp#3
+ */
+ int ucs4 = (((c & 0x3ff) << 10) | (chars[++i] & 0x3ff)) + 0x10000;
+ buf.append('u');
+ buf.append(Integer.toHexString(ucs4).toUpperCase());
+ }
+ else
+ {
+ /* Try the Adobe Glyph List. */
+ name = getAGLFNName(c);
+ if (name != null)
+ buf.append(name);
+ else
+ {
+ char nibble;
+ buf.append("uni");
+ nibble = (char) (((c >> 12) & 0xf) + 0x30);
+ if (nibble > 0x39)
+ nibble += 7;
+ buf.append(nibble);
+ nibble = (char) (((c >> 8) & 0xf) + 0x30);
+ if (nibble > 0x39)
+ nibble += 7;
+ buf.append(nibble);
+ nibble = (char) (((c >> 4) & 0xf) + 0x30);
+ if (nibble > 0x39)
+ nibble += 7;
+ buf.append(nibble);
+ nibble = (char) (((c >> 0) & 0xf) + 0x30);
+ if (nibble > 0x39)
+ nibble += 7;
+ buf.append(nibble);
+ }
+ }
+ }
+ return buf.toString();
+ }
+}
diff --git a/gnu/java/awt/font/opentype/MacResourceFork.java b/gnu/java/awt/font/opentype/MacResourceFork.java
new file mode 100644
index 000000000..8115e0403
--- /dev/null
+++ b/gnu/java/awt/font/opentype/MacResourceFork.java
@@ -0,0 +1,235 @@
+/* MacResourceFork.java -- Parses MacOS resource forks.
+ 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 java.nio.ByteBuffer;
+
+
+/**
+ * A class for accessing data that is stored in the resource fork of
+ * Macintosh files. Writing resource forks is currently not supported.
+ *
+ * <p>The gnu.java.awt.font package uses this class for accessing
+ * fonts in the MacOS X ".dfont" format, which is is a file in the
+ * format of a Macintosh resource fork, but stored in the normal data
+ * fork of the file.
+ *
+ * <p>The implementation has been designed to work efficiently with
+ * the virtual memory subsystem. It is recommended to pass an
+ * instance of {@link java.nio.MappedByteBuffer} to the constructor.
+ *
+ * <p>Thread Safety: All access is synchronized on the ByteBuffer
+ * that is passed to the constructor.
+ *
+ * @see <a href=
+ * "http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html"
+ * >Apple&#x2019; developer documentation about the Resource File
+ * Format</a>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class MacResourceFork
+{
+ int[] types;
+ Resource[][] resources;
+ ByteBuffer buf;
+
+ public MacResourceFork(ByteBuffer buf)
+ {
+ int typeListOffset;
+ int refListOffset;
+ int nameListOffset;
+ int mapOffset, mapLen;
+ int dataOffset, dataLen;
+ int numTypes;
+
+ synchronized (buf)
+ {
+ buf = buf.duplicate();
+ this.buf = buf;
+ buf.position(0);
+ dataOffset = buf.getInt();
+ mapOffset = buf.getInt();
+ dataLen = buf.getInt();
+ mapLen = buf.getInt();
+ buf.position(mapOffset + 24);
+ refListOffset = mapOffset + buf.getChar();
+ nameListOffset = mapOffset + buf.getChar();
+ numTypes = buf.getChar() + 1;
+ types = new int[numTypes];
+ resources = new Resource[numTypes][];
+
+ /* Parse resource type list. */
+ typeListOffset = buf.position();
+ for (int i = 0; i < numTypes; i++)
+ {
+ buf.position(typeListOffset + 8 * i);
+ int resType = buf.getInt();
+ int numRes = buf.getChar() + 1;
+
+ types[i] = resType;
+ resources[i] = new Resource[numRes];
+
+ buf.position(refListOffset + buf.getChar());
+ for (int j = 0; j < numRes; j++)
+ {
+ short resID = buf.getShort();
+ int resNameOffset = nameListOffset + buf.getChar();
+ int resDataOffset = buf.getInt();
+ byte resAttr = (byte) (resDataOffset >> 24);
+ resDataOffset = dataOffset + (resDataOffset & 0x00ffffff);
+ buf.getInt(); /* skip four reserved bytes */
+
+ Resource rsrc = new Resource(buf, resType, resID, resDataOffset,
+ resNameOffset);
+ resources[i][j] = rsrc;
+ }
+ }
+ }
+ }
+
+
+ public Resource[] getResources(int type)
+ {
+ synchronized (buf)
+ {
+ for (int i = 0; i < types.length; i++)
+ {
+ if (types[i] == type)
+ return resources[i];
+ }
+ }
+ return null;
+ }
+
+
+ public Resource getResource(int type, short id)
+ {
+ Resource[] res;
+
+ synchronized (buf)
+ {
+ for (int i = 0; i < types.length; i++)
+ {
+ if (types[i] != type)
+ continue;
+
+ res = resources[i];
+ for (int j = 0; j < res.length; j++)
+ if (res[j].getID() == id)
+ return res[j];
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * A single resource that is contained in a resource fork.
+ */
+ public static final class Resource
+ {
+ int type;
+ short id;
+ byte attribute;
+ int nameOffset;
+ int dataOffset;
+ ByteBuffer buf;
+
+ private Resource(ByteBuffer buf,
+ int type, short id, int dataOffset, int nameOffset)
+ {
+ this.buf = buf;
+ this.type = type;
+ this.id = id;
+ this.dataOffset = dataOffset;
+ this.nameOffset = nameOffset;
+ }
+
+
+ /**
+ * Returns the type of this resource.
+ *
+ * @return an <code>int</code> encoding a four-byte type tag,
+ * such as <code>0x464f4e54</code> for <code>'FONT'</code>.
+ */
+ public int getType()
+ {
+ return type;
+ }
+
+
+ /**
+ * Returns the ID of this resource.
+ */
+ public short getID()
+ {
+ return id;
+ }
+
+
+ /**
+ * Retrieves the content of the resource. Only one page of memory
+ * is touched, irrespective of the actual size of the resource.
+ */
+ public ByteBuffer getContent()
+ {
+ synchronized (buf)
+ {
+ buf.limit(buf.capacity());
+ int len = buf.getInt(dataOffset);
+ buf.position(dataOffset + 4).limit(dataOffset + 4 + len);
+ return buf.slice();
+ }
+ }
+
+
+ /**
+ * Determines the length of the resource in bytes.
+ */
+ public int getLength()
+ {
+ synchronized (buf)
+ {
+ return buf.getInt(dataOffset);
+ }
+ }
+ }
+}
diff --git a/gnu/java/awt/font/opentype/NameDecoder.java b/gnu/java/awt/font/opentype/NameDecoder.java
new file mode 100644
index 000000000..bc0c0df09
--- /dev/null
+++ b/gnu/java/awt/font/opentype/NameDecoder.java
@@ -0,0 +1,686 @@
+/* NameDecoder.java -- Decodes names of OpenType and TrueType fonts.
+ 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 java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Locale;
+
+
+/**
+ * A utility class that helps with decoding the names of OpenType
+ * and TrueType fonts.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+class NameDecoder
+{
+ public static final int NAME_COPYRIGHT = 0;
+
+
+ /**
+ * Specifies the name of the family to which a font belongs, for
+ * example &#x201c;Univers&#x201d;.
+ */
+ public static final int NAME_FAMILY = 1;
+
+
+ /**
+ * Specified the name of the font inside its family, for
+ * example &#x201c;Light&#x201d;.
+ */
+ public static final int NAME_SUBFAMILY = 2;
+
+
+ public static final int NAME_UNIQUE = 3;
+
+
+ /**
+ * Specifies the full human-readable name of a font, for example
+ * &#x201c;Univers Light&#x201d;
+ */
+ public static final int NAME_FULL = 4;
+
+
+ public static final int NAME_VERSION = 5;
+
+
+ /**
+ * Specifies the PostScript name of a font, for example
+ * &#x201c;Univers-Light&#x201d;.
+ */
+ public static final int NAME_POSTSCRIPT = 6;
+
+
+ public static final int NAME_TRADEMARK = 7;
+ public static final int NAME_MANUFACTURER = 8;
+ public static final int NAME_DESIGNER = 9;
+ public static final int NAME_DESCRIPTION = 10;
+ public static final int NAME_VENDOR_URL = 11;
+ public static final int NAME_DESIGNER_URL = 12;
+ public static final int NAME_LICENSE = 13;
+ public static final int NAME_LICENSE_URL = 14;
+ public static final int NAME_PREFERRED_FAMILY = 16;
+ public static final int NAME_PREFERRED_SUBFAMILY = 17;
+ public static final int NAME_FULL_MACCOMPATIBLE = 18;
+ public static final int NAME_SAMPLE_TEXT = 19;
+ public static final int NAME_POSTSCRIPT_CID = 20;
+
+
+ private static final int PLATFORM_MACINTOSH = 1;
+ private static final int PLATFORM_MICROSOFT = 3;
+
+
+ public static String getName(ByteBuffer nameTable,
+ int name, Locale locale)
+ {
+ int numRecords;
+ int macLanguage, msLanguage;
+ int offset;
+ int namePlatform, nameEncoding, nameLanguage, nameID, nameLen;
+ int nameStart;
+ String result;
+ boolean match;
+
+ if (nameTable == null)
+ return null;
+
+ nameTable.position(0);
+ /* We understand only format 0 of the name table. */
+ if (nameTable.getChar() != 0)
+ return null;
+
+ macLanguage = getMacLanguageCode(locale);
+ msLanguage = getMicrosoftLanguageCode(locale);
+ numRecords = nameTable.getChar();
+ offset = nameTable.getChar();
+
+ for (int i = 0; i < numRecords; i++)
+ {
+ namePlatform = nameTable.getChar();
+ nameEncoding = nameTable.getChar();
+ nameLanguage = nameTable.getChar();
+ nameID = nameTable.getChar();
+ nameLen = nameTable.getChar();
+ nameStart = offset + nameTable.getChar();
+
+
+ if (nameID != name)
+ continue;
+
+ match = false;
+ switch (namePlatform)
+ {
+ case PLATFORM_MACINTOSH:
+ if ((nameLanguage == macLanguage) || (locale == null))
+ match = true;
+ else
+ {
+ switch (macLanguage)
+ {
+ case 49: /* Azerbaijani/Cyrillic */
+ match = (nameLanguage == /* Azerbaijani/Arabic */ 50)
+ || (nameLanguage == /* Azerbaijani/Roman */ 150);
+ break;
+
+ case 57: /* Mongolian/Mongolian */
+ match = (nameLanguage == /* Mongolian/Cyrillic */ 58);
+ break;
+
+ case 83: /* Malay/Roman */
+ match = (nameLanguage == /* Malay/Arabic */ 84);
+ break;
+ }
+ }
+ break;
+
+ case PLATFORM_MICROSOFT:
+ if (((nameLanguage & 0xff) == msLanguage) || (locale == null))
+ match = true;
+ break;
+ }
+
+
+ if (match)
+ {
+ result = decodeName(namePlatform, nameEncoding, nameLanguage,
+ nameTable, nameStart, nameLen);
+ if (result != null)
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * The language codes used by the Macintosh operating system. MacOS
+ * defines numeric language identifiers in the range [0 .. 95] and
+ * [128 .. 150]. To map this numeric identifier into an ISO 639
+ * language code, multiply it by two and take the substring at that
+ * position.
+ *
+ * <p>ISO 639 has revised the code for some languages, namely
+ * <code>he</code> for Hebrew (formerly <code>iw</code>),
+ * <code>yi</code> (formerly <code>ji</code>), and <code>id</code>
+ * for Indonesian (formerly <code>in</code>). In those cases, this
+ * table intentionally contains the older, obsolete code. The
+ * reason is that this is the code which
+ * java.util.Locale.getLanguage() is specified to return. The
+ * implementation of {@link #getMacLanguageCode} depends on this.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/unicode/onlinedat/languages.html"
+ * >Language Codes: ISO 639, Microsoft and Macintosh</a>
+ */
+ private static final String macLanguageCodes
+ // 0 1 2
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ = "enfrdeitnlsvesdaptnoiwjaarfielismttrhrzhurhithkoltplhuetlv "
+
+ // 3 4 5
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + "fofaruzhnlgdsqrocssksljisrmkbgukbeuzkkazazhykamokytgtkmnmnps"
+
+ // 6 7 8
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + "kukssdbonesamrbnasgupaormlkntatesimykmloviintlmsmsamti sosw"
+
+ // 9 10 11
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + "rwrn mgeo "
+
+ // 12 13 14
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + " cyeucalaqugnayttugtsjwsuglafbriugdgvgatoelkl"
+
+ // 15
+ // 0
+ + "az";
+
+
+ /**
+ * The primary language IDs used by the Microsoft operating systems.
+ *
+ * <p>ISO 639 has revised the code for some languages, namely
+ * <code>he</code> for Hebrew (formerly <code>iw</code>),
+ * <code>yi</code> (formerly <code>ji</code>), and <code>id</code>
+ * for Indonesian (formerly <code>in</code>). In those cases, this
+ * table intentionally contains the older, obsolete code. The
+ * reason is that this is the code which
+ * java.util.Locale.getLanguage() is specified to return. The
+ * implementation of {@link #getMicrosoftLanguageCode} depends on
+ * this.
+ *
+ * @see <a href=
+ * "http://www.unicode.org/unicode/onlinedat/languages.html"
+ * >Language Codes: ISO 639, Microsoft and Macintosh</a>
+ */
+ private static final String microsoftLanguageCodes
+ // 0 1 2
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ = " arbgcazhcsdadeelenesfifriwhuisitjakonlnoplptrmrorushsksqsv"
+
+ // 3 4 5
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + "thtrurinukbesletlvlttgfavihyazeu mk ts xhzuafkafohimt "
+
+ // 6 7 8
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + "gajimskkkyswtkuzttbnpaguortateknmlasmrsamnbocykmlomygl sd"
+
+ // 9 10 11
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
+ + " si iuam ksnefypstl ha yo omtign laso";
+
+
+ /**
+ * Maps a Java Locale into a MacOS language code.
+ *
+ * <p>For languages that are written in several script systems,
+ * MacOS defines multiple language codes. Java Locales have a
+ * variant which could be used for that purpose, but a small
+ * test program revealed that with Sun's JDK 1.4.1_01, only two
+ * of 134 available Locales have a variant tag (namely no_NO_NY
+ * and th_TH_TH).</p>
+ *
+ * <p>The following cases are problematic:
+ *
+ * <ul> <li>Azerbaijani (az): The MacOS language code is 49 if
+ * Azerbaijani is written in the Cyrillic script; 50 if written in
+ * the Arabic script; 150 if written in the Roman script. This
+ * method will always return 49 for the Azerbaijani locale.</li>
+ *
+ * <li>Mongolian (mn): The MacOS language code is 57 if Mongolian is
+ * written in the Mongolian script; 58 if written in the Cyrillic
+ * script. This method will always return 57 for the Mongolian
+ * locale.</li>
+ *
+ * <li>Malay (ms): The MacOS language code is 83 if Malay is written
+ * in the Roman script; 84 if written in the Arabic script. This
+ * method will always return 83 for the Malay locale.</li> </ul>
+ *
+ * @return a MacOS language code, or -1 if there is no such code for
+ * <code>loc</code>&#x2019;s language.
+ */
+ private static int getMacLanguageCode(Locale loc)
+ {
+ int code;
+
+ if (loc == null)
+ return -1;
+
+ code = findLanguageCode(loc.getLanguage(), macLanguageCodes);
+ switch (code)
+ {
+ case 19:
+ /* Traditional Chinese (MacOS language #19) and and Simplified
+ * Chinese (MacOS language #33) both have "zh" as their ISO 639
+ * code.
+ */
+ if (loc.equals(Locale.SIMPLIFIED_CHINESE))
+ code = 33;
+ break;
+
+ // Other special cases would be 49, 57 and 83, but we do not
+ // know what do do about them. See the method documentation for
+ // details.
+ }
+
+ return code;
+ }
+
+
+ /**
+ * Maps a Java Locale into a Microsoft language code.
+ */
+ private static int getMicrosoftLanguageCode(Locale locale)
+ {
+ String isoCode;
+ int code;
+
+ if (locale == null)
+ return -1;
+
+ isoCode = locale.getLanguage();
+ code = findLanguageCode(isoCode, microsoftLanguageCodes);
+ if (code == -1)
+ {
+ if (isoCode.equals("hr") || isoCode.equals("sr"))
+ {
+ /* Microsoft uses code 26 for "sh" (Serbo-Croatian),
+ * "hr" (Croatian) and "sr" (Serbian). Our table contains
+ * "sh".
+ */
+ code = 26;
+ }
+ else if (isoCode.equals("gd"))
+ {
+ /* Microsoft uses code 60 for "gd" (Scottish Gaelic) and
+ * "ga" (Irish Gaelic). Out table contains "ga".
+ */
+ code = 60;
+ }
+ }
+ return code;
+ }
+
+
+ private static int findLanguageCode(String lang, String langCodes)
+ {
+ int index;
+ if (lang == null)
+ return -1;
+
+ if (lang.length() != 2)
+ return -1;
+
+ index = 0;
+ do
+ {
+ index = langCodes.indexOf(lang, index);
+
+ /* The index must be even to be considered a match. Otherwise, we
+ * could match with the second letter of one language and the
+ * first of antoher one.
+ */
+ }
+ while (!((index < 0) || ((index & 1) == 0)));
+ if (index < 0)
+ return -1;
+
+ index = index / 2;
+ return index;
+ }
+
+
+ private static String decodeName(int platform, int encoding, int language,
+ ByteBuffer buffer, int offset, int len)
+ {
+ byte[] byteBuf;
+ String charsetName;
+ int oldPosition;
+
+ charsetName = getCharsetName(platform, language, encoding);
+ if (charsetName == null)
+ return null;
+
+ byteBuf = new byte[len];
+ oldPosition = buffer.position();
+ try
+ {
+ buffer.position(offset);
+ buffer.get(byteBuf);
+ try
+ {
+ return new String(byteBuf, charsetName);
+ }
+ catch (UnsupportedEncodingException uex)
+ {
+ }
+ }
+ finally
+ {
+ buffer.position(oldPosition);
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Maps a MacOS language code into a Java Locale.
+ *
+ * @param macLanguageCode the MacOS language code for
+ * the language whose Java locale is to be retrieved.
+ *
+ * @return an suitable Locale, or <code>null</code> if
+ * the mapping cannot be performed.
+ */
+ private static Locale getMacLocale(int macLanguageCode)
+ {
+ String isoCode;
+
+ switch (macLanguageCode)
+ {
+ case 0: return Locale.ENGLISH;
+ case 1: return Locale.FRENCH;
+ case 2: return Locale.GERMAN;
+ case 3: return Locale.ITALIAN;
+ case 11: return Locale.JAPANESE;
+ case 23: return Locale.KOREAN;
+ case 19: return Locale.TRADITIONAL_CHINESE;
+ case 33: return Locale.SIMPLIFIED_CHINESE;
+ }
+
+ if ((macLanguageCode < 0) || (macLanguageCode > 150))
+ return null;
+
+ isoCode = macLanguageCodes.substring(macLanguageCode << 1,
+ (macLanguageCode + 1) << 1);
+ if (isoCode.charAt(0) == ' ')
+ return null;
+
+ return new Locale(isoCode);
+ }
+
+
+
+ /**
+ * Maps a Windows LCID into a Java Locale.
+ *
+ * @param lcid the Windows language ID whose Java locale
+ * is to be retrieved.
+ *
+ * @return an suitable Locale, or <code>null</code> if
+ * the mapping cannot be performed.
+ */
+ private static Locale getWindowsLocale(int lcid)
+ {
+ /* FIXME: This is grossly incomplete. */
+ switch (lcid)
+ {
+ case 0x0407: return Locale.GERMAN;
+ case 0x0408: return new Locale("el", "GR");
+ case 0x0409: return Locale.ENGLISH;
+ case 0x040b: return new Locale("fi");
+ case 0x040c: return Locale.FRENCH;
+ case 0x0416: return new Locale("pt");
+ case 0x0807: return new Locale("de", "CH");
+ case 0x0809: return new Locale("en", "UK");
+ case 0x080c: return new Locale("fr", "BE");
+ case 0x0816: return new Locale("pt", "BR");
+ case 0x0c07: return new Locale("de", "AT");
+ case 0x0c09: return new Locale("en", "AU");
+ case 0x0c0c: return new Locale("fr", "CA");
+ case 0x1007: return new Locale("de", "LU");
+ case 0x1009: return new Locale("en", "CA");
+ case 0x100c: return new Locale("fr", "CH");
+ case 0x1407: return new Locale("de", "LI");
+ case 0x1409: return new Locale("en", "NZ");
+ case 0x140c: return new Locale("fr", "LU");
+ case 0x1809: return new Locale("en", "IE");
+
+ default:
+ return null;
+ }
+ }
+
+
+ /**
+ * Maps a Macintosh Script Manager code to the name of the
+ * corresponding Java Charset.
+ *
+ * @param macScript a MacOS ScriptCode, for example
+ * 6 for <code>smGreek</code>.
+ *
+ * @return a String that can be used to retrieve a Java
+ * CharsetDecorder, for example <code>MacGreek</code>, or
+ * <code>null</code> if <code>macScript</code> has an
+ * unsupported value.
+ */
+ private static String getMacCharsetName(int macScript)
+ {
+ switch (macScript)
+ {
+ case 0: return "MacRoman";
+ case 1: return "MacJapanese";
+ case 2: return "MacKorean";
+ case 3: return "MacTradChinese";
+ case 4: return "MacArabic";
+ case 5: return "MacHebrew";
+ case 6: return "MacGreek";
+ case 7: return "MacCyrillic";
+ case 8: return "MacRSymbol";
+ case 9: return "MacDevanagari";
+ case 10: return "MacGurmukhi";
+ case 11: return "MacGujarati";
+ case 12: return "MacOriya";
+ case 13: return "MacBengali";
+ case 14: return "MacTamil";
+ case 15: return "MacTelugu";
+ case 16: return "MacKannada";
+ case 17: return "MacMalayalam";
+ case 18: return "MacSinhalese";
+ case 19: return "MacBurmese";
+ case 20: return "MacKhmer";
+ case 21: return "MacThai";
+ case 22: return "MacLao";
+ case 23: return "MacGeorgian";
+ case 24: return "MacArmenian";
+ case 25: return "MacSimpChinese";
+ case 26: return "MacTibetan";
+ case 27: return "MacMongolian";
+ case 28: return "MacEthiopic";
+ case 29: return "MacCentralEurope";
+ case 30: return "MacVietnamese";
+ case 31: return "MacExtArabic";
+
+ default: return null;
+ }
+ }
+
+
+ /**
+ * Maps a Microsoft locale ID (LCID) to the name of the
+ * corresponding Java Charset.
+ *
+ * @param lcid the Microsoft locale ID.
+ *
+ * @return a String that can be used to retrieve a Java
+ * CharsetDecorder, for example <code>windows-1252</code>, or
+ * <code>null</code> if <code>lcid</code> has an unsupported value.
+ */
+ private static String getMicrosoftCharsetName(int lcid)
+ {
+ int lang;
+ char codePage = '?';
+
+ /* Extract the language code from the LCID. */
+ lang = lcid & 0x3ff;
+
+ /* In the majority of cases, the language alone determines the
+ * codepage.
+ */
+ if (lang < 100)
+ codePage = (" 612D022322225022EC2202201?002A462110777 68 ?2 1 "
+ + " 2 2 2112 ?1 1 2 2 ")
+ .charAt(lang);
+
+ /* There are a few exceptions, however, where multiple code pages
+ * are used for the same language. */
+ if (codePage == '?')
+ {
+ switch (lcid)
+ {
+ case 0x041a: // Croatian --> Windows-1250 (Central Europe)
+ case 0x081a: // Serbian (Latin) --> Windows-1250 (Central Europe)
+ codePage = '0';
+ break;
+
+ case 0x42c: // Azeri (Latin) --> Windows-1254 (Turkish)
+ case 0x443: // Uzbek (Latin) --> Windows-1254 (Turkish)
+ codePage = '4';
+ break;
+
+ case 0x82c: // Azeri (Cyrillic) --> Windows-1251 (Cyrillic)
+ case 0x843: // Uzbek (Cyrillic) --> Windows-1251 (Cyrillic)
+ case 0xc1a: // Serbian (Cyrillic) --> Windows-1251 (Cyrillic)
+ codePage = '1';
+ break;
+ }
+ }
+
+ switch (codePage)
+ {
+ case '0': return "windows-1250"; // Central Europe
+ case '1': return "windows-1251"; // Cyrillic
+ case '2': return "windows-1252"; // Latin 1
+ case '3': return "windows-1253"; // Greek
+ case '4': return "windows-1254"; // Turkish
+ case '5': return "windows-1255"; // Hebrew
+ case '6': return "windows-1256"; // Arabic
+ case '7': return "windows-1257"; // Baltic
+ case '8': return "windows-1258"; // Vietnam
+ case 'A': return "windows-874"; // Thai
+ case 'B': return "windows-936"; // Simplified Chinese, GBK
+ case 'C': return "windows-949"; // Korean
+ case 'D': return "windows-950"; // Traditional Chinese, Big5
+ case 'E': return "windows-932"; // Japanese Shift-JIS
+ default: return null;
+ }
+ }
+
+
+ /**
+ * Returns the Locale of an OpenType name.
+ *
+ * @param platform the OpenType platform ID.
+ *
+ * @param language the language tag of the OpenType name. If
+ * <code>platform</code> is 1, this is the MacOS language code.
+ *
+ * @param encoding the encoding tag of the OpenType name. If
+ * <code>platform</code> is 1, this is the MacOS script code.
+ */
+ public static Locale getLocale(int platform, int language, int encoding)
+ {
+ switch (platform)
+ {
+ case 1: /* Apple Macintosh */
+ return getMacLocale(language);
+
+ case 3: /* Microsoft Windows */
+ return getWindowsLocale(language);
+
+ default:
+ return null;
+ }
+ }
+
+
+ /**
+ * Determines the name of the charset for an OpenType font name.
+ *
+ * @param platform the OpenType platform ID.
+ *
+ * @param language the language tag of the OpenType name. If
+ * <code>platform</code> is 1, this is the MacOS language code.
+ *
+ * @param encoding the encoding tag of the OpenType name. If
+ * <code>platform</code> is 1, this is the MacOS script code.
+ *
+ * @return a charset name such as <code>&quot;MacRoman&quot;</code>,
+ * or <code>null</code> if the combination is not known.
+ */
+ public static String getCharsetName(int platform, int language, int encoding)
+ {
+ switch (platform)
+ {
+ case 1: /* Apple Macintosh */
+ return getMacCharsetName(encoding);
+
+ case 3: /* Microsoft Windows */
+ return getMicrosoftCharsetName(language);
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/gnu/java/awt/font/opentype/OpenTypeFont.java b/gnu/java/awt/font/opentype/OpenTypeFont.java
new file mode 100644
index 000000000..9ee28d76b
--- /dev/null
+++ b/gnu/java/awt/font/opentype/OpenTypeFont.java
@@ -0,0 +1,825 @@
+/* OpenTypeFont.java -- Manages OpenType and TrueType fonts.
+ 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 java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.OpenType;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.nio.ByteBuffer;
+import java.text.CharacterIterator;
+import java.util.Locale;
+
+import gnu.java.awt.font.FontDelegate;
+import gnu.java.awt.font.GNUGlyphVector;
+import gnu.java.awt.font.opentype.truetype.TrueTypeScaler;
+
+
+/**
+ * A font that takes its data from OpenType or TrueType font tables.
+ *
+ * <p>OpenType is an extension of the TrueType font format. In addition
+ * to tables for names, kerning or layout, it also stores the shapes
+ * of individual glyphs. Three formats are recognized for glyphs:
+ * Quadratic splines (classic TrueType), cubic splines (PostScript),
+ * and bitmaps.
+ *
+ * @see <a
+ * href="http://partners.adobe.com/asn/tech/type/opentype/">Adobe&#x2019;s
+ * OpenType specification</a>
+ *
+ * @see <a
+ * href="http://developer.apple.com/fonts/TTRefMan/">Apple&#x2019;s</code>
+ * TrueType specification</a>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class OpenTypeFont
+ implements FontDelegate
+{
+ static final int TAG_OTTO = 0x4f54544f; // 'OTTO'
+ static final int TAG_SFNT = 0x73666e74; // 'sfnt'
+ static final int TAG_TRUE = 0x74727565; // 'true'
+ static final int TAG_TTCF = 0x74746366; // 'ttcf'
+ static final int TAG_ZAPF = 0x5a617066; // 'Zapf'
+
+
+ /**
+ * A buffer containing the font data. Note that this may well be an
+ * instance of the subclass MappedByteBuffer, in which case the
+ * virtual memory subsystem can more efficiently handle requests for
+ * font data. This is especially recommended for large font files
+ * that contain many glyphs that are rarely accessed.
+ */
+ ByteBuffer buf;
+
+
+ /**
+ * The number of glyphs in this font.
+ */
+ final int numGlyphs;
+
+ int[] tableTag, tableStart, tableLength;
+
+
+ /**
+ * The version of the font in 16.16 fixed-point encoding, for
+ * example 0x00010000 for version 1.0. There are also two special
+ * version IDs used by fonts for Apple Macintosh, namely 'true'
+ * (0x74727565) and 'typ1'. OpenType fonts sometimes have 'OTTO' as
+ * their version.
+ */
+ private int version;
+
+
+ /**
+ * The number of font units per em. For fonts with TrueType
+ * outlines, this is usually a power of two (such as 2048). For
+ * OpenType fonts with PostScript outlines, other values are
+ * acceptable (such as 1000).
+ */
+ private int unitsPerEm;
+
+
+ /**
+ * A factor to convert font units into ems. This value is <code>1 /
+ * unitsPerEm</code>.
+ */
+ private float emsPerUnit;
+
+
+ /**
+ * The scaler to which the actual scaling work is delegated.
+ */
+ private Scaler scaler;
+
+
+ /**
+ * A delegate object for mapping Unicode UCS-4 codepoints to glyph
+ * IDs.
+ */
+ private CharGlyphMap cmap;
+
+
+ /**
+ * A delegate object for providing a name for each glyph.
+ */
+ private GlyphNamer glyphNamer;
+
+
+ /**
+ * Constructs an OpenType or TrueType font.
+ *
+ * @param buf a buffer with the contents of the font file. It is
+ * recommended to use a <code>MappedByteBuffer</code> for very
+ * large font files.
+ *
+ * @param offsetTablePosition the position of the OpenType offset
+ * table in the font file. The offset table of most OpenType and
+ * TrueType fonts starts at position 0. However, so-called TrueType
+ * Collections support multiple OpenType fonts in a single file,
+ * which allows sharing some glyphs between fonts. If many glyphs
+ * are shared (for example all the Kanji glyphs between multiple
+ * Japanese fonts), the space savings can be considerable. In that
+ * case, the offset table of each individual font would start at its
+ * own position.
+ *
+ * @throws java.awt.FontFormatException if the font data is
+ * not in OpenType or TrueType format.
+ */
+ OpenTypeFont(ByteBuffer buf, int offsetTablePosition)
+ throws FontFormatException
+ {
+ int numTables, searchRange, entrySelector, rangeShift;
+
+ //buf = buf.duplicate();
+ this.buf = buf;
+ buf.limit(buf.capacity());
+ buf.position(offsetTablePosition);
+
+ /* Check that the font data is in a supported format. */
+ version = buf.getInt();
+ switch (version)
+ {
+ case 0x00010000: // Microsoft TrueType
+ case OpenType.TAG_TYP1: // Adobe PostScript embeded in Apple SFNT ('typ1')
+ case TAG_SFNT: // Apple TrueType
+ case TAG_TRUE: // Apple TrueType
+ case TAG_OTTO: // OpenType
+ break;
+
+ default:
+ throw new FontFormatException("not in OpenType or TrueType format");
+ }
+
+ numTables = buf.getShort();
+ searchRange = buf.getShort();
+ entrySelector = buf.getShort();
+ rangeShift = buf.getShort();
+
+ tableTag = new int[numTables];
+ tableStart = new int[numTables];
+ tableLength = new int[numTables];
+ int lastTag = 0;
+ for (int i = 0; i < numTables; i++)
+ {
+ tableTag[i] = buf.getInt();
+ if (lastTag >= tableTag[i])
+ throw new FontFormatException("unordered OpenType table");
+
+ buf.getInt(); // ignore checksum
+ tableStart[i] = buf.getInt();
+ tableLength[i] = buf.getInt();
+
+ //System.out.println(tagToString(tableTag[i]) + ", " + tableLength[i]);
+ }
+
+ ByteBuffer head = getFontTable(OpenType.TAG_HEAD);
+ if ((head.getInt(0) != 0x00010000)
+ || (head.getInt(12) != 0x5f0f3cf5))
+ throw new FontFormatException("unsupported head version");
+
+ unitsPerEm = head.getChar(18);
+ emsPerUnit = 1.0f / (float) unitsPerEm;
+
+
+ ByteBuffer maxp = getFontTable(OpenType.TAG_MAXP);
+ int maxpVersion = maxp.getInt(0);
+ switch (maxpVersion)
+ {
+ case 0x00005000: /* version 0.5, with wrong fractional part */
+ numGlyphs = maxp.getChar(4);
+ break;
+
+ case 0x00010000: /* version 1.0 */
+ numGlyphs = maxp.getChar(4);
+ scaler = new TrueTypeScaler(unitsPerEm,
+ getFontTable(OpenType.TAG_HHEA),
+ getFontTable(OpenType.TAG_HMTX),
+ getFontTable(OpenType.TAG_VHEA),
+ getFontTable(OpenType.TAG_VMTX),
+ maxp,
+ getFontTable(OpenType.TAG_CVT),
+ getFontTable(OpenType.TAG_FPGM),
+ /* loca format */ head.getShort(50),
+ getFontTable(OpenType.TAG_LOCA),
+ getFontTable(OpenType.TAG_GLYF),
+ getFontTable(OpenType.TAG_PREP));
+ break;
+
+ default:
+ throw new FontFormatException("unsupported maxp version");
+ }
+ }
+
+
+ /**
+ * Determines the index of a table into the offset table. The
+ * result can be used to find the offset and length of a table, as
+ * in <code>tableStart[getTableIndex(TAG_NAME)]</code>.
+ *
+ * @param tag the table identifier, for instance
+ * <code>OpenType.TAG_NAME</code>.
+ *
+ * @return the index of that table into the offset table, or
+ * -1 if the font does not contain the table specified by
+ * <code>tag</code>.
+ */
+ private int getTableIndex(int tag)
+ {
+ /* FIXME: Since the font specification requires tableTag[] to be
+ * ordered, one should do binary search here.
+ */
+ for (int i = 0; i < tableTag.length; i++)
+ if (tableTag[i] == tag)
+ return i;
+ return -1;
+ }
+
+
+
+ /**
+ * Returns the name of the family to which this font face belongs,
+ * for example <i>&#x201c;Univers&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the family name.
+ */
+ public synchronized String getFamilyName(Locale locale)
+ {
+ String name;
+
+ if (locale == null)
+ locale = Locale.getDefault();
+
+ name = getName(NameDecoder.NAME_FAMILY, locale);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FAMILY, Locale.ENGLISH);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FAMILY, /* any language */ null);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FULL, locale);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FULL, /* any language */ null);
+ return name;
+ }
+
+
+ /**
+ * Returns the name of this font face inside the family, for example
+ * <i>&#x201c;Light&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the name of the face inside its family.
+ */
+ public synchronized String getSubFamilyName(Locale locale)
+ {
+ String name;
+
+ if (locale == null)
+ locale = Locale.getDefault();
+
+ name = getName(NameDecoder.NAME_SUBFAMILY, locale);
+ if (name == null)
+ {
+ name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
+ if ("Regular".equals(name))
+ name = null;
+ }
+
+ if (name == null)
+ {
+ String lang = locale.getLanguage();
+ if ("de".equals(lang))
+ name = "Standard";
+ else if ("fr".equals(lang))
+ name = "Standard";
+ else if ("it".equals(lang))
+ name = "Normale";
+ else if ("nl".equals(lang))
+ name = "Normaal";
+ else if ("fi".equals(lang))
+ name = "Normaali";
+ else if ("sv".equals(lang))
+ name = "Normal";
+ else
+ name = "Regular";
+ }
+
+ return name;
+ }
+
+
+
+ /**
+ * Returns the full name of this font face, for example
+ * <i>&#x201c;Univers Light&#x201d;</i>.
+ *
+ * @param locale the locale for which to localize the name.
+ *
+ * @return the face name.
+ */
+ public synchronized String getFullName(Locale locale)
+ {
+ String name;
+
+ if (locale == null)
+ locale = Locale.getDefault();
+
+ name = getName(NameDecoder.NAME_FULL, locale);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FULL, Locale.ENGLISH);
+ if (name == null)
+ name = getName(NameDecoder.NAME_FULL, /* any language */ null);
+
+ return name;
+ }
+
+
+ /**
+ * Returns the PostScript name of this font face, for example
+ * <i>&#x201c;Univers-Light&#x201d;</i>.
+ *
+ * @return the PostScript name, or <code>null</code> if the font
+ * does not provide a PostScript name.
+ */
+ public synchronized String getPostScriptName()
+ {
+ return getName(NameDecoder.NAME_POSTSCRIPT, /* any language */ null);
+ }
+
+
+ /**
+ * Returns the number of glyphs in this font face.
+ */
+ public int getNumGlyphs()
+ {
+ /* No synchronization is needed because the number of glyphs is
+ * set in the constructor, and it cannot change during the
+ * lifetime of the object.
+ */
+ return numGlyphs;
+ }
+
+
+ /**
+ * Returns the index of the glyph which gets displayed if the font
+ * cannot map a Unicode code point to a glyph. Many fonts show this
+ * glyph as an empty box.
+ */
+ public int getMissingGlyphCode()
+ {
+ /* No synchronization is needed because the result is constant. */
+ return 0;
+ }
+
+
+ /**
+ * The font&#x2019;s name table, or <code>null</code> if this
+ * table has not yet been accessed.
+ */
+ private ByteBuffer nameTable;
+
+
+ /**
+ * Extracts a String from the font&#x2019;s name table.
+ *
+ * @param name the numeric TrueType or OpenType name ID.
+ *
+ * @param locale the locale for which names shall be localized, or
+ * <code>null</code> if the locale does mot matter because the name
+ * is known to be language-independent (for example, because it is
+ * the PostScript name).
+ */
+ private String getName(int name, Locale locale)
+ {
+ if (nameTable == null)
+ nameTable = getFontTable(OpenType.TAG_NAME);
+ return NameDecoder.getName(nameTable, name, locale);
+ }
+
+
+ /**
+ * Returns the version of the font.
+ *
+ * @see java.awt.font.OpenType#getVersion
+ *
+ * @return the version in 16.16 fixed-point encoding, for example
+ * 0x00010000 for version 1.0.
+ */
+ public int getVersion()
+ {
+ /* No synchronization is needed because the version is set in the
+ * constructor, and it cannot change during the lifetime of the
+ * object.
+ */
+ return version;
+ }
+
+
+ /**
+ * Creates a view buffer for an OpenType table. The caller can
+ * access the returned buffer without needing to synchronize access
+ * from multiple threads.
+ *
+ * @param tag the table identifier, for example
+ * <code>OpenType.GLYF</code>.
+ *
+ * @return a slice of the underlying buffer containing the table, or
+ * <code>null</code> if the font does not contain the requested
+ * table.
+ */
+ public synchronized ByteBuffer getFontTable(int tag)
+ {
+ int index, start, len;
+ ByteBuffer result;
+
+ index = getTableIndex(tag);
+ if (index < 0)
+ return null;
+
+ start = tableStart[index];
+ len = tableLength[index];
+ buf.limit(start + len).position(start);
+ result = buf.slice();
+ result.limit(len);
+ return result;
+ }
+
+
+ /**
+ * Returns the size of one of the tables in the font,
+ * or -1 if the table does not exist.
+ */
+ public int getFontTableSize(int tag)
+ {
+ int index = getTableIndex(tag);
+ if (index == -1)
+ return index;
+ return tableLength[index];
+ }
+
+
+ private CharGlyphMap getCharGlyphMap()
+ {
+ if (cmap != null)
+ return cmap;
+
+ synchronized (this)
+ {
+ if (cmap == null)
+ {
+ int index = getTableIndex(OpenType.TAG_CMAP);
+ int start = tableStart[index];
+ buf.limit(start + tableLength[index]).position(start);
+ cmap = CharGlyphMap.forTable(buf);
+ }
+ return cmap;
+ }
+ }
+
+
+
+ /**
+ * Looks up a glyph in the font&#x2019;s <code>cmap</code> tables,
+ * without performing any glyph substitution or reordering. Because
+ * of this limitation, this method cannot be used for script systems
+ * that need advanced glyph mapping, such as Arabic, Korean, or even
+ * Latin with exotic accents.
+ *
+ * <p>It is safe to call this method from any thread.
+ *
+ * @param ucs4 the Unicode codepoint in the 32-bit Unicode character
+ * set UCS-4. Because UTF-16 surrogates do not correspond to a single
+ * glyph, it does not make sense to pass them here.
+ *
+ * @return the glyph index, or zero if the font does not contain
+ * a glyph for the specified codepoint.
+ */
+ public int getGlyph(int ucs4)
+ {
+ return getCharGlyphMap().getGlyph(ucs4);
+ }
+
+
+ /**
+ * Creates a GlyphVector by mapping each character in a
+ * CharacterIterator to the corresponding glyph.
+ *
+ * <p>The mapping takes only the font&#x2019;s <code>cmap</code>
+ * tables into consideration. No other operations (such as glyph
+ * re-ordering, composition, or ligature substitution) are
+ * performed. This means that the resulting GlyphVector will not be
+ * correct for text in languages that have complex
+ * character-to-glyph mappings, such as Arabic, Hebrew, Hindi, or
+ * Thai.
+ *
+ * @param font the font object that the created GlyphVector
+ * will return when it gets asked for its font. This argument is
+ * needed because the public API works with java.awt.Font,
+ * not with some private delegate like OpenTypeFont.
+ *
+ * @param frc the font rendering parameters that are used for
+ * measuring glyphs. The exact placement of text slightly depends on
+ * device-specific characteristics, for instance the device
+ * resolution or anti-aliasing. For this reason, any measurements
+ * will only be accurate if the passed
+ * <code>FontRenderContext</code> correctly reflects the relevant
+ * parameters. Hence, <code>frc</code> should be obtained from the
+ * same <code>Graphics2D</code> that will be used for drawing, and
+ * any rendering hints should be set to the desired values before
+ * obtaining <code>frc</code>.
+ *
+ * @param ci a CharacterIterator for iterating over the
+ * characters to be displayed.
+ */
+ public synchronized GlyphVector createGlyphVector(Font font,
+ FontRenderContext frc,
+ CharacterIterator ci)
+ {
+ CharGlyphMap cmap;
+ int numGlyphs;
+ int[] glyphs;
+ int glyph;
+ int c;
+
+ cmap = getCharGlyphMap();
+ numGlyphs = ci.getEndIndex() - ci.getBeginIndex();
+ glyphs = new int[numGlyphs];
+ glyph = 0;
+ for (c = ci.first(); c != CharacterIterator.DONE; c = ci.next())
+ {
+ /* handle surrogate pairs */
+ if (c >> 10 == 0x36) // U+D800 .. U+DBFF: High surrogate
+ c = (((c & 0x3ff) << 10) | (ci.next() & 0x3ff)) + 0x10000;
+ glyphs[glyph] = cmap.getGlyph(c);
+ glyph += 1;
+ }
+
+ /* If we had surrogates, the allocated array is too large.
+ * Because this will occur very rarely, it seems acceptable to
+ * re-allocate a shorter array and copy the contents around.
+ */
+ if (glyph != numGlyphs)
+ {
+ int[] newGlyphs = new int[glyph];
+ System.arraycopy(glyphs, 0, newGlyphs, 0, glyph);
+ glyphs = newGlyphs;
+ }
+
+ return new GNUGlyphVector(this, font, frc, glyphs);
+ }
+
+
+
+ /**
+ * Determines the advance width for a glyph.
+ *
+ * @param glyphIndex the glyph whose advance width is to be
+ * determined.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @param advance a point whose <code>x</code> and <code>y</code>
+ * fields will hold the advance in each direction. It is possible
+ * that both values are non-zero, for example if
+ * <code>transform</code> is a rotation, or in the case of Urdu
+ * fonts.
+ */
+ public synchronized void getAdvance(int glyphIndex,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal,
+ Point2D advance)
+ {
+ /* Delegate the measurement to the scaler. The synchronization is
+ * needed because the scaler is not synchronized.
+ */
+ scaler.getAdvance(glyphIndex, pointSize, transform,
+ antialias, fractionalMetrics, horizontal,
+ advance);
+ }
+
+
+ /**
+ * Returns the shape of a glyph.
+ *
+ * @param glyph the glyph whose advance width is to be determined
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts, this
+ * parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional
+ * metrics, <code>false</code> for rounding the result to a pixel
+ * boundary.
+ *
+ * @return the scaled and grid-fitted outline of the specified
+ * glyph, or <code>null</code> for bitmap fonts.
+ */
+ public synchronized GeneralPath getGlyphOutline(int glyph,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics)
+ {
+ /* The synchronization is needed because the scaler is not
+ * synchronized.
+ */
+ return scaler.getOutline(glyph, pointSize, transform,
+ antialias, fractionalMetrics);
+ }
+
+
+ /**
+ * Returns a name for the specified glyph. This is useful for
+ * generating PostScript or PDF files that embed some glyphs of a
+ * font.
+ *
+ * <p><b>Names are not unique:</b> Under some rare circumstances,
+ * the same name can be returned for different glyphs. It is
+ * therefore recommended that printer drivers check whether the same
+ * name has already been returned for antoher glyph, and make the
+ * name unique by adding the string ".alt" followed by the glyph
+ * index.</p>
+ *
+ * <p>This situation would occur for an OpenType or TrueType font
+ * that has a <code>post</code> table of format 3 and provides a
+ * mapping from glyph IDs to Unicode sequences through a
+ * <code>Zapf</code> table. If the same sequence of Unicode
+ * codepoints leads to different glyphs (depending on contextual
+ * position, for example, or on typographic sophistication level),
+ * the same name would get synthesized for those glyphs.
+ *
+ * @param glyphIndex the glyph whose name the caller wants to
+ * retrieve.
+ */
+ public synchronized String getGlyphName(int glyphIndex)
+ {
+ if (glyphNamer == null)
+ glyphNamer = GlyphNamer.forTables(numGlyphs,
+ getFontTable(OpenType.TAG_POST),
+ getFontTable(TAG_ZAPF));
+
+ return glyphNamer.getGlyphName(glyphIndex);
+ }
+
+
+ /**
+ * Determines the distance between the base line and the highest
+ * ascender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the ascent, which usually is a positive number.
+ */
+ public synchronized float getAscent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal)
+ {
+ return scaler.getAscent(pointSize, transform,
+ antialiased, fractionalMetrics,
+ horizontal);
+ }
+
+
+ /**
+ * Determines the distance between the base line and the lowest
+ * descender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the descent, which usually is a nagative number.
+ */
+ public synchronized float getDescent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal)
+ {
+ return scaler.getDescent(pointSize, transform,
+ antialiased, fractionalMetrics,
+ horizontal);
+ }
+
+
+ /**
+ * Converts a four-byte tag identifier into a String that can be
+ * displayed when debugging this class.
+ *
+ * @param tag the tag as an <code>int</code>.
+ *
+ * @return the tag in human-readable form, for example
+ * <code>name</code> or <code>glyf</code>.
+ */
+ static String tagToString(int tag)
+ {
+ char[] c = new char[4];
+ c[0] = (char) ((tag >> 24) & 0xff);
+ c[1] = (char) ((tag >> 16) & 0xff);
+ c[2] = (char) ((tag >> 8) & 0xff);
+ c[3] = (char) (tag & 0xff);
+ return new String(c);
+ }
+}
diff --git a/gnu/java/awt/font/opentype/OpenTypeFontFactory.java b/gnu/java/awt/font/opentype/OpenTypeFontFactory.java
new file mode 100644
index 000000000..3a00dfba2
--- /dev/null
+++ b/gnu/java/awt/font/opentype/OpenTypeFontFactory.java
@@ -0,0 +1,140 @@
+/* OpenTypeFontFactory.java -- Creates OpenType and TrueType fonts.
+ 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.FontDelegate;
+import java.awt.FontFormatException;
+import java.awt.font.OpenType;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A factory for creating fonts that are stored in an
+ * <i>sfnt</i>-housed format, for example OpenType or TrueType.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class OpenTypeFontFactory
+{
+ /**
+ * The constructor is private so nobody can construct an instance
+ * of this class.
+ */
+ private OpenTypeFontFactory()
+ {
+ }
+
+
+ /**
+ * Creates FontDelegate objects for the fonts in the specified
+ * buffer. The following font formats are currently recognized:
+ *
+ * <p><ul>
+ * <li>OpenType (*.otf);</li>
+ * <li>TrueType (*.ttf);</li>
+ * <li>TrueType Collections (*.ttc);</li>
+ * <li>Apple MacOS X data-fork font (*.dfont).</li></ul>
+ *
+ * <p>Some formats may contain more than a single font, for example
+ * *.ttc and *.dfont files. This is the reason why this function
+ * returns an array.
+ *
+ * <p>The implementation reads data from the buffer only when
+ * needed. Therefore, it greatly increases efficiency if
+ * <code>buf</code> has been obtained through mapping a file into
+ * the virtual address space.
+ *
+ * @throws FontFormatException if the font data is not in one of the
+ * known formats.
+ */
+ public static FontDelegate[] createFonts(ByteBuffer buf)
+ throws FontFormatException
+ {
+ OpenTypeFont[] fonts;
+ int version;
+
+ version = buf.getInt(0);
+ switch (version)
+ {
+ case 0x00010000: // Microsoft Windows TrueType
+ case OpenType.TAG_TYP1: // Apple MacOS PostScript ('typ1')
+ case OpenTypeFont.TAG_SFNT: // Apple MacOS TrueType ('sfnt')
+ case OpenTypeFont.TAG_TRUE: // Apple MacOS TrueType ('true')
+ case OpenTypeFont.TAG_OTTO: // OpenType
+ return new OpenTypeFont[] { new OpenTypeFont(buf, 0) };
+ }
+
+
+ /* TrueType Collection, see "TrueType Collections" in
+ * http://partners.adobe.com/asn/tech/type/opentype/otff.html
+ */
+ if (version == OpenTypeFont.TAG_TTCF)
+ {
+ // This code has never been tested.
+ fonts = new OpenTypeFont[buf.getInt(8)];
+ for (int i = 0; i < fonts.length; i++)
+ fonts[i] = new OpenTypeFont(buf, buf.getInt(16 + 4 * i));
+ return fonts;
+ }
+
+
+ /* The MacOS X .dfont format is a Macintosh resource fork in
+ * a normal file, contaning one or several 'sfnt' resources.
+ * Unfortunately, MacOS resource forks have no magic code
+ * that could be used for identification. Instead, we just try
+ * to extract at least one 'sfnt'.
+ */
+ try
+ {
+ MacResourceFork fork = new MacResourceFork(buf);
+ MacResourceFork.Resource[] rsrc;
+
+ rsrc = fork.getResources(OpenTypeFont.TAG_SFNT);
+ fonts = new OpenTypeFont[rsrc.length];
+ for (int i = 0; i < fonts.length; i++)
+ fonts[i] = new OpenTypeFont(rsrc[i].getContent(), 0);
+
+ return fonts;
+ }
+ catch (Exception ex)
+ {
+ }
+
+ throw new FontFormatException("not in OpenType or TrueType format");
+ }
+}
diff --git a/gnu/java/awt/font/opentype/Scaler.java b/gnu/java/awt/font/opentype/Scaler.java
new file mode 100644
index 000000000..499c3ea52
--- /dev/null
+++ b/gnu/java/awt/font/opentype/Scaler.java
@@ -0,0 +1,192 @@
+/* Scaler.java -- Common superclass for font scalers.
+ 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 java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+
+
+/**
+ * An common superclass for all font scalers. The main task of font
+ * scaler is to retrieve a scaled and hinted outline for a glyph.
+ *
+ * <p>To make text more legible, high-quality fonts contain
+ * instructions (sometimes also called &#x201c;hints&#x201d;) for
+ * moving the scaled control points towards the coordinate grid of the
+ * display device.
+ *
+ * <p><b>Lack of Thread Safety:</b> Font scalers are intentionally
+ * <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font that uses this scaler already has obtained a lock before
+ * calling the scaler.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public abstract class Scaler
+{
+ /**
+ * Retrieves the scaled outline of a glyph, adjusting control points
+ * to the raster grid if necessary.
+ *
+ * @param glyph the glyph number whose outline is retrieved.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias whether or not the rasterizer will perform
+ * anti-aliasing on the returned path.
+ *
+ * @param fractionalMetrics <code>false</code> for adjusting glyph
+ * positions to the raster grid of device space.
+ *
+ * @return the scaled and grid-fitted outline of the specified
+ * glyph, or <code>null</code> for bitmap fonts.
+ */
+ public abstract GeneralPath getOutline(int glyph,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics);
+
+
+ /**
+ * Determines the advance width and height for a glyph.
+ *
+ * @param glyphIndex the glyph whose advance width is to be
+ * determined.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @param advance a point whose <code>x</code> and <code>y</code>
+ * fields will hold the advance in each direction. It is well
+ * possible that both values are non-zero, for example for rotated
+ * text or for Urdu fonts.
+ */
+ public abstract void getAdvance(int glyphIndex,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal,
+ Point2D advance);
+
+
+ /**
+ * Determines the distance between the base line and the highest
+ * ascender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the ascent, which usually is a positive number.
+ */
+ public abstract float getAscent(float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal);
+
+
+ /**
+ * Determines the distance between the base line and the lowest
+ * descender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the descent, which usually is a nagative number.
+ */
+ public abstract float getDescent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal);
+}
diff --git a/gnu/java/awt/font/opentype/truetype/Fixed.java b/gnu/java/awt/font/opentype/truetype/Fixed.java
new file mode 100644
index 000000000..5d81c5d2e
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/Fixed.java
@@ -0,0 +1,161 @@
+/* Fixed.java -- Fixed-point arithmetics for TrueType coordinates.
+ 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;
+
+
+/**
+ * A utility class for fixed-point arithmetics, where numbers are
+ * represented with 26 dot 6 digits. This representation is used by
+ * TrueType coordinates.
+ *
+ * <p>A good compiler will inline calls of methods in this class.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class Fixed
+{
+ public static final int ONE = 1<<6;
+
+
+ /**
+ * The constructor is private so nobody can use it.
+ */
+ private Fixed()
+ {
+ }
+
+
+ /**
+ * Multiplies two fixed-point numbers.
+ */
+ public static int mul(int a, int b)
+ {
+ return (int) ((((long) a) * b) >> 6);
+ }
+
+
+ public static int div(int a, int b)
+ {
+ return (int) ((((long) a) << 6) / b);
+ }
+
+
+
+ public static int ceil(int a)
+ {
+ return (a + 63) & -64;
+ }
+
+
+ public static int floor(int a)
+ {
+ return a & -64;
+ }
+
+
+ /**
+ * Calculates the length of a fixed-point vector.
+ */
+ public static int vectorLength(int x, int y)
+ {
+ int shift;
+ float fx, fy;
+
+ if (x == 0)
+ return Math.abs(y);
+ else if (y == 0)
+ return Math.abs(x);
+
+ /* Use the FPU. */
+ fx = ((float) x) / 64.0f;
+ fy = ((float) y) / 64.0f;
+ return (int) (Math.sqrt(fx * fx + fy * fy) * 64.0);
+ }
+
+
+ public static int intValue(int f)
+ {
+ return f >> 6;
+ }
+
+
+ public static float floatValue(int f)
+ {
+ return ((float) f) / 64;
+ }
+
+
+ public static double doubleValue(int f)
+ {
+ return ((double) f) / 64;
+ }
+
+
+ public static int valueOf(float f)
+ {
+ return (int) (f * 64);
+ }
+
+
+ public static int valueOf(double d)
+ {
+ return (int) (d * 64);
+ }
+
+
+ /**
+ * Makes a string representation of a fixed-point number.
+ */
+ public static String toString(int f)
+ {
+ return String.valueOf(floatValue(f));
+ }
+
+
+ public static String toString(int x, int y)
+ {
+ StringBuffer sbuf = new StringBuffer(40);
+ sbuf.append('(');
+ sbuf.append(((float) x) / 64);
+ sbuf.append(", ");
+ sbuf.append(((float) y) / 64);
+ sbuf.append(')');
+ return sbuf.toString();
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/GlyphLoader.java b/gnu/java/awt/font/opentype/truetype/GlyphLoader.java
new file mode 100644
index 000000000..b12d7782b
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/GlyphLoader.java
@@ -0,0 +1,437 @@
+/* GlyphLoader.java -- Helper for loading TrueType glyph outlines.
+ 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;
+
+import java.awt.geom.AffineTransform;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A class for loading scaled and hinted glyph outlines.
+ *
+ * <p><b>Lack of Thread Safety:</b> Glyph loaders are intentionally
+ * <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font has already obtained a lock before calling the scaler,
+ * which in turn calls the GlyphLoader. It would thus be wasteful to
+ * acquire additional locks for the GlyphLoader.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class GlyphLoader
+{
+ /**
+ * A helper object for locating glyph data. GlyphLocator is an
+ * abstract superclass, and there is a concretization for each glyph
+ * location table ('loca') format.
+ */
+ private final GlyphLocator glyphLocator;
+
+
+ /**
+ * A helper object for measuring the advance width and height of a
+ * glyph.
+ */
+ private final GlyphMeasurer glyphMeasurer;
+
+
+ /**
+ * The virtual machine for executing TrueType bytecodes.
+ */
+ private final VirtualMachine vm;
+
+
+ /**
+ * The number of font units in one em. A typical value is 2048,
+ * but this depends on the font.
+ */
+ private final int unitsPerEm;
+
+ private final int[] contourEndPoints;
+ private final byte[] pointFlags;
+
+
+ /**
+ * Constructs a GlyphLoader.
+ */
+ GlyphLoader(GlyphLocator glyphLocator, VirtualMachine vm,
+ int unitsPerEm, int maxContours, int maxPoints,
+ GlyphMeasurer glyphMeasurer)
+ {
+ this.glyphLocator = glyphLocator;
+ this.glyphMeasurer = glyphMeasurer;
+ this.unitsPerEm = unitsPerEm;
+ this.vm = vm;
+
+ contourEndPoints = new int[maxContours];
+ pointFlags = new byte[maxPoints];
+ }
+
+
+ /**
+ * @param glyphIndex the number of the glyph whose outlines are to be
+ * retrieved.
+ */
+ public void loadGlyph(int glyphIndex,
+ double pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ Zone glyphZone)
+ {
+ glyphZone.setNumPoints(4);
+ loadSubGlyph(glyphIndex, pointSize, transform, antialias, glyphZone,
+ 0, 0);
+ }
+
+
+ private void loadSubGlyph(int glyphIndex,
+ double pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ Zone glyphZone,
+ int preTranslateX,
+ int preTranslateY)
+ {
+ ByteBuffer glyph;
+ int numContours;
+ int xMin, yMin, xMax, yMax;
+ byte flag;
+
+ glyph = glyphLocator.getGlyphData(glyphIndex);
+
+ if (glyph == null)
+ {
+ glyphZone.setNumPoints(4);
+ setPhantomPoints(glyphIndex, 0, glyphZone);
+ glyphZone.transform(pointSize, transform, unitsPerEm,
+ preTranslateX, preTranslateY);
+ return;
+ }
+
+ numContours = glyph.getShort();
+ xMin = glyph.getChar();
+ yMin = glyph.getChar();
+ xMax = glyph.getChar();
+ yMax = glyph.getChar();
+
+
+ if (numContours >= 0)
+ loadSimpleGlyph(glyphIndex, pointSize, transform, antialias,
+ numContours, glyph, glyphZone,
+ preTranslateX, preTranslateY);
+ else
+ loadCompoundGlyph(glyphIndex, pointSize, transform, antialias,
+ glyph, glyphZone,
+ preTranslateX, preTranslateY);
+ }
+
+
+ private void loadSimpleGlyph(int glyphIndex,
+ double pointSize, AffineTransform transform,
+ boolean antialias,
+ int numContours, ByteBuffer glyph,
+ Zone glyphZone,
+ int preTranslateX, int preTranslateY)
+ {
+ int numPoints;
+ int posInstructions, numInstructions;
+ boolean execInstructions;
+
+ execInstructions = vm.setup(pointSize, transform, antialias);
+
+ /* Load the contour end points and determine the number of
+ * points.
+ */
+ for (int i = 0; i < numContours; i++)
+ contourEndPoints[i] = glyph.getChar();
+ if (numContours > 0)
+ numPoints = 1 + contourEndPoints[numContours - 1];
+ else
+ numPoints = 0;
+ glyphZone.setNumPoints(numPoints + 4);
+
+ numInstructions = glyph.getChar();
+ posInstructions = glyph.position();
+ glyph.position(posInstructions + numInstructions);
+ loadFlags(numPoints, glyph);
+ loadCoordinates(numPoints, glyph, glyphZone);
+ for (int i = 0; i < numContours; i++)
+ glyphZone.setContourEnd(contourEndPoints[i], true);
+
+ setPhantomPoints(glyphIndex, numPoints, glyphZone);
+ glyphZone.transform(pointSize, transform, unitsPerEm,
+ preTranslateX, preTranslateY);
+
+ if (execInstructions)
+ {
+ // FIXME: Hint the glyph.
+ }
+ }
+
+
+ private static final short ARGS_ARE_WORDS = 1;
+ private static final short ARGS_ARE_XY_VALUES = 2;
+ private static final short ROUND_XY_TO_GRID = 4;
+ private static final short WE_HAVE_A_SCALE = 8;
+ private static final short MORE_COMPONENTS = 32;
+ private static final short WE_HAVE_AN_X_AND_Y_SCALE = 64;
+ private static final short WE_HAVE_A_TWO_BY_TWO = 128;
+ private static final short WE_HAVE_INSTRUCTIONS = 256;
+ private static final short USE_MY_METRICS = 512;
+ private static final short OVERLAP_COMPOUND = 1024;
+ private static final short SCALED_COMPONENT_OFFSET = 2048;
+ private static final short UNSCALED_COMPONENT_OFFSET = 4096;
+
+ private void loadCompoundGlyph(int glyphIndex,
+ double pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ ByteBuffer glyph,
+ Zone glyphZone,
+ int preTranslateX, int preTranslateY)
+ {
+ short flags;
+ int subGlyphIndex;
+ int metricsGlyphIndex;
+ Zone subGlyphZone = new Zone(glyphZone.getCapacity());
+ int arg1, arg2;
+ double a, b, c, d, e, f;
+ AffineTransform componentTransform = new AffineTransform();
+
+ /* By default, use the metrics of the compound glyph. The default
+ * is overridden if some component glyph has the USE_MY_METRICS
+ * flag set.
+ */
+ metricsGlyphIndex = glyphIndex;
+
+ do
+ {
+ flags = glyph.getShort();
+ subGlyphIndex = glyph.getChar();
+
+ if ((flags & USE_MY_METRICS) != 0)
+ metricsGlyphIndex = subGlyphIndex;
+
+ if ((flags & ARGS_ARE_WORDS) != 0)
+ {
+ arg1 = glyph.getShort();
+ arg2 = glyph.getShort();
+ }
+ else
+ {
+ arg1 = glyph.get();
+ arg2 = glyph.get();
+ }
+
+ if ((flags & WE_HAVE_A_SCALE) != 0)
+ {
+ a = d = getDouble214(glyph);
+ b = c = 0.0;
+ }
+ else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0)
+ {
+ a = getDouble214(glyph);
+ d = getDouble214(glyph);
+ b = c = 0.0;
+ }
+ else if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0)
+ {
+ a = getDouble214(glyph);
+ b = getDouble214(glyph);
+ c = getDouble214(glyph);
+ d = getDouble214(glyph);
+ }
+ else
+ {
+ a = d = 1.0;
+ b = c = 0.0;
+ }
+
+ double m = Math.max(Math.abs(a), Math.abs(b));
+ double n = Math.max(Math.abs(c), Math.abs(d));
+
+ /* The Apple TrueType specification actually says that m is
+ * multiplied by two if
+ *
+ * abs(abs(a) - abs(c)) <= 33/65536,
+ *
+ * but this is probably a typo. On 2003-07-23, Sascha Brawer
+ * wrote an e-mail message to applefonts@apple.com, asking
+ * whether this might possibly be an error in the specification.
+ */
+ if (Math.abs(Math.abs(a) - Math.abs(b)) <= 33.0/65536.0)
+ m = m * 2;
+
+ if (Math.abs(Math.abs(c) - Math.abs(d)) <= 33.0/65536.0)
+ n = n * 2;
+
+ if ((flags & ARGS_ARE_XY_VALUES) != 0)
+ {
+ e = m * arg1;
+ f = n * arg2;
+ }
+ else
+ e = f = 0.0;
+
+ componentTransform.setTransform(a, b, c, d, 0.0, 0.0);
+
+ // System.out.println("componentTransform = " + componentTransform
+ // + ", e=" + e + ", f=" + f);
+ componentTransform.concatenate(transform);
+
+ int pos = glyph.position();
+ int lim = glyph.limit();
+
+ loadSubGlyph(subGlyphIndex, pointSize, componentTransform,
+ antialias, subGlyphZone,
+ Math.round((float) e + preTranslateX),
+ Math.round(-((float) f + preTranslateY)));
+ glyphZone.combineWithSubGlyph(subGlyphZone, 4);
+ glyph.limit(lim).position(pos);
+ }
+ while ((flags & MORE_COMPONENTS) != 0);
+
+ setPhantomPoints(metricsGlyphIndex, glyphZone.getSize() - 4, glyphZone);
+ }
+
+
+ private double getDouble214(ByteBuffer buf)
+ {
+ return ((double) buf.getShort()) / (1 << 14);
+ }
+
+
+ /**
+ * Loads the per-point flags of a glyph into the
+ * <code>pointFlags</code> field.
+ */
+ private void loadFlags(int numPoints, ByteBuffer glyph)
+ {
+ byte flag;
+ int numRepetitions;
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ pointFlags[i] = flag = glyph.get();
+ if ((flag & 8) != 0)
+ {
+ numRepetitions = ((int) glyph.get()) & 0xff;
+ while (numRepetitions > 0)
+ {
+ pointFlags[++i] = flag;
+ --numRepetitions;
+ }
+ }
+ }
+ }
+
+
+ private void loadCoordinates(int numPoints, ByteBuffer glyph,
+ Zone glyphZone)
+ {
+ int x, y;
+ byte flag;
+
+ x = 0;
+ for (int i = 0; i < numPoints; i++)
+ {
+ flag = pointFlags[i];
+ if ((flag & 2) == 0)
+ {
+ if ((flag & 16) == 0)
+ x += glyph.getShort();
+ }
+ else
+ {
+ if ((flag & 16) != 0)
+ x += (glyph.get() & 0xff);
+ else
+ x -= (glyph.get() & 0xff);
+ }
+ glyphZone.setOriginalX(i, x);
+ glyphZone.setOnCurve(i, (flag & 1) == 1);
+ }
+
+ y = 0;
+ for (int i = 0; i < numPoints; i++)
+ {
+ flag = pointFlags[i];
+ if ((flag & 4) == 0)
+ {
+ if ((flag & 32) == 0)
+ y += glyph.getShort();
+ }
+ else
+ {
+ if ((flag & 32) != 0)
+ y += (glyph.get() & 0xff);
+ else
+ y -= (glyph.get() & 0xff);
+ }
+ glyphZone.setOriginalY(i, -y);
+ }
+ }
+
+
+ private void setPhantomPoints(int glyphIndex, int numPoints,
+ Zone glyphZone)
+ {
+ /* Phantom point 0: Character origin. */
+ glyphZone.setOriginalX(numPoints, 0);
+ glyphZone.setOriginalY(numPoints, 0);
+
+ /* Phantom point 1: Horizontal advance point. */
+ glyphZone.setOriginalX(numPoints + 1,
+ glyphMeasurer.getAdvanceWidth(glyphIndex, true));
+ glyphZone.setOriginalY(numPoints + 1,
+ glyphMeasurer.getAdvanceHeight(glyphIndex, true));
+
+ /* Phantom point 2: Vertical origin. */
+ int vertX = glyphMeasurer.getAscent(/* vertical */ false);
+ int vertY = glyphMeasurer.getAscent(/* horizontal */ true);
+ glyphZone.setOriginalX(numPoints + 2, vertX);
+ glyphZone.setOriginalY(numPoints + 2, vertY);
+
+ /* Phantom point 3: Vertical advance point. */
+ glyphZone.setOriginalX(numPoints + 3,
+ vertX + glyphMeasurer.getAdvanceWidth(glyphIndex, false));
+ glyphZone.setOriginalY(numPoints + 3,
+ vertY + glyphMeasurer.getAdvanceHeight(glyphIndex, false));
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/GlyphLocator.java b/gnu/java/awt/font/opentype/truetype/GlyphLocator.java
new file mode 100644
index 000000000..a2db8aca7
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/GlyphLocator.java
@@ -0,0 +1,187 @@
+/* GlyphLocator.java -- Locates outlines of TrueType glyphs.
+ 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;
+
+import java.awt.FontFormatException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.IntBuffer;
+
+
+/**
+ * Locates glyph outlines in a TrueType or OpenType <code>glyf</code>
+ * table.
+ *
+ * @see <a href=
+ * "http://partners.adobe.com/asn/tech/type/opentype/loca.html"
+ * >Adobe&#x2019;s specification of the OpenType &#x2018;loca&#x2019;
+ * table</a>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+abstract class GlyphLocator
+{
+ /**
+ * The actual glyph data of the font, which is contained in the
+ * 'glyf' table.
+ */
+ protected ByteBuffer glyfTable;
+
+
+ /**
+ * Creates a new GlyphLocator for a <code>loca</code> table.
+ *
+ * @param format the format of the <code>loca</code> table. The
+ * value must be 0 for two-byte offsets, or 1 for four-byte
+ * offsets. TrueType and OpenType fonts indicate the format in the
+ * <code>indexToLoc</code> field of the <a href=
+ * "http://partners.adobe.com/asn/tech/type/opentype/head.html"
+ * >font header</a>.
+ *
+ * @param loca the <code>loca</code> table of the font, which
+ * contains the position of each glyph in the <code>glyf</code>
+ * table.
+ *
+ * @param glyf the <code>glyf</code> table of the font, which
+ * contains the outline data of each glyph.
+ *
+ * @throws FontFormatException if <code>format</code> is neither 0
+ * nor 1.
+ */
+ public static GlyphLocator forTable(int format, ByteBuffer loca,
+ ByteBuffer glyf)
+ throws FontFormatException
+ {
+ switch (format)
+ {
+ case 0:
+ return new GlyphLocator.TwoByte(loca, glyf);
+
+ case 1:
+ return new GlyphLocator.FourByte(loca, glyf);
+
+ default:
+ throw new FontFormatException("unsupported loca format");
+ }
+ }
+
+
+ /**
+ * Locates the outline data for a glyph.
+ *
+ * <p>For efficiency, the glyph locator does not create a new buffer
+ * for each invocation. Instead, this method always returns the same
+ * buffer object. Therefore, the data of a glyph must have been read
+ * completely before another glyph of the same font gets requested
+ * through this method.
+ *
+ * @param glyph the number of the glyph whose outlines are to be
+ * retrieved.
+ *
+ * @return a buffer whose position is set to the first byte of glyph
+ * data, and whose limit is set to disallow accessing any data that
+ * does not belong to the glyph. If there is no outline data for the
+ * requested glyph, as would be the case for the space glyph, the
+ * result will be <code>null</code>.
+ */
+ public abstract ByteBuffer getGlyphData(int glyph);
+
+
+ /**
+ * A GlyphLocator that locates glyphs using two-byte offsets,
+ * interpreting <code>loca</code> tables of format 0.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private final static class TwoByte
+ extends GlyphLocator
+ {
+ final CharBuffer indexToLoc;
+
+ TwoByte(ByteBuffer loca, ByteBuffer glyf)
+ {
+ this.glyfTable = glyf;
+ indexToLoc = loca.asCharBuffer();
+ }
+
+
+ public ByteBuffer getGlyphData(int glyph)
+ {
+ int offset, limit;
+ offset = ((int) indexToLoc.get(glyph)) << 1;
+ limit = ((int) indexToLoc.get(glyph + 1)) << 1;
+ if (offset >= limit)
+ return null;
+
+ glyfTable.limit(limit).position(offset);
+ return glyfTable;
+ }
+ }
+
+
+ /**
+ * A GlyphLocator that locates glyphs using four-byte offsets,
+ * interpreting <code>loca</code> tables of format 1.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private final static class FourByte
+ extends GlyphLocator
+ {
+ final IntBuffer indexToLoc;
+
+ FourByte(ByteBuffer loca, ByteBuffer glyf)
+ {
+ this.glyfTable = glyf;
+ indexToLoc = loca.asIntBuffer();
+ }
+
+
+ public ByteBuffer getGlyphData(int glyph)
+ {
+ int offset, limit;
+ offset = indexToLoc.get(glyph);
+ limit = indexToLoc.get(glyph + 1);
+ if (offset >= limit)
+ return null;
+
+ glyfTable.limit(limit).position(offset);
+ return glyfTable;
+ }
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java b/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java
new file mode 100644
index 000000000..bbd0b9bff
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/GlyphMeasurer.java
@@ -0,0 +1,228 @@
+/* GlyphMeasurer.java -- Helper for measuring TrueType glyphs.
+ 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;
+
+import java.awt.FontFormatException;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+
+/**
+ * A class for measuring TrueType and OpenType glyphs.
+ *
+ * <p><b>Lack of Thread Safety:</b> Glyph measurers are intentionally
+ * <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font has already obtained a lock before calling the scaler,
+ * which in turn calls the GlyphMeasurer. It would thus be wasteful to
+ * acquire additional locks for the GlyphMeasurer.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class GlyphMeasurer
+{
+ /**
+ * A view buffer that allows accessing the contents of the
+ * font&#x2019;s <code>hmtx</code> table as shorts.
+ */
+ private final ShortBuffer horizontalGlyphMetrics;
+
+
+ /**
+ * A view buffer that allows accessing the contents of the
+ * font&#x2019;s <code>vmtx</code> table as shorts.
+ */
+ private final ShortBuffer verticalGlyphMetrics;
+
+
+ private final int numLongHorizontalMetricsEntries;
+ private final int numLongVerticalMetricsEntries;
+
+ private final int horizontalAscent;
+ private final int verticalAscent;
+
+ private final int horizontalDescent;
+ private final int verticalDescent;
+
+ private final int horizontalLineGap;
+
+
+ /**
+ * Constructs a GlyphMeasurer from TrueType/OpenType font tables.
+ *
+ * @param hhea the <code>hhea</code> table, which contains
+ * information about horizontal metrics that is common to all
+ * glyphs.
+ *
+ * @param hmtx the <code>hmtx</code> table, which contains
+ * glyph-specific information about horizontal metrics.
+ *
+ * @param vhea the <code>vhea</code> table, which contains
+ * information about vertical metrics that is common to all
+ * glyphs. If a font does not provide such a table, pass
+ * <code>null</code>.
+ *
+ * @param vmtx the <code>vmtx</code> table, which contains
+ * glyph-specific information about vertical metrics. If a font
+ * does not provide such a table, pass <code>null</code>.
+ */
+ GlyphMeasurer(ByteBuffer hhea, ByteBuffer hmtx,
+ ByteBuffer vhea, ByteBuffer vmtx)
+ throws FontFormatException
+ {
+ if ((hhea.getInt(0) != 0x00010000) || (hhea.getInt(30) != 0))
+ throw new FontFormatException("unsupported hhea format");
+
+ horizontalAscent = hhea.getShort(4);
+ horizontalDescent = hhea.getShort(6);
+ horizontalLineGap = hhea.getShort(8);
+
+ numLongHorizontalMetricsEntries = hhea.getChar(34);
+ horizontalGlyphMetrics = hmtx.asShortBuffer();
+
+ if (vhea != null)
+ {
+ verticalAscent = vhea.getShort(4);
+ verticalDescent = vhea.getShort(6);
+ numLongVerticalMetricsEntries = vhea.getChar(34);
+ verticalGlyphMetrics = vmtx.asShortBuffer();
+ }
+ else
+ {
+ verticalAscent = /* advanceWidthMax */ hhea.getChar(10) / 2;
+ verticalDescent = -verticalAscent;
+ numLongVerticalMetricsEntries = 0;
+ verticalGlyphMetrics = null;
+ }
+ }
+
+
+ /**
+ * Returns the distance from the baseline to the highest ascender.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the maximal ascent, in font units.
+ */
+ public int getAscent(boolean horizontal)
+ {
+ return horizontal ? horizontalAscent : verticalAscent;
+ }
+
+
+ /**
+ * Returns the distance from the baseline to the lowest descender.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the maximal descent, in font units.
+ */
+ public int getDescent(boolean horizontal)
+ {
+ return horizontal ? horizontalDescent : verticalDescent;
+ }
+
+
+ /**
+ * Returns the typographic line gap.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the line gap, in font units.
+ */
+ public int getLineGap(boolean horizontal)
+ {
+ return horizontalLineGap;
+ }
+
+
+ /**
+ * Determines the advance width of a glyph, without considering
+ * hinting.
+ *
+ * @param glyphIndex the index of the glyph whose advance width is
+ * to be determined.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the advance width, in font units.
+ */
+ public int getAdvanceWidth(int glyphIndex, boolean horizontal)
+ {
+ if (!horizontal)
+ return 0;
+
+ glyphIndex = Math.min(glyphIndex,
+ numLongHorizontalMetricsEntries - 1);
+ return horizontalGlyphMetrics.get(glyphIndex << 1);
+ }
+
+
+ /**
+ * Determines the advance width of a glyph, without considering
+ * hinting.
+ *
+ * @param glyphIndex the index of the glyph whose advance width is
+ * to be determined.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the advance width, in font units.
+ */
+ public int getAdvanceHeight(int glyphIndex, boolean horizontal)
+ {
+ if (horizontal)
+ return 0;
+
+ /* If a font does not provide vertical glyph metrics, advance
+ * by the height of one horizontal line.
+ */
+ if (verticalGlyphMetrics == null)
+ return horizontalAscent - horizontalDescent + horizontalLineGap;
+
+ glyphIndex = Math.min(glyphIndex,
+ numLongVerticalMetricsEntries - 1);
+ return verticalGlyphMetrics.get(glyphIndex << 1);
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java b/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
new file mode 100644
index 000000000..e4d7309cb
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
@@ -0,0 +1,372 @@
+/* TrueTypeScaler.java -- Font scaler for TrueType outlines.
+ 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;
+
+import gnu.java.awt.font.opentype.Scaler;
+
+import java.awt.FontFormatException;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A scaler for fonts whose outlines are described in the TrueType
+ * format.
+ *
+ * <p><b>Lack of Thread Safety:</b> Font scalers are intentionally
+ * <i>not</i> safe to access from multiple concurrent threads.
+ * Synchronization needs to be performed externally. Usually, the font
+ * that uses this scaler already has obtained a lock before calling
+ * the scaler.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public final class TrueTypeScaler
+ extends Scaler
+{
+ /**
+ * The TrueType or OpenType table that contains the glyph outlines.
+ */
+ private ByteBuffer glyfTable;
+
+
+ /**
+ * A helper object for loading glyph outlines.
+ */
+ private GlyphLoader glyphLoader;
+
+
+ /**
+ * A helper object for measuring the advance width and height of a
+ * glyph.
+ */
+ private final GlyphMeasurer glyphMeasurer;
+
+ private final Zone glyphZone;
+
+
+ /**
+ * The number of units per em. A typical value is 2048, but some
+ * font use other numbers as well.
+ */
+ private int unitsPerEm;
+
+
+ /**
+ * Constructs a new TrueTypeScaler.
+ *
+ * @param unitsPerEm the number of font units per em. This value can
+ * be retrieved from the font&#x2019;s <code>head</code> table.
+ *
+ * @param maxp the <code>maxp</code> table of the font, which
+ * contains various constants needed for setting up the virtual
+ * machine that interprets TrueType bytecodes.
+ *
+ * @param controlValueTable the <code>cvt</code> table of the font,
+ * which contains the initial values of the control value table.
+ *
+ * @param fpgm the <code>fpgm</code> table of the font, which
+ * contains a font program that is executed exactly once. The
+ * purpose of the font program is to define functions and to patch
+ * the interpreter.
+ *
+ * @param locaFormat the format of the <code>loca</code> table. The
+ * value must be 0 for two-byte offsets, or 1 for four-byte
+ * offsets. TrueType and OpenType fonts indicate the format in the
+ * <code>indexToLoc</code> field of the <a href=
+ * "http://partners.adobe.com/asn/tech/type/opentype/head.html"
+ * >font header</a>.
+ *
+ * @param loca the <code>loca</code> table of the font, which
+ * contains for each glyph the offset of its outline data
+ * in <code>glyf</code>.
+ *
+ * @param glyf the <code>glyf</code> table of the font, which
+ * contains the outline data for all glyphs in the font.
+ *
+ * @param preProgram the <code>prep</code> table of the font, which
+ * contains a program that is executed whenever the point size or
+ * the device transform have changed. This program is called
+ * pre-program because it gets executed before the instructions of
+ * the individual glyphs. If the font does not contain a
+ * pre-program, pass <code>null</code>.
+ *
+ * @throws FontFormatException if <code>format</code> is neither 0
+ * nor 1.
+ */
+ public TrueTypeScaler(int unitsPerEm,
+ ByteBuffer hhea,
+ ByteBuffer htmx,
+ ByteBuffer vhea,
+ ByteBuffer vtmx,
+ ByteBuffer maxp,
+ ByteBuffer controlValueTable,
+ ByteBuffer fpgm,
+ int locaFormat, ByteBuffer loca,
+ ByteBuffer glyf,
+ ByteBuffer preProgram)
+ throws FontFormatException
+ {
+ int maxContours, maxPoints;
+ VirtualMachine vm;
+
+ maxContours = Math.max(/* maxContours */ (int) maxp.getChar(8),
+ /* maxCompositeContours */ (int) maxp.getChar(12))
+ + /* fix for some broken fonts */ 8;
+ maxPoints = Math.max(/* maxPoints */ (int) maxp.getChar(6),
+ /* maxCompositePoints */ (int) maxp.getChar(10))
+ + /* fix for some broken fonts */ 12;
+
+
+ glyphZone = new Zone(maxPoints + /* four phantom points */ 4);
+ this.glyfTable = glyf;
+ vm = new VirtualMachine(unitsPerEm, maxp,
+ controlValueTable, fpgm,
+ preProgram);
+
+ GlyphLocator locator = GlyphLocator.forTable(locaFormat, loca, glyf);
+ glyphMeasurer = new GlyphMeasurer(hhea, htmx, vhea, vtmx);
+ glyphLoader = new GlyphLoader(locator, vm, unitsPerEm,
+ maxContours, maxPoints,
+ glyphMeasurer);
+
+ this.unitsPerEm = unitsPerEm;
+ }
+
+
+ /**
+ * Retrieves the scaled outline of a glyph, adjusting control points
+ * to the raster grid if necessary.
+ *
+ * @param glyphIndex the glyph number whose outline is retrieved.
+ *
+ * @param pointSize the point size for the glyph.
+ *
+ * @param deviceTransform an affine transformation for the device.
+ *
+ * @param antialias whether or not the rasterizer will perform
+ * anti-aliasing on the returned path.
+ *
+ * @param fractionalMetrics <code>false</code> for adjusting glyph
+ * positions to the raster grid of device space.
+ */
+ public GeneralPath getOutline(int glyphIndex,
+ float pointSize,
+ AffineTransform deviceTransform,
+ boolean antialias,
+ boolean fractionalMetrics)
+ {
+ glyphLoader.loadGlyph(glyphIndex, pointSize, deviceTransform,
+ antialias, glyphZone);
+ return glyphZone.getPath();
+ }
+
+
+ /**
+ * Determines the advance width and height for a glyph.
+ *
+ * @param glyphIndex the glyph whose advance width and height is to
+ * be determined.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @param advance a point whose <code>x</code> and <code>y</code>
+ * fields will hold the advance in each direction. It is possible
+ * that both values are non-zero, for example if
+ * <code>transform</code> is a rotation, or in the case of Urdu
+ * fonts.
+ */
+ public void getAdvance(int glyphIndex,
+ float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal,
+ Point2D advance)
+ {
+ double x, y;
+ double scaleFactor = (double) pointSize / unitsPerEm;
+
+ /* FIXME: Should grid-fit if needed. Also, use cache if present
+ * in the font.
+ */
+ advance.setLocation(
+ scaleFactor * glyphMeasurer.getAdvanceWidth(glyphIndex, horizontal),
+ scaleFactor * glyphMeasurer.getAdvanceHeight(glyphIndex, horizontal));
+
+ transform.transform(advance, advance);
+ }
+
+
+ /**
+ * Scales a value from font units to pixels, given the point size
+ * and the transform.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional
+ * metrics, <code>false</code> for rounding the result to a pixel
+ * boundary.
+ *
+ * @param horizontal <code>true</code> if the <code>funits</code>
+ * value is along the x axis, <code>false</code> if it is along the
+ * y axis.
+ */
+ private float scaleFromFUnits(int funits,
+ float pointSize,
+ AffineTransform transform,
+ boolean fractionalMetrics,
+ boolean horizontal)
+ {
+ double s;
+
+ s = (double) pointSize / unitsPerEm;
+ if (transform != null)
+ s *= horizontal ? transform.getScaleY() : transform.getScaleX();
+ s *= funits;
+ if (!fractionalMetrics)
+ s = Math.round(s);
+ return (float) s;
+ }
+
+
+ /**
+ * Determines the distance between the base line and the highest
+ * ascender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialias <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the ascent, which usually is a positive number.
+ */
+ public float getAscent(float pointSize,
+ AffineTransform transform,
+ boolean antialias,
+ boolean fractionalMetrics,
+ boolean horizontal)
+ {
+ /* Note that the ascent is orthogonal to the direction of line
+ * layout: If the line direction is horizontal, the measurement of
+ * ascent is along the vertical axis, and vice versa.
+ */
+ return scaleFromFUnits(glyphMeasurer.getAscent(horizontal),
+ pointSize,
+ transform,
+ fractionalMetrics,
+ /* reverse */ !horizontal);
+ }
+
+
+ /**
+ * Determines the distance between the base line and the lowest
+ * descender.
+ *
+ * @param pointSize the point size of the font.
+ *
+ * @param transform a transform that is applied in addition to
+ * scaling to the specified point size. This is often used for
+ * scaling according to the device resolution. Those who lack any
+ * aesthetic sense may also use the transform to slant or stretch
+ * glyphs.
+ *
+ * @param antialiased <code>true</code> for anti-aliased rendering,
+ * <code>false</code> for normal rendering. For hinted fonts,
+ * this parameter may indeed affect the result.
+ *
+ * @param fractionalMetrics <code>true</code> for fractional metrics,
+ * <code>false</code> for rounding the result to a pixel boundary.
+ *
+ * @param horizontal <code>true</code> for horizontal line layout,
+ * <code>false</code> for vertical line layout.
+ *
+ * @return the descent, which usually is a nagative number.
+ */
+ public float getDescent(float pointSize,
+ AffineTransform transform,
+ boolean antialiased,
+ boolean fractionalMetrics,
+ boolean horizontal)
+ {
+ /* Note that the descent is orthogonal to the direction of line
+ * layout: If the line direction is horizontal, the measurement of
+ * descent is along the vertical axis, and vice versa.
+ */
+ return scaleFromFUnits(glyphMeasurer.getDescent(horizontal),
+ pointSize,
+ transform,
+ fractionalMetrics,
+ /* reverse */ !horizontal);
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/VirtualMachine.java b/gnu/java/awt/font/opentype/truetype/VirtualMachine.java
new file mode 100644
index 000000000..6f53af672
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/VirtualMachine.java
@@ -0,0 +1,1809 @@
+/* VirtualMachine.java -- Virtual machine for TrueType bytecodes.
+ 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;
+
+import java.awt.FontFormatException;
+import java.awt.geom.AffineTransform;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+
+/**
+ * A virtual machine for interpreting TrueType bytecodes.
+ *
+ * <p><b>Lack of Thread Safety:</b> The virtual machine is
+ * intentionally <i>not</i> safe to access from multiple concurrent
+ * threads. Synchronization needs to be performed externally. Usually,
+ * the font has already obtained a lock before calling the scaler,
+ * which in turn calls the VM. It would be wasteful to acquire
+ * additional locks for the VM.
+ *
+ * <p><b>Implementation Status:</b> The current implementation can
+ * execute pre-programs of fonts, but it does not yet actually move
+ * any points. Control flow and arithmeti instructions are
+ * implemented, but most geometric instructions are not working
+ * yet. So, the VirtualMachine class is currently a no-op. However,
+ * not very much is missing. You are more than welcome to complete the
+ * implementation.
+ *
+ * <p><b>Patents:</b> Apple Computer holds three United States Patents
+ * for the mathematical algorithms that are used by TrueType
+ * instructions. The monopoly granted by these patents will expire in
+ * October 2009. Before the expiration date, a license must be
+ * obtained from Apple Computer to use the patented technology inside
+ * the United States. For other countries, different dates might
+ * apply, or no license might be needed.
+ *
+ * <p>The default build of this class does not use the patented
+ * algorithms. If you have obtained a license from Apple, or if the
+ * patent protection has expired, or if no license is required for
+ * your contry, you can set a flag in the source file which will
+ * enable the use of the patented mathematical algorithms.</p>
+ *
+ * <p>The relevant patents are listed subsequently.</p>
+ *
+ * <p><ol><li>United States Patent 5155805, <i>Method and Apparatus
+ * for Moving Control Points in Displaying Digital Typeface on Raster
+ * Output Devices,</i> invented by Sampo Kaasila, assigned to Apple
+ * Computer. Filing date: May 8, 1989. Date of patent: October 13,
+ * 1992.</li>
+ *
+ * <li>United States Patent 5159668, <i>Method and Apparatus for
+ * Manipulating Outlines in Improving Digital Typeface on Raster
+ * Output Devices,</i> invented by Sampo Kaasila, assigned to Apple
+ * Computer. Filing date: May 8, 1989. Date of patent: October 27,
+ * 1992.</li>
+ *
+ * <li>United States Patent 5325479, <i>Method and Apparatus for
+ * Moving Control Points in Displaying Digital Typeface on Raster
+ * Output Devices,</i> invented by Sampo Kaasila, assigned to Apple
+ * Computer. Filing date: May 28, 1989. Date of patent: June 28, 1994
+ * (with a statement that &#x201c;[t]he portion of the term of this
+ * patent subsequent to Oct. 13, 2009 has been
+ * disclaimed&#x201d;).</li></ol>
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+class VirtualMachine
+{
+ /**
+ * Indicates whether or not to perform hinting operations that are
+ * protected by a number of US patents, two of which will expire on
+ * October 13, 2009, and one of which will expire on October 27,
+ * 2009.
+ */
+ private final static boolean PATENTED_HINTING = false;
+
+
+ /**
+ * Indicates whether the execution of the Virtual Machine is traced
+ * to System.out.
+ */
+ private final static boolean TRACE_EXECUTION = false;
+
+
+ /**
+ * The value 1 in 2-dot-14 fixed notation.
+ */
+ private static final short ONE_214 = 0x4000; // 1 << 14
+
+
+ /**
+ * The storage area of the virtual machine.
+ */
+ private final int[] storage;
+
+
+ /**
+ * The stack. The stack grows from bottom to top, so
+ * <code>sp[0]</code> gets used before <code>sp[1]</code>.
+ */
+ private int[] stack;
+
+
+ /**
+ * The maximum number of stack elements.
+ */
+ private final int maxStackElements;
+
+
+ /**
+ * The current stack pointer of the virtual machine.
+ */
+ private int sp;
+
+
+ /**
+ * fdefBuffer[i] is the buffer that contains the TrueType
+ * instructions of function #i. Most of the time, functions are
+ * defined in the font program, but a font may also re-define
+ * functions in its CVT program.
+ */
+ private ByteBuffer[] fdefBuffer;
+
+
+ /**
+ * fdefEntryPoint[i] is the position in fdefBuffer[i] where the
+ * first TrueType instruction after the FDEF is located.
+ */
+ private int[] fdefEntryPoint;
+
+
+ /**
+ * The original Control Value Table, sometimes abbreviated as CVT.
+ * The table contains signed 16-bit FUnits. Some fonts have no CVT,
+ * in which case the field will be <code>null</code>.
+ */
+ private ShortBuffer controlValueTable;
+
+
+ /**
+ * The scaled values inside the control value table.
+ */
+ private int[] cvt;
+
+
+ /**
+ * A value that is used by rounding operations to compensate for dot
+ * gain.
+ */
+ private int engineCompensation = 0;
+
+
+ /**
+ * The contents of the font&#x2019;s <code>fpgm</code> table, or
+ * <code>null</code> after the font program has been executed once.
+ */
+ private ByteBuffer fontProgram;
+
+
+ /**
+ * The <code>prep</code> table of the font, which contains a program
+ * that is executed whenever the point size or the device transform
+ * have changed. This program is called pre-program because it gets
+ * executed before the instructions of the individual glyphs. If
+ * the font does not contain a pre-program, the value of this field
+ * is <code>null</code>.
+ */
+ private ByteBuffer preProgram;
+
+
+ /**
+ * The number of points in the Twilight Zone.
+ */
+ private int numTwilightPoints;
+
+
+ /**
+ * The current point size of the scaled font. The value is in Fixed
+ * 26.6 notation.
+ */
+ private int pointSize; // 26.6
+
+ private AffineTransform deviceTransform;
+
+ private int scaleX, scaleY, shearX, shearY; // 26.6
+
+
+ /**
+ * Indicates whether or not scan-line conversion will use
+ * anti-aliasing (with gray levels). Font programs can ask for this
+ * value with the <code>GETINFO</code> instruction, and some
+ * programs may behave differently according to this setting.
+ */
+ private boolean antialiased;
+
+
+ /* Graphics State. FIXME: Move this to its own class? Some
+ * documentation would not hurt, either.
+ */
+ private int cvtCutIn; // 26.6
+ private int deltaBase; // uint32
+ private int deltaShift; // uint32
+ private short freeX; // 2.14
+ private short freeY; // 2.14
+ private int loop; // int
+ private int minimumDistance; // 26.6
+ private short projX; // 2.14
+ private short projY; // 2.14
+ private short dualX; // 2.14
+ private short dualY; // 2.14
+ private int rp0, rp1, rp2; // point numbers
+ private boolean scanControl;
+ private int scanType;
+ private int singleWidthValue; // 26.6
+ private Zone zp0, zp1, zp2;
+
+ private Zone twilightZone;
+ private Zone glyphZone;
+
+
+ /**
+ * Indicates whether or not the instructions that are associated
+ * with individual glyphs shall be executed. Set as a side effect
+ * of executing the pre-program when the point size, device
+ * transform or some other relevant parameter have changed.
+ */
+ private boolean executeGlyphInstructions;
+
+
+ /**
+ * Indicates whether to ignore any modifications to the control
+ * value table that the font&#x2019;s pre-program might have
+ * performed. Set as a side effect of executing the pre-program
+ * when the point size, device transform or some other relevant
+ * parameter have changed.
+ */
+ private boolean ignoreCVTProgram;
+
+
+ /**
+ * The length of the space between rounded values. A value
+ * of zero means that rounding has been switched off.
+ */
+ private int roundPeriod; // 26.6
+
+
+ /**
+ * The offset of the rounded values from multiples of
+ * <code>roundPeriod</code>.
+ */
+ private int roundPhase; // 26.6
+
+
+ private int roundThreshold; // 26.6
+
+
+ /**
+ * A cache for the number of pixels per EM. The value is a normal
+ * integer, not a fixed point notation.
+ *
+ * @see #getPixelsPerEM()
+ */
+ private int cachedPixelsPerEM;
+
+
+ /**
+ * The number of font units per EM.
+ */
+ private int unitsPerEm;
+
+
+ /**
+ * Constructs a new Virtual Machine for executing TrueType
+ * instructions.
+ *
+ * @param unitsPerEm the number of font units in one typographic
+ * em.
+ *
+ * @param preProgram the <code>prep</code> table of the font, which
+ * contains a program that is executed whenever the point size or
+ * the device transform have changed. This program is called
+ * pre-program because it gets executed before the instructions of
+ * the individual glyphs. If the font does not contain a
+ * pre-program, pass <code>null</code>.
+ */
+ VirtualMachine(int unitsPerEm,
+ ByteBuffer maxp,
+ ByteBuffer controlValueTable,
+ ByteBuffer fontProgram,
+ ByteBuffer preProgram)
+ throws FontFormatException
+ {
+ int maxStorage, numFunctionDefs, maxInstructionDefs;
+
+ if (maxp.getInt(0) != 0x00010000)
+ throw new FontFormatException("unsupported maxp version");
+
+ this.unitsPerEm = unitsPerEm;
+ maxStorage = maxp.getChar(18);
+
+ /* FreeType says that there exist some broken fonts (like
+ * "Keystrokes MT") that contain function defs, but have a zero
+ * value in their maxp table.
+ */
+ numFunctionDefs = maxp.getChar(20);
+ if (numFunctionDefs == 0)
+ numFunctionDefs = 64;
+ fdefBuffer = new ByteBuffer[numFunctionDefs];
+ fdefEntryPoint = new int[numFunctionDefs];
+
+ /* Read the contents of the Control Value Table. */
+ if (controlValueTable != null)
+ this.controlValueTable = controlValueTable.asShortBuffer();
+
+ maxInstructionDefs = maxp.getChar(22);
+ maxStackElements = maxp.getChar(24);
+ storage = new int[maxStorage];
+ this.fontProgram = fontProgram;
+ this.preProgram = preProgram;
+ numTwilightPoints = maxp.getChar(16);
+ }
+
+
+ /**
+ * Sets the graphics state to default values.
+ */
+ private void resetGraphicsState()
+ {
+ /* The freedom, projection and dual vector default to the x axis. */
+ freeX = projX = dualX = ONE_214;
+ freeY = projY = dualX = 0;
+ cachedPixelsPerEM = 0;
+
+ cvtCutIn = 68; // 17/16 in 26.6 notation
+ deltaBase = 9;
+ deltaShift = 3;
+ loop = 1;
+ minimumDistance = Fixed.ONE;
+ singleWidthValue = 0;
+ rp0 = rp1 = rp2 = 0;
+ scanControl = false;
+ scanType = 2;
+ zp0 = zp1 = zp2 = getZone(1);
+
+ setRoundingMode(Fixed.ONE, 0x48); // round to grid
+ }
+
+
+ /**
+ * Reloads the control value table and scales each entry from font
+ * units to pixel values.
+ */
+ private void reloadControlValueTable()
+ {
+ /* Some TrueType fonts have no control value table. */
+ if (controlValueTable == null)
+ return;
+
+ /* Read in the Control Value Table. */
+ if (cvt == null)
+ cvt = new int[controlValueTable.capacity()];
+
+ /* Scale the entries. */
+ for (int i = 0; i < cvt.length; i++)
+ cvt[i] = funitsToPixels(controlValueTable.get(i));
+ }
+
+
+ /**
+ * Scales a value from font unites to pixels.
+ *
+ * @return the scaled value.
+ */
+ private int funitsToPixels(int funits)
+ {
+ return (int) (((long) funits * scaleY + (unitsPerEm>>1))
+ / unitsPerEm);
+ }
+
+
+ /**
+ * Sets up the virtual machine for the specified parameters. If
+ * there is no change to the last set-up, the method will quickly
+ * return. Otherwise, the font&#x2019;s pre-program will be
+ * executed.
+ *
+ * @param pointSize the point size of the scaled font.
+ *
+ * @param deviceTransform an affine transformation which gets
+ * applied in addition to scaling by <code>pointSize</code>. Font
+ * programs can separately inquire about the point size. For this
+ * reason, it is not recommended to pre-multiply the point size to
+ * the device transformation.
+ *
+ * @param antialiased <code>true</code> if the scan-line conversion
+ * algorithm will use gray levels to give a smoother appearance,
+ * <code>false</code> otherwise. Font programs can ask for this
+ * value with the <code>GETINFO</code> instruction, and some
+ * programs may behave differently according to this setting.
+ */
+ public boolean setup(double pointSize,
+ AffineTransform deviceTransform,
+ boolean antialiased)
+ {
+ boolean changeCTM;
+ int pointSize_Fixed;
+
+ if (stack == null)
+ stack = new int[maxStackElements];
+
+ if (twilightZone == null)
+ twilightZone = new Zone(numTwilightPoints);
+
+ /* If the font program has not yet been executed, do so. */
+ if (fontProgram != null)
+ {
+ resetGraphicsState();
+ sp = -1;
+ execute(fontProgram, 0);
+ fontProgram = null; // prevent further execution
+ }
+
+ /* Determine whether the transformation matrix has changed. */
+ pointSize_Fixed = Fixed.valueOf(pointSize);
+ changeCTM = ((pointSize_Fixed != this.pointSize)
+ || !deviceTransform.equals(this.deviceTransform)
+ || (antialiased != this.antialiased));
+
+ if (changeCTM)
+ {
+ this.pointSize = pointSize_Fixed;
+ this.deviceTransform = deviceTransform;
+ this.antialiased = antialiased;
+ scaleX = (int) (deviceTransform.getScaleX() * pointSize * 64);
+ scaleY = (int) (deviceTransform.getScaleY() * pointSize * 64);
+ shearX = (int) (deviceTransform.getShearX() * pointSize * 64);
+ shearY = (int) (deviceTransform.getShearY() * pointSize * 64);
+
+ resetGraphicsState();
+ reloadControlValueTable();
+ executeGlyphInstructions = true;
+ ignoreCVTProgram = false;
+
+ if (preProgram != null)
+ {
+ sp = -1;
+ execute(preProgram, 0);
+ if (ignoreCVTProgram)
+ reloadControlValueTable();
+ }
+ }
+
+ return executeGlyphInstructions;
+ }
+
+
+ /**
+ * Executes a stream of TrueType instructions.
+ */
+ private void execute(ByteBuffer instructions, int pos)
+ {
+ instructions.position(pos);
+
+ // FIXME: SECURITY: Possible denial-of-service attack
+ // via instructions that have an endless loop.
+ while (instructions.hasRemaining()
+ && executeInstruction(instructions))
+ ;
+ }
+
+
+ /**
+ * Writes a textual description of the current TrueType instruction,
+ * including the top stack elements, to <code>System.out</code>.
+ * This is useful for debugging.
+ *
+ * @param inst the instruction stream, positioned at the current
+ * instruction.
+ */
+ private void dumpInstruction(ByteBuffer inst)
+ {
+ StringBuffer sbuf = new StringBuffer(40);
+ int pc = inst.position();
+ int bcode = inst.get(pc) & 0xff;
+ int count;
+ int delta;
+
+ char pcPrefix = 'c';
+ for (int i = 0; i < fdefBuffer.length; i++)
+ {
+ if (fdefBuffer[i] == inst)
+ {
+ pcPrefix = 'f';
+ break;
+ }
+ }
+ sbuf.append(pcPrefix);
+
+
+ sbuf.append(getHex((short) inst.position()));
+ sbuf.append(": ");
+ sbuf.append(getHex((byte) bcode));
+ sbuf.append(" ");
+ sbuf.append(INST_NAME[bcode]);
+
+ if (bcode == 0x40) // NPUSHB
+ {
+ count = inst.get(pc + 1) & 0xff;
+ sbuf.append(" (");
+ sbuf.append(count);
+ sbuf.append(") ");
+ for (int i = 0; i < count; i++)
+ {
+ if (i > 0)
+ sbuf.append(" ");
+ sbuf.append('$');
+ sbuf.append(getHex(inst.get(pc + 2 + i)));
+ }
+ }
+ if (bcode == 0x41) // NPUSHW
+ {
+ count = inst.get(pc + 1) & 0xff;
+ sbuf.append(" (");
+ sbuf.append(count);
+ sbuf.append(") ");
+ for (int i = 0; i < count; i++)
+ {
+ if (i > 0)
+ sbuf.append(' ');
+ sbuf.append('$');
+ sbuf.append(getHex(inst.getShort(pc + 2 + 2*i)));
+ }
+ }
+ else
+ {
+ count = getInstructionLength(bcode) - 1;
+ for (int i = 0; i < count; i++)
+ {
+ sbuf.append(" $");
+ sbuf.append(getHex(inst.get(pc + 1 + i)));
+ }
+ }
+
+ while (sbuf.length() < 30)
+ sbuf.append(' ');
+ sbuf.append('|');
+ sbuf.append(sp + 1);
+ sbuf.append("| ");
+ for (int i = sp; i >= Math.max(0, sp - 5); i = i - 1)
+ {
+ if (i < sp)
+ sbuf.append(" ");
+ if ((stack[i] >> 16) != 0)
+ sbuf.append(getHex((short) (stack[i] >> 16)));
+ sbuf.append(getHex((short) stack[i]));
+ }
+ System.out.println(sbuf);
+ }
+
+
+ private static char getNibble(int i, int rightShift)
+ {
+ i = (i >> rightShift) & 15;
+ if (i < 10)
+ return (char) (i + '0');
+ else
+ return (char) (i + 'a' - 10);
+ }
+
+
+ private static String getHex(byte b)
+ {
+ char[] a = new char[2];
+ a[0] = getNibble(b, 4);
+ a[1] = getNibble(b, 0);
+ return new String(a);
+ }
+
+
+ private static String getHex(short b)
+ {
+ char[] a = new char[4];
+ a[0] = getNibble(b, 12);
+ a[1] = getNibble(b, 8);
+ a[2] = getNibble(b, 4);
+ a[3] = getNibble(b, 0);
+ return new String(a);
+ }
+
+
+ /**
+ * Skips any instructions until the specified opcode has been
+ * encoutered.
+ *
+ * @param inst the current instruction stream. After the call,
+ * the position of <code>inst</code> is right after the first
+ * occurence of <code>opcode</code>.
+ *
+ * @param opcode1 the opcode for which to look.
+ *
+ * @param opcode2 another opcode for which to look. Pass -1
+ * if only <code>opcode1</code> would terminate skipping.
+ *
+ * @param illegalCode1 an opcode that must not be encountered
+ * while skipping. Pass -1 if any opcode is acceptable.
+ *
+ * @param illegalCode2 another opcode that must not be encountered
+ * while skipping. Pass -1 to perform no check.
+ *
+ * @param handleNestedIfClauses <code>true</code> to handle
+ * nested <code>IF [ELSE] EIF</code> clauses, <code>false</code>
+ * to ignore them. From the TrueType specification document,
+ * one would think that nested if clauses would not be valid,
+ * but they do appear in some fonts.
+ *
+ * @throws IllegalStateException if <code>illegalCode1</code> or
+ * <code>illegalCode2</code> has been encountered while skipping.
+ */
+ private static void skipAfter(ByteBuffer inst,
+ int opcode1, int opcode2,
+ int illegalCode1, int illegalCode2,
+ boolean handleNestedIfClauses)
+ {
+ int pos = inst.position();
+ int curOpcode;
+ int instLen;
+ int nestingLevel = 0; // increased inside IF [ELSE] EIF sequences
+
+ while (true)
+ {
+ curOpcode = inst.get(pos) & 0xff;
+ instLen = getInstructionLength(curOpcode);
+
+ if (false && TRACE_EXECUTION)
+ {
+ for (int i = 0; i < nestingLevel; i++)
+ System.out.print("--");
+ System.out.print("--" + pos + "-" + INST_NAME[curOpcode]);
+ if (nestingLevel > 0)
+ System.out.print(", ifNestingLevel=" + nestingLevel);
+ System.out.println();
+ }
+
+ if (curOpcode == 0x40) // NPUSHB
+ pos += 1 + (inst.get(pos + 1) & 0xff);
+ else if (curOpcode == 0x41) // NPUSHW
+ pos += 1 + 2 * (inst.get(pos + 1) & 0xff);
+ else
+ pos += instLen;
+
+ if ((nestingLevel == 0)
+ && ((curOpcode == opcode1) || (curOpcode == opcode2)))
+ break;
+
+ if (handleNestedIfClauses)
+ {
+ if (curOpcode == /* IF */ 0x58)
+ ++nestingLevel;
+ else if (curOpcode == /* EIF */ 0x59)
+ --nestingLevel;
+ }
+
+ if ((nestingLevel < 0)
+ || (curOpcode == illegalCode1)
+ || (curOpcode == illegalCode2))
+ throw new IllegalStateException();
+ }
+
+ inst.position(pos);
+ }
+
+
+ /**
+ * Returns the number of bytes that a TrueType instruction occupies.
+ *
+ * @param opcode the instruction.
+ *
+ * @return the number of bytes occupied by the instructions and its
+ * operands. For <code>NPUSHB</code> and <code>NPUSHW</code>, where
+ * the instruction length depends on the first operand byte, the
+ * result is -1.
+ */
+ private static int getInstructionLength(int opcode)
+ {
+ /* NPUSHB, NPUSHW --> see following byte */
+ if ((opcode == 0x40) || (opcode == 0x41))
+ return -1;
+
+ /* PUSHB[0] .. PUSHB[7] --> 2, 3, 4, 5, 6, 7, 8, 9 */
+ if ((opcode >= 0xb0) && (opcode <= 0xb7))
+ return opcode - 0xae;
+
+ /* PUSHW[0] .. PUSHW[7] --> 3, 5, 6, 7, 11, 13, 15, 17*/
+ if ((opcode >= 0xb8) && (opcode <= 0xbf))
+ return 1 + ((opcode - 0xb7) << 1);
+
+ return 1;
+ }
+
+
+ /**
+ * Executes a single TrueType instruction. This is the core
+ * routine of the Virtual Machine.
+ *
+ * @return <code>true</code> if another instruction shall be
+ * executed in the same call frame; <code>false</code> if the
+ * current call frame shall be popped.
+ */
+ private boolean executeInstruction(ByteBuffer inst)
+ {
+ if (TRACE_EXECUTION)
+ dumpInstruction(inst);
+
+ int i, count, e1, e2, e3, e4, x, y;
+ int bcode = inst.get() & 0xff;
+
+ switch (bcode)
+ {
+ case 0x00: // SVTCA[0], Set freedom and proj. Vectors To Coord. Axis [y]
+ setFreedomVector((short) 0, ONE_214);
+ setProjectionVector((short) 0, ONE_214);
+ break;
+
+ case 0x01: // SVTCA[1], Set freedom and proj. Vectors To Coord. Axis [x]
+ setFreedomVector(ONE_214, (short) 0);
+ setProjectionVector(ONE_214, (short) 0);
+ break;
+
+ case 0x02: // SPVTCA[0], Set Projection Vector To Coordinate Axis [y]
+ setProjectionVector((short) 0, ONE_214);
+ break;
+
+ case 0x03: // SPVTCA[1], Set Projection Vector To Coordinate Axis [x]
+ setProjectionVector(ONE_214, (short) 0);
+ break;
+
+ case 0x0c: // GPV, Get Projection Vector
+ stack[++sp] = projX;
+ stack[++sp] = projY;
+ break;
+
+ case 0x0d: // GPV, Get Freedom Vector
+ stack[++sp] = freeX;
+ stack[++sp] = freeY;
+ break;
+
+ case 0x0F: // ISECT, move point p to the InterSECTION of two lines
+ sp -= 4;
+ handleISECT(stack[sp], stack[sp+1], stack[sp+2],
+ stack[sp+3], stack[sp+4]);
+ break;
+
+ case 0x10: // SRP0, Set Reference Point 0
+ rp0 = stack[sp--];
+ break;
+
+ case 0x11: // SRP1, Set Reference Point 1
+ rp1 = stack[sp--];
+ break;
+
+ case 0x12: // SRP2, Set Reference Point 2
+ rp2 = stack[sp--];
+ break;
+
+ case 0x13: // SZP0, Set Zone Pointer 0
+ zp0 = getZone(stack[sp--]);
+ break;
+
+ case 0x14: // SZP1, Set Zone Pointer 1
+ zp1 = getZone(stack[sp--]);
+ break;
+
+ case 0x15: // SZP2, Set Zone Pointer 2
+ zp2 = getZone(stack[sp--]);
+ break;
+
+ case 0x16: // SZPS, Set Zone PointerS
+ zp0 = zp1 = zp2 = getZone(stack[sp--]);
+ break;
+
+ case 0x17: // SLOOP, Set LOOP variable
+ loop = stack[sp--];
+ break;
+
+ case 0x18: // RTG, Round To Grid
+ setRoundingMode(Fixed.ONE, 0x48);
+ break;
+
+ case 0x19: // RTHG, Round To Half Grid
+ setRoundingMode(Fixed.ONE, 0x68);
+ break;
+
+ case 0x1a: // SMD, Set Minimum Distance
+ minimumDistance = stack[sp--];
+ break;
+
+ case 0x1B: // ELSE, ELSE clause
+ skipAfter(inst,
+ /* look for: EIF, -- */ 0x59, -1,
+ /* illegal: --, -- */ -1, -1,
+ /* handle nested if clauses */ true);
+ break;
+
+ case 0x1C: // JMPR, JuMP Relative
+ inst.position(inst.position() - 1 + stack[sp--]);
+ break;
+
+ case 0x1D: // SCVTCI, Set Control Value Table Cut-In
+ cvtCutIn = stack[sp--];
+ break;
+
+ case 0x1F: // SSW, Set Single Width
+ singleWidthValue = stack[sp--];
+ break;
+
+ case 0x20: // DUP, DUPlicate top stack element
+ e1 = stack[sp];
+ stack[++sp] = e1;
+ break;
+
+ case 0x21: // POP, POP top stack element
+ sp--;
+ break;
+
+ case 0x22: // CLEAR, CLEAR the stack
+ sp = -1;
+ break;
+
+ case 0x23: // SWAP, SWAP the top two elements on the stack
+ e1 = stack[sp--];
+ e2 = stack[sp];
+ stack[sp] = e1;
+ stack[++sp] = e2;
+ break;
+
+ case 0x24: // DEPTH, DEPTH of the stack
+ stack[++sp] = sp + 1;
+ break;
+
+ case 0x25: // CINDEX, Copy the INDEXed element to the top of the stack
+ stack[sp] = stack[sp - stack[sp]];
+ break;
+
+ case 0x26: // MINDEX, Move the INDEXed element to the top of the stack
+ i = stack[sp];
+ e1 = stack[sp - i];
+ System.arraycopy(/* src */ stack, /* srcPos */ sp - i + 1,
+ /* dest */ stack, /* destPos*/ sp - i,
+ /* length */ i - 1);
+ --sp;
+ stack[sp] = e1;
+ break;
+
+ case 0x2a: // LOOPCALL, LOOP and CALL function
+ i = stack[sp--];
+ count = stack[sp--];
+ e1 = inst.position();
+ e2 = sp;
+ for (int j = 0; j < count; j++)
+ execute(fdefBuffer[i], fdefEntryPoint[i]);
+ inst.position(e1);
+ break;
+
+ case 0x2B: // CALL, CALL function
+ i = stack[sp--];
+ e1 = inst.position();
+ e2 = sp;
+ execute(fdefBuffer[i], fdefEntryPoint[i]);
+ inst.position(e1);
+ break;
+
+ case 0x2C: // FDEF, Function DEFinition
+ i = stack[sp--];
+ fdefBuffer[i] = inst;
+ fdefEntryPoint[i] = inst.position();
+ skipAfter(inst,
+ /* look for: ENDF */ 0x2d,
+ /* look for: --- */ -1,
+ /* illegal: IDEF */ 0x89,
+ /* illegal: FDEF */ 0x2c,
+ /* do not handle nested if clauses */ false);
+ break;
+
+ case 0x2D: // ENDF, END Function definition
+ /* Pop the current stack frame. */
+ return false;
+
+ case 0x2e: // MDAP[0], Move Direct Absolute Point
+ handleMDAP(stack[sp--], /* round */ false);
+ break;
+
+ case 0x2f: // MDAP[1], Move Direct Absolute Point
+ handleMDAP(stack[sp--], /* round */ true);
+ break;
+
+ case 0x39: // IP, Interpolate Point by the last relative stretch
+ handleIP();
+ break;
+
+ case 0x3d: // RTDG, Round To Double Grid
+ setRoundingMode(Fixed.ONE, 0x08);
+ roundThreshold = roundThreshold / 64; // period/128
+ break;
+
+ case 0x3e: // MIAP[0], Move Indirect Absolute Point
+ e1 = stack[sp--];
+ handleMIAP(e1, stack[sp--], /* round */ false);
+ break;
+
+ case 0x3f: // MIAP[1], Move Indirect Absolute Point
+ e1 = stack[sp--];
+ handleMIAP(e1, stack[sp--], /* round */ true);
+ break;
+
+ case 0x40: // NPUSHB
+ count = inst.get() & 0xff;
+ for (i = 0; i < count; i++)
+ stack[++sp] = inst.get() & 0xff;
+ break;
+
+ case 0x41: // NPUSHW
+ count = inst.get() & 0xff;
+ for (i = 0; i < count; i++)
+ stack[++sp] = inst.getShort();
+ break;
+
+ case 0x42: // WS, Write Store
+ e1 = stack[sp--]; i = stack[sp--];
+ storage[i] = e1;
+ break;
+
+ case 0x43: // RS, Read Store
+ stack[sp] = storage[stack[sp]];
+ break;
+
+ case 0x44: // WCVTP, Write Control Value Table in Pixel units
+ e1 = stack[sp--];
+ i = stack[sp--];
+ if (i < cvt.length)
+ cvt[i] = e1;
+ break;
+
+ case 0x45: // RCVT, Read Control Value Table entry
+ if (stack[sp] < cvt.length)
+ stack[sp] = cvt[stack[sp]];
+ else
+ stack[sp] = 0;
+ break;
+
+ case 0x46: // GC[0], Get Coordinate projected onto the projection vector
+ stack[sp] = getProjection(zp2, stack[sp]);
+ break;
+
+ case 0x47: // GC[1], Get Coordinate projected onto the projection vector
+ stack[sp] = getOriginalProjection(zp2, stack[sp]);
+ break;
+
+ case 0x4B: // MPPEM, Measure Pixels Per EM
+ stack[++sp] = getPixelsPerEM();
+ break;
+
+ case 0x4c: // MPS, Measure Point Size
+ /* FreeType2 returns pixels per em here, because they think that
+ * the point size would be irrelevant in a given font program.
+ * This is extremely surprising, because the appearance of good
+ * fonts _should_ change with point size. For example, a good
+ * font should be wider at small point sizes, and the holes
+ * inside glyphs ("Punzen" in German, I do not know the correct
+ * English expression) should be larger. Note that this change
+ * of appearance is dependent on point size, _not_ the
+ * resolution of the display device.
+ */
+ stack[++sp] = pointSize;
+ break;
+
+ case 0x4f: // DEBUG, DEBUG call
+ sp--;
+ break;
+
+ case 0x50: // LT, Less Than
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] < e1) ? 1 : 0;
+ break;
+
+ case 0x51: // LTEQ, Greater Than or EQual
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] <= e1) ? 1 : 0;
+ break;
+
+ case 0x52: // GT, Greater Than
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] > e1) ? 1 : 0;
+ break;
+
+ case 0x53: // GTEQ, Greater Than or EQual
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] >= e1) ? 1 : 0;
+ break;
+
+ case 0x54: // EQ, EQual
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] == e1) ? 1 : 0;
+ break;
+
+ case 0x55: // NEQ, Not EQual
+ e1 = stack[sp--];
+ stack[sp] = (stack[sp] != e1) ? 1 : 0;
+ break;
+
+ case 0x58: // IF, IF test
+ if (stack[sp--] == 0)
+ skipAfter(inst,
+ /* look for: ELSE */ 0x1B,
+ /* look for: EIF */ 0x59,
+ /* illegal: -- */ -1,
+ /* illegal: -- */ -1,
+ /* handle nested if clauses */ true);
+ break;
+
+ case 0x59: // EIF, End IF
+ // Do nothing.
+ break;
+
+ case 0x5A: // AND
+ e1 = stack[sp--];
+ stack[sp] = ((e1 != 0) && (stack[sp] != 0)) ? 1 : 0;
+ break;
+
+ case 0x5B: // OR
+ e1 = stack[sp--];
+ stack[sp] = ((e1 != 0) || (stack[sp] != 0)) ? 1 : 0;
+ break;
+
+ case 0x5e: // SDB, Set Delta Base in the graphics state
+ deltaBase = stack[sp--];
+ break;
+
+ case 0x5f: // SDS, Set Delta Shift in the graphics state
+ deltaShift = stack[sp--];
+ break;
+
+ case 0x60: // ADD
+ e1 = stack[sp--];
+ stack[sp] += e1;
+ break;
+
+ case 0x61: // SUB, SUBtract
+ e1 = stack[sp--];
+ stack[sp] -= e1;
+ break;
+
+ case 0x62: // DIV, DIVide
+ e1 = stack[sp--];
+ stack[sp] = Fixed.div(e1, stack[sp]);
+ break;
+
+ case 0x63: // MUL, MULtiply
+ e1 = stack[sp--];
+ stack[sp] = Fixed.mul(e1, stack[sp]);
+ break;
+
+ case 0x64: // ABS, ABSolute value
+ stack[sp] = Math.abs(stack[sp]);
+ break;
+
+ case 0x65: // NEG, NEGate
+ stack[sp] = -stack[sp];
+ break;
+
+ case 0x66: // FLOOR
+ stack[sp] = Fixed.floor(stack[sp]);
+ break;
+
+ case 0x67: // CEILING
+ stack[sp] = Fixed.ceil(stack[sp]);
+ break;
+
+ case 0x68: // ROUND[0] -- round grey distance
+ stack[sp] = round(stack[sp], /* no engine compensation */ 0);
+ break;
+
+ case 0x69: // ROUND[1] -- round black distance
+ stack[sp] = round(stack[sp], -engineCompensation);
+ break;
+
+ case 0x6a: // ROUND[2] -- round white distance
+ stack[sp] = round(stack[sp], engineCompensation);
+ break;
+
+ case 0x6b: // ROUND[3] -- round distance (not yet defined)
+ stack[sp] = round(stack[sp], /* no engine compensation */ 0);
+ break;
+
+ case 0x6c: // NROUND[0] -- compensate grey distance
+ stack[sp] = nround(stack[sp], 0);
+ break;
+
+ case 0x6d: // NROUND[1] -- compensate black distance
+ stack[sp] = nround(stack[sp], -engineCompensation);
+ break;
+
+ case 0x6e: // NROUND[2] -- compensate white distance
+ stack[sp] = nround(stack[sp], engineCompensation);
+ break;
+
+ case 0x6f: // NROUND[3] -- compensate distance (not yet defined)
+ stack[sp] = nround(stack[sp], 0);
+ break;
+
+ case 0x70: // WCVTF, Write Control Value Table in Funits
+ e1 = stack[sp--];
+ cvt[stack[sp--]] = e1 * getPixelsPerEM();
+ break;
+
+ case 0x73: // DELTAC1, DELTA exception C1
+ count = stack[sp--];
+ sp -= 2 * count;
+ deltaC(stack, sp + 1, count, 0);
+ break;
+
+ case 0x74: // DELTAC2, DELTA exception C2
+ count = stack[sp--];
+ sp -= 2 * count;
+ deltaC(stack, sp + 1, count, 16);
+ break;
+
+ case 0x75: // DELTAC3, DELTA exception C3
+ count = stack[sp--];
+ sp -= 2 * count;
+ deltaC(stack, sp + 1, count, 32);
+ break;
+
+ case 0x76: // SROUND, Super ROUND
+ setRoundingMode(Fixed.ONE, stack[sp--]);
+ break;
+
+ case 0x77: // S45ROUND, Super ROUND 45 degrees
+ setRoundingMode(/* sqrt(2)/2 */ 0x2d, stack[sp--]);
+ break;
+
+ case 0x78: // JROT, Jump Relative On True
+ e1 = stack[sp--];
+ i = inst.position() - 1 + stack[sp--];
+ if (e1 != 0)
+ inst.position(i);
+ break;
+
+ case 0x79: // JROF, Jump Relative On False
+ e1 = stack[sp--];
+ i = inst.position() - 1 + stack[sp--];
+ if (e1 == 0)
+ inst.position(i);
+ break;
+
+ case 0x7a: // ROFF, Round OFF
+ roundPeriod = 0;
+ break;
+
+ case 0x7c: // RUTG, Round Up To Grid
+ setRoundingMode(Fixed.ONE, 0x40);
+ break;
+
+ case 0x7d: // RDTG, Round Down To Grid
+ setRoundingMode(Fixed.ONE, 0x40);
+ roundThreshold = 0;
+ break;
+
+ case 0x7e: // SANGW, Set ANGle Weight (no-op according to TrueType spec)
+ case 0x7f: // AA, Adjust Angle (no-op according to TrueType spec)
+ sp--;
+ break;
+
+ case 0x85: // SCANCTRL, SCAN conversion ConTRoL
+ e1 = stack[sp--];
+ int ppemThreshold = e1 & 255;
+ scanControl = false;
+ boolean ppemCondition = (ppemThreshold == 255)
+ || ((ppemThreshold != 0) && (getPixelsPerEM() > ppemThreshold));
+ if (((e1 & (1<<8)) != 0) && ppemCondition)
+ scanControl = true;
+ if (((e1 & (1<<9)) != 0) && isRotated())
+ scanControl = true;
+ if (((e1 & (1<<10)) != 0) && isStretched())
+ scanControl = true;
+ if (((e1 & (1<<11)) != 0) && !ppemCondition)
+ scanControl = false;
+ if (((e1 & (1<<12)) != 0) && !isRotated())
+ scanControl = false;
+ if (((e1 & (1<<13)) != 0) && !isStretched())
+ scanControl = false;
+ break;
+
+ case 0x88: // GETINFO, GET INFOrmation
+ e1 = 0;
+ if ((stack[sp] & 1) != 0) // ask for rasterizer version
+ e1 |= 35; // "Microsoft Rasterizer version 1.7" (grayscale-capable)
+ if (((stack[sp] & 2) != 0) && isRotated())
+ e1 |= 1 << 8; // bit 8: glyph has been rotated
+ if (((stack[sp] & 4) != 0) && isStretched())
+ e1 |= 1 << 9; // bit 9: glyph has been stretched
+ if (((stack[sp] & 32) != 0) && antialiased)
+ e1 |= 1 << 12; // bit 12: antialiasing is active
+ stack[sp] = e1;
+ break;
+
+ case 0x8a: // ROLL, ROLL the top three stack elements
+ e1 = stack[sp - 2];
+ stack[sp - 2] = stack[sp - 1];
+ stack[sp - 1] = stack[sp];
+ stack[sp] = e1;
+ break;
+
+ case 0x8b: // MAX, MAXimum of top two stack elements
+ e1 = stack[sp--];
+ stack[sp] = Math.max(e1, stack[sp]);
+ break;
+
+ case 0x8c: // MIN, MINimum of top two stack elements
+ e1 = stack[sp--];
+ stack[sp] = Math.min(e1, stack[sp]);
+ break;
+
+ case 0x8d: // SCANTYPE
+ scanType = stack[sp--];
+ break;
+
+ case 0x8e: // INSTCTRL, INSTRuction execution ConTRoL
+ e1 = stack[sp--]; // selector
+ e2 = stack[sp--]; // value
+ switch (e1)
+ {
+ case 1:
+ executeGlyphInstructions = (e2 == 0);
+ break;
+
+ case 2:
+ ignoreCVTProgram = (e2 != 0);
+ break;
+ }
+ break;
+
+ case 0xb0: // PUSHB[0]
+ case 0xb1: // PUSHB[1]
+ case 0xb2: // PUSHB[2]
+ case 0xb3: // PUSHB[3]
+ case 0xb4: // PUSHB[4]
+ case 0xb5: // PUSHB[5]
+ case 0xb6: // PUSHB[6]
+ case 0xb7: // PUSHB[7]
+ count = bcode - 0xb0 + 1;
+ for (i = 0; i < count; i++)
+ stack[++sp] = inst.get() & 0xff;
+ break;
+
+ case 0xb8: // PUSHW[0]
+ case 0xb9: // PUSHW[1]
+ case 0xba: // PUSHW[2]
+ case 0xbb: // PUSHW[3]
+ case 0xbc: // PUSHW[4]
+ case 0xbd: // PUSHW[5]
+ case 0xbe: // PUSHW[6]
+ case 0xbf: // PUSHW[7]
+ count = bcode - 0xb8 + 1;
+ for (i = 0; i < count; i++)
+ stack[++sp] = inst.getShort();
+ break;
+
+ // MIRPxxxx, Move Indirect Relative Point
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+ case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ case 0xe8: case 0xe9: case 0xea: case 0xeb:
+ case 0xec: case 0xed: case 0xee: case 0xef:
+ case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+ case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+ case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+ case 0xfc: case 0xfd: case 0xfe: case 0xff:
+ e1 = stack[sp--];
+ handleMIRP(bcode, /* point */ e1, /* cvtIndex */ stack[sp--]);
+ break;
+
+ default:
+ throw new IllegalStateException();
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Sets the rounding mode.
+ *
+ * @param period the grid period in fixed-point notation, such as
+ * {@link Fixed#ONE} for the <code>SROUND</code> instruction or
+ * <code>sqrt(2)/2</code> for the <code>S45ROUND</code> instruction.
+ *
+ * @param mode a byte whose bits are set according to the TrueType
+ * specification for SROUND and S45ROUND parameters.
+ */
+ private void setRoundingMode(int period, int mode)
+ {
+ /* Set the period. */
+ switch ((mode & 0xc0) >> 6)
+ {
+ case 0:
+ roundPeriod = period / 2;
+ break;
+
+ case 2:
+ roundPeriod = period * 2;
+ break;
+
+ default:
+ roundPeriod = period;
+ break;
+ }
+
+ /* Set the phase. */
+ switch ((mode & 0x30) >> 4)
+ {
+ case 0:
+ roundPhase = 0;
+ break;
+
+ case 1:
+ roundPhase = roundPeriod >> 2; // period/4
+ break;
+
+ case 2:
+ roundPhase = roundPeriod >> 1; // period/2
+ break;
+
+ case 3:
+ roundPhase = (roundPeriod >> 1) + (roundPeriod >> 2); // period * 3/4
+ break;
+ }
+
+ /* Set the threshold. */
+ int threshold = mode & 0x0f;
+ if (threshold == 0)
+ roundThreshold = roundPeriod - Fixed.ONE;
+ else
+ roundThreshold = ((threshold - 4) * roundPeriod) / 8;
+ }
+
+
+
+ /**
+ * Implements the DELTAC instructions. These instructions check
+ * whether the current number of pixels per em is contained in an
+ * exception table. If it is, a delta value is determined, and the
+ * specified entry in the Control Value Table is modified according
+ * to the delta.
+ *
+ * @param pairs the delta table. Because the delta table is on
+ * the stack, callers usually just want to pass the stack array.
+ *
+ * @param offset the offset of the first pair in <code>pairs</code>.
+ *
+ * @param numPairs the number of pairs.
+ *
+ * @param base 0 for <code>DELTAC1</code>, 16 for <code>DELTAC2</code>,
+ * or 32 for <code>DELTAC2</code>.
+ *
+ * @see <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html#DELTAC1"
+ * >Apple&#x2019;s documentation for <code>DELTAC1</code></a>, <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html#DELTAC2"
+ * ><code>DELTAC2</code></a>, and <a href=
+ * "http://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html#DELTAC3"
+ * ><code>DELTAC3</code></a>
+ */
+ private void deltaC(int[] pairs, int offset, int numPairs, int base)
+ {
+ int arg, relativePpem;
+ int ppemTrigger = getPixelsPerEM() - (deltaBase + base);
+ int delta, cvtIndex, rightShift;
+ for (int i = 0; i < numPairs; i++)
+ {
+ arg = pairs[offset + 2 * i];
+ relativePpem = (arg >> 4) & 15;
+ if (relativePpem == ppemTrigger)
+ {
+ delta = (arg & 15) - 8;
+ if (delta >= 0)
+ ++delta;
+
+ rightShift = deltaShift - 6;
+ if (rightShift > 0)
+ delta = delta >> rightShift;
+ else if (rightShift < 0)
+ delta = delta << (-rightShift);
+ cvt[pairs[offset + 2 * i + 1]] += delta;
+
+ break;
+ }
+ }
+ }
+
+
+ private Zone getZone(int zoneNumber)
+ {
+ return (zoneNumber == 0) ? twilightZone : glyphZone;
+ }
+
+
+ /**
+ * Projects the specified vector along the current projection
+ * vector.
+ *
+ * @param x the x component of the input vector, in 26.6 fixed-point
+ * notation.
+ *
+ * @param y the y component of the input vector, in 26.6 fixed-point
+ * notation.
+ *
+ * @return the projected distance, in 26.6 fixed-point notation.
+ */
+ private int getProjection(int x, int y)
+ {
+ return (int) (((((long) x) * projX + ((long) y) * projY)) >> 14);
+ }
+
+
+ /**
+ * Projects the specified vector along the current dual projection
+ * vector.
+ *
+ * @param x the x component of the input vector, in 26.6 fixed-point
+ * notation.
+ *
+ * @param y the y component of the input vector, in 26.6 fixed-point
+ * notation.
+ *
+ * @return the projected distance, in 26.6 fixed-point notation.
+ */
+ private int getDualProjection(int x, int y)
+ {
+ return (int) (((((long) x) * dualX + ((long) y) * dualY)) >> 14);
+ }
+
+
+ private int getProjection(Zone zone, int point)
+ {
+ return getProjection(zone.getX(point), zone.getY(point));
+ }
+
+
+ private int getOriginalProjection(Zone zone, int point)
+ {
+ return getDualProjection(zone.getOriginalX(point),
+ zone.getOriginalY(point));
+ }
+
+
+ private void handleISECT(int a0, int a1, int b0, int b1, int p)
+ {
+ System.out.println("FIXME: Unimplemented ISECT " + p);
+ }
+
+
+ private static int muldiv(int a, int b, int c)
+ {
+ int s;
+ s = a; a = Math.abs(a);
+ s ^= b; b = Math.abs(b);
+ s ^= c; c = Math.abs(c);
+ a = (int) ((((long) a) * b + (c>>1)) / c);
+ return (s < 0) ? -a : a;
+ }
+
+
+ private int getFreeDotProj()
+ {
+ int result;
+
+ result = ((((int) projX) * freeX) << 2)
+ + ((((int) projY) * freeY) << 2);
+
+ /* FIXME: This seems somewhat bogus. Need to contact the
+ * developers of FreeType.
+ */
+ if (Math.abs(result) < 0x4000000)
+ result = 0x40000000;
+ return result;
+ }
+
+
+ private void movePoint(Zone zone, int point, int distance)
+ {
+ int freeDotProj = getFreeDotProj();
+ int c;
+
+ if (freeX != 0)
+ {
+ c = zone.getX(point);
+ c += muldiv(distance, freeX << 16, freeDotProj);
+ zone.setX(point, c, /* touch */ true);
+ }
+
+ if (freeY != 0)
+ {
+ c = zone.getY(point);
+ c += muldiv(distance, freeY << 16, freeDotProj);
+ zone.setY(point, c, /* touch */ true);
+ }
+
+ if (TRACE_EXECUTION)
+ {
+ System.out.println("point[" + point + "] moved to "
+ + Fixed.toString(zone.getX(point),
+ zone.getY(point)));
+ dumpVectors();
+ }
+ }
+
+ private void dumpVectors()
+ {
+ System.out.println(" proj=" + Fixed.toString(projX>>8, projY>>8)
+ + ", free=" + Fixed.toString(freeX>>8, freeY>>8));
+ }
+
+
+ private void handleIP()
+ {
+ // Implementation taken from FreeType.
+ int p, org_a, org_b, org_x, cur_a, cur_b, cur_x, distance;
+ int freeDotProj;
+
+ org_a = getOriginalProjection(zp0, rp1);
+ cur_a = getProjection(zp0, rp1);
+
+ org_b = getOriginalProjection(zp1, rp2);
+ cur_b = getProjection(zp1, rp2);
+
+ while (--loop >= 0)
+ {
+ p = stack[sp--];
+ org_x = getOriginalProjection(zp2, p);
+ cur_x = getProjection(zp2, p);
+
+ if (((org_a <= org_b) && (org_x <= org_a))
+ || ((org_a > org_b) && (org_x >= org_a)))
+ distance = (cur_a - org_a) + (org_x - cur_x);
+ else if (((org_a <= org_b) && (org_x >= org_b))
+ || ((org_a > org_b) && (org_x < org_b)))
+ distance = (cur_b - org_b) + (org_x - cur_x);
+ else
+ distance = muldiv(cur_b - cur_a, org_x - org_a, org_b - org_a)
+ + (cur_a - cur_x);
+ movePoint(zp2, p, distance);
+ }
+ loop = 1;
+ }
+
+
+ private void handleMDAP(int point, boolean round)
+ {
+ System.out.println("FIXME: Unimplemented MDAP: point "
+ + point + "/" + zp0);
+ }
+
+
+ private void handleMIAP(int cvtIndex, int point, boolean round)
+ {
+ int previousPos, pos;
+
+ previousPos = getProjection(zp0, point);
+ pos = cvt[cvtIndex];
+
+ if (round)
+ {
+ if (Math.abs(pos - previousPos) > cvtCutIn)
+ pos = previousPos;
+ pos = round(pos, /* no engine compensation */ 0);
+ }
+ movePoint(zp0, point, pos - previousPos);
+ rp0 = rp1 = point;
+ }
+
+
+ private void handleMIRP(int bcode, int point, int cvtIndex)
+ {
+ System.out.println("FIXME: Unimplemented mirp " + point + ", " + cvtIndex);
+ }
+
+
+
+ private int round(int distance, int compensation)
+ {
+ int result;
+
+ if (roundPeriod == 0)
+ return nround(distance, compensation);
+
+ if (distance >= 0)
+ {
+ result = distance + compensation - roundPhase + roundThreshold;
+ result &= -roundPeriod; // truncate to the next lowest periodic value
+ return Math.max(result, 0) + roundPhase;
+ }
+ else
+ {
+ result = compensation - roundPhase + roundThreshold - distance;
+ result &= -roundPeriod;
+ return Math.max(-result, 0) - roundPhase;
+ }
+ }
+
+
+ private static int nround(int distance, int compensation)
+ {
+ if (distance >= 0)
+ return Math.max(distance + compensation, 0);
+ else
+ return Math.min(distance - compensation, 0);
+ }
+
+
+ /**
+ * Determines whether the current glyph is rotated.
+ *
+ * @return <code>false</code> if the shearing factors for the
+ * <i>x</i> and <i>y</i> axes are zero; <code>true</code> if they
+ * are non-zero.
+ */
+ private boolean isRotated()
+ {
+ return (shearX != 0) || (shearY != 0);
+ }
+
+
+ /**
+ * Determines whether the current glyph is stretched.
+ *
+ * @return <code>false</code> if the scaling factors for the
+ * <i>x</i> and <i>y</i> axes are are equal; <code>true</code> if
+ * they differ.
+ */
+ private boolean isStretched()
+ {
+ return scaleX != scaleY;
+ }
+
+
+ /**
+ * Returns how many pixels there are per EM, in direction of the
+ * current projection vector. The result is a normal integer,
+ * not a Fixed.
+ */
+ private int getPixelsPerEM()
+ {
+ if (cachedPixelsPerEM == 0)
+ {
+ cachedPixelsPerEM = Fixed.intValue(Fixed.vectorLength(
+ applyCTM_x(projX >> 8, projY >> 8),
+ applyCTM_y(projX >> 8, projY >> 8)));
+ }
+
+ return cachedPixelsPerEM;
+ }
+
+
+ private void setProjectionVector(short x, short y)
+ {
+ if (PATENTED_HINTING)
+ {
+ if ((x != projX) || (y != projY))
+ cachedPixelsPerEM = 0;
+
+ projX = x;
+ projY = y;
+ }
+ }
+
+
+ private void setFreedomVector(short x, short y)
+ {
+ if (PATENTED_HINTING)
+ {
+ freeX = x;
+ freeY = y;
+ }
+ }
+
+
+ private void setDualVector(short x, short y)
+ {
+ if (PATENTED_HINTING)
+ {
+ dualX = x;
+ dualY = y;
+ }
+ }
+
+
+ private int applyCTM_x(int x, int y)
+ {
+ return (int) (((long) scaleX * x + (long) shearX * y) >> 6);
+ }
+
+ private int applyCTM_y(int x, int y)
+ {
+ return (int) (((long) shearY * x + (long) scaleY * y) >> 6);
+ }
+
+
+ private static final String[] INST_NAME =
+ {
+ /* 00 */ "SVTCA[0]", "SVTCA[1]", "SPVTCA[0]", "SPVTCA[1]",
+ /* 04 */ "INST_04", "INST_05", "INST_06", "INST_07",
+ /* 08 */ "INST_08", "INST_09", "INST_0A", "INST_0B",
+ /* 0c */ "GPV", "GFV", "INST_0E", "ISECT",
+ /* 10 */ "SRP0", "SRP1", "SRP2", "SZP0",
+ /* 14 */ "SZP1", "SZP2", "SZPS", "SLOOP",
+ /* 18 */ "RTG", "RTHG", "SMD", "ELSE",
+ /* 1c */ "JMPR", "SCVTCI", "INST_1E", "SSW",
+ /* 20 */ "DUP", "POP", "CLEAR", "SWAP",
+ /* 24 */ "DEPTH", "CINDEX", "MINDEX", "INST_27",
+ /* 28 */ "INST_28", "INST_29", "LOOPCALL", "CALL",
+ /* 2c */ "FDEF", "ENDF", "MDAP[0]", "MDAP[1]",
+ /* 30 */ "IUP[0]", "IUP[1]", "SHP[0]", "SHP[1]",
+ /* 34 */ "INST_34", "INST_35", "INST_36", "INST_37",
+ /* 38 */ "INST_38", "IP", "INST_3A", "INST_3B",
+ /* 3c */ "INST_3C", "RTDG", "MIAP[0]", "MIAP[1]",
+ /* 40 */ "NPUSHB", "NPUSHW", "WS", "RS",
+ /* 44 */ "WCVTP", "RCVT", "GC[0]", "GC[1]",
+ /* 48 */ "INST_48", "INST_49", "INST_4A", "MPPEM",
+ /* 4c */ "MPS", "FLIPON", "FLIPOFF", "DEBUG",
+ /* 50 */ "LT", "LTEQ", "GT", "GTEQ",
+ /* 54 */ "EQ", "NEQ", "INST_56", "INST_57",
+ /* 58 */ "IF", "EIF", "AND", "OR",
+ /* 5c */ "INST_5C", "INST_5D", "SDB", "SDS",
+ /* 60 */ "ADD", "SUB", "DIV", "MUL",
+ /* 64 */ "ABS", "NEG", "FLOOR", "CEILING",
+ /* 68 */ "ROUND[0]", "ROUND[1]", "ROUND[2]", "ROUND[3]",
+ /* 6c */ "NROUND[0]", "NROUND[1]", "NROUND[2]", "NROUND[3]",
+ /* 70 */ "WCVTF", "INST_71", "INST_72", "DELTAC1",
+ /* 74 */ "DELTAC2", "DELTAC3", "SROUND", "S45ROUND",
+ /* 78 */ "JROT", "JROF", "ROFF", "INST_7B",
+ /* 7c */ "RUTG", "RDTG", "SANGW", "AA",
+ /* 80 */ "FLIPPT", "FLIPRGON", "FLIPRGOFF", "INST_83",
+ /* 84 */ "INST_84", "SCANCTRL", "INST_86", "INST_87",
+ /* 88 */ "GETINFO", "INST_89", "ROLL", "MAX",
+ /* 8c */ "MIN", "SCANTYPE", "INSTCTRL", "INST_8F",
+ /* 90 */ "INST_90", "INST_91", "INST_92", "INST_93",
+ /* 94 */ "INST_94", "INST_95", "INST_96", "INST_97",
+ /* 98 */ "INST_98", "INST_99", "INST_9A", "INST_9B",
+ /* 9c */ "INST_9C", "INST_9D", "INST_9E", "INST_9F",
+ /* a0 */ "INST_A0", "INST_A1", "INST_A2", "INST_A3",
+ /* a4 */ "INST_A4", "INST_A5", "INST_A6", "INST_A7",
+ /* a8 */ "INST_A8", "INST_A9", "INST_AA", "INST_AB",
+ /* ac */ "INST_AC", "INST_AD", "INST_AE", "INST_AF",
+ /* b0 */ "PUSHB[0]", "PUSHB[1]", "PUSHB[2]", "PUSHB[3]",
+ /* b4 */ "PUSHB[4]", "PUSHB[5]", "PUSHB[6]", "PUSHB[7]",
+ /* b8 */ "PUSHW[0]", "PUSHW[1]", "PUSHW[2]", "PUSHW[3]",
+ /* bc */ "PUSHW[4]", "PUSHW[5]", "PUSHW[6]", "PUSHW[7]",
+ /* c0 */ "INST_C0", "INST_C1", "INST_C2", "INST_C3",
+ /* c4 */ "INST_C4", "INST_C5", "INST_C6", "INST_C7",
+ /* c8 */ "INST_C8", "INST_C9", "INST_CA", "INST_CB",
+ /* cc */ "INST_CC", "INST_CD", "INST_CE", "INST_CF",
+ /* d0 */ "INST_D0", "INST_D1", "INST_D2", "INST_D3",
+ /* d4 */ "INST_D4", "INST_D5", "INST_D6", "INST_D7",
+ /* d8 */ "INST_D8", "INST_D9", "INST_DA", "INST_DB",
+ /* dc */ "INST_DC", "INST_DD", "INST_DE", "INST_DF",
+ /* e0 */ "MIRP00000", "MIRP00001", "MIRP00010", "MIRP00011",
+ /* e4 */ "MIRP00100", "MIRP00101", "MIRP00110", "MIRP00111",
+ /* e8 */ "MIRP01000", "MIRP01001", "MIRP01010", "MIRP01011",
+ /* ec */ "MIRP01100", "MIRP01101", "MIRP01110", "MIRP01111",
+ /* f0 */ "MIRP10000", "MIRP10001", "MIRP10010", "MIRP10011",
+ /* f4 */ "MIRP10100", "MIRP10101", "MIRP10110", "MIRP10111",
+ /* f8 */ "MIRP11000", "MIRP11001", "MIRP11010", "MIRP11011",
+ /* fc */ "MIRP11100", "MIRP11101", "MIRP11110", "MIRP11111"
+ };
+}
diff --git a/gnu/java/awt/font/opentype/truetype/Zone.java b/gnu/java/awt/font/opentype/truetype/Zone.java
new file mode 100644
index 000000000..c0a3947f6
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/Zone.java
@@ -0,0 +1,243 @@
+/* Zone.java -- A collection of points with some additional information.
+ 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;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+
+
+/**
+ * A collection of points with some additional information.
+ */
+final class Zone
+{
+ private final int[] pos;
+ private final int[] origPos;
+ private final byte[] flags;
+ 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 Zone(int maxNumPoints)
+ {
+ origPos = new int[maxNumPoints * 2];
+ pos = new int[maxNumPoints * 2];
+ flags = new byte[maxNumPoints];
+ }
+
+
+ public int getCapacity()
+ {
+ return flags.length;
+ }
+
+
+ public int getSize()
+ {
+ return numPoints;
+ }
+
+
+ public int getX(int point)
+ {
+ return pos[2 * point];
+ }
+
+
+ public void setX(int point, int value, boolean touch)
+ {
+ pos[2 * point] = value;
+ if (touch)
+ flags[point] |= FLAG_TOUCHED_X;
+ }
+
+
+ public void setY(int point, int value, boolean touch)
+ {
+ pos[2 * point + 1] = value;
+ if (touch)
+ flags[point] |= FLAG_TOUCHED_Y;
+ }
+
+
+ public int getY(int point)
+ {
+ return pos[2 * point + 1];
+ }
+
+
+ public int getOriginalX(int point)
+ {
+ return origPos[2 * point];
+ }
+
+
+ public int getOriginalY(int point)
+ {
+ return origPos[2 * point + 1];
+ }
+
+
+ public void setOriginalX(int point, int x)
+ {
+ origPos[2 * point] = x;
+ }
+
+ public void setOriginalY(int point, int y)
+ {
+ origPos[2 * point + 1] = 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;
+ }
+
+
+ public boolean isOnCurve(int point)
+ {
+ return (flags[point] & FLAG_ON_CURVE) != 0;
+ }
+
+
+ public void setOnCurve(int point, boolean onCurve)
+ {
+ if (onCurve)
+ flags[point] |= FLAG_ON_CURVE;
+ else
+ flags[point] &= ~FLAG_ON_CURVE;
+ }
+
+
+ public boolean isContourEnd(int point)
+ {
+ return (flags[point] & FLAG_CONTOUR_END) != 0;
+ }
+
+
+ public void setContourEnd(int point, boolean segEnd)
+ {
+ if (segEnd)
+ flags[point] |= FLAG_CONTOUR_END;
+ else
+ flags[point] &= ~FLAG_CONTOUR_END;
+ }
+
+
+
+
+ void transform(double pointSize, AffineTransform deviceTransform,
+ int unitsPerEm, int preTranslateX, int preTranslateY)
+ {
+ double scaleX, scaleY, shearX, shearY;
+ double factor;
+
+ factor = pointSize / (double) unitsPerEm;
+ scaleX = deviceTransform.getScaleX() * factor;
+ scaleY = deviceTransform.getScaleY() * factor;
+ shearX = deviceTransform.getShearX() * factor;
+ shearY = deviceTransform.getShearY() * factor;
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ int x = origPos[2 * i] + preTranslateX;
+ int y = origPos[2 * i + 1] + 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);
+ }
+ }
+
+
+
+ void combineWithSubGlyph(Zone zone, int numPhantomPoints)
+ {
+ 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);
+ this.numPoints += count - numPhantomPoints;
+ }
+
+
+ private void dump()
+ {
+ 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(' ');
+ System.out.print(Fixed.toString(origPos[i*2], origPos[i*2+1]));
+ System.out.print(' ');
+ if (isOnCurve(i))
+ System.out.print('.');
+ else
+ System.out.print('c');
+ if (isContourEnd(i))
+ System.out.print('E');
+ System.out.println();
+ if (isContourEnd(i))
+ System.out.println();
+ }
+ }
+
+
+ public PathIterator getPathIterator()
+ {
+ return new ZonePathIterator(this);
+ }
+
+
+ public GeneralPath getPath()
+ {
+ GeneralPath p = new GeneralPath(GeneralPath.WIND_NON_ZERO, numPoints);
+ p.append(getPathIterator(), /* connect */ false);
+ return p;
+ }
+}
diff --git a/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java b/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java
new file mode 100644
index 000000000..d000b9c3e
--- /dev/null
+++ b/gnu/java/awt/font/opentype/truetype/ZonePathIterator.java
@@ -0,0 +1,391 @@
+/* ZonePathIterator.java -- A PathIterator over glyph zones.
+ 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;
+
+import java.awt.geom.PathIterator;
+
+
+/**
+ * A PathIterator that enumerates the non-phantom points in a zone.
+ *
+ * <p><b>Lack of thread safety:</b> Instances of this class are
+ * <i>not</i> safe to access from multiple concurrent threads.
+ *
+ * @see Zone
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+final class ZonePathIterator
+ implements PathIterator
+{
+ /**
+ * If <code>state</code> has this value, <code>currentSegment</code>
+ * will emit a <code>SEG_LINETO</code> or <code>SEG_QUADTO</code> segment
+ * to the current point. For a discussion of subtleties of on-curve
+ * and off-curve points, please refer to the documentation for
+ * {@link #getSegment}.
+ */
+ private static final int EMIT_SEGMENT = 0;
+
+
+ /**
+ * If <code>state</code> has this value, <code>currentSegment</code>
+ * will emit a <code>SEG_CLOSE</code> in order to close the sub-path
+ * for the current contour.
+ */
+ private static final int EMIT_CLOSE = 1;
+
+
+ /**
+ * If <code>state</code> has this value, <code>currentSegment</code>
+ * will emit a <code>SEG_MOVETO</code> segment to the first point in
+ * the current contour. If the first point is off-curve, a suitable
+ * on-curve point is calculated.
+ *
+ * @see #getStartSegment
+ */
+ private static final int EMIT_MOVETO = 2;
+
+
+ /**
+ * The state of the iterator, which is one of
+ * <code>EMIT_SEGMENT</code>, <code>EMIT_CLOSE</code>, or
+ * <code>EMIT_MOVETO</code>.
+ */
+ private int state;
+
+
+
+ /**
+ * The zone whose segments are enumerated by this iterator.
+ */
+ private Zone zone;
+
+
+ /**
+ * The total number of points in the zone, not including the four
+ * phantom points at its end.
+ */
+ private int numPoints;
+
+
+ /**
+ * The number of the current point.
+ */
+ private int curPoint;
+
+
+ /**
+ * The number of the first point in the current contour.
+ */
+ private int contourStart;
+
+
+
+ /**
+ * Constructs a ZonePathIterator for the specified zone.
+ *
+ * @param zone the zone whose segments will be enumerated
+ * by this iterator.
+ */
+ ZonePathIterator(Zone zone)
+ {
+ this.zone = zone;
+ numPoints = zone.getSize() - /* four phantom points */ 4;
+
+ // The first segment that needs to be emitted is a SEG_MOVETO.
+ state = EMIT_MOVETO;
+ }
+
+
+ /**
+ * Returns the winding rule. TrueType glyphs always use the non-zero
+ * winding rule, so this method will always return {@link
+ * PathIterator#WIND_NON_ZERO}.
+ */
+ public int getWindingRule()
+ {
+ return PathIterator.WIND_NON_ZERO;
+ }
+
+
+
+ public boolean isDone()
+ {
+ return (state != EMIT_CLOSE) && (curPoint >= numPoints);
+ }
+
+
+ public void next()
+ {
+ boolean onCurve;
+
+ /* If the current point is the end of a segment, and no SEG_CLOSE
+ * has been emitted yet, this will be the next segment.
+ */
+ if (zone.isContourEnd(curPoint) && (state != EMIT_CLOSE))
+ {
+ state = EMIT_CLOSE;
+ return;
+ }
+
+ /* If the previously emitted segment was a SEG_CLOSE, we are now
+ * at the beginning of a new contour.
+ */
+ if (state == EMIT_CLOSE)
+ {
+ contourStart = ++curPoint;
+ state = EMIT_MOVETO;
+ return;
+ }
+
+ onCurve = zone.isOnCurve(curPoint);
+
+ /* If the last segment was a moveto, and the current point
+ * (which is the first point in the contour) is off-curve,
+ * we need to emit a quadto segment for the first point.
+ */
+ if ((state == EMIT_MOVETO) && !onCurve)
+ {
+ state = EMIT_SEGMENT;
+ return;
+ }
+
+
+ curPoint++;
+
+ /* If the last point has been off-curve, and the now current
+ * point is on-curve, the last segment was a quadto that
+ * had the now current point at its end. In this case, we can
+ * skip a segment.
+ */
+ if (!onCurve && zone.isOnCurve(curPoint))
+ {
+ /* But if the skipped point is the end of a contour, we must not
+ * skip the SEG_CLOSE. An example where this matters is the 'o'
+ * glyph in the Helvetica font face that comes with MacOS X
+ * 10.1.5.
+ */
+ if (zone.isContourEnd(curPoint))
+ {
+ state = EMIT_CLOSE;
+ return;
+ }
+
+ curPoint++;
+ }
+
+ state = EMIT_SEGMENT;
+ }
+
+
+ /**
+ * Determines the successor of the current point in the current
+ * contour. The successor of the last point in a contour is the
+ * start of that contour.
+ *
+ * @return the number of the point that follows the current point in
+ * the same contour.
+ */
+ private int getSuccessor(int p)
+ {
+ if (zone.isContourEnd(p))
+ return contourStart;
+ else
+ return p + 1;
+ }
+
+
+
+ /**
+ * Retrieves the current path segment using single-precision
+ * coordinate values.
+ */
+ public int currentSegment(float[] coords)
+ {
+ switch (state)
+ {
+ case EMIT_CLOSE:
+ return PathIterator.SEG_CLOSE;
+
+ case EMIT_MOVETO:
+ return getStartSegment(curPoint, coords);
+
+ default:
+ return getSegment(curPoint, coords);
+ }
+ }
+
+
+ /**
+ * A helper array that is used by {@link
+ * #currentSegment(double[])}.
+ */
+ float[] floats;
+
+
+ /**
+ * Retrieves the current path segment using double-precision
+ * coordinate values.
+ */
+ public int currentSegment(double[] coords)
+ {
+ if (floats == null)
+ floats = new float[6];
+ int result;
+
+ result = currentSegment(floats);
+ for (int i = 0; i < 6; i++)
+ coords[i] = floats[i];
+ return result;
+ }
+
+
+ /**
+ * Returns the segment for the specified point.
+ *
+ * <p><img src="doc-files/ZonePathIterator-1.png" width="426"
+ * height="194" alt="An example curve" /></p>
+ *
+ * <p>If <code>cur</code> is an on-curve point, the returned segment
+ * is a straight line to <code>cur</code>. In the illustration, this
+ * would be the case for <code>cur = 4</code>.</p>
+ *
+ * <p>If <code>cur</code> is an off-curve point, and
+ * <code>cur</code>&#x2019;s successor <code>succ</code> is also
+ * off-curve, the returned segment is a quadratic B&eacute;zier
+ * spline whose control point is <code>cur</code>, and whose end
+ * point is located at the middle of the line connecting
+ * <code>cur</code> and <code>succ</code>. In the illustration,
+ * this would be the case for <code>cur = 5</code>.</p>
+ *
+ * <p>If <code>cur</code> is an off-curve point, and
+ * <code>cur</code>&#x2019;s successor <code>succ</code> is
+ * on-curve, the returned segment is a quadratic B&eacute;zier
+ * spline whose control point is <code>cur</code>, and whose end
+ * point is <code>succ</code>. In the illustration, this would
+ * be the case for <code>cur = 6</code>.</p>
+ *
+ * @return either <code>PathIterator.SEG_LINETO</code> or
+ * <code>PathIterator.SEG_QUADTO</code>.
+ */
+ private int getSegment(int cur, float[] coords)
+ {
+ int curX, curY;
+ int succ, succX, succY;
+
+ curX = zone.getX(cur);
+ curY = zone.getY(cur);
+ coords[0] = Fixed.floatValue(curX);
+ coords[1] = Fixed.floatValue(curY);
+
+ if (zone.isOnCurve(cur))
+ return PathIterator.SEG_LINETO;
+
+ succ = getSuccessor(cur);
+ succX = zone.getX(succ);
+ succY = zone.getY(succ);
+
+ if (zone.isOnCurve(succ))
+ {
+ coords[2] = Fixed.floatValue(succX);
+ coords[3] = Fixed.floatValue(succY);
+ }
+ else
+ {
+ coords[2] = Fixed.floatValue((curX + succX) / 2);
+ coords[3] = Fixed.floatValue((curY + succY) / 2);
+ }
+ return PathIterator.SEG_QUADTO;
+ }
+
+
+ /**
+ * Returns the start segment for the contour which starts
+ * at the specified point.
+ *
+ * <p>If the contour starts with an on-curve point, the returned
+ * segment is a <code>SEG_MOVETO</code> to that point.</p>
+ *
+ * <p>If the contour starts with an off-curve point, and the contour
+ * ends with an on-curve point, the returned segment is a
+ * <code>SEG_MOVETO</code> to the end point.</p>
+ *
+ * <p>If the contour starts with an off-curve point, and the contour
+ * also ends with an off-curve point, the returned segment is a
+ * <code>SEG_MOVETO</code> to the location at the middle between the
+ * start and end points of the contour.</p>
+ *
+ * @return <code>PathIterator.SEG_MOVETO</code>.
+ */
+ private int getStartSegment(int contourStart, float[] coords)
+ {
+ int x, y;
+
+ if (zone.isOnCurve(contourStart))
+ {
+ x = zone.getX(contourStart);
+ y = zone.getY(contourStart);
+ }
+ else
+ {
+ /* Find the last point of the current contour. */
+ int contourEnd = contourStart;
+ while (!zone.isContourEnd(contourEnd))
+ ++contourEnd;
+
+ if (zone.isOnCurve(contourEnd))
+ {
+ /* 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);
+ }
+ else
+ {
+ x = (zone.getX(contourStart) + zone.getX(contourEnd)) / 2;
+ y = (zone.getY(contourStart) + zone.getY(contourEnd)) / 2;
+ }
+ }
+
+ coords[0] = Fixed.floatValue(x);
+ coords[1] = Fixed.floatValue(y);
+ return PathIterator.SEG_MOVETO;
+ }
+}
diff --git a/gnu/java/awt/java2d/AbstractGraphics2D.java b/gnu/java/awt/java2d/AbstractGraphics2D.java
new file mode 100644
index 000000000..7338a327e
--- /dev/null
+++ b/gnu/java/awt/java2d/AbstractGraphics2D.java
@@ -0,0 +1,1585 @@
+/* AbstractGraphics2D.java -- Abstract Graphics2D 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.java2d;
+
+import java.awt.AWTError;
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.RenderingHints.Key;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+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;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Implements general and shared behaviour for Graphics2D implementation.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public abstract class AbstractGraphics2D
+ extends Graphics2D
+ implements Cloneable
+{
+
+ /**
+ * The transformation for this Graphics2D instance
+ */
+ private AffineTransform transform;
+
+ /**
+ * The foreground.
+ */
+ private Paint paint;
+
+ /**
+ * The background.
+ */
+ private Color background;
+
+ /**
+ * The current font.
+ */
+ private Font font;
+
+ /**
+ * The current composite setting.
+ */
+ private Composite composite;
+
+ /**
+ * The current stroke setting.
+ */
+ private Stroke stroke;
+
+ /**
+ * The current clip. This clip is in user coordinate space.
+ */
+ private Shape clip;
+
+ /**
+ * The rendering hints.
+ */
+ private RenderingHints renderingHints;
+
+ /**
+ * The paint context to use for draw and fill operations.
+ */
+ private PaintContext paintContext;
+
+ /**
+ * The paint raster.
+ */
+ private Raster paintRaster;
+
+ /**
+ * The composite context to use for draw and fill operations.
+ */
+ private CompositeContext compositeContext;
+
+ /**
+ * A cached pixel array.
+ */
+ private int[] pixel;
+
+ /**
+ * Indicates if cerain graphics primitives can be rendered in an optimized
+ * fashion. This will be the case if the following conditions are met:
+ * - The transform may only be a translation, no rotation, shearing or
+ * scaling.
+ * - The paint must be a solid color.
+ * - The composite must be an AlphaComposite.SrcOver.
+ * - The clip must be a Rectangle.
+ * - The stroke must be a plain BasicStroke().
+ *
+ * These conditions represent the standard settings of a new
+ * AbstractGraphics2D object and will be the most commonly used setting
+ * in Swing rendering and should therefore be optimized as much as possible.
+ */
+ private boolean isOptimized;
+
+ /**
+ * Creates a new AbstractGraphics2D instance.
+ */
+ protected AbstractGraphics2D()
+ {
+ transform = new AffineTransform();
+ background = Color.WHITE;
+ composite = AlphaComposite.SrcOver;
+ stroke = new BasicStroke();
+ renderingHints = new RenderingHints(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_DEFAULT);
+
+ pixel = new int[4];
+ }
+
+ /**
+ * Draws the specified shape. The shape is passed through the current stroke
+ * and is then forwarded to {@link #fillShape}.
+ *
+ * @param shape the shape to draw
+ */
+ public void draw(Shape shape)
+ {
+ // Clip the shape.
+ Shape clipped = clipShape(shape);
+ if (clipped != null)
+ {
+ // Stroke the shape.
+ Shape strokedShape = stroke.createStrokedShape(clipped);
+ // Fill the shape.
+ fillShape(strokedShape);
+ }
+ }
+
+ public boolean drawImage(Image image, AffineTransform xform, ImageObserver obs)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public void drawRenderableImage(RenderableImage image, AffineTransform xform)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Draws the specified string at the specified location.
+ *
+ * @param text the string to draw
+ * @param x the x location, relative to the bounding rectangle of the text
+ * @param y the y location, relative to the bounding rectangle of the text
+ */
+ public void drawString(String text, int x, int y)
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
+ drawGlyphVector(gv, x, y);
+ }
+
+ /**
+ * Draws the specified string at the specified location.
+ *
+ * @param text the string to draw
+ * @param x the x location, relative to the bounding rectangle of the text
+ * @param y the y location, relative to the bounding rectangle of the text
+ */
+ public void drawString(String text, float x, float y)
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
+ drawGlyphVector(gv, x, y);
+ }
+
+ /**
+ * Draws the specified string (as AttributedCharacterIterator) at the
+ * specified location.
+ *
+ * @param iterator the string to draw
+ * @param x the x location, relative to the bounding rectangle of the text
+ * @param y the y location, relative to the bounding rectangle of the text
+ */
+ public void drawString(AttributedCharacterIterator iterator, int x, int y)
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, iterator);
+ drawGlyphVector(gv, x, y);
+ }
+
+ /**
+ * Draws the specified string (as AttributedCharacterIterator) at the
+ * specified location.
+ *
+ * @param iterator the string to draw
+ * @param x the x location, relative to the bounding rectangle of the text
+ * @param y the y location, relative to the bounding rectangle of the text
+ */
+ public void drawString(AttributedCharacterIterator iterator, float x, float y)
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, iterator);
+ drawGlyphVector(gv, x, y);
+ }
+
+ /**
+ * Fills the specified shape with the current foreground.
+ *
+ * @param shape the shape to fill
+ */
+ public void fill(Shape shape)
+ {
+ Shape clipped = clipShape(shape);
+ if (clipped != null)
+ fillShape(shape);
+ }
+
+ public boolean hit(Rectangle rect, Shape text, boolean onStroke)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Sets the composite.
+ *
+ * @param comp the composite to set
+ */
+ public void setComposite(Composite comp)
+ {
+ composite = comp;
+ compositeContext = composite.createContext(getColorModel(),
+ getDestinationColorModel(),
+ renderingHints);
+ if (! (comp.equals(AlphaComposite.SrcOver)))
+ isOptimized = false;
+ else
+ updateOptimization();
+ }
+
+ /**
+ * Sets the current foreground.
+ *
+ * @param p the foreground to set.
+ */
+ public void setPaint(Paint p)
+ {
+ paint = p;
+
+ if (paint != null && ! (paint instanceof Color))
+ isOptimized = false;
+ else
+ {
+ updateOptimization();
+ rawSetForeground((Color) paint);
+ }
+ }
+
+ /**
+ * Sets the stroke for this graphics object.
+ *
+ * @param s the stroke to set
+ */
+ public void setStroke(Stroke s)
+ {
+ stroke = s;
+ if (! stroke.equals(new BasicStroke()))
+ isOptimized = false;
+ else
+ updateOptimization();
+ }
+
+ /**
+ * Sets the specified rendering hint.
+ *
+ * @param hintKey the key of the rendering hint
+ * @param hintValue the value
+ */
+ public void setRenderingHint(Key hintKey, Object hintValue)
+ {
+ renderingHints.put(hintKey, hintValue);
+ }
+
+ /**
+ * Returns the rendering hint for the specified key.
+ *
+ * @param hintKey the rendering hint key
+ *
+ * @return the rendering hint for the specified key
+ */
+ public Object getRenderingHint(Key hintKey)
+ {
+ return renderingHints.get(hintKey);
+ }
+
+ /**
+ * Sets the specified rendering hints.
+ *
+ * @param hints the rendering hints to set
+ */
+ public void setRenderingHints(Map hints)
+ {
+ renderingHints.clear();
+ renderingHints.putAll(hints);
+ }
+
+ /**
+ * Adds the specified rendering hints.
+ *
+ * @param hints the rendering hints to add
+ */
+ public void addRenderingHints(Map hints)
+ {
+ renderingHints.putAll(hints);
+ }
+
+ /**
+ * Returns the current rendering hints.
+ *
+ * @return the current rendering hints
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return (RenderingHints) renderingHints.clone();
+ }
+
+ /**
+ * Translates the coordinate system by (x, y).
+ *
+ * @param x the translation X coordinate
+ * @param y the translation Y coordinate
+ */
+ public void translate(int x, int y)
+ {
+ transform.translate(x, y);
+
+ // Update the clip. We special-case rectangular clips here, because they
+ // are so common (e.g. in Swing).
+ if (clip != null)
+ {
+ if (clip instanceof Rectangle)
+ {
+ Rectangle r = (Rectangle) clip;
+ r.x -= x;
+ r.y -= y;
+ }
+ else
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.translate(-x, -y);
+ updateClip(clipTransform);
+ }
+ }
+ }
+
+ /**
+ * Translates the coordinate system by (tx, ty).
+ *
+ * @param tx the translation X coordinate
+ * @param ty the translation Y coordinate
+ */
+ public void translate(double tx, double ty)
+ {
+ transform.translate(tx, ty);
+
+ // Update the clip. We special-case rectangular clips here, because they
+ // are so common (e.g. in Swing).
+ if (clip != null)
+ {
+ if (clip instanceof Rectangle)
+ {
+ Rectangle r = (Rectangle) clip;
+ r.x -= tx;
+ r.y -= ty;
+ }
+ else
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.translate(-tx, -ty);
+ updateClip(clipTransform);
+ }
+ }
+ }
+
+ /**
+ * Rotates the coordinate system by <code>theta</code> degrees.
+ *
+ * @param theta the angle be which to rotate the coordinate system
+ */
+ public void rotate(double theta)
+ {
+ transform.rotate(theta);
+ if (clip != null)
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.rotate(-theta);
+ updateClip(clipTransform);
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Rotates the coordinate system by <code>theta</code> around the point
+ * (x, y).
+ *
+ * @param theta the angle by which to rotate the coordinate system
+ * @param x the point around which to rotate, X coordinate
+ * @param y the point around which to rotate, Y coordinate
+ */
+ public void rotate(double theta, double x, double y)
+ {
+ transform.rotate(theta, x, y);
+ if (clip != null)
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.rotate(-theta, x, y);
+ updateClip(clipTransform);
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Scales the coordinate system by the factors <code>scaleX</code> and
+ * <code>scaleY</code>.
+ *
+ * @param scaleX the factor by which to scale the X axis
+ * @param scaleY the factor by which to scale the Y axis
+ */
+ public void scale(double scaleX, double scaleY)
+ {
+ transform.scale(scaleX, scaleY);
+ if (clip != null)
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.scale(-scaleX, -scaleY);
+ updateClip(clipTransform);
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Shears the coordinate system by <code>shearX</code> and
+ * <code>shearY</code>.
+ *
+ * @param shearX the X shearing
+ * @param shearY the Y shearing
+ */
+ public void shear(double shearX, double shearY)
+ {
+ transform.shear(shearX, shearY);
+ if (clip != null)
+ {
+ AffineTransform clipTransform = new AffineTransform();
+ clipTransform.shear(-shearX, -shearY);
+ updateClip(clipTransform);
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Transforms the coordinate system using the specified transform
+ * <code>t</code>.
+ *
+ * @param t the transform
+ */
+ public void transform(AffineTransform t)
+ {
+ transform.concatenate(t);
+ try
+ {
+ AffineTransform clipTransform = t.createInverse();
+ updateClip(clipTransform);
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // TODO: How can we deal properly with this?
+ ex.printStackTrace();
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Sets the transformation for this Graphics object.
+ *
+ * @param t the transformation to set
+ */
+ public void setTransform(AffineTransform t)
+ {
+ // Transform clip into target space using the old transform.
+ updateClip(transform);
+ transform.setTransform(t);
+ // Transform the clip back into user space using the inverse new transform.
+ try
+ {
+ updateClip(transform.createInverse());
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // TODO: How can we deal properly with this?
+ ex.printStackTrace();
+ }
+ updateOptimization();
+ }
+
+ /**
+ * Returns the transformation of this coordinate system.
+ *
+ * @return the transformation of this coordinate system
+ */
+ public AffineTransform getTransform()
+ {
+ return (AffineTransform) transform.clone();
+ }
+
+ /**
+ * Returns the current foreground.
+ *
+ * @return the current foreground
+ */
+ public Paint getPaint()
+ {
+ return paint;
+ }
+
+
+ /**
+ * Returns the current composite.
+ *
+ * @return the current composite
+ */
+ public Composite getComposite()
+ {
+ return composite;
+ }
+
+ /**
+ * Sets the current background.
+ *
+ * @param color the background to set.
+ */
+ public void setBackground(Color color)
+ {
+ background = color;
+ }
+
+ /**
+ * Returns the current background.
+ *
+ * @return the current background
+ */
+ public Color getBackground()
+ {
+ return background;
+ }
+
+ /**
+ * Returns the current stroke.
+ *
+ * @return the current stroke
+ */
+ public Stroke getStroke()
+ {
+ return stroke;
+ }
+
+ /**
+ * Intersects the clip of this graphics object with the specified clip.
+ *
+ * @param s the clip with which the current clip should be intersected
+ */
+ public void clip(Shape s)
+ {
+ // Initialize clip if not already present.
+ if (clip == null)
+ clip = s;
+
+ // This is so common, let's optimize this.
+ else if (clip instanceof Rectangle && s instanceof Rectangle)
+ {
+ Rectangle clipRect = (Rectangle) clip;
+ Rectangle r = (Rectangle) s;
+ computeIntersection(r.x, r.y, r.width, r.height, clipRect);
+ }
+ else
+ {
+ Area current;
+ if (clip instanceof Area)
+ current = (Area) clip;
+ else
+ current = new Area(clip);
+
+ Area intersect;
+ if (s instanceof Area)
+ intersect = (Area) s;
+ else
+ intersect = new Area(s);
+
+ current.intersect(intersect);
+ clip = current;
+ isOptimized = false;
+ }
+ }
+
+ public FontRenderContext getFontRenderContext()
+ {
+ //return new FontRenderContext(transform, false, false);
+ return new FontRenderContext(new AffineTransform(), false, false);
+ }
+
+ /**
+ * Draws the specified glyph vector at the specified location.
+ *
+ * @param gv the glyph vector to draw
+ * @param x the location, x coordinate
+ * @param y the location, y coordinate
+ */
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ int numGlyphs = gv.getNumGlyphs();
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+
+ // TODO: We could use fill(gv.getOutline()), but that doesn't seem
+ // to work yet with the font infrastructure I use.
+ for (int i = 0; i < numGlyphs; i++)
+ {
+ //fill(gv.getGlyphVisualBounds(i));
+ GeneralPath p = new GeneralPath(gv.getGlyphOutline(i));
+ p.transform(t);
+ fill(p);
+ }
+ }
+
+ /**
+ * Creates a copy of this graphics object.
+ *
+ * @return a copy of this graphics object
+ */
+ public Graphics create()
+ {
+ AbstractGraphics2D copy = (AbstractGraphics2D) clone();
+ return copy;
+ }
+
+ /**
+ * Creates and returns a copy of this Graphics object. This should
+ * be overridden by subclasses if additional state must be handled when
+ * cloning. This is called by {@link #create()}.
+ *
+ * @return a copy of this Graphics object
+ */
+ protected Object clone()
+ {
+ try
+ {
+ AbstractGraphics2D copy = (AbstractGraphics2D) super.clone();
+ // Copy the clip. If it's a Rectangle, preserve that for optimization.
+ if (clip instanceof Rectangle)
+ copy.clip = new Rectangle((Rectangle) clip);
+ else
+ copy.clip = new GeneralPath(clip);
+
+ copy.renderingHints = new RenderingHints(null);
+ copy.renderingHints.putAll(renderingHints);
+ copy.transform = new AffineTransform(transform);
+ // The remaining state is inmmutable and doesn't need to be copied.
+ return copy;
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ AWTError err = new AWTError("Unexpected exception while cloning");
+ err.initCause(ex);
+ throw err;
+ }
+ }
+
+ /**
+ * Returns the current foreground.
+ */
+ public Color getColor()
+ {
+ Color c = null;
+ if (paint instanceof Color)
+ c = (Color) paint;
+ return c;
+ }
+
+ /**
+ * Sets the current foreground.
+ *
+ * @param color the foreground to set
+ */
+ public void setColor(Color color)
+ {
+ setPaint(color);
+ }
+
+ public void setPaintMode()
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public void setXORMode(Color color)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns the current font.
+ *
+ * @return the current font
+ */
+ public Font getFont()
+ {
+ return font;
+ }
+
+ /**
+ * Sets the font on this graphics object. When <code>f == null</code>, the
+ * current setting is not changed.
+ *
+ * @param f the font to set
+ */
+ public void setFont(Font f)
+ {
+ if (f != null)
+ font = f;
+ }
+
+ /**
+ * Returns the font metrics for the specified font.
+ *
+ * @param font the font for which to fetch the font metrics
+ *
+ * @return the font metrics for the specified font
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return Toolkit.getDefaultToolkit().getFontMetrics(font);
+ }
+
+ /**
+ * Returns the bounds of the current clip.
+ *
+ * @return the bounds of the current clip
+ */
+ public Rectangle getClipBounds()
+ {
+ return clip.getBounds();
+ }
+
+ /**
+ * Intersects the current clipping region with the specified rectangle.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public void clipRect(int x, int y, int width, int height)
+ {
+ clip(new Rectangle(x, y, width, height));
+ }
+
+ /**
+ * Sets the clip to the specified rectangle.
+ *
+ * @param x the x coordinate of the clip rectangle
+ * @param y the y coordinate of the clip rectangle
+ * @param width the width of the clip rectangle
+ * @param height the height of the clip rectangle
+ */
+ public void setClip(int x, int y, int width, int height)
+ {
+ setClip(new Rectangle(x, y, width, height));
+ }
+
+ /**
+ * Returns the current clip.
+ *
+ * @return the current clip
+ */
+ public Shape getClip()
+ {
+ return clip;
+ }
+
+ /**
+ * Sets the current clipping area to <code>clip</code>.
+ *
+ * @param c the clip to set
+ */
+ public void setClip(Shape c)
+ {
+ clip = c;
+ if (! (clip instanceof Rectangle))
+ isOptimized = false;
+ else
+ updateOptimization();
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Draws a line from (x1, y1) to (x2, y2).
+ *
+ * This implementation transforms the coordinates and forwards the call to
+ * {@link #rawDrawLine}.
+ */
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ if (isOptimized)
+ rawDrawLine(x1, y1, x2, y2);
+ else
+ {
+ Line2D line = new Line2D.Double(x1, y1, x2, y2);
+ draw(line);
+ }
+ }
+
+ /**
+ * Fills a rectangle with the current paint.
+ *
+ * @param x the upper left corner, X coordinate
+ * @param y the upper left corner, Y coordinate
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public void fillRect(int x, int y, int width, int height)
+ {
+ if (isOptimized)
+ rawFillRect(x, y, width, height);
+ else
+ {
+ fill(new Rectangle(x, y, width, height));
+ }
+ }
+
+ /**
+ * Fills a rectangle with the current background color.
+ *
+ * This implementation temporarily sets the foreground color to the
+ * background and forwards the call to {@link #fillRect(int, int, int, int)}.
+ *
+ * @param x the upper left corner, X coordinate
+ * @param y the upper left corner, Y coordinate
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ */
+ public void clearRect(int x, int y, int width, int height)
+ {
+ Paint savedForeground = getPaint();
+ setPaint(getBackground());
+ //System.err.println("clearRect transform type: " + transform.getType());
+ fillRect(x, y, width, height);
+ setPaint(savedForeground);
+ }
+
+ /**
+ * Draws a rounded rectangle.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ * @param arcWidth the width of the arcs
+ * @param arcHeight the height of the arcs
+ */
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth,
+ arcHeight));
+ }
+
+ /**
+ * Fills a rounded rectangle.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param width the width of the rectangle
+ * @param height the height of the rectangle
+ * @param arcWidth the width of the arcs
+ * @param arcHeight the height of the arcs
+ */
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth,
+ arcHeight));
+ }
+
+ /**
+ * Draws the outline of an oval.
+ *
+ * @param x the upper left corner of the bounding rectangle of the ellipse
+ * @param y the upper left corner of the bounding rectangle of the ellipse
+ * @param width the width of the ellipse
+ * @param height the height of the ellipse
+ */
+ public void drawOval(int x, int y, int width, int height)
+ {
+ draw(new Ellipse2D.Double(x, y, width, height));
+ }
+
+ /**
+ * Fills an oval.
+ *
+ * @param x the upper left corner of the bounding rectangle of the ellipse
+ * @param y the upper left corner of the bounding rectangle of the ellipse
+ * @param width the width of the ellipse
+ * @param height the height of the ellipse
+ */
+ public void fillOval(int x, int y, int width, int height)
+ {
+ fill(new Ellipse2D.Double(x, y, width, height));
+ }
+
+ /**
+ * Draws an arc.
+ */
+ public void drawArc(int x, int y, int width, int height, int arcStart,
+ int arcAngle)
+ {
+ draw(new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
+ Arc2D.OPEN));
+ }
+
+ /**
+ * Fills an arc.
+ */
+ public void fillArc(int x, int y, int width, int height, int arcStart,
+ int arcAngle)
+ {
+ fill(new Arc2D.Double(x, y, width, height, arcStart, arcAngle,
+ Arc2D.OPEN));
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int npoints)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Draws the outline of a polygon.
+ */
+ public void drawPolygon(int[] xPoints, int[] yPoints, int npoints)
+ {
+ draw(new Polygon(xPoints, yPoints, npoints));
+ }
+
+ /**
+ * Fills the outline of a polygon.
+ */
+ public void fillPolygon(int[] xPoints, int[] yPoints, int npoints)
+ {
+ fill(new Polygon(xPoints, yPoints, npoints));
+ }
+
+ public boolean drawImage(Image image, int x, int y, ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean drawImage(Image image, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean drawImage(Image image, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean drawImage(Image image, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+ ImageObserver observer)
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Disposes this graphics object.
+ */
+ public void dispose()
+ {
+ // Nothing special to do here.
+ }
+
+ /**
+ * Fills the specified shape. The shape has already been clipped against the
+ * current clip.
+ *
+ * @param s the shape to fill
+ */
+ protected void fillShape(Shape s)
+ {
+ PathIterator path = s.getPathIterator(getTransform(), 1.0);
+ // Build up polygons and let the native backend render this using
+ // rawFillPolygon() 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())
+ {
+ 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);
+ segs.add(edge);
+ }
+ else if (segType == PathIterator.SEG_LINETO)
+ {
+ PolyEdge edge = new PolyEdge(segX, segY, seg[0], seg[1]);
+ segs.add(edge);
+ segX = seg[0];
+ segY = seg[1];
+ }
+ path.next();
+ }
+ if (segs.size() > 0)
+ rawFillShape(segs, minX, minY, maxX, maxY);
+ }
+
+ /**
+ * Draws one pixel in the target coordinate space. This method draws the
+ * specified pixel by getting the painting pixel for that coordinate
+ * from the paintContext and compositing the pixel with the compositeContext.
+ * The resulting pixel is then set by calling {@link #rawSetPixel}.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ protected void drawPixel(int x, int y)
+ {
+ // FIXME: Implement efficient compositing.
+ if (! (paint instanceof Color))
+ {
+ int[] paintPixel = paintRaster.getPixel(x, y, pixel);
+ Color c = new Color(paintPixel[0], paintPixel[1], paintPixel[2]);
+ rawSetForeground(c);
+ }
+ rawSetPixel(x, y);
+ }
+
+ /**
+ * Draws a pixel in the target coordinate space using the specified color.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ protected abstract void rawSetPixel(int x, int y);
+
+ /**
+ * Sets the foreground color for drawing.
+ *
+ * @param c the color to set
+ */
+ protected abstract void rawSetForeground(Color c);
+
+ /**
+ * Returns the color model of this Graphics object.
+ *
+ * @return the color model of this Graphics object
+ */
+ protected abstract ColorModel getColorModel();
+
+ /**
+ * Returns the color model of the target device.
+ *
+ * @return the color model of the target device
+ */
+ protected abstract ColorModel getDestinationColorModel();
+
+ /**
+ * Returns the bounds of the target.
+ *
+ * @return the bounds of the target
+ */
+ protected abstract Rectangle getDeviceBounds();
+
+ /**
+ * Returns the bounds of the drawing area in user space.
+ *
+ * @return the bounds of the drawing area in user space
+ */
+ protected Rectangle2D getUserBounds()
+ {
+ PathIterator pathIter = getDeviceBounds().getPathIterator(getTransform());
+ GeneralPath path = new GeneralPath();
+ path.append(pathIter, true);
+ return path.getBounds();
+
+ }
+ /**
+ * Draws a line in optimization mode. The implementation should respect the
+ * clip but can assume that it is a rectangle.
+ *
+ * @param x0 the starting point, X coordinate
+ * @param y0 the starting point, Y coordinate
+ * @param x1 the end point, X coordinate
+ * @param y1 the end point, Y coordinate
+ */
+ protected void rawDrawLine(int x0, int y0, int x1, int y1)
+ {
+ // This is an implementation of Bresenham's line drawing algorithm.
+ int dy = y1 - y0;
+ int dx = x1 - x0;
+ int stepx, stepy;
+
+ if (dy < 0)
+ {
+ dy = -dy;
+ stepy = -1;
+ }
+ else
+ {
+ stepy = 1;
+ }
+ if (dx < 0)
+ {
+ dx = -dx;
+ stepx = -1;
+ }
+ else
+ {
+ stepx = 1;
+ }
+ dy <<= 1;
+ dx <<= 1;
+
+ drawPixel(x0, y0);
+ if (dx > dy)
+ {
+ int fraction = dy - (dx >> 1); // same as 2*dy - dx
+ while (x0 != x1)
+ {
+ if (fraction >= 0)
+ {
+ y0 += stepy;
+ fraction -= dx;
+ }
+ x0 += stepx;
+ fraction += dy;
+ drawPixel(x0, y0);
+ }
+ }
+ else
+ {
+ int fraction = dx - (dy >> 1);
+ while (y0 != y1)
+ {
+ if (fraction >= 0)
+ {
+ x0 += stepx;
+ fraction -= dy;
+ }
+ y0 += stepy;
+ fraction += dx;
+ drawPixel(x0, y0);
+ }
+ }
+ }
+
+ /**
+ * Fills a rectangle in optimization mode. The implementation should respect
+ * the clip but can assume that it is a rectangle.
+ *
+ * @param x the upper left corner, X coordinate
+ * @param y the upper left corner, Y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ protected void rawFillRect(int x, int y, int w, int h)
+ {
+ int x2 = x + w;
+ int y2 = y + h;
+ for (int xc = x; xc < x2; xc++)
+ {
+ for (int yc = y; yc < y2; yc++)
+ {
+ drawPixel(xc, yc);
+ }
+ }
+ }
+
+ /**
+ * Fills the specified polygon. This should be overridden by backends
+ * that support accelerated (native) polygon filling, which is the
+ * case for most toolkit window and offscreen image implementations.
+ *
+ * The polygon is already clipped when this method is called.
+ */
+ protected void rawFillShape(ArrayList segs, double minX, double minY,
+ double maxX, double maxY)
+ {
+ // 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.
+ ArrayList[] edgeTable = new ArrayList[(int) Math.ceil(maxY)
+ - (int) Math.ceil(minY) + 1];
+
+ for (Iterator i = segs.iterator(); i.hasNext();)
+ {
+ PolyEdge edge = (PolyEdge) i.next();
+
+ // Horizontal edges are not needed and make things only more
+ // complicated. Skip them.
+ if (Math.ceil(edge.y0) == Math.ceil(edge.y1))
+ continue;
+
+ int yindex = (int) ((int) Math.ceil(edge.y0) - (int) Math.ceil(minY));
+ 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(minY);
+ for (int y = minYInt; y <= maxY; 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.y0 && 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.
+ int x0 = 0; // Gets initialized in the first else branch below.
+ boolean active = false;
+ //System.err.println("scanline: " + y);
+ for (Iterator i = activeEdges.iterator(); i.hasNext();)
+ {
+ PolyEdge edge = (PolyEdge) i.next();
+ //System.err.println("edge: " + edge);
+ int x = (int) edge.xIntersection;
+ if (active)
+ {
+ fillScanline(x0, x, y);
+ active = false;
+ }
+ else
+ {
+ x0 = x;
+ active = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Fills a horizontal line between x0 and x1 with the current paint and
+ * composize. Backends should override this if they want to accelerate
+ * general shape drawing. They should respect the current paint and
+ * composite though (or call super for these tasks). It is not necessary
+ * to clip the line.
+ *
+ * @param x0 the beginning of the scanline
+ * @param x1 the end of the scanline
+ * @param y the y coordinate of the line
+ */
+ protected void fillScanline(int x0, int x1, int y)
+ {
+ for (int x = x0; x < x1; x++)
+ drawPixel(x, y);
+ }
+
+ /**
+ * Initializes this graphics object. This must be called by subclasses in
+ * order to correctly initialize the state of this object.
+ */
+ protected void init()
+ {
+ setPaint(Color.BLACK);
+ setFont(new Font("SansSerif", Font.PLAIN, 12));
+ isOptimized = true;
+ }
+
+ //protected abstract Raster getDestinationRaster(int x, int y, int w, int h);
+
+ // Some helper methods.
+
+ /**
+ * Helper method to check and update the optimization conditions.
+ */
+ private void updateOptimization()
+ {
+ int transformType = transform.getType();
+ boolean optimizedTransform =
+ (transformType &
+ (AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_IDENTITY)) != 0;
+
+ isOptimized = clip instanceof Rectangle
+ && optimizedTransform && paint instanceof Color
+ && composite == AlphaComposite.SrcOver
+ && stroke.equals(new BasicStroke());
+ }
+
+ /**
+ * Calculates the intersection of two rectangles. The result is stored
+ * in <code>rect</code>. This is basically the same
+ * like {@link Rectangle#intersection(Rectangle)}, only that it does not
+ * create new Rectangle instances. The tradeoff is that you loose any data in
+ * <code>rect</code>.
+ *
+ * @param x upper-left x coodinate of first rectangle
+ * @param y upper-left y coodinate of first rectangle
+ * @param w width of first rectangle
+ * @param h height of first rectangle
+ * @param rect a Rectangle object of the second rectangle
+ *
+ * @throws NullPointerException if rect is null
+ *
+ * @return a rectangle corresponding to the intersection of the
+ * two rectangles. An empty rectangle is returned if the rectangles
+ * do not overlap
+ */
+ private static Rectangle computeIntersection(int x, int y, int w, int h,
+ Rectangle rect)
+ {
+ int x2 = (int) rect.x;
+ int y2 = (int) rect.y;
+ int w2 = (int) rect.width;
+ int h2 = (int) rect.height;
+
+ int dx = (x > x2) ? x : x2;
+ int dy = (y > y2) ? y : y2;
+ int dw = (x + w < x2 + w2) ? (x + w - dx) : (x2 + w2 - dx);
+ int dh = (y + h < y2 + h2) ? (y + h - dy) : (y2 + h2 - dy);
+
+ if (dw >= 0 && dh >= 0)
+ rect.setBounds(dx, dy, dw, dh);
+ else
+ rect.setBounds(0, 0, 0, 0);
+
+ return rect;
+ }
+
+ /**
+ * Helper method to transform the clip. This is called by the various
+ * transformation-manipulation methods to update the clip (which is in
+ * userspace) accordingly.
+ *
+ * The transform usually is the inverse transform that was applied to the
+ * graphics object.
+ *
+ * @param t the transform to apply to the clip
+ */
+ private void updateClip(AffineTransform t)
+ {
+ if (! (clip instanceof GeneralPath))
+ clip = new GeneralPath(clip);
+
+ GeneralPath p = (GeneralPath) clip;
+ p.transform(t);
+ }
+
+ /**
+ * Clips the specified shape using the current clip. If the resulting shape
+ * is empty, this will return <code>null</code>.
+ *
+ * @param s the shape to clip
+ *
+ * @return the clipped shape or <code>null</code> if the result is empty
+ */
+ private Shape clipShape(Shape s)
+ {
+ Shape clipped = null;
+
+ // Clip the shape if necessary.
+ if (clip != null)
+ {
+ Area a;
+ if (! (s instanceof Area))
+ a = new Area(s);
+ else
+ a = (Area) s;
+
+ Area clipArea;
+ if (! (clip instanceof Area))
+ clipArea = new Area(clip);
+ else
+ clipArea = (Area) clip;
+
+ a.intersect(clipArea);
+ if (! a.isEmpty())
+ clipped = a;
+ }
+ else
+ {
+ clipped = s;
+ }
+ return clipped;
+ }
+}
diff --git a/gnu/java/awt/java2d/CubicSegment.java b/gnu/java/awt/java2d/CubicSegment.java
new file mode 100644
index 000000000..1e568f722
--- /dev/null
+++ b/gnu/java/awt/java2d/CubicSegment.java
@@ -0,0 +1,128 @@
+/* CubicSegment.java -- Cubic segment used for BasicStroke
+ 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 java.awt.geom.Point2D;
+
+/**
+ * Cubic Bezier curve segment
+ */
+public class CubicSegment extends Segment
+{
+ public Point2D cp1; // control points
+ public Point2D cp2; // control points
+
+ /**
+ * Constructor - takes coordinates of the starting point,
+ * first control point, second control point and end point,
+ * respecively.
+ */
+ public CubicSegment(double x1, double y1, double c1x, double c1y,
+ double c2x, double c2y, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp1 = new Point2D.Double(c1x, c1y);
+ cp2 = new Point2D.Double(c2x, c2y);
+ }
+
+ public CubicSegment(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2)
+ {
+ super();
+ P1 = p1;
+ P2 = p2;
+ this.cp1 = cp1;
+ this.cp2 = cp2;
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(),
+ cp2.getX(), cp2.getY(), P2.getX(), P2.getY());
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of this segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp1.getX();
+ double y1 = cp1.getY();
+ double x2 = cp2.getX();
+ double y2 = cp2.getY();
+ double x3 = P2.getX();
+ double y3 = P2.getY();
+ double[] p1 = normal(x0, y0, x1, y1);
+ double[] p2 = normal(x2, y2, x3, y3);
+
+
+ // FIXME: Doesn't compile.
+ // return new Segment[]{s1, s2};
+ return new Segment[0];
+ }
+
+ public void reverse()
+ {
+ Point2D temp = P1;
+ P1 = P2;
+ P2 = temp;
+ temp = cp1;
+ cp1 = cp2;
+ cp2 = temp;
+ }
+
+ public double[] first()
+ {
+ return new double[]{cp1.getX(), cp1.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{cp2.getX(), cp2.getY()};
+ }
+} // class CubicSegment
diff --git a/gnu/java/awt/java2d/LineSegment.java b/gnu/java/awt/java2d/LineSegment.java
new file mode 100644
index 000000000..9c0bcc7ea
--- /dev/null
+++ b/gnu/java/awt/java2d/LineSegment.java
@@ -0,0 +1,103 @@
+/* LineSegment.java -- Line segment used for BasicStroke
+ 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 java.awt.geom.Point2D;
+
+public class LineSegment extends Segment
+{
+ public LineSegment(double x1, double y1, double x2, double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ }
+
+ public LineSegment(Point2D p1, Point2D p2)
+ {
+ super();
+ P1 = (Point2D) p1.clone();
+ P2 = (Point2D) p2.clone();
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new LineSegment(P1, P2);
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of this segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = P2.getX();
+ double y1 = P2.getY();
+ double[] p = normal(x0, y0, x1, y1);
+ Segment s1 = (new LineSegment(x0 + p[0], y0 + p[1],
+ x1 + p[0], y1 + p[1] ));
+ Segment s2 = (new LineSegment(x0 - p[0], y0 - p[1],
+ x1 - p[0], y1 - p[1] ));
+ return new Segment[]{s1, s2};
+ }
+
+ public void reverse()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ public double[] first()
+ {
+ return new double[]{P2.getX(), P2.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{P1.getX(), P1.getY()};
+ }
+} // class LineSegment
diff --git a/gnu/java/awt/java2d/PolyEdge.java b/gnu/java/awt/java2d/PolyEdge.java
new file mode 100644
index 000000000..621bd3ad8
--- /dev/null
+++ b/gnu/java/awt/java2d/PolyEdge.java
@@ -0,0 +1,117 @@
+/* PolyEdge.java -- An edge in a polygon, used for polygon filling
+ 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;
+
+/**
+ * An edge in a polygon. This is used by the scanline conversion algorithm
+ * implemented in {@link AbstractGraphics2D#rawFillShape}.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class PolyEdge
+ implements Comparable
+{
+
+ /**
+ * The start and end coordinates of the edge. y0 is always smaller or equal
+ * than y1.
+ */
+ public double x0, y0, x1, y1;
+
+ /**
+ * The slope of the edge. This is dx / dy.
+ */
+ double slope;
+
+ /**
+ * The intersection of this edge with the current scanline.
+ */
+ double xIntersection;
+
+ /**
+ * Creates a new PolyEdge with the specified coordinates.
+ *
+ * @param x0 the starting point, x coordinate
+ * @param y0 the starting point, y coordinate
+ * @param x1 the end point, x coordinate
+ * @param y1 the end point, y coordinate
+ */
+ PolyEdge(double x0, double y0, double x1, double y1)
+ {
+ if (y0 < y1)
+ {
+ this.x0 = x0;
+ this.y0 = y0;
+ this.x1 = x1;
+ this.y1 = y1;
+ }
+ else
+ {
+ this.x0 = x1;
+ this.y0 = y1;
+ 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);
+ }
+
+ /**
+ * Sorts PolyEdges by the x coordinate from the minimum x value.
+ */
+ public int compareTo(Object o)
+ {
+ PolyEdge other = (PolyEdge) o;
+ int comp = 0;
+ if (x0 < other.x0)
+ comp = -1;
+ else if (x0 > other.x0)
+ comp = 1;
+ return comp;
+ }
+
+ public String toString()
+ {
+ return "Edge: " + x0 + ", " + y0 + ", " + x1 + ", " + y1 + ", slope: "
+ + slope + ", xIntersection: " + xIntersection;
+ }
+}
diff --git a/gnu/java/awt/java2d/PolyEdgeComparator.java b/gnu/java/awt/java2d/PolyEdgeComparator.java
new file mode 100644
index 000000000..6706f2294
--- /dev/null
+++ b/gnu/java/awt/java2d/PolyEdgeComparator.java
@@ -0,0 +1,70 @@
+/* PolyEdgeComparator.java -- Sorts PolyEdges by their current intersection
+ points
+ 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 java.util.Comparator;
+
+/**
+ * Sorts {@link PolyEdge}s by their current intersection points.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class PolyEdgeComparator
+ implements Comparator
+{
+
+ /**
+ * The current scanline.
+ */
+ int y;
+
+ public int compare(Object o1, Object o2)
+ {
+ PolyEdge edge1 = (PolyEdge) o1;
+ PolyEdge edge2 = (PolyEdge) o2;
+ int comp = 0;
+ if (edge1.xIntersection < edge2.xIntersection)
+ comp = -1;
+ else if (edge1.xIntersection > edge2.xIntersection)
+ comp = 1;
+ return comp;
+ }
+
+}
diff --git a/gnu/java/awt/java2d/QuadSegment.java b/gnu/java/awt/java2d/QuadSegment.java
new file mode 100644
index 000000000..9c15a8cfd
--- /dev/null
+++ b/gnu/java/awt/java2d/QuadSegment.java
@@ -0,0 +1,213 @@
+/* QuadSegment.java -- QuadCurve segment used for BasicStroke
+ 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 java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+
+/**
+ * Quadratic Bezier curve segment
+ *
+ * Note: Most peers don't support quadratics directly, so it might make
+ * sense to represent them as cubics internally and just be done with it.
+ * I think we should be peer-agnostic, however, and stay faithful to the
+ * input geometry types as far as possible.
+ */
+public class QuadSegment extends Segment
+{
+ public Point2D cp; // control point
+
+ /**
+ * Constructor, takes the coordinates of the start, control,
+ * and end point, respectively.
+ */
+ public QuadSegment(double x1, double y1, double cx, double cy, double x2,
+ double y2)
+ {
+ super();
+ P1 = new Point2D.Double(x1, y1);
+ P2 = new Point2D.Double(x2, y2);
+ cp = new Point2D.Double(cx, cy);
+ }
+
+ public QuadSegment(Point2D p1, Point2D cp, Point2D p2)
+ {
+ super();
+ P1 = p1;
+ P2 = p2;
+ this.cp = cp;
+ }
+
+ public QuadSegment(QuadCurve2D curve)
+ {
+ super();
+ P1 = curve.getP1();
+ P2 = curve.getP2();
+ this.cp = curve.getCtrlPt();
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Get the "top" and "bottom" segments of a given segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public Segment[] getDisplacedSegments(double radius)
+ {
+ this.radius = radius;
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ QuadCurve2D left = new QuadCurve2D.Double();
+ QuadCurve2D right = new QuadCurve2D.Double();
+ QuadCurve2D orig = new QuadCurve2D.Double(x0, y0, x1, y1, x2, y2);
+ orig.subdivide(left, right);
+
+ QuadSegment s1 = offsetSubdivided(left, true);
+ QuadSegment s2 = offsetSubdivided(left, false);
+
+ s1.add( offsetSubdivided(right, true) );
+ s2.add( offsetSubdivided(right, false) );
+
+ return new Segment[]{s1, s2};
+ }
+
+ private QuadSegment offsetSubdivided(QuadCurve2D curve, boolean plus)
+ {
+ double[] n1 = normal(curve.getX1(), curve.getY1(),
+ curve.getCtrlX(), curve.getCtrlY());
+ double[] n2 = normal(curve.getCtrlX(), curve.getCtrlY(),
+ curve.getX2(), curve.getY2());
+
+ Point2D cp;
+ QuadSegment s;
+ if( plus )
+ {
+ cp = lineIntersection(curve.getX1() + n1[0],
+ curve.getY1() + n1[1],
+ curve.getCtrlX() + n1[0],
+ curve.getCtrlY() + n1[1],
+ curve.getCtrlX() + n2[0],
+ curve.getCtrlY() + n2[1],
+ curve.getX2() + n2[0],
+ curve.getY2() + n2[1], true);
+ s = new QuadSegment(curve.getX1() + n1[0], curve.getY1() + n1[1],
+ cp.getX(), cp.getY(),
+ curve.getX2() + n2[0], curve.getY2() + n2[1]);
+ }
+ else
+ {
+ cp = lineIntersection(curve.getX1() - n1[0],
+ curve.getY1() - n1[1],
+ curve.getCtrlX() - n1[0],
+ curve.getCtrlY() - n1[1],
+ curve.getCtrlX() - n2[0],
+ curve.getCtrlY() - n2[1],
+ curve.getX2() - n2[0],
+ curve.getY2() - n2[1], true);
+
+ s = new QuadSegment(curve.getX1() - n1[0], curve.getY1() - n1[1],
+ cp.getX(), cp.getY(),
+ curve.getX2() - n2[0], curve.getY2() - n2[1]);
+ }
+
+ return s;
+ }
+
+ private Point2D lineIntersection(double X1, double Y1,
+ double X2, double Y2,
+ double X3, double Y3,
+ double X4, double Y4,
+ boolean infinite)
+ {
+ double x1 = X1;
+ double y1 = Y1;
+ double rx = X2 - x1;
+ double ry = Y2 - y1;
+
+ double x2 = X3;
+ double y2 = Y3;
+ double sx = X4 - x2;
+ double sy = Y4 - y2;
+
+ double determinant = sx * ry - sy * rx;
+ double nom = (sx * (y2 - y1) + sy * (x1 - x2));
+
+ // lines can be considered parallel.
+ if (Math.abs(determinant) < 1E-6)
+ return null;
+
+ nom = nom / determinant;
+
+ // check if lines are within the bounds
+ if(!infinite && (nom > 1.0 || nom < 0.0))
+ return null;
+
+ return new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
+ }
+
+ public void reverse()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ public double[] first()
+ {
+ return new double[]{cp.getX(), cp.getY()};
+ }
+
+ public double[] last()
+ {
+ return new double[]{cp.getX(), cp.getY()};
+ }
+}
diff --git a/gnu/java/awt/java2d/Segment.java b/gnu/java/awt/java2d/Segment.java
new file mode 100644
index 000000000..9a985f696
--- /dev/null
+++ b/gnu/java/awt/java2d/Segment.java
@@ -0,0 +1,131 @@
+/* Segment.java -- Abstract segment used for BasicStroke
+ 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 java.awt.geom.Point2D;
+
+public abstract class Segment implements Cloneable
+{
+ // segment type, PathIterator segment types are used.
+ public Point2D P1;
+ public Point2D P2;
+ public Segment next;
+ public Segment last;
+ protected double radius;
+
+ public Segment()
+ {
+ P1 = P2 = null;
+ next = null;
+ last = this;
+ }
+
+ public void add(Segment newsegment)
+ {
+ last.next = newsegment;
+ last = last.next;
+ }
+
+ /**
+ * Reverses the orientation of the whole polygon
+ */
+ public void reverseAll()
+ {
+ reverse();
+ Segment v = next;
+ Segment former = this;
+ next = null;
+
+ while (v != null)
+ {
+ v.reverse();
+ v.last = this;
+ Segment oldnext = v.next;
+ v.next = former;
+
+ former = v;
+ v = oldnext; // move to the next in list
+ }
+ }
+
+ public String toString()
+ {
+ return "Segment:"+P1+", "+P2;
+ }
+
+ /**
+ * Get the normal vector to the slope of the line.
+ * Returns: 0.5*width*(norm of derivative of the (x0,y0)-(x1,y1) vector)
+ */
+ protected double[] normal(double x0, double y0, double x1, double y1)
+ {
+ double dx = (x1 - x0);
+ double dy = (y1 - y0);
+ if( dy == 0 )
+ {
+ dy = radius * ((dx > 0)?1:-1);
+ dx = 0;
+ }
+ else if( dx == 0 )
+ {
+ dx = radius * ((dy > 0)?-1:1);
+ dy = 0;
+ }
+ else
+ {
+ double N = Math.sqrt(dx * dx + dy * dy);
+ double odx = dx;
+ dx = -radius * dy / N;
+ dy = radius * odx / N;
+ }
+ return new double[]{ dx, dy };
+ }
+
+ public abstract void reverse();
+
+ /**
+ * Get the "top" and "bottom" segments of a segment.
+ * First array element is p0 + normal, second is p0 - normal.
+ */
+ public abstract Segment[] getDisplacedSegments(double radius);
+
+ public abstract double[] first();
+ public abstract double[] last();
+
+}
diff --git a/gnu/java/awt/peer/swing/SwingComponentPeer.java b/gnu/java/awt/peer/swing/SwingComponentPeer.java
index 5e34bc9dd..5d484e021 100644
--- a/gnu/java/awt/peer/swing/SwingComponentPeer.java
+++ b/gnu/java/awt/peer/swing/SwingComponentPeer.java
@@ -590,8 +590,7 @@ public class SwingComponentPeer
*/
public void setBounds(int x, int y, int width, int height)
{
- if (swingComponent != null)
- swingComponent.getJComponent().setBounds(x, y, width, height);
+ reshape(x, y, width, height);
}
/**
diff --git a/gnu/java/awt/peer/swing/SwingContainerPeer.java b/gnu/java/awt/peer/swing/SwingContainerPeer.java
index 37bea751f..0b2fb992f 100644
--- a/gnu/java/awt/peer/swing/SwingContainerPeer.java
+++ b/gnu/java/awt/peer/swing/SwingContainerPeer.java
@@ -61,7 +61,7 @@ public class SwingContainerPeer
*
* @param awtCont
*/
- public SwingContainerPeer(Container awtCont)
+ public SwingContainerPeer(Component awtCont)
{
init(awtCont, null);
}
@@ -92,12 +92,7 @@ public class SwingContainerPeer
*/
public Insets getInsets()
{
- Insets retVal;
- if (swingComponent != null)
- retVal = swingComponent.getJComponent().getInsets();
- else
- retVal = new Insets(0, 0, 0, 0);
- return retVal;
+ return insets();
}
/**
@@ -214,12 +209,15 @@ public class SwingContainerPeer
protected void handleMouseEvent(MouseEvent ev)
{
Component comp = awtComponent.getComponentAt(ev.getPoint());
- ComponentPeer peer = comp.getPeer();
- if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
+ if (comp != null)
{
- ev.translatePoint(comp.getX(), comp.getY());
- ev.setSource(comp);
- ((SwingComponentPeer) peer).handleMouseEvent(ev);
+ ComponentPeer peer = comp.getPeer();
+ if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
+ {
+ ev.translatePoint(comp.getX(), comp.getY());
+ ev.setSource(comp);
+ ((SwingComponentPeer) peer).handleMouseEvent(ev);
+ }
}
}
@@ -231,11 +229,14 @@ public class SwingContainerPeer
protected void handleMouseMotionEvent(MouseEvent ev)
{
Component comp = awtComponent.getComponentAt(ev.getPoint());
- ComponentPeer peer = comp.getPeer();
- if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
+ if (comp != null)
{
- ev.translatePoint(comp.getX(), comp.getY());
- ((SwingComponentPeer) peer).handleMouseMotionEvent(ev);
+ ComponentPeer peer = comp.getPeer();
+ if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer)
+ {
+ ev.translatePoint(comp.getX(), comp.getY());
+ ((SwingComponentPeer) peer).handleMouseMotionEvent(ev);
+ }
}
}
}
diff --git a/gnu/java/net/local/LocalServerSocket.java b/gnu/java/net/local/LocalServerSocket.java
new file mode 100644
index 000000000..15163f243
--- /dev/null
+++ b/gnu/java/net/local/LocalServerSocket.java
@@ -0,0 +1,172 @@
+/* LocalServerSocket.java -- a unix domain server socket.
+ 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.net.local;
+
+import java.io.IOException;
+
+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
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private LocalSocketImpl myImpl;
+ private boolean closed;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public LocalServerSocket () throws IOException
+ {
+ myImpl = new LocalSocketImpl ();
+ }
+
+ public LocalServerSocket (SocketAddress bindPoint) throws IOException
+ {
+ this ();
+ bind (bindPoint);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void bind (SocketAddress bindPoint) throws IOException
+ {
+ bind (bindPoint, 0);
+ }
+
+ public void bind (SocketAddress bindPoint, int backlog) throws IOException
+ {
+ myImpl.doCreate ();
+ myImpl.bind (bindPoint);
+ myImpl.listen (backlog);
+ }
+
+ public InetAddress getInetAddress ()
+ {
+ return null;
+ }
+
+ public int getLocalPort ()
+ {
+ return -1;
+ }
+
+ public SocketAddress getLocalSocketAddress ()
+ {
+ return myImpl.getLocalAddress ();
+ }
+
+ public Socket accept () throws IOException
+ {
+ LocalSocket s = new LocalSocket (true);
+ myImpl.accept (s.getLocalImpl());
+ s.localConnected = true;
+ return s;
+ }
+
+ public void close () throws IOException
+ {
+ myImpl.close ();
+ myImpl.unlink ();
+ closed = true;
+ }
+
+ public boolean isBound ()
+ {
+ return myImpl.getLocalAddress () != null;
+ }
+
+ public boolean isClosed ()
+ {
+ return closed;
+ }
+
+ public void setSoTimeout (int timeout)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support timeouts");
+ }
+
+ public int getSoTimeout ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support timeouts");
+ }
+
+ public void setReuseAddress (boolean b)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support reuse address");
+ }
+
+ public boolean getReuseAddress ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support reuse address");
+ }
+
+ public String toString ()
+ {
+ return LocalServerSocket.class.getName() + " [ address="
+ + myImpl.getLocalAddress() + " ]";
+ }
+
+ public void setReceiveBufferSize (int size)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public int getReceiveBufferSize ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public void setSendBufferSize (int size)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public int getSendBufferSize ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+}
diff --git a/gnu/java/net/local/LocalSocket.java b/gnu/java/net/local/LocalSocket.java
new file mode 100644
index 000000000..b977d69c1
--- /dev/null
+++ b/gnu/java/net/local/LocalSocket.java
@@ -0,0 +1,312 @@
+/* LocalSocket.java -- a unix domain client socket.
+ 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.net.local;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+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;
+
+/**
+ * A local, or unix-domain socket. Unix domain sockets are connected on the
+ * local filesystem itself, rather than a remote address.
+ */
+public final class LocalSocket extends Socket
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private final LocalSocketImpl localimpl;
+ boolean localClosed;
+ boolean localConnected;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public LocalSocket () throws SocketException
+ {
+ super ();
+ localimpl = new LocalSocketImpl ();
+ }
+
+ public LocalSocket (LocalSocketAddress addr) throws SocketException
+ {
+ this ();
+ try
+ {
+ connect (addr);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException ();
+ se.initCause (ioe);
+ throw se;
+ }
+ }
+
+ LocalSocket (boolean nocreate) throws IOException
+ {
+ super ();
+ localimpl = new LocalSocketImpl (nocreate);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void bind (SocketAddress bindpoint) throws IOException
+ {
+ throw new SocketException ("binding local client sockets is nonsensical");
+ }
+
+ public void connect (SocketAddress endpoint, int timeout) throws IOException
+ {
+ if (isClosed ())
+ {
+ throw new SocketException ("socket is closed");
+ }
+ if (! (endpoint instanceof LocalSocketAddress))
+ {
+ throw new IllegalArgumentException ("socket address is not a local address");
+ }
+ if (getChannel() != null && !getChannel().isBlocking())
+ {
+ throw new IllegalBlockingModeException ();
+ }
+
+ try
+ {
+ localimpl.doCreate ();
+ localimpl.localConnect ((LocalSocketAddress) endpoint);
+ }
+ catch (IOException ioe)
+ {
+ close ();
+ throw ioe;
+ }
+ localConnected = true;
+ }
+
+ public InetAddress getInetAddress ()
+ {
+ return null;
+ }
+
+ public InetAddress getLocalAddress ()
+ {
+ return null;
+ }
+
+ public int getPort ()
+ {
+ return -1;
+ }
+
+ public int getLocalPort ()
+ {
+ return -1;
+ }
+
+ public SocketChannel getChannel ()
+ {
+ return null;
+ }
+
+ public SocketAddress getLocalSocketAddress ()
+ {
+ return localimpl.getLocalAddress ();
+ }
+
+ public SocketAddress getRemoteSocketAddress ()
+ {
+ return localimpl.getRemoteAddress ();
+ }
+
+ public InputStream getInputStream () throws IOException
+ {
+ return localimpl.getInputStream ();
+ }
+
+ public OutputStream getOutputStream () throws IOException
+ {
+ return localimpl.getOutputStream ();
+ }
+
+ public void sendUrgentData (int b) throws IOException
+ {
+ localimpl.sendUrgentData (b);
+ }
+
+ public synchronized void close () throws IOException
+ {
+ localimpl.close ();
+ localClosed = true;
+ }
+
+ public void shutdownInput () throws IOException
+ {
+ localimpl.shutdownInput ();
+ }
+
+ public void shutdownOutput () throws IOException
+ {
+ localimpl.shutdownOutput ();
+ }
+
+ public boolean isClosed ()
+ {
+ return localClosed;
+ }
+
+ public boolean isBound ()
+ {
+ return false;
+ }
+
+ public boolean isConnected ()
+ {
+ return localConnected;
+ }
+
+ // Unsupported methods.
+ // -------------------------------------------------------------------------
+
+ public void setTcpNoDelay (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getTcpNoDelay() throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSoLinger (boolean b, int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSoLinger () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setOOBInline (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getOOBInline () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSoTimeout (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSoTimeout () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSendBufferSize (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSendBufferSize() throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setReceiveBufferSize (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getReceiveBufferSize () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setKeepAlive (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getKeepAlive () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setTrafficClass (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getTrafficClass () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setReuseAddress (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getReuseAddress () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ LocalSocketImpl getLocalImpl ()
+ {
+ return localimpl;
+ }
+}
diff --git a/gnu/java/net/local/LocalSocketAddress.java b/gnu/java/net/local/LocalSocketAddress.java
new file mode 100644
index 000000000..ac5c53db2
--- /dev/null
+++ b/gnu/java/net/local/LocalSocketAddress.java
@@ -0,0 +1,100 @@
+/* LocalSocketAddress.java -- unix-domain socket address.
+ 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.net.local;
+
+import java.net.SocketAddress;
+
+public final class LocalSocketAddress extends SocketAddress
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private final String path;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Creates a new unix domain socket address.
+ *
+ * @param path The path to the socket.
+ * @throws NullPointerException If <i>path</i> is <tt>null</tt>.
+ */
+ public LocalSocketAddress (String path)
+ {
+ if (path == null)
+ {
+ throw new NullPointerException ();
+ }
+ this.path = path;
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the path of the socket.
+ *
+ * @return The path.
+ */
+ public String getPath ()
+ {
+ return path;
+ }
+
+ public boolean equals (Object o)
+ {
+ if (!(o instanceof LocalSocketAddress))
+ {
+ return false;
+ }
+ return getPath ().equals (((LocalSocketAddress) o).getPath ());
+ }
+
+ public int hashCode ()
+ {
+ return path.hashCode();
+ }
+
+ public String toString ()
+ {
+ return super.toString() + " [ " + path + " ]";
+ }
+}
diff --git a/gnu/java/net/local/LocalSocketImpl.java b/gnu/java/net/local/LocalSocketImpl.java
new file mode 100644
index 000000000..f907e5f46
--- /dev/null
+++ b/gnu/java/net/local/LocalSocketImpl.java
@@ -0,0 +1,322 @@
+/* LocalSocketImpl.java -- a unix domain client socket implementation.
+ 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.net.local;
+
+import java.io.FileDescriptor;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+final class LocalSocketImpl extends SocketImpl
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private boolean created;
+ private InputStream in;
+ private OutputStream out;
+ private int socket_fd;
+ private LocalSocketAddress local;
+ private LocalSocketAddress remote;
+
+ static
+ {
+ try
+ {
+ System.loadLibrary ("javanet");
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace ();
+ }
+ }
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ LocalSocketImpl ()
+ {
+ this (false);
+ }
+
+ LocalSocketImpl (boolean nocreate)
+ {
+ created = nocreate;
+ socket_fd = -1;
+ fd = new FileDescriptor ();
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void setOption (int opt, Object value) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support options");
+ }
+
+ public Object getOption (int opt) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support options");
+ }
+
+ protected native void create (boolean stream) throws IOException;
+ protected native void listen (int timeout) throws IOException;
+ protected native void accept (LocalSocketImpl socket) throws IOException;
+ protected native int available () throws IOException;
+ protected native void close () throws IOException;
+ protected native void sendUrgentData (int data) throws IOException;
+ protected native void shutdownInput () throws IOException;
+ protected native void shutdownOutput () throws IOException;
+
+ native void unlink () throws IOException;
+ native void localBind (LocalSocketAddress addr) throws IOException;
+ native void localConnect (LocalSocketAddress addr) throws IOException;
+ native int read (byte[] buf, int off, int len) throws IOException;
+ native void write (byte[] buf, int off, int len) throws IOException;
+
+ void doCreate () throws IOException
+ {
+ if (!created)
+ {
+ create (true);
+ }
+ }
+
+ LocalSocketAddress getLocalAddress ()
+ {
+ return local;
+ }
+
+ LocalSocketAddress getRemoteAddress ()
+ {
+ return remote;
+ }
+
+ protected InputStream getInputStream()
+ {
+ if (in == null)
+ {
+ in = new LocalInputStream (this);
+ }
+
+ return in;
+ }
+
+ protected OutputStream getOutputStream()
+ {
+ if (out == null)
+ {
+ out = new LocalOutputStream (this);
+ }
+
+ return out;
+ }
+
+ protected void accept (SocketImpl impl) throws IOException
+ {
+ if (! (impl instanceof LocalSocketImpl))
+ {
+ throw new IllegalArgumentException ("not a local socket");
+ }
+ accept ((LocalSocketImpl) impl);
+ }
+
+ protected void connect (String host, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void connect (InetAddress addr, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void connect(SocketAddress addr, int timeout) throws IOException
+ {
+ if (! (addr instanceof LocalSocketAddress))
+ {
+ throw new SocketException ("address is not local");
+ }
+ localConnect ((LocalSocketAddress) addr);
+ }
+
+ protected void bind (InetAddress addr, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void bind (SocketAddress addr) throws IOException
+ {
+ if (! (addr instanceof LocalSocketAddress))
+ {
+ throw new SocketException ("address is not local");
+ }
+ localBind ((LocalSocketAddress) addr);
+ }
+
+ // Inner classes.
+ // -------------------------------------------------------------------------
+
+ class LocalInputStream extends InputStream
+ {
+
+ // Field.
+ // -----------------------------------------------------------------------
+
+ private final LocalSocketImpl impl;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ LocalInputStream (LocalSocketImpl impl)
+ {
+ this.impl = impl;
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public int available () throws IOException
+ {
+ return impl.available();
+ }
+
+ public boolean markSupported ()
+ {
+ return false;
+ }
+
+ public void mark (int readLimit)
+ {
+ }
+
+ public void reset () throws IOException
+ {
+ throw new IOException ("mark/reset not supported");
+ }
+
+ public void close () throws IOException
+ {
+ impl.close();
+ }
+
+ public int read () throws IOException
+ {
+ byte[] buf = new byte[1];
+ int ret = read (buf);
+ if (ret != -1)
+ {
+ return buf[0] & 0xFF;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ public int read (byte[] buf) throws IOException
+ {
+ return read (buf, 0, buf.length);
+ }
+
+ public int read (byte[] buf, int off, int len) throws IOException
+ {
+ int ret = impl.read (buf, off, len);
+
+ if (ret == 0)
+ {
+ return -1;
+ }
+
+ return ret;
+ }
+ }
+
+ class LocalOutputStream extends OutputStream
+ {
+
+ // Field.
+ // -----------------------------------------------------------------------
+
+ private final LocalSocketImpl impl;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ LocalOutputStream (LocalSocketImpl impl)
+ {
+ this.impl = impl;
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public void close () throws IOException
+ {
+ impl.close ();
+ }
+
+ public void flush () throws IOException
+ {
+ }
+
+ public void write (int b) throws IOException
+ {
+ byte[] buf = new byte [1];
+ buf[0] = (byte) b;
+ write (buf);
+ }
+
+ public void write (byte[] buf) throws IOException
+ {
+ write (buf, 0, buf.length);
+ }
+
+ public void write (byte[] buf, int off, int len) throws IOException
+ {
+ impl.write (buf, off, len);
+ }
+ }
+}
diff --git a/gnu/java/net/protocol/ftp/FTPConnection.java b/gnu/java/net/protocol/ftp/FTPConnection.java
index d0f48727c..f5317d479 100644
--- a/gnu/java/net/protocol/ftp/FTPConnection.java
+++ b/gnu/java/net/protocol/ftp/FTPConnection.java
@@ -429,6 +429,9 @@ public class FTPConnection
public boolean changeWorkingDirectory(String path)
throws IOException
{
+ // Do nothing if the path is empty.
+ if (path.length() == 0)
+ return true;
String cmd = CWD + ' ' + path;
send(cmd);
FTPResponse response = getResponse();
diff --git a/gnu/java/net/protocol/http/HTTPURLConnection.java b/gnu/java/net/protocol/http/HTTPURLConnection.java
index 5300c664c..0dce7c75b 100644
--- a/gnu/java/net/protocol/http/HTTPURLConnection.java
+++ b/gnu/java/net/protocol/http/HTTPURLConnection.java
@@ -267,6 +267,8 @@ public class HTTPURLConnection
secure = false;
start = 7;
int end = location.indexOf('/', start);
+ if (end == -1)
+ end = location.length();
host = location.substring(start, end);
int ci = host.lastIndexOf(':');
if (ci != -1)
@@ -288,6 +290,8 @@ public class HTTPURLConnection
secure = true;
start = 8;
int end = location.indexOf('/', start);
+ if (end == -1)
+ end = location.length();
host = location.substring(start, end);
int ci = host.lastIndexOf(':');
if (ci != -1)
diff --git a/gnu/java/security/Properties.java b/gnu/java/security/Properties.java
index 813888c20..860b7d928 100644
--- a/gnu/java/security/Properties.java
+++ b/gnu/java/security/Properties.java
@@ -333,9 +333,9 @@ public final class Properties
handleBooleanProperty(DO_RSA_BLINDING);
// re-sync the 'known' properties
- reproducible = new Boolean((String) props.get(REPRODUCIBLE_PRNG)).booleanValue();
- checkForWeakKeys = new Boolean((String) props.get(CHECK_WEAK_KEYS)).booleanValue();
- doRSABlinding = new Boolean((String) props.get(DO_RSA_BLINDING)).booleanValue();
+ reproducible = Boolean.valueOf((String) props.get(REPRODUCIBLE_PRNG)).booleanValue();
+ checkForWeakKeys = Boolean.valueOf((String) props.get(CHECK_WEAK_KEYS)).booleanValue();
+ doRSABlinding = Boolean.valueOf((String) props.get(DO_RSA_BLINDING)).booleanValue();
// This does not change.
props.put(VERSION, Registry.VERSION_STRING);
diff --git a/gnu/java/security/hash/Haval.java b/gnu/java/security/hash/Haval.java
index f9f3282f2..1bf75652d 100644
--- a/gnu/java/security/hash/Haval.java
+++ b/gnu/java/security/hash/Haval.java
@@ -567,7 +567,7 @@ public class Haval extends BaseHash
{
if (valid == null)
{
- valid = new Boolean(DIGEST0.equals(Util.toString(new Haval().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Haval().digest())));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/MD2.java b/gnu/java/security/hash/MD2.java
index 41e876983..2a93c42c4 100644
--- a/gnu/java/security/hash/MD2.java
+++ b/gnu/java/security/hash/MD2.java
@@ -181,7 +181,7 @@ public class MD2 extends BaseHash
{
if (valid == null)
{
- valid = new Boolean(DIGEST0.equals(Util.toString(new MD2().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD2().digest())));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/MD4.java b/gnu/java/security/hash/MD4.java
index 54dda358b..a09eb1705 100644
--- a/gnu/java/security/hash/MD4.java
+++ b/gnu/java/security/hash/MD4.java
@@ -154,7 +154,7 @@ public class MD4 extends BaseHash
{
if (valid == null)
{
- valid = new Boolean(DIGEST0.equals(Util.toString(new MD4().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD4().digest())));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/MD5.java b/gnu/java/security/hash/MD5.java
index 463292984..165392394 100644
--- a/gnu/java/security/hash/MD5.java
+++ b/gnu/java/security/hash/MD5.java
@@ -358,7 +358,7 @@ public class MD5 extends BaseHash
{
if (valid == null)
{
- valid = new Boolean(DIGEST0.equals(Util.toString(new MD5().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD5().digest())));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/RipeMD128.java b/gnu/java/security/hash/RipeMD128.java
index 83e8f2504..31874a0c2 100644
--- a/gnu/java/security/hash/RipeMD128.java
+++ b/gnu/java/security/hash/RipeMD128.java
@@ -283,7 +283,7 @@ public class RipeMD128 extends BaseHash
{
if (valid == null)
{
- valid = new Boolean
+ valid = Boolean.valueOf
(DIGEST0.equals(Util.toString(new RipeMD128().digest())));
}
return valid.booleanValue();
diff --git a/gnu/java/security/hash/RipeMD160.java b/gnu/java/security/hash/RipeMD160.java
index 73ecc5161..642ffb32d 100644
--- a/gnu/java/security/hash/RipeMD160.java
+++ b/gnu/java/security/hash/RipeMD160.java
@@ -320,7 +320,7 @@ public class RipeMD160 extends BaseHash
{
if (valid == null)
{
- valid = new Boolean
+ valid = Boolean.valueOf
(DIGEST0.equals(Util.toString(new RipeMD160().digest())));
}
return valid.booleanValue();
diff --git a/gnu/java/security/hash/Sha160.java b/gnu/java/security/hash/Sha160.java
index bf5f45652..037b118e6 100644
--- a/gnu/java/security/hash/Sha160.java
+++ b/gnu/java/security/hash/Sha160.java
@@ -229,7 +229,7 @@ public class Sha160 extends BaseHash
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
- valid = new Boolean(DIGEST0.equals(result));
+ valid = Boolean.valueOf(DIGEST0.equals(result));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/Sha256.java b/gnu/java/security/hash/Sha256.java
index 9ef70a1a6..284425ea4 100644
--- a/gnu/java/security/hash/Sha256.java
+++ b/gnu/java/security/hash/Sha256.java
@@ -217,7 +217,7 @@ public class Sha256 extends BaseHash
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
- valid = new Boolean(DIGEST0.equals(result));
+ valid = Boolean.valueOf(DIGEST0.equals(result));
}
return valid.booleanValue();
diff --git a/gnu/java/security/hash/Sha384.java b/gnu/java/security/hash/Sha384.java
index 2f619dc98..332f048d7 100644
--- a/gnu/java/security/hash/Sha384.java
+++ b/gnu/java/security/hash/Sha384.java
@@ -254,7 +254,7 @@ public class Sha384 extends BaseHash
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
- valid = new Boolean(DIGEST0.equals(result));
+ valid = Boolean.valueOf(DIGEST0.equals(result));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/Sha512.java b/gnu/java/security/hash/Sha512.java
index 798b34dfc..da035dcfc 100644
--- a/gnu/java/security/hash/Sha512.java
+++ b/gnu/java/security/hash/Sha512.java
@@ -256,7 +256,7 @@ public class Sha512 extends BaseHash
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
- valid = new Boolean(DIGEST0.equals(result));
+ valid = Boolean.valueOf(DIGEST0.equals(result));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/Tiger.java b/gnu/java/security/hash/Tiger.java
index f39fed30d..be0921dce 100644
--- a/gnu/java/security/hash/Tiger.java
+++ b/gnu/java/security/hash/Tiger.java
@@ -640,7 +640,7 @@ public class Tiger extends BaseHash
{
if (valid == null)
{
- valid = new Boolean(DIGEST0.equals(Util.toString(new Tiger().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Tiger().digest())));
}
return valid.booleanValue();
}
diff --git a/gnu/java/security/hash/Whirlpool.java b/gnu/java/security/hash/Whirlpool.java
index 95a4515d9..b10fa53cd 100644
--- a/gnu/java/security/hash/Whirlpool.java
+++ b/gnu/java/security/hash/Whirlpool.java
@@ -642,7 +642,7 @@ public final class Whirlpool extends BaseHash
public boolean selfTest()
{
if (valid == null)
- valid = new Boolean(DIGEST0.equals(Util.toString(new Whirlpool().digest())));
+ valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Whirlpool().digest())));
return valid.booleanValue();
}
diff --git a/gnu/java/security/jce/sig/RSAKeyFactory.java b/gnu/java/security/jce/sig/RSAKeyFactory.java
index fecf54cb8..674e2afb6 100644
--- a/gnu/java/security/jce/sig/RSAKeyFactory.java
+++ b/gnu/java/security/jce/sig/RSAKeyFactory.java
@@ -84,7 +84,7 @@ public class RSAKeyFactory
PublicKey result;
try
{
- result = new RSAKeyPairX509Codec().decodePublicKey(encoded);
+ return new RSAKeyPairX509Codec().decodePublicKey(encoded);
}
catch (RuntimeException x)
{
@@ -131,7 +131,7 @@ public class RSAKeyFactory
PrivateKey result;
try
{
- result = new RSAKeyPairPKCS8Codec().decodePrivateKey(encoded);
+ return new RSAKeyPairPKCS8Codec().decodePrivateKey(encoded);
}
catch (RuntimeException x)
{
diff --git a/gnu/java/security/key/dss/DSSKey.java b/gnu/java/security/key/dss/DSSKey.java
index c4d3847a5..40aaea893 100644
--- a/gnu/java/security/key/dss/DSSKey.java
+++ b/gnu/java/security/key/dss/DSSKey.java
@@ -185,6 +185,7 @@ public abstract class DSSKey implements Key, DSAKey
{
String ls = SystemProperties.getProperty("line.separator");
str = new StringBuilder().append(ls)
+ .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
.append("p=0x").append(p.toString(16)).append(",").append(ls)
.append("q=0x").append(q.toString(16)).append(",").append(ls)
.append("g=0x").append(g.toString(16))
diff --git a/gnu/java/security/key/rsa/GnuRSAKey.java b/gnu/java/security/key/rsa/GnuRSAKey.java
index 098d372dc..3009dd71f 100644
--- a/gnu/java/security/key/rsa/GnuRSAKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAKey.java
@@ -38,8 +38,8 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
+import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
-import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
@@ -67,6 +67,9 @@ public abstract class GnuRSAKey implements Key, RSAKey
*/
protected final int defaultFormat;
+ /** String representation of this key. Cached for speed. */
+ private transient String str;
+
// Constructor(s)
// -------------------------------------------------------------------------
@@ -111,7 +114,7 @@ public abstract class GnuRSAKey implements Key, RSAKey
/** @deprecated see getEncoded(int). */
public byte[] getEncoded()
{
- return getEncoded(IKeyPairCodec.RAW_FORMAT);
+ return getEncoded(defaultFormat);
}
public String getFormat()
@@ -173,6 +176,20 @@ public abstract class GnuRSAKey implements Key, RSAKey
return n.equals(that.getModulus());
}
+ public String toString()
+ {
+ if (str == null)
+ {
+ String ls = SystemProperties.getProperty("line.separator");
+ str = new StringBuilder().append(ls)
+ .append("defaultFormat=").append(defaultFormat).append(",").append(ls)
+ .append("n=0x").append(n.toString(16)).append(",").append(ls)
+ .append("e=0x").append(e.toString(16))
+ .toString();
+ }
+ return str;
+ }
+
// abstract methods to be implemented by subclasses ------------------------
public abstract byte[] getEncoded(int format);
diff --git a/gnu/java/security/key/rsa/GnuRSAPrivateKey.java b/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
index 7d3144bcd..920534487 100644
--- a/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAPrivateKey.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
+import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
@@ -60,10 +61,11 @@ import java.security.interfaces.RSAPrivateKey;
public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
RSAPrivateCrtKey
{
-
// Constants and variables
// -------------------------------------------------------------------------
+ private static final boolean DEBUG = false;
+
/** The first prime divisor of the modulus. */
private final BigInteger p;
@@ -84,6 +86,9 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
/** The CRT (Chinese Remainder Theorem) coefficient. */
private final BigInteger qInv;
+ /** String representation of this key. Cached for speed. */
+ private transient String str;
+
// Constructor(s)
// -------------------------------------------------------------------------
@@ -294,4 +299,22 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
}
return false;
}
+
+ public String toString()
+ {
+ if (str == null)
+ {
+ String ls = SystemProperties.getProperty("line.separator");
+ str = new StringBuilder(this.getClass().getName()).append("(")
+ .append(super.toString()).append(",").append(ls)
+ .append("d=0x").append(DEBUG ? d.toString(16) : "**...*").append(ls)
+ .append("p=0x").append(DEBUG ? p.toString(16) : "**...*").append(ls)
+ .append("q=0x").append(DEBUG ? q.toString(16) : "**...*").append(ls)
+ .append("dP=0x").append(DEBUG ? dP.toString(16) : "**...*").append(ls)
+ .append("dQ=0x").append(DEBUG ? dQ.toString(16) : "**...*").append(ls)
+ .append("qInv=0x").append(DEBUG ? qInv.toString(16) : "**...*").append(ls)
+ .append(")").toString();
+ }
+ return str;
+ }
}
diff --git a/gnu/java/security/key/rsa/GnuRSAPublicKey.java b/gnu/java/security/key/rsa/GnuRSAPublicKey.java
index bb5d0a49f..8badede14 100644
--- a/gnu/java/security/key/rsa/GnuRSAPublicKey.java
+++ b/gnu/java/security/key/rsa/GnuRSAPublicKey.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
+import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
@@ -59,10 +60,12 @@ import java.security.interfaces.RSAPublicKey;
public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
RSAPublicKey
{
-
// Constants and variables
// -------------------------------------------------------------------------
+ /** String representation of this key. Cached for speed. */
+ private transient String str;
+
// Constructor(s)
// -------------------------------------------------------------------------
@@ -180,4 +183,16 @@ public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
return super.equals(that)
&& getPublicExponent().equals(that.getPublicExponent());
}
+
+ public String toString()
+ {
+ if (str == null)
+ {
+ String ls = SystemProperties.getProperty("line.separator");
+ str = new StringBuilder(this.getClass().getName()).append("(")
+ .append(super.toString()).append(",").append(ls)
+ .append(")").toString();
+ }
+ return str;
+ }
}
diff --git a/gnu/java/security/key/rsa/RSAKeyPairGenerator.java b/gnu/java/security/key/rsa/RSAKeyPairGenerator.java
index 9c7338f66..39063381f 100644
--- a/gnu/java/security/key/rsa/RSAKeyPairGenerator.java
+++ b/gnu/java/security/key/rsa/RSAKeyPairGenerator.java
@@ -50,6 +50,7 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Map;
+import java.util.logging.Logger;
/**
* <p>A key-pair generator for asymetric keys to use in conjunction with the RSA
@@ -68,10 +69,11 @@ import java.util.Map;
*/
public class RSAKeyPairGenerator implements IKeyPairGenerator
{
-
// Constants and variables
// -------------------------------------------------------------------------
+ private static final Logger log = Logger.getLogger(RSAKeyPairGenerator.class.getName());
+
/** The BigInteger constant 1. */
private static final BigInteger ONE = BigInteger.ONE;
@@ -150,6 +152,8 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
*/
public void setup(Map attributes)
{
+ log.entering(this.getClass().getName(), "setup", attributes);
+
// do we have a SecureRandom, or should we use our own?
rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
@@ -177,6 +181,8 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT
: formatID.intValue();
+
+ log.exiting(this.getClass().getName(), "setup");
}
/**
@@ -187,6 +193,8 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
*/
public KeyPair generate()
{
+ log.entering(this.getClass().getName(), "generate");
+
BigInteger p, q, n, d;
// 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where
@@ -234,7 +242,9 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e);
PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d);
- return new KeyPair(pubK, secK);
+ KeyPair result = new KeyPair(pubK, secK);
+ log.exiting(this.getClass().getName(), "generate", result);
+ return result;
}
// helper methods ----------------------------------------------------------
diff --git a/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java b/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
index a7f65b610..0b9809032 100644
--- a/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
+++ b/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java
@@ -45,6 +45,7 @@ import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
+import java.util.logging.Logger;
import gnu.java.security.OID;
import gnu.java.security.Registry;
@@ -62,6 +63,7 @@ import gnu.java.security.util.DerUtil;
public class RSAKeyPairPKCS8Codec
implements IKeyPairCodec
{
+ private static final Logger log = Logger.getLogger(RSAKeyPairPKCS8Codec.class.getName());
private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING);
// implicit 0-arguments constructor
@@ -120,6 +122,8 @@ public class RSAKeyPairPKCS8Codec
*/
public byte[] encodePrivateKey(PrivateKey key)
{
+ log.entering(this.getClass().getName(), "encodePrivateKey()", key);
+
if (! (key instanceof GnuRSAPrivateKey))
throw new InvalidParameterException("Wrong key type");
@@ -187,6 +191,7 @@ public class RSAKeyPairPKCS8Codec
throw y;
}
+ log.exiting(this.getClass().getName(), "encodePrivateKey()", result);
return result;
}
@@ -208,6 +213,8 @@ public class RSAKeyPairPKCS8Codec
*/
public PrivateKey decodePrivateKey(byte[] input)
{
+ log.entering(this.getClass().getName(), "decodePrivateKey()", input);
+
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
@@ -278,7 +285,9 @@ public class RSAKeyPairPKCS8Codec
throw y;
}
- return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e, d, p, q,
- dP, dQ, qInv);
+ PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e,
+ d, p, q, dP, dQ, qInv);
+ log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
+ return result;
}
}
diff --git a/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java b/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java
index 1c362784b..882d9c7b2 100644
--- a/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java
+++ b/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java
@@ -128,8 +128,9 @@ public class RSAKeyPairX509Codec
DERValue derN = new DERValue(DER.INTEGER, n);
DERValue derE = new DERValue(DER.INTEGER, e);
- ArrayList algorithmID = new ArrayList(1);
+ ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
+ algorithmID.add(new DERValue(DER.NULL, null));
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
diff --git a/gnu/java/security/provider/Gnu.java b/gnu/java/security/provider/Gnu.java
index 061356644..6ea96c1e4 100644
--- a/gnu/java/security/provider/Gnu.java
+++ b/gnu/java/security/provider/Gnu.java
@@ -86,6 +86,7 @@ public final class Gnu extends Provider
put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
+ put("Alg.Alias.Signature.RSA", "MD5withRSA");
put("Signature.SHA160withRSA",
gnu.java.security.jce.sig.SHA160withRSA.class.getName());
diff --git a/gnu/java/security/x509/X500DistinguishedName.java b/gnu/java/security/x509/X500DistinguishedName.java
index daf746f5d..02adad7d2 100644
--- a/gnu/java/security/x509/X500DistinguishedName.java
+++ b/gnu/java/security/x509/X500DistinguishedName.java
@@ -1,5 +1,5 @@
/* X500DistinguishedName.java -- X.500 distinguished name.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -61,7 +61,6 @@ import java.util.Set;
public class X500DistinguishedName implements Principal
{
-
// Constants and fields.
// -------------------------------------------------------------------------
@@ -221,6 +220,10 @@ public class X500DistinguishedName implements Principal
putComponent(DC, value);
else if (name.equals("uid"))
putComponent(UID, value);
+ else if (name.equals("o"))
+ putComponent(O, value);
+ else if (name.equals("ou"))
+ putComponent(OU, value);
else
putComponent(new OID(name), value);
}
@@ -328,16 +331,18 @@ public class X500DistinguishedName implements Principal
{
if (fixed && encoded != null)
return (byte[]) encoded.clone();
+
ArrayList name = new ArrayList(components.size());
for (Iterator it = components.iterator(); it.hasNext(); )
{
Map m = (Map) it.next();
if (m.isEmpty())
continue;
+
Set rdn = new HashSet();
for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
{
- Map.Entry e = (Map.Entry) it.next();
+ Map.Entry e = (Map.Entry) it2.next();
ArrayList atav = new ArrayList(2);
atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey()));
atav.add(new DERValue(DER.UTF8_STRING, e.getValue()));
@@ -486,6 +491,9 @@ public class X500DistinguishedName implements Principal
throw new EOFException();
default:
buf.append((char) ch);
+ ch = in.read();
+ if (ch == -1)
+ return buf.toString();
}
}
}
diff --git a/gnu/javax/crypto/cipher/Anubis.java b/gnu/javax/crypto/cipher/Anubis.java
index 63b97ce4e..ca4e8edfe 100644
--- a/gnu/javax/crypto/cipher/Anubis.java
+++ b/gnu/javax/crypto/cipher/Anubis.java
@@ -576,7 +576,7 @@ public final class Anubis extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Blowfish.java b/gnu/javax/crypto/cipher/Blowfish.java
index 5cb958ee4..ca1fdfbd3 100644
--- a/gnu/javax/crypto/cipher/Blowfish.java
+++ b/gnu/javax/crypto/cipher/Blowfish.java
@@ -688,7 +688,7 @@ public class Blowfish extends BaseCipher
{
result = testKat(TV_KEY, TV_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Cast5.java b/gnu/javax/crypto/cipher/Cast5.java
index cbdfe61f5..a0e0c60f3 100644
--- a/gnu/javax/crypto/cipher/Cast5.java
+++ b/gnu/javax/crypto/cipher/Cast5.java
@@ -1341,7 +1341,7 @@ public class Cast5 extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT, KAT_PT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Khazad.java b/gnu/javax/crypto/cipher/Khazad.java
index b6c27833e..3a95874da 100644
--- a/gnu/javax/crypto/cipher/Khazad.java
+++ b/gnu/javax/crypto/cipher/Khazad.java
@@ -514,7 +514,7 @@ public final class Khazad extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Rijndael.java b/gnu/javax/crypto/cipher/Rijndael.java
index 058c8b346..bcd1872fc 100644
--- a/gnu/javax/crypto/cipher/Rijndael.java
+++ b/gnu/javax/crypto/cipher/Rijndael.java
@@ -852,7 +852,7 @@ public final class Rijndael extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Serpent.java b/gnu/javax/crypto/cipher/Serpent.java
index b323b5017..2ed1e4b55 100644
--- a/gnu/javax/crypto/cipher/Serpent.java
+++ b/gnu/javax/crypto/cipher/Serpent.java
@@ -789,7 +789,7 @@ public class Serpent extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Square.java b/gnu/javax/crypto/cipher/Square.java
index 97773e5ea..a73116eb4 100644
--- a/gnu/javax/crypto/cipher/Square.java
+++ b/gnu/javax/crypto/cipher/Square.java
@@ -511,7 +511,7 @@ public final class Square extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/cipher/Twofish.java b/gnu/javax/crypto/cipher/Twofish.java
index bea7f5d2c..f5565d4b4 100644
--- a/gnu/javax/crypto/cipher/Twofish.java
+++ b/gnu/javax/crypto/cipher/Twofish.java
@@ -902,7 +902,7 @@ public final class Twofish extends BaseCipher
{
result = testKat(KAT_KEY, KAT_CT);
}
- valid = new Boolean(result);
+ valid = Boolean.valueOf(result);
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java b/gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java
index 5b3badc8d..0d09d5cef 100644
--- a/gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java
+++ b/gnu/javax/crypto/jce/sig/DHKeyPairGeneratorSpi.java
@@ -44,6 +44,7 @@ import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import javax.crypto.spec.DHGenParameterSpec;
+import javax.crypto.spec.DHParameterSpec;
import gnu.java.security.Registry;
import gnu.java.security.jce.sig.KeyPairGeneratorAdapter;
@@ -75,7 +76,8 @@ public class DHKeyPairGeneratorSpi
HashMap attributes = new HashMap();
if (params != null)
{
- if (! (params instanceof DHGenParameterSpec))
+ if (! (params instanceof DHGenParameterSpec) &&
+ ! (params instanceof DHParameterSpec))
throw new InvalidAlgorithmParameterException("params");
attributes.put(GnuDHKeyPairGenerator.DH_PARAMETERS, params);
diff --git a/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java b/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java
index eafc8d01c..5626a2979 100644
--- a/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java
+++ b/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java
@@ -187,9 +187,19 @@ public class GnuDHKeyPairGenerator implements IKeyPairGenerator
}
else if (params instanceof DHParameterSpec)
{
+ // FIXME: I'm not sure this is correct. It seems to behave the
+ // same way as Sun's RI, but I don't know if this behavior is
+ // documented anywhere.
DHParameterSpec jceSpec = (DHParameterSpec) params;
- l = jceSpec.getP().bitLength();
+ p = jceSpec.getP();
+ g = jceSpec.getG();
+ l = p.bitLength();
m = jceSpec.getL();
+
+ // If no exponent size was given, generate an exponent as
+ // large as the prime.
+ if (m == 0)
+ m = l;
}
else
{
@@ -242,7 +252,12 @@ public class GnuDHKeyPairGenerator implements IKeyPairGenerator
}
// generate a private number x of length m such as: 1 < x < q - 1
- BigInteger q_minus_1 = q.subtract(BigInteger.ONE);
+ BigInteger q_minus_1 = null;
+ if (q != null)
+ q_minus_1 = q.subtract(BigInteger.ONE);
+
+ // We already check if m is modulo 8 in `setup.' This could just
+ // be m >>> 3.
byte[] mag = new byte[(m + 7) / 8];
BigInteger x;
while (true)
@@ -250,7 +265,7 @@ public class GnuDHKeyPairGenerator implements IKeyPairGenerator
nextRandomBytes(mag);
x = new BigInteger(1, mag);
if (x.bitLength() == m && x.compareTo(BigInteger.ONE) > 0
- && x.compareTo(q_minus_1) < 0)
+ && (q_minus_1 == null || x.compareTo(q_minus_1) < 0))
{
break;
}
diff --git a/gnu/javax/crypto/mac/UMac32.java b/gnu/javax/crypto/mac/UMac32.java
index d20d4f4a9..013888856 100644
--- a/gnu/javax/crypto/mac/UMac32.java
+++ b/gnu/javax/crypto/mac/UMac32.java
@@ -419,7 +419,7 @@ public class UMac32 extends BaseMac
mac.update(data, 0, 128);
byte[] result = mac.digest();
// System.out.println("UMAC test vector: "+Util.toString(result));
- valid = new Boolean(TV1.equals(Util.toString(result)));
+ valid = Boolean.valueOf(TV1.equals(Util.toString(result)));
}
return valid.booleanValue();
}
diff --git a/gnu/javax/crypto/prng/CSPRNG.java b/gnu/javax/crypto/prng/CSPRNG.java
index 197009232..6585dcb90 100644
--- a/gnu/javax/crypto/prng/CSPRNG.java
+++ b/gnu/javax/crypto/prng/CSPRNG.java
@@ -364,7 +364,7 @@ public class CSPRNG extends BasePRNG
{
CSPRNG instance = new CSPRNG();
HashMap attrib = new HashMap();
- attrib.put(BLOCKING, new Boolean(getProperty(BLOCK)));
+ attrib.put(BLOCKING, Boolean.valueOf(getProperty(BLOCK)));
String s = null;
// Get each file source "gnu.crypto.csprng.file.N".
diff --git a/gnu/javax/crypto/prng/IPBE.java b/gnu/javax/crypto/prng/IPBE.java
index ef0f3aa48..66921d635 100644
--- a/gnu/javax/crypto/prng/IPBE.java
+++ b/gnu/javax/crypto/prng/IPBE.java
@@ -39,29 +39,43 @@ exception statement from your version. */
package gnu.javax.crypto.prng;
/**
- * <p>Trivial interface to group Password-based encryption property names.</p>
+ * Trivial interface to group Password-based encryption property names and
+ * constants.
*/
public interface IPBE
{
-
- // Constants
- // -------------------------------------------------------------------------
-
/**
* Property name for the iteration count in a PBE algorithm. The property
* associated with this is expected to be an {@link Integer}.
*/
- public static final String ITERATION_COUNT = "gnu.crypto.pbe.iteration.count";
+ String ITERATION_COUNT = "gnu.crypto.pbe.iteration.count";
/**
* Property name for the password in a PBE algorithm. The property associated
* with this is expected to be a char array.
*/
- public static final String PASSWORD = "gnu.crypto.pbe.password";
+ String PASSWORD = "gnu.crypto.pbe.password";
+
+ /**
+ * Property name for the password character encoding in a PBE algorithm. The
+ * property associated with this is expected to be a String denoting a valid
+ * character-encoding name. If this property is not set, and a password is
+ * used, then {@link #DEFAULT_PASSWORD_ENCODING} will be used when converting
+ * the password character(s) to bytes.
+ */
+ String PASSWORD_ENCODING = "gnu.crypto.pbe.password.encoding";
/**
* Property name for the salt in a PBE algorithm. The property associated
* with this is expected to be a byte array.
*/
- public static final String SALT = "gnu.crypto.pbe.salt";
+ String SALT = "gnu.crypto.pbe.salt";
+
+ /**
+ * The default character set encoding name to be used if (a) a password is
+ * to be used as the source for a PBE-based Key Derivation Function (KDF) and
+ * (b) no character set encoding name was specified among the attributes used
+ * to initialize the instance.
+ */
+ String DEFAULT_PASSWORD_ENCODING = "UTF-8";
}
diff --git a/gnu/javax/crypto/prng/PBKDF2.java b/gnu/javax/crypto/prng/PBKDF2.java
index 78e4ae0da..d39cd0a65 100644
--- a/gnu/javax/crypto/prng/PBKDF2.java
+++ b/gnu/javax/crypto/prng/PBKDF2.java
@@ -127,23 +127,34 @@ public class PBKDF2 extends BasePRNG implements Cloneable
salt = s;
}
+ byte[] macKeyMaterial;
char[] password = (char[]) attributes.get(IPBE.PASSWORD);
if (password != null)
{
+ String encoding = (String) attributes.get(IPBE.PASSWORD_ENCODING);
+ if (encoding == null || encoding.trim().length() == 0)
+ encoding = IPBE.DEFAULT_PASSWORD_ENCODING;
+ else
+ encoding = encoding.trim();
+
try
{
- macAttrib.put(IMac.MAC_KEY_MATERIAL,
- new String(password).getBytes("UTF-8"));
+ macKeyMaterial = new String(password).getBytes(encoding);
}
catch (UnsupportedEncodingException uee)
{
- throw new Error(uee.getMessage());
+ throw new IllegalArgumentException("Unknown or unsupported encoding: "
+ + encoding, uee);
}
}
+ else
+ macKeyMaterial = (byte[]) attributes.get(IMac.MAC_KEY_MATERIAL);
+
+ if (macKeyMaterial != null)
+ macAttrib.put(IMac.MAC_KEY_MATERIAL, macKeyMaterial);
else if (!initialised)
- {
- throw new IllegalArgumentException("no password specified");
- } // otherwise re-use previous password.
+ throw new IllegalArgumentException("Neither password nor key-material were specified");
+ // otherwise re-use previous password/key-material
try
{
diff --git a/gnu/javax/security/auth/callback/ConsoleCallbackHandler.java b/gnu/javax/security/auth/callback/ConsoleCallbackHandler.java
index 4ce22cb30..052b6c43d 100644
--- a/gnu/javax/security/auth/callback/ConsoleCallbackHandler.java
+++ b/gnu/javax/security/auth/callback/ConsoleCallbackHandler.java
@@ -157,7 +157,8 @@ public class ConsoleCallbackHandler extends AbstractCallbackHandler
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
if (c.getPrompt() != null)
- out.println(c.getPrompt());
+ out.print(c.getPrompt());
+
String[] choices = null;
int[] values = null;
switch (c.getOptionType())
@@ -175,6 +176,7 @@ public class ConsoleCallbackHandler extends AbstractCallbackHandler
ConfirmationCallback.OK, ConfirmationCallback.CANCEL
};
break;
+
case ConfirmationCallback.YES_NO_CANCEL_OPTION:
out.print(messages.getString("callback.yesNoCancel"));
choices = new String[] {
@@ -191,19 +193,26 @@ public class ConsoleCallbackHandler extends AbstractCallbackHandler
ConfirmationCallback.NO, ConfirmationCallback.CANCEL
};
break;
+
case ConfirmationCallback.YES_NO_OPTION:
out.print(messages.getString("callback.yesNo"));
- choices = new String[] {
- messages.getString("callback.yes"),
- messages.getString("callback.no"),
- messages.getString("callback.shortYes"),
- messages.getString("callback.shortNo")
- };
- values = new int[] {
- ConfirmationCallback.YES, ConfirmationCallback.NO,
- ConfirmationCallback.YES, ConfirmationCallback.NO
- };
+ choices = new String[] { messages.getString("callback.yes"),
+ messages.getString("callback.no"),
+ messages.getString("callback.shortYes"),
+ messages.getString("callback.shortNo") };
+ values = new int[] { ConfirmationCallback.YES,
+ ConfirmationCallback.NO,
+ ConfirmationCallback.YES,
+ ConfirmationCallback.NO };
+ int defaultOption = c.getDefaultOption();
+ if (defaultOption > -1 && defaultOption < choices.length)
+ {
+ out.print("[");
+ out.print(choices[defaultOption]);
+ out.print("] ");
+ }
break;
+
case ConfirmationCallback.UNSPECIFIED_OPTION:
choices = c.getOptions();
values = new int[choices.length];
@@ -220,6 +229,7 @@ public class ConsoleCallbackHandler extends AbstractCallbackHandler
out.print(choices[c.getDefaultOption()]);
out.print("] ");
break;
+
default:
throw new IllegalArgumentException();
}
@@ -242,7 +252,7 @@ public class ConsoleCallbackHandler extends AbstractCallbackHandler
protected void handleLanguage(LanguageCallback c) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
- out.println(messages.getString("callback.language"));
+ out.print(messages.getString("callback.language"));
String reply = null;
reply = in.readLine();
if (reply == null)
diff --git a/gnu/javax/swing/text/html/parser/support/Parser.java b/gnu/javax/swing/text/html/parser/support/Parser.java
index cef94942e..92f9b27c5 100644
--- a/gnu/javax/swing/text/html/parser/support/Parser.java
+++ b/gnu/javax/swing/text/html/parser/support/Parser.java
@@ -934,7 +934,7 @@ public class Parser
optional(WS);
attributeReading:
- while (getTokenAhead().kind == NUMTOKEN)
+ while (getTokenAhead().kind == NUMTOKEN)
{
name = getNextToken();
optional(WS);
@@ -949,46 +949,90 @@ public class Parser
switch (next.kind)
{
- case QUOT :
-
- // read "quoted" attribute.
- buffer.setLength(0);
- readTillTokenE(QUOT);
- attrValue = buffer.toString();
- break;
-
- case AP :
-
- // read 'quoted' attribute.
- buffer.setLength(0);
- readTillTokenE(AP);
- attrValue = buffer.toString();
- break;
-
- // read unquoted attribute.
- case NUMTOKEN :
- value = next;
- optional(WS);
-
- // Check maybe the opening quote is missing.
- next = getTokenAhead();
- if (bQUOTING.get(next.kind))
- {
- hTag = next;
- error("The value without opening quote is closed with '" +
- next.getImage() + "'"
- );
- }
+ case QUOT:
+
+ // read "quoted" attribute.
+ buffer.setLength(0);
+ readTillTokenE(QUOT);
+ attrValue = buffer.toString();
+ break;
+
+ case AP:
+
+ // read 'quoted' attribute.
+ buffer.setLength(0);
+ readTillTokenE(AP);
+ attrValue = buffer.toString();
+ break;
+
+ // read unquoted attribute.
+ case NUMTOKEN:
+ value = next;
+ optional(WS);
+
+ // Check maybe the opening quote is missing.
+ next = getTokenAhead();
+ if (bQUOTING.get(next.kind))
+ {
+ hTag = next;
+ error("The value without opening quote is closed with '"
+ + next.getImage() + "'");
+ attrValue = value.getImage();
+ }
+ else if (next.kind == SLASH)
+ // The slash in this context is treated as the ordinary
+ // character, not as a token. The slash may be part of
+ // the unquoted URL.
+ {
+ StringBuffer image = new StringBuffer(value.getImage());
+ while (next.kind == NUMTOKEN || next.kind == SLASH)
+ {
+ image.append(getNextToken().getImage());
+ next = getTokenAhead();
+ }
+ attrValue = image.toString();
+ }
+ else
attrValue = value.getImage();
- break;
-
- default :
- break attributeReading;
+ break;
+
+ case SLASH:
+ value = next;
+ optional(WS);
+
+ // Check maybe the opening quote is missing.
+ next = getTokenAhead();
+ if (bQUOTING.get(next.kind))
+ {
+ hTag = next;
+ error("The value without opening quote is closed with '"
+ + next.getImage() + "'");
+ attrValue = value.getImage();
+ }
+ else if (next.kind == NUMTOKEN || next.kind == SLASH)
+ // The slash in this context is treated as the ordinary
+ // character, not as a token. The slash may be part of
+ // the unquoted URL.
+ {
+ StringBuffer image = new StringBuffer(value.getImage());
+ while (next.kind == NUMTOKEN || next.kind == SLASH)
+ {
+ image.append(getNextToken().getImage());
+ next = getTokenAhead();
+ }
+ attrValue = image.toString();
+ }
+ else
+ attrValue = value.getImage();
+ break;
+ default:
+ break attributeReading;
}
attributes.addAttribute(name.getImage(), attrValue);
optional(WS);
}
- else // The '=' is missing: attribute without value.
+ else
+ // The '=' is missing: attribute without value.
{
noValueAttribute(element, name.getImage());
}
@@ -996,9 +1040,8 @@ public class Parser
}
/**
- * Return string, corresponding the given named entity.
- * The name is passed with the preceeding &, but without
- * the ending semicolon.
+ * Return string, corresponding the given named entity. The name is passed
+ * with the preceeding &, but without the ending semicolon.
*/
protected String resolveNamedEntity(final String a_tag)
{
diff --git a/gnu/xml/dom/DomDocument.java b/gnu/xml/dom/DomDocument.java
index 0d52a23ff..5d06a428b 100644
--- a/gnu/xml/dom/DomDocument.java
+++ b/gnu/xml/dom/DomDocument.java
@@ -150,6 +150,14 @@ public class DomDocument
}
/**
+ * Sets whether to check for document characters.
+ */
+ public void setCheckingCharacters(boolean flag)
+ {
+ checkingCharacters = flag;
+ }
+
+ /**
* <b>DOM L1</b>
* Returns the constant "#document".
*/
@@ -235,6 +243,18 @@ public class DomDocument
if (current.getNodeType() == ELEMENT_NODE)
{
DomElement element = (DomElement) current;
+ if (element.userIdAttrs != null)
+ {
+ for (Iterator i = element.userIdAttrs.iterator();
+ i.hasNext(); )
+ {
+ Node idAttr = (Node) i.next();
+ if (id.equals(idAttr.getNodeValue()))
+ {
+ return element;
+ }
+ }
+ }
if (doctype != null)
{
DTDElementTypeInfo info =
@@ -244,18 +264,6 @@ public class DomDocument
{
return element;
}
- else if (element.userIdAttrs != null)
- {
- for (Iterator i = element.userIdAttrs.iterator();
- i.hasNext(); )
- {
- Node idAttr = (Node) i.next();
- if (id.equals(idAttr.getNodeValue()))
- {
- return element;
- }
- }
- }
}
// xml:id
String xmlId = element.getAttribute("xml:id");
@@ -535,10 +543,9 @@ public class DomDocument
int index = name.indexOf(':');
if (index != -1)
{
- if (index == 0 || name.lastIndexOf(':') != index)
+ if (index == 0 || index == (len - 1) || name.lastIndexOf(':') != index)
{
- throw new DomDOMException(DOMException.NAMESPACE_ERR,
- name, null, 0);
+ throw new DomDOMException(DOMException.NAMESPACE_ERR, name, null, 0);
}
}
}
diff --git a/gnu/xml/dom/html2/DomHTMLParser.java b/gnu/xml/dom/html2/DomHTMLParser.java
index 2164e052c..2d329fd4c 100644
--- a/gnu/xml/dom/html2/DomHTMLParser.java
+++ b/gnu/xml/dom/html2/DomHTMLParser.java
@@ -125,6 +125,7 @@ public class DomHTMLParser
{
document = new DomHTMLDocument();
document.setCheckWellformedness(false);
+ document.setCheckingCharacters(false);
cursor = document;
diff --git a/include/gnu_java_net_local_LocalSocketImpl.h b/include/gnu_java_net_local_LocalSocketImpl.h
new file mode 100644
index 000000000..3309053f1
--- /dev/null
+++ b/include/gnu_java_net_local_LocalSocketImpl.h
@@ -0,0 +1,31 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_net_local_LocalSocketImpl__
+#define __gnu_java_net_local_LocalSocketImpl__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_net_local_LocalSocketImpl_available (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_net_local_LocalSocketImpl_read (JNIEnv *env, jobject, jbyteArray, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_write (JNIEnv *env, jobject, jbyteArray, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_net_local_LocalSocketImpl__ */
diff --git a/java/awt/BasicStroke.java b/java/awt/BasicStroke.java
index bee183ca3..bf111d080 100644
--- a/java/awt/BasicStroke.java
+++ b/java/awt/BasicStroke.java
@@ -38,8 +38,15 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
+import gnu.java.awt.java2d.CubicSegment;
+import gnu.java.awt.java2d.LineSegment;
+import gnu.java.awt.java2d.QuadSegment;
+import gnu.java.awt.java2d.Segment;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
import java.util.Arrays;
/**
@@ -111,6 +118,8 @@ public class BasicStroke implements Stroke
/** The dash phase. */
private final float phase;
+ private Segment start, end;
+
/**
* Creates a new <code>BasicStroke</code> instance with the given attributes.
*
@@ -250,10 +259,13 @@ public class BasicStroke implements Stroke
* @param s the shape.
*/
public Shape createStrokedShape(Shape s)
- throws NotImplementedException
{
- // FIXME: Implement this
- throw new Error("not implemented");
+ PathIterator pi = s.getPathIterator( new AffineTransform() );
+
+ if( dash == null )
+ return solidStroke( pi );
+
+ return dashedStroke( pi );
}
/**
@@ -369,4 +381,355 @@ public class BasicStroke implements Stroke
return width == s.width && cap == s.cap && join == s.join
&& limit == s.limit && Arrays.equals(dash, s.dash) && phase == s.phase;
}
+
+ private Shape solidStroke(PathIterator pi)
+ {
+ double[] coords = new double[6];
+ double x, y, x0, y0;
+ boolean pathOpen = false;
+ GeneralPath output = new GeneralPath( );
+ Segment[] p;
+ x = x0 = y = y0 = 0;
+
+ while( !pi.isDone() )
+ {
+ switch( pi.currentSegment(coords) )
+ {
+ case PathIterator.SEG_MOVETO:
+ x0 = x = coords[0];
+ y0 = y = coords[1];
+ if( pathOpen )
+ {
+ capEnds();
+ convertPath(output, start);
+ start = end = null;
+ pathOpen = false;
+ }
+ break;
+
+ case PathIterator.SEG_LINETO:
+ p = (new LineSegment(x, y, coords[0], coords[1])).
+ getDisplacedSegments(width/2.0);
+ if( !pathOpen )
+ {
+ start = p[0];
+ end = p[1];
+ pathOpen = true;
+ }
+ else
+ addSegments(p);
+
+ x = coords[0];
+ y = coords[1];
+ break;
+
+ case PathIterator.SEG_QUADTO:
+ p = (new QuadSegment(x, y, coords[0], coords[1], coords[2],
+ coords[3])).getDisplacedSegments(width/2.0);
+ if( !pathOpen )
+ {
+ start = p[0];
+ end = p[1];
+ pathOpen = true;
+ }
+ else
+ addSegments(p);
+
+ x = coords[0];
+ y = coords[1];
+ break;
+
+ case PathIterator.SEG_CUBICTO:
+ p = new CubicSegment(x, y, coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5]).getDisplacedSegments(width/2.0);
+ if( !pathOpen )
+ {
+ start = p[0];
+ end = p[1];
+ pathOpen = true;
+ }
+ else
+ addSegments(p);
+
+ x = coords[0];
+ y = coords[1];
+ break;
+
+ case PathIterator.SEG_CLOSE:
+ p = (new LineSegment(x, y, x0, y0)).getDisplacedSegments(width/2.0);
+ addSegments(p);
+ convertPath(output, start);
+ convertPath(output, end);
+ start = end = null;
+ pathOpen = false;
+ break;
+ }
+ pi.next();
+ }
+
+ if( pathOpen )
+ {
+ capEnds();
+ convertPath(output, start);
+ }
+ return output;
+ }
+
+ private Shape dashedStroke(PathIterator pi)
+ {
+ GeneralPath out = new GeneralPath();
+ return out;
+ }
+
+ /**
+ * Cap the ends of the path (joining the start and end list of segments)
+ */
+ private void capEnds()
+ {
+ Segment returnPath = end.last;
+
+ end.reverseAll(); // reverse the path.
+ end = null;
+ capEnd(start, returnPath);
+ start.last = returnPath.last;
+ end = null;
+
+ capEnd(start, start);
+ }
+
+ /**
+ * Convert and add the linked list of Segments in s to a GeneralPath p.
+ */
+ private void convertPath(GeneralPath p, Segment s)
+ {
+ Segment v = s;
+ p.moveTo((float)s.P1.getX(), (float)s.P1.getY());
+
+ do
+ {
+ if(v instanceof LineSegment)
+ p.lineTo((float)v.P2.getX(), (float)v.P2.getY());
+ else if(v instanceof QuadSegment)
+ p.quadTo((float)((QuadSegment)v).cp.getX(),
+ (float)((QuadSegment)v).cp.getY(),
+ (float)v.P2.getX(),
+ (float)v.P2.getY());
+ else if(v instanceof CubicSegment)
+ p.curveTo((float)((CubicSegment)v).cp1.getX(),
+ (float)((CubicSegment)v).cp1.getY(),
+ (float)((CubicSegment)v).cp2.getX(),
+ (float)((CubicSegment)v).cp2.getY(),
+ (float)v.P2.getX(),
+ (float)v.P2.getY());
+ v = v.next;
+ } while(v != s && v != null);
+
+ p.closePath();
+ }
+
+ /**
+ * Add to segments to start and end, joining the outer pair and
+ */
+ private void addSegments(Segment[] segments)
+ {
+ double[] p0 = start.last.last();
+ double[] p1 = new double[]{start.last.P2.getX(), start.last.P2.getY()};
+ double[] p2 = new double[]{segments[0].P1.getX(), segments[0].P1.getY()};
+ double[] p3 = segments[0].first();
+ Point2D p;
+
+ double det = (p1[0] - p0[0])*(p3[1] - p2[1]) -
+ (p3[0] - p2[0])*(p1[1] - p0[1]);
+
+ if( det > 0 )
+ {
+ // start and segment[0] form the 'inner' part of a join,
+ // connect the overlapping segments
+ p = lineIntersection(p0[0],p0[1],p1[0],p1[1],p2[0],p2[1],p3[0],p3[1], false);
+ if( p == null )
+ {
+ // Dodgy.
+ start.add(new LineSegment(start.last.P2, segments[0].P1));
+ p = new Point2D.Double((segments[0].P1.getX()+ start.last.P2.getX())/2.0,
+ (segments[0].P1.getY()+ start.last.P2.getY())/2.0);
+ }
+ else
+ segments[0].P1 = start.last.P2 = p;
+
+ start.add( segments[0] );
+ joinSegments(end, segments[1], p);
+ }
+ else
+ {
+ // end and segment[1] form the 'inner' part
+ p0 = end.last.last();
+ p1 = new double[]{end.last.P2.getX(), end.last.P2.getY()};
+ p2 = new double[]{segments[1].P1.getX(), segments[1].P1.getY()};
+ p3 = segments[1].first();
+
+ p = lineIntersection(p0[0],p0[1],p1[0],p1[1],
+ p2[0],p2[1],p3[0],p3[1], false);
+ if( p == null )
+ {
+ // Dodgy.
+ end.add(new LineSegment(end.last.P2, segments[1].P1));
+ p = new Point2D.Double((segments[1].P1.getX()+ end.last.P2.getX())/2.0,
+ (segments[1].P1.getY()+ end.last.P2.getY())/2.0);
+ }
+ else
+ segments[1].P1 = end.last.P2 = p;
+
+ end.add( segments[1] );
+ joinSegments(start, segments[0], p);
+ }
+ }
+
+ /**
+ * Make a cap between a and b segments,
+ * where a-->b is the direction of iteration.
+ */
+ private void capEnd(Segment a, Segment b)
+ {
+ double[] p0, p1;
+ double dx, dy, l;
+ Point2D c1,c2;
+
+ switch( cap )
+ {
+ case CAP_BUTT:
+ a.add(new LineSegment(a.last.P2, b.P1));
+ break;
+
+ case CAP_SQUARE:
+ p0 = a.last.last();
+ p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
+ dx = p1[0] - p0[0];
+ dy = p1[1] - p0[1];
+ l = Math.sqrt(dx * dx + dy * dy);
+ dx = 0.5*width*dx/l;
+ dy = 0.5*width*dy/l;
+ c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
+ c2 = new Point2D.Double(b.P1.getX() + dx, b.P1.getY() + dy);
+ a.add(new LineSegment(a.last.P2, c1));
+ a.add(new LineSegment(c1, c2));
+ a.add(new LineSegment(c2, b.P1));
+ break;
+
+ case CAP_ROUND:
+ p0 = a.last.last();
+ p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
+ dx = p1[0] - p0[0];
+ dy = p1[1] - p0[1];
+ l = Math.sqrt(dx * dx + dy * dy);
+ dx = (2.0/3.0)*width*dx/l;
+ dy = (2.0/3.0)*width*dy/l;
+ c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
+ c2 = new Point2D.Double(b.P1.getX() + dx, b.P1.getY() + dy);
+ a.add(new CubicSegment(a.last.P2, c1, c2, b.P1));
+ break;
+ }
+ a.add(b);
+ }
+
+ /**
+ * Returns the intersection of two lines, or null if there isn't one.
+ * @param infinite - true if the lines should be regarded as infinite, false
+ * if the intersection must be within the given segments.
+ * @return a Point2D or null.
+ */
+ private Point2D lineIntersection(double X1, double Y1,
+ double X2, double Y2,
+ double X3, double Y3,
+ double X4, double Y4,
+ boolean infinite)
+ {
+ double x1 = X1;
+ double y1 = Y1;
+ double rx = X2 - x1;
+ double ry = Y2 - y1;
+
+ double x2 = X3;
+ double y2 = Y3;
+ double sx = X4 - x2;
+ double sy = Y4 - y2;
+
+ double determinant = sx * ry - sy * rx;
+ double nom = (sx * (y2 - y1) + sy * (x1 - x2));
+
+ // lines can be considered parallel.
+ if (Math.abs(determinant) < 1E-6)
+ return null;
+
+ nom = nom / determinant;
+
+ // check if lines are within the bounds
+ if(!infinite && (nom > 1.0 || nom < 0.0))
+ return null;
+
+ return new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
+ }
+
+ /**
+ * Join a and b segments, where a-->b is the direction of iteration.
+ *
+ * insideP is the inside intersection point of the join, needed for
+ * calculating miter lengths.
+ */
+ private void joinSegments(Segment a, Segment b, Point2D insideP)
+ {
+ double[] p0, p1;
+ double dx, dy, l;
+ Point2D c1,c2;
+
+ switch( join )
+ {
+ case JOIN_MITER:
+ p0 = a.last.last();
+ p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
+ double[] p2 = new double[]{b.P1.getX(), b.P1.getY()};
+ double[] p3 = b.first();
+ Point2D p = lineIntersection(p0[0],p0[1],p1[0],p1[1],p2[0],p2[1],p3[0],p3[1], true);
+ if( p == null || insideP == null )
+ a.add(new LineSegment(a.last.P2, b.P1));
+ else if((p.distance(insideP)/width) < limit)
+ {
+ a.add(new LineSegment(a.last.P2, p));
+ a.add(new LineSegment(p, b.P1));
+ }
+ else
+ {
+ // outside miter limit, do a bevel join.
+ a.add(new LineSegment(a.last.P2, b.P1));
+ }
+ break;
+
+ case JOIN_ROUND:
+ p0 = a.last.last();
+ p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
+ dx = p1[0] - p0[0];
+ dy = p1[1] - p0[1];
+ l = Math.sqrt(dx * dx + dy * dy);
+ dx = 0.5*width*dx/l;
+ dy = 0.5*width*dy/l;
+ c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
+
+ p0 = new double[]{b.P1.getX(), b.P1.getY()};
+ p1 = b.first();
+
+ dx = p0[0] - p1[0]; // backwards direction.
+ dy = p0[1] - p1[1];
+ l = Math.sqrt(dx * dx + dy * dy);
+ dx = 0.5*width*dx/l;
+ dy = 0.5*width*dy/l;
+ c2 = new Point2D.Double(p0[0] + dx, p0[1] + dy);
+ a.add(new CubicSegment(a.last.P2, c1, c2, b.P1));
+ break;
+
+ case JOIN_BEVEL:
+ a.add(new LineSegment(a.last.P2, b.P1));
+ break;
+ }
+ a.add(b);
+ }
}
diff --git a/java/awt/LightweightDispatcher.java b/java/awt/LightweightDispatcher.java
index 2f254bccf..860646402 100644
--- a/java/awt/LightweightDispatcher.java
+++ b/java/awt/LightweightDispatcher.java
@@ -129,7 +129,8 @@ class LightweightDispatcher
{
Window window = (Window) ev.getSource();
Component target = window.findComponentAt(ev.getX(), ev.getY());
- if (target != null && target.isLightweight())
+ target = findTarget(target);
+ if (target == null || target.isLightweight())
{
// Dispatch additional MOUSE_EXITED and MOUSE_ENTERED if event target
// is different from the last event target.
@@ -145,13 +146,16 @@ class LightweightDispatcher
ev.getClickCount(), ev.isPopupTrigger());
lastTarget.dispatchEvent(mouseExited);
}
- Point p = AWTUtilities.convertPoint(window, ev.getX(), ev.getY(),
- target);
- MouseEvent mouseEntered =
- new MouseEvent(target, MouseEvent.MOUSE_ENTERED, ev.getWhen(),
- ev.getModifiers(), p.x, p.y, ev.getClickCount(),
- ev.isPopupTrigger());
- target.dispatchEvent(mouseEntered);
+ if (target != null)
+ {
+ Point p = AWTUtilities.convertPoint(window, ev.getX(), ev.getY(),
+ target);
+ MouseEvent mouseEntered =
+ new MouseEvent(target, MouseEvent.MOUSE_ENTERED, ev.getWhen(),
+ ev.getModifiers(), p.x, p.y, ev.getClickCount(),
+ ev.isPopupTrigger());
+ target.dispatchEvent(mouseEntered);
+ }
}
switch (ev.getID())
@@ -182,21 +186,43 @@ class LightweightDispatcher
lastTarget = target;
- Point targetCoordinates =
- AWTUtilities.convertPoint(window, ev.getX(), ev.getY(), target);
- int dx = targetCoordinates.x - ev.getX();
- int dy = targetCoordinates.y - ev.getY();
- ev.translatePoint(dx, dy);
- ev.setSource(target);
- target.dispatchEvent(ev);
-
- // We reset the event, so that the normal event dispatching is not
- // influenced by this modified event.
- ev.setSource(window);
- ev.translatePoint(-dx, -dy);
+ if (target != null)
+ {
+ Point targetCoordinates =
+ AWTUtilities.convertPoint(window, ev.getX(), ev.getY(), target);
+ int dx = targetCoordinates.x - ev.getX();
+ int dy = targetCoordinates.y - ev.getY();
+ ev.translatePoint(dx, dy);
+ ev.setSource(target);
+ target.dispatchEvent(ev);
+ // We reset the event, so that the normal event dispatching is not
+ // influenced by this modified event.
+ ev.setSource(window);
+ ev.translatePoint(-dx, -dy);
+ }
+
return true;
}
else
return false;
}
+
+ /**
+ * Finds the actual target for a mouseevent, starting at <code>c</code>.
+ * This searches upwards the component hierarchy until it finds a component
+ * that has a mouselistener attached.
+ *
+ * @param c the component to start searching from
+ *
+ * @return the actual receiver of the mouse event
+ */
+ private Component findTarget(Component c)
+ {
+ Component target = c;
+ while (target != null && target.getMouseListeners().length == 0)
+ {
+ target = target.getParent();
+ }
+ return target;
+ }
}
diff --git a/java/awt/Toolkit.java b/java/awt/Toolkit.java
index 24b72de86..ee9123b1e 100644
--- a/java/awt/Toolkit.java
+++ b/java/awt/Toolkit.java
@@ -1,5 +1,5 @@
/* Toolkit.java -- AWT Toolkit superclass
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -534,11 +534,20 @@ public abstract class Toolkit
{
if (toolkit != null)
return toolkit;
- String toolkit_name = System.getProperty("awt.toolkit",
- default_toolkit_name);
+ String toolkit_name = SystemProperties.getProperty("awt.toolkit",
+ default_toolkit_name);
try
{
- Class cls = Class.forName(toolkit_name);
+ ClassLoader cl;
+ cl = (ClassLoader) AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return ClassLoader.getSystemClassLoader();
+ }
+ });
+ Class cls = cl.loadClass(toolkit_name);
Object obj = cls.newInstance();
if (!(obj instanceof Toolkit))
throw new AWTError(toolkit_name + " is not a subclass of " +
diff --git a/java/awt/image/ReplicateScaleFilter.java b/java/awt/image/ReplicateScaleFilter.java
index 7b24afc10..933527b43 100644
--- a/java/awt/image/ReplicateScaleFilter.java
+++ b/java/awt/image/ReplicateScaleFilter.java
@@ -46,7 +46,6 @@ import java.util.Hashtable;
* exact method is not defined by Sun but some sort of fast Box filter should
* probably be correct.
* <br>
- * Currently this filter does nothing and needs to be implemented.
*
* @author C. Brian Jones (cbj@gnu.org)
*/
diff --git a/java/awt/image/renderable/RenderableImageProducer.java b/java/awt/image/renderable/RenderableImageProducer.java
index a84191987..d8cca6535 100644
--- a/java/awt/image/renderable/RenderableImageProducer.java
+++ b/java/awt/image/renderable/RenderableImageProducer.java
@@ -1,5 +1,5 @@
/* RenderableImageProducer.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,11 +38,15 @@ exception statement from your version. */
package java.awt.image.renderable;
-import gnu.classpath.NotImplementedException;
-
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
import java.util.ArrayList;
+import java.util.Iterator;
public class RenderableImageProducer implements ImageProducer, Runnable
{
@@ -88,17 +92,75 @@ public class RenderableImageProducer implements ImageProducer, Runnable
public void startProduction(ImageConsumer consumer)
{
+ addConsumer(consumer);
Thread t = new Thread(this, "RenderableImageProducerWorker");
t.start();
}
public void requestTopDownLeftRightResend(ImageConsumer consumer)
- throws NotImplementedException
{
+ // Do nothing. The contract says we can ignore this call, so we do.
}
public void run()
- throws NotImplementedException
{
+ // This isn't ideal but it avoids fail-fast problems.
+ // Alternatively, we could clone 'consumers' here.
+ synchronized (consumers)
+ {
+ RenderedImage newImage;
+ if (context == null)
+ newImage = image.createDefaultRendering();
+ else
+ newImage = image.createRendering(context);
+ Raster newData = newImage.getData();
+ ColorModel colorModel = newImage.getColorModel();
+ if (colorModel == null)
+ colorModel = ColorModel.getRGBdefault();
+ SampleModel sampleModel = newData.getSampleModel();
+ DataBuffer dataBuffer = newData.getDataBuffer();
+ int width = newData.getWidth();
+ int height = newData.getHeight();
+
+ // Initialize the consumers.
+ Iterator it = consumers.iterator();
+ while (it.hasNext())
+ {
+ ImageConsumer target = (ImageConsumer) it.next();
+ target.setHints(ImageConsumer.COMPLETESCANLINES
+ | ImageConsumer.SINGLEFRAME
+ | ImageConsumer.SINGLEPASS
+ | ImageConsumer.TOPDOWNLEFTRIGHT);
+ target.setDimensions(width, height);
+ }
+
+ // Work in scan-line order.
+ int[] newLine = new int[width];
+ int[] bands = new int[sampleModel.getNumBands()];
+ for (int y = 0; y < height; ++y)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ sampleModel.getPixel(x, y, bands, dataBuffer);
+ newLine[x] = colorModel.getDataElement(bands, 0);
+ }
+
+ // Tell the consumers about the new scan line.
+ it = consumers.iterator();
+ while (it.hasNext())
+ {
+ ImageConsumer target = (ImageConsumer) it.next();
+ target.setPixels(0, y, width, 1, colorModel, newLine, 0, width);
+ }
+ }
+
+ // Tell the consumers that we're done.
+ it = consumers.iterator();
+ while (it.hasNext())
+ {
+ ImageConsumer target = (ImageConsumer) it.next();
+ target.imageComplete(ImageConsumer.STATICIMAGEDONE);
+ }
+ }
}
} // class RenderableImageProducer
diff --git a/java/beans/beancontext/BeanContextSupport.java b/java/beans/beancontext/BeanContextSupport.java
index f964e2e75..f3d5ff609 100644
--- a/java/beans/beancontext/BeanContextSupport.java
+++ b/java/beans/beancontext/BeanContextSupport.java
@@ -108,13 +108,11 @@ public class BeanContextSupport extends BeanContextChildSupport
}
public boolean hasNext ()
- throws NotImplementedException
{
return child.hasNext();
}
public Object next ()
- throws NotImplementedException
{
return child.next();
}
diff --git a/java/lang/Boolean.java b/java/lang/Boolean.java
index 1041eab39..2b0236d1b 100644
--- a/java/lang/Boolean.java
+++ b/java/lang/Boolean.java
@@ -225,7 +225,7 @@ public final class Boolean implements Serializable, Comparable<Boolean>
/**
* Compares this Boolean to another.
*
- * @param b the Boolean to compare this Boolean to
+ * @param other the Boolean to compare this Boolean to
* @return 0 if both Booleans represent the same value, a positive number
* if this Boolean represents true and the other false, and a negative
* number otherwise.
diff --git a/java/lang/Class.java b/java/lang/Class.java
index c5ec1536d..ad51044c3 100644
--- a/java/lang/Class.java
+++ b/java/lang/Class.java
@@ -1,5 +1,5 @@
/* Class.java -- Representation of a Java class.
- Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
Free Software Foundation
This file is part of GNU Classpath.
@@ -104,6 +104,23 @@ public final class Class<T>
*/
private static final long serialVersionUID = 3206093459760846163L;
+ /**
+ * Flag indicating a synthetic member.
+ * Note that this duplicates a constant in Modifier.
+ */
+ private static final int SYNTHETIC = 0x1000;
+
+ /**
+ * Flag indiciating an annotation class.
+ */
+ private static final int ANNOTATION = 0x2000;
+
+ /**
+ * Flag indicating an enum constant or an enum class.
+ * Note that this duplicates a constant in Modifier.
+ */
+ private static final int ENUM = 0x4000;
+
/** The class signers. */
private Object[] signers = null;
/** The class protection domain. */
@@ -1409,7 +1426,8 @@ public final class Class<T>
*/
public boolean isEnum()
{
- return VMClass.isEnum(this);
+ int mod = VMClass.getModifiers (this, true);
+ return (mod & ENUM) != 0;
}
/**
@@ -1421,7 +1439,8 @@ public final class Class<T>
*/
public boolean isSynthetic()
{
- return VMClass.isSynthetic(this);
+ int mod = VMClass.getModifiers (this, true);
+ return (mod & SYNTHETIC) != 0;
}
/**
@@ -1432,7 +1451,8 @@ public final class Class<T>
*/
public boolean isAnnotation()
{
- return VMClass.isAnnotation(this);
+ int mod = VMClass.getModifiers (this, true);
+ return (mod & ANNOTATION) != 0;
}
/**
diff --git a/java/lang/ClassLoader.java b/java/lang/ClassLoader.java
index 4cdfe9299..3d7c32cc9 100644
--- a/java/lang/ClassLoader.java
+++ b/java/lang/ClassLoader.java
@@ -469,7 +469,7 @@ public abstract class ClassLoader
domain = StaticData.defaultProtectionDomain;
return VMClassLoader.defineClassWithTransformers(this, name, data, offset,
- len, domain);
+ len, domain);
}
/**
diff --git a/java/lang/Package.java b/java/lang/Package.java
index c0ed28a35..1141a0722 100644
--- a/java/lang/Package.java
+++ b/java/lang/Package.java
@@ -1,5 +1,6 @@
/* Package.java -- information about a package
- Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
diff --git a/java/lang/StringBuilder.java b/java/lang/StringBuilder.java
index 1eb36bfaf..95d04d1e7 100644
--- a/java/lang/StringBuilder.java
+++ b/java/lang/StringBuilder.java
@@ -1062,7 +1062,7 @@ public final class StringBuilder
if (count < value.length)
{
char[] newValue = new char[count];
- System.arraycopy(value, 0, newValue, 0, count);
+ VMSystem.arraycopy(value, 0, newValue, 0, count);
value = newValue;
}
}
diff --git a/java/lang/Thread.java b/java/lang/Thread.java
index 99c8381aa..55d134fe6 100644
--- a/java/lang/Thread.java
+++ b/java/lang/Thread.java
@@ -1065,7 +1065,9 @@ public class Thread implements Runnable
* <li>If this thread has its own handler, this is returned.</li>
* <li>If not, then the handler of the thread's <code>ThreadGroup</code>
* object is returned.</li>
- * <li>If both are unavailable, then <code>null</code> is returned.</li>
+ * <li>If both are unavailable, then <code>null</code> is returned
+ * (which can only happen when the thread was terminated since
+ * then it won't have an associated thread group anymore).</li>
* </ul>
*
* @return the appropriate <code>UncaughtExceptionHandler</code> or
@@ -1074,7 +1076,7 @@ public class Thread implements Runnable
*/
public UncaughtExceptionHandler getUncaughtExceptionHandler()
{
- return exceptionHandler;
+ return exceptionHandler != null ? exceptionHandler : group;
}
/**
diff --git a/java/security/KeyStore.java b/java/security/KeyStore.java
index cb409f6bc..e31e8a6c9 100644
--- a/java/security/KeyStore.java
+++ b/java/security/KeyStore.java
@@ -212,7 +212,7 @@ public class KeyStore
/**
* Returns the default KeyStore type. This method looks up the
* type in &lt;JAVA_HOME&gt;/lib/security/java.security with the
- * property "keystore.type" or if that fails then "jks" .
+ * property "keystore.type" or if that fails then "gkr" .
*/
public static final String getDefaultType()
{
@@ -221,7 +221,7 @@ public class KeyStore
String tmp = Security.getProperty("keystore.type");
if (tmp == null)
- tmp = "jks";
+ tmp = "gkr";
return tmp;
}
diff --git a/java/security/SecureRandom.java b/java/security/SecureRandom.java
index 5ac9a4a8c..d403d4964 100644
--- a/java/security/SecureRandom.java
+++ b/java/security/SecureRandom.java
@@ -38,11 +38,19 @@ exception statement from your version. */
package java.security;
+import gnu.classpath.SystemProperties;
import gnu.java.security.Engine;
+import gnu.java.security.action.GetSecurityPropertyAction;
import gnu.java.security.jce.prng.Sha160RandomSpi;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Enumeration;
import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* An interface to a cryptographically secure pseudo-random number
@@ -74,6 +82,8 @@ public class SecureRandom extends Random
byte[] state = null;
private String algorithm;
+ private boolean isSeeded = false;
+
// Constructors.
// ------------------------------------------------------------------------
@@ -303,6 +313,7 @@ public class SecureRandom extends Random
public void setSeed(byte[] seed)
{
secureRandomSpi.engineSetSeed(seed);
+ isSeeded = true;
}
/**
@@ -330,6 +341,7 @@ public class SecureRandom extends Random
(byte) (0xff & seed)
};
secureRandomSpi.engineSetSeed(tmp);
+ isSeeded = true;
}
}
@@ -341,6 +353,8 @@ public class SecureRandom extends Random
*/
public void nextBytes(byte[] bytes)
{
+ if (!isSeeded)
+ setSeed(getSeed(32));
randomBytesUsed += bytes.length;
counter++;
secureRandomSpi.engineNextBytes(bytes);
@@ -386,10 +400,8 @@ public class SecureRandom extends Random
public static byte[] getSeed(int numBytes)
{
byte[] tmp = new byte[numBytes];
-
- new Random().nextBytes(tmp);
+ generateSeed(tmp);
return tmp;
- //return secureRandomSpi.engineGenerateSeed( numBytes );
}
/**
@@ -404,4 +416,64 @@ public class SecureRandom extends Random
return secureRandomSpi.engineGenerateSeed(numBytes);
}
+ // Seed methods.
+
+ private static final String SECURERANDOM_SOURCE = "securerandom.source";
+ private static final String JAVA_SECURITY_EGD = "java.security.egd";
+ private static final Logger logger = Logger.getLogger(SecureRandom.class.getName());
+
+ private static int generateSeed(byte[] buffer)
+ {
+ return generateSeed(buffer, 0, buffer.length);
+ }
+
+ private static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ URL sourceUrl = null;
+ String urlStr = null;
+
+ GetSecurityPropertyAction action = new GetSecurityPropertyAction(SECURERANDOM_SOURCE);
+ try
+ {
+ urlStr = (String) AccessController.doPrivileged(action);
+ if (urlStr != null)
+ sourceUrl = new URL(urlStr);
+ }
+ catch (MalformedURLException ignored)
+ {
+ logger.log(Level.WARNING, SECURERANDOM_SOURCE + " property is malformed: {0}",
+ urlStr);
+ }
+
+ if (sourceUrl == null)
+ {
+ try
+ {
+ urlStr = SystemProperties.getProperty(JAVA_SECURITY_EGD);
+ if (urlStr != null)
+ sourceUrl = new URL(urlStr);
+ }
+ catch (MalformedURLException mue)
+ {
+ logger.log(Level.WARNING, JAVA_SECURITY_EGD + " property is malformed: {0}",
+ urlStr);
+ }
+ }
+
+ if (sourceUrl != null)
+ {
+ try
+ {
+ InputStream in = sourceUrl.openStream();
+ return in.read(buffer, offset, length);
+ }
+ catch (IOException ioe)
+ {
+ logger.log(Level.FINE, "error reading random bytes", ioe);
+ }
+ }
+
+ // If we get here, we did not get any seed from a property URL.
+ return VMSecureRandom.generateSeed(buffer, offset, length);
+ }
}
diff --git a/java/security/Security.java b/java/security/Security.java
index 8cc6c8367..d3d2c1ebc 100644
--- a/java/security/Security.java
+++ b/java/security/Security.java
@@ -101,7 +101,12 @@ public final class Security
System.err.println
(" Falling back to standard GNU security provider");
}
+ // Note that this matches our classpath.security file.
providers.addElement (new gnu.java.security.provider.Gnu());
+ providers.addElement(new gnu.javax.crypto.jce.GnuCrypto());
+ providers.addElement(new gnu.javax.crypto.jce.GnuSasl());
+ providers.addElement(new gnu.javax.net.ssl.provider.Jessie());
+ providers.addElement(new gnu.javax.security.auth.callback.GnuCallbacks());
}
}
// This class can't be instantiated.
diff --git a/java/sql/Array.java b/java/sql/Array.java
index 2cc1aa130..cdd60a42f 100644
--- a/java/sql/Array.java
+++ b/java/sql/Array.java
@@ -1,5 +1,5 @@
/* Array.java -- Interface for accessing SQL array object
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -87,22 +87,22 @@ public interface Array
Object getArray(Map<String, Class<?>> map) throws SQLException;
/**
- * Returns a portion of this array starting at <code>index</code>
+ * Returns a portion of this array starting at <code>start</code>
* into the array and continuing for <code>count</code>
* elements. Fewer than the requested number of elements will be
* returned if the array does not contain the requested number of elements.
* The object returned will be an array of Java objects of
* the appropriate types.
*
- * @param index The offset into this array to start returning elements from.
+ * @param start The offset into this array to start returning elements from.
* @param count The requested number of elements to return.
* @return The requested portion of the array.
* @exception SQLException If an error occurs.
*/
- Object getArray(long index, int count) throws SQLException;
+ Object getArray(long start, int count) throws SQLException;
/**
- * This method returns a portion of this array starting at <code>index</code>
+ * This method returns a portion of this array starting at <code>start</code>
* into the array and continuing for <code>count</code>
* elements. Fewer than the requested number of elements will be
* returned if the array does not contain the requested number of elements.
@@ -110,13 +110,13 @@ public interface Array
* <code>Map</code> will be used for overriding selected SQL type to
* Java class mappings.
*
- * @param index The offset into this array to start returning elements from.
+ * @param start The offset into this array to start returning elements from.
* @param count The requested number of elements to return.
* @param map A mapping of SQL types to Java classes.
* @return The requested portion of the array.
* @exception SQLException If an error occurs.
*/
- Object getArray(long index, int count, Map<String, Class<?>> map)
+ Object getArray(long start, int count, Map<String, Class<?>> map)
throws SQLException;
/**
@@ -148,24 +148,24 @@ public interface Array
/**
* This method returns a portion of the array as a <code>ResultSet</code>.
- * The returned portion will start at <code>index</code> into the
+ * The returned portion will start at <code>start</code> into the
* array and up to <code>count</code> elements will be returned.
* <p>
* Each row of the result set will have two columns. The first will be
* the index into the array of that row's contents. The second will be
* the actual value of that array element.
*
- * @param index The index into the array to start returning elements from.
+ * @param start The index into the array to start returning elements from.
* @param count The requested number of elements to return.
* @return The requested elements of this array as a <code>ResultSet</code>.
* @exception SQLException If an error occurs.
* @see ResultSet
*/
- ResultSet getResultSet(long index, int count) throws SQLException;
+ ResultSet getResultSet(long start, int count) throws SQLException;
/**
* This method returns a portion of the array as a <code>ResultSet</code>.
- * The returned portion will start at <code>index</code> into the
+ * The returned portion will start at <code>start</code> into the
* array and up to <code>count</code> elements will be returned.
*
* <p> Each row of the result set will have two columns. The first will be
@@ -174,13 +174,13 @@ public interface Array
* will be used to override selected default mappings of SQL types to
* Java classes.</p>
*
- * @param index The index into the array to start returning elements from.
+ * @param start The index into the array to start returning elements from.
* @param count The requested number of elements to return.
* @param map A mapping of SQL types to Java classes.
* @return The requested elements of this array as a <code>ResultSet</code>.
* @exception SQLException If an error occurs.
* @see ResultSet
*/
- ResultSet getResultSet(long index, int count, Map<String, Class<?>> map)
+ ResultSet getResultSet(long start, int count, Map<String, Class<?>> map)
throws SQLException;
}
diff --git a/java/sql/Blob.java b/java/sql/Blob.java
index 616839d01..c662aad5f 100644
--- a/java/sql/Blob.java
+++ b/java/sql/Blob.java
@@ -1,5 +1,5 @@
/* Blob.java -- Access a SQL Binary Large OBject.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,48 +41,51 @@ import java.io.InputStream;
import java.io.OutputStream;
/**
- * This interface specified methods for accessing a SQL BLOB (Binary
- * Large OBject) type.
- *
+ * This interface specified methods for accessing a SQL BLOB (Binary Large
+ * OBject) type.
+ *
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.2
*/
-public interface Blob
+public interface Blob
{
/**
- * This method returns the number of bytes in the BLOB.
- *
- * @return The number of bytes in the BLOB.
+ * This method returns the number of bytes in this <code>Blob</code>.
+ *
+ * @return The number of bytes in this <code>Blob</code>.
* @exception SQLException If an error occurs.
*/
long length() throws SQLException;
/**
- * This method returns up to the requested bytes of this BLOB as a
- * <code>byte</code> array.
- *
- * @param pos The index into the BLOB to start returning bytes from.
- * @param length The requested number of bytes to return.
- * @return The requested bytes from the BLOB.
+ * This method returns up to the requested bytes of this <code>Blob</code>
+ * as a <code>byte</code> array.
+ *
+ * @param start The index into this <code>Blob</code> to start returning
+ * bytes from.
+ * @param count The requested number of bytes to return.
+ * @return The requested bytes from this <code>Blob</code>.
* @exception SQLException If an error occurs.
*/
- byte[] getBytes(long pos, int length) throws SQLException;
+ byte[] getBytes(long start, int count) throws SQLException;
/**
- * This method returns a stream that will read the bytes of the BLOB.
- *
- * @return A stream that will read the bytes of the BLOB.
+ * This method returns a stream that will read the bytes of this
+ * <code>Blob</code>.
+ *
+ * @return A stream that will read the bytes of this <code>Blob</code>.
* @exception SQLException If an error occurs.
*/
InputStream getBinaryStream() throws SQLException;
/**
- * This method returns the index into the BLOB at which the first instance
- * of the specified bytes occur. The searching starts at the specified
- * index into the BLOB.
- *
+ * This method returns the index into this <code>Blob</code> at which the
+ * first instance of the specified bytes occur. The searching starts at the
+ * specified index into this <code>Blob</code>.
+ *
* @param pattern The byte pattern to search for.
- * @param offset The index into the BLOB to starting searching for the pattern.
+ * @param start The index into this <code>Blob</code> to start searching for
+ * the pattern.
* @return The offset at which the pattern is first found, or -1 if the
* pattern is not found.
* @exception SQLException If an error occurs.
@@ -90,14 +93,15 @@ public interface Blob
long position(byte[] pattern, long start) throws SQLException;
/**
- * This method returns the index into the BLOB at which the first instance
- * of the specified pattern occurs. The searching starts at the specified
- * index into this BLOB. The bytes in the specified <code>Blob</code> are
- * used as the search pattern.
- *
+ * This method returns the index into this <code>Blob</code> at which the
+ * first instance of the specified pattern occurs. The searching starts at the
+ * specified index into this <code>Blob</code>. The bytes in the specified
+ * <code>Blob</code> are used as the search pattern.
+ *
* @param pattern The <code>Blob</code> containing the byte pattern to
- * search for.
- * @param offset The index into the BLOB to starting searching for the pattern.
+ * search for.
+ * @param start The index into this <code>Blob</code> to start searching for
+ * the pattern.
* @return The offset at which the pattern is first found, or -1 if the
* pattern is not found.
* @exception SQLException If an error occurs.
@@ -105,27 +109,49 @@ public interface Blob
long position(Blob pattern, long start) throws SQLException;
/**
+ * Writes the specified data into this <code>Blob</code>, starting at the
+ * specified index.
+ *
+ * @param start The index at which the writing starts.
+ * @param bytes The data to write.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- int setBytes(long pos, byte[] bytes) throws SQLException;
+ int setBytes(long start, byte[] bytes) throws SQLException;
/**
+ * Writes a portion of the specified data into this <code>Blob</code>,
+ * starting at the specified index.
+ *
+ * @param startWrite The index into this <code>Blob</code> at which writing
+ * starts.
+ * @param bytes The data to write a portion of.
+ * @param startRead The offset into the data where the portion to copy starts.
+ * @param count The number of bytes to write.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- int setBytes(long pos, byte[] bytes, int offset, int len)
- throws SQLException;
+ int setBytes(long startWrite, byte[] bytes, int startRead, int count)
+ throws SQLException;
/**
+ * Returns a binary stream that writes into this <code>Blob</code>,
+ * starting at the specified index.
+ *
+ * @param start The index at which the writing starts.
+ * @return A binary stream to write into this <code>Blob</code>.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- OutputStream setBinaryStream(long pos) throws SQLException;
+ OutputStream setBinaryStream(long start) throws SQLException;
/**
+ * Truncates this <code>Blob</code> to be at most the specified number of
+ * bytes long.
+ *
+ * @param count The length this <code>Blob</code> is truncated to.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- void truncate(long len) throws SQLException;
+ void truncate(long count) throws SQLException;
}
diff --git a/java/sql/CallableStatement.java b/java/sql/CallableStatement.java
index 765e9b633..e605b381d 100644
--- a/java/sql/CallableStatement.java
+++ b/java/sql/CallableStatement.java
@@ -1,5 +1,5 @@
/* CallableStatement.java -- A statement for calling stored procedures.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -56,10 +56,10 @@ public interface CallableStatement extends PreparedStatement
* of the specified SQL type.
*
* @param index The index of the parameter to register as output.
- * @param type The SQL type value from <code>Types</code>.
+ * @param sqlType The SQL type value from <code>Types</code>.
* @exception SQLException If an error occurs.
*/
- void registerOutParameter(int parameterIndex, int sqlType)
+ void registerOutParameter(int index, int sqlType)
throws SQLException;
/**
@@ -67,11 +67,11 @@ public interface CallableStatement extends PreparedStatement
* of the specified SQL type and scale.
*
* @param index The index of the parameter to register as output.
- * @param type The SQL type value from <code>Types</code>.
+ * @param sqlType The SQL type value from <code>Types</code>.
* @param scale The scale of the value that will be returned.
* @exception SQLException If an error occurs.
*/
- void registerOutParameter(int parameterIndex, int sqlType, int scale)
+ void registerOutParameter(int index, int sqlType, int scale)
throws SQLException;
/**
@@ -92,7 +92,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>String</code>.
* @exception SQLException If an error occurs.
*/
- String getString(int parameterIndex) throws SQLException;
+ String getString(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -102,7 +102,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>boolean</code>.
* @exception SQLException If an error occurs.
*/
- boolean getBoolean(int parameterIndex) throws SQLException;
+ boolean getBoolean(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -112,7 +112,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>byte</code>.
* @exception SQLException If an error occurs.
*/
- byte getByte(int parameterIndex) throws SQLException;
+ byte getByte(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -122,7 +122,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>short</code>.
* @exception SQLException If an error occurs.
*/
- short getShort(int parameterIndex) throws SQLException;
+ short getShort(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -132,7 +132,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>int</code>.
* @exception SQLException If an error occurs.
*/
- int getInt(int parameterIndex) throws SQLException;
+ int getInt(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -142,7 +142,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>long</code>.
* @exception SQLException If an error occurs.
*/
- long getLong(int parameterIndex) throws SQLException;
+ long getLong(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -152,7 +152,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>float</code>.
* @exception SQLException If an error occurs.
*/
- float getFloat(int parameterIndex) throws SQLException;
+ float getFloat(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -162,31 +162,31 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>double</code>.
* @exception SQLException If an error occurs.
*/
- double getDouble(int parameterIndex) throws SQLException;
+ double getDouble(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
* <code>BigDecimal</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @param scale The number of digits to the right of the decimal to return.
* @return The parameter value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
- * @deprecated Use getBigDecimal(int parameterIndex)
- * or getBigDecimal(String parameterName) instead.
+ * @deprecated Use getBigDecimal(int index)
+ * or getBigDecimal(String name) instead.
*/
- BigDecimal getBigDecimal(int parameterIndex, int scale)
+ BigDecimal getBigDecimal(int index, int scale)
throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
* byte array.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @return The parameter value as a byte array
* @exception SQLException If an error occurs.
*/
- byte[] getBytes(int parameterIndex) throws SQLException;
+ byte[] getBytes(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -196,7 +196,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
*/
- Date getDate(int parameterIndex) throws SQLException;
+ Date getDate(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -206,7 +206,7 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
*/
- Time getTime(int parameterIndex) throws SQLException;
+ Time getTime(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -216,29 +216,29 @@ public interface CallableStatement extends PreparedStatement
* @return The parameter value as a <code>java.sql.Timestamp</code>.
* @exception SQLException If an error occurs.
*/
- Timestamp getTimestamp(int parameterIndex) throws SQLException;
+ Timestamp getTimestamp(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
* <code>Object</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @return The parameter value as an <code>Object</code>.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- Object getObject(int parameterIndex) throws SQLException;
+ Object getObject(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
* <code>BigDecimal</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @return The parameter value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- BigDecimal getBigDecimal(int parameterIndex) throws SQLException;
+ BigDecimal getBigDecimal(int index) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -289,7 +289,7 @@ public interface CallableStatement extends PreparedStatement
* This method returns the value of the specified parameter as a Java
* <code>Array</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @return The parameter value as a <code>Array</code>.
* @exception SQLException If an error occurs.
* @since 1.2
@@ -300,25 +300,25 @@ public interface CallableStatement extends PreparedStatement
* This method returns the value of the specified parameter as a Java
* <code>java.sql.Date</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @param cal The <code>Calendar</code> to use for timezone and locale.
* @return The parameter value as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- Date getDate(int parameterIndex, Calendar cal) throws SQLException;
+ Date getDate(int index, Calendar cal) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
* <code>java.sql.Time</code>.
*
- * @param parameterIndex The index of the parameter to return.
+ * @param index The index of the parameter to return.
* @param cal The <code>Calendar</code> to use for timezone and locale.
* @return The parameter value as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- Time getTime(int parameterIndex, Calendar cal) throws SQLException;
+ Time getTime(int index, Calendar cal) throws SQLException;
/**
* This method returns the value of the specified parameter as a Java
@@ -329,7 +329,7 @@ public interface CallableStatement extends PreparedStatement
* @exception SQLException If an error occurs.
* @since 1.2
*/
- Timestamp getTimestamp(int parameterIndex, Calendar cal)
+ Timestamp getTimestamp(int index, Calendar cal)
throws SQLException;
/**
@@ -337,25 +337,24 @@ public interface CallableStatement extends PreparedStatement
* of the specified SQL type.
*
* @param index The index of the parameter to register as output.
- * @param type The SQL type value from <code>Types</code>.
- * @param name The user defined data type name.
+ * @param sqlType The SQL type value from <code>Types</code>.
+ * @param typeName The user defined data type name.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- void registerOutParameter(int paramIndex, int sqlType,
- String typeName)
+ void registerOutParameter(int index, int sqlType, String typeName)
throws SQLException;
/**
* This method registers the specified parameter as an output parameter
* of the specified SQL type.
*
- * @param parameterName The name of the parameter to register as output.
+ * @param name The name of the parameter to register as output.
* @param sqlType The SQL type value from <code>Types</code>.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- void registerOutParameter(String parameterName, int sqlType)
+ void registerOutParameter(String name, int sqlType)
throws SQLException;
/**
@@ -363,14 +362,13 @@ public interface CallableStatement extends PreparedStatement
* of the specified SQL type. This version of registerOutParameter is used
* for NUMERIC or DECIMAL types.
*
- * @param parameterName The name of the parameter to register as output.
+ * @param name The name of the parameter to register as output.
* @param sqlType The SQL type value from <code>Types</code>.
* @param scale Number of digits to the right of the decimal point.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- void registerOutParameter(String parameterName, int sqlType,
- int scale)
+ void registerOutParameter(String name, int sqlType, int scale)
throws SQLException;
@@ -380,273 +378,584 @@ public interface CallableStatement extends PreparedStatement
* for user-named or REF types. If the type of the output parameter does
* not have such a type, the typeName argument is ignored.
*
- * @param parameterName The name of the parameter to register as output.
+ * @param name The name of the parameter to register as output.
* @param sqlType The SQL type value from <code>Types</code>.
* @param typeName The SQL structured type name.
* @exception SQLException If an error occurs.
* @since 1.4
*/
- void registerOutParameter(String parameterName, int sqlType,
- String typeName)
+ void registerOutParameter(String name, int sqlType, String typeName)
throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.net.URL</code>.
+ *
+ * @param index The index of the parameter to return.
+ * @return The parameter value as a <code>URL</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- URL getURL(int parameterIndex) throws SQLException;
+ URL getURL(int index) throws SQLException;
/**
+ * This method sets the value of the specified parameter to the specified
+ * <code>java.net.URL</code>
+ *
+ * @param name The name of the parameter to set.
+ * @param value The value the parameter.
* @since 1.4
*/
- void setURL(String parameterName, URL val) throws SQLException;
+ void setURL(String name, URL value) throws SQLException;
/**
+ * This method populates the specified parameter with a SQL NULL value
+ * for the specified type.
+ *
+ * @param name The name of the parameter to set.
+ * @param sqlType The SQL type identifier of the parameter from
+ * <code>Types</code>
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setNull(String parameterName, int sqlType) throws SQLException;
+ void setNull(String name, int sqlType) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>boolean</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setBoolean(String parameterName, boolean x) throws SQLException;
+ void setBoolean(String name, boolean value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>byte</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setByte(String parameterName, byte x) throws SQLException;
+ void setByte(String name, byte value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>short</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setShort(String parameterName, short x) throws SQLException;
+ void setShort(String name, short value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>int</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setInt(String parameterName, int x) throws SQLException;
+ void setInt(String name, int value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>long</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setLong(String parameterName, long x) throws SQLException;
+ void setLong(String name, long value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>float</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setFloat(String parameterName, float x) throws SQLException;
+ void setFloat(String name, float value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>double</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setDouble(String parameterName, double x) throws SQLException;
+ void setDouble(String name, double value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>BigDecimal</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setBigDecimal(String parameterName, BigDecimal x)
+ void setBigDecimal(String name, BigDecimal value)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>String</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setString(String parameterName, String x) throws SQLException;
+ void setString(String name, String value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>byte</code> array value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setBytes(String parameterName, byte[] x) throws SQLException;
+ void setBytes(String name, byte[] value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Date</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setDate(String parameterName, Date x) throws SQLException;
+ void setDate(String name, Date value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Time</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setTime(String parameterName, Time x) throws SQLException;
+ void setTime(String name, Time value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Timestamp</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setTimestamp(String parameterName, Timestamp x)
+ void setTimestamp(String name, Timestamp value)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * ASCII <code>InputStream</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param stream The stream from which the parameter value is read.
+ * @param count The number of bytes in the stream.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setAsciiStream(String parameterName, InputStream x, int length)
+ void setAsciiStream(String name, InputStream stream, int count)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * binary <code>InputStream</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param stream The stream from which the parameter value is read.
+ * @param count The number of bytes in the stream.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setBinaryStream(String parameterName, InputStream x, int length)
+ void setBinaryStream(String name, InputStream stream, int count)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>Object</code> value. The specified SQL object type will be used.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @param sqlType The SQL type to use for the parameter, from
+ * <code>Types</code>
+ * @param scale The scale of the value, for numeric values only.
+ * @exception SQLException If an error occurs.
+ * @see Types
* @since 1.4
*/
- void setObject(String parameterName, Object x, int targetSqlType,
- int scale)
+ void setObject(String name, Object value, int sqlType, int scale)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>Object</code> value. The specified SQL object type will be used.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @param sqlType The SQL type to use for the parameter, from
+ * <code>Types</code>
+ * @exception SQLException If an error occurs.
+ * @see Types
* @since 1.4
*/
- void setObject(String parameterName, Object x, int targetSqlType)
+ void setObject(String name, Object value, int sqlType)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>Object</code> value. The default object type to SQL type mapping
+ * will be used.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setObject(String parameterName, Object x) throws SQLException;
+ void setObject(String name, Object value) throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * character <code>Reader</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param reader The reader from which the parameter value is read.
+ * @param count The number of characters in the stream.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setCharacterStream(String parameterName, Reader reader,
- int length)
+ void setCharacterStream(String name, Reader reader, int count)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Date</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setDate(String parameterName, Date x, Calendar cal)
+ void setDate(String name, Date value, Calendar cal)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Time</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setTime(String parameterName, Time x, Calendar cal)
+ void setTime(String name, Time value, Calendar cal)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.sql.Timestamp</code> value.
+ *
+ * @param name The name of the parameter value to set.
+ * @param value The value of the parameter.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setTimestamp(String parameterName, Timestamp x, Calendar cal)
+ void setTimestamp(String name, Timestamp value, Calendar cal)
throws SQLException;
/**
+ * This method populates the specified parameter with a SQL NULL value
+ * for the specified type.
+ *
+ * @param name The name of the parameter to set.
+ * @param sqlType The SQL type identifier of the parameter from
+ * <code>Types</code>
+ * @param typeName The name of the data type, for user defined types.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setNull(String parameterName, int sqlType, String typeName)
+ void setNull(String name, int sqlType, String typeName)
throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>String</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>String</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- String getString(String parameterName) throws SQLException;
+ String getString(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>boolean</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>boolean</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- boolean getBoolean(String parameterName) throws SQLException;
+ boolean getBoolean(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>byte</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>byte</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- byte getByte(String parameterName) throws SQLException;
+ byte getByte(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>short</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>short</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- short getShort(String parameterName) throws SQLException;
+ short getShort(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>int</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>int</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- int getInt(String parameterName) throws SQLException;
+ int getInt(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>long</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>long</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- long getLong(String parameterName) throws SQLException;
+ long getLong(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>float</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>float</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- float getFloat(String parameterName) throws SQLException;
+ float getFloat(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>double</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>double</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- double getDouble(String parameterName) throws SQLException;
+ double getDouble(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>byte</code> array.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>byte[]</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- byte[] getBytes(String parameterName) throws SQLException;
+ byte[] getBytes(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Date</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>java.sql.Date</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Date getDate(String parameterName) throws SQLException;
+ Date getDate(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Time</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>java.sql.Time</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Time getTime(String parameterName) throws SQLException;
+ Time getTime(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Timestamp</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>java.sql.Timestamp</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Timestamp getTimestamp(String parameterName) throws SQLException;
+ Timestamp getTimestamp(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Object</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>Object</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Object getObject(String parameterName) throws SQLException;
+ Object getObject(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>BigDecimal</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>BigDecimal</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- BigDecimal getBigDecimal(String parameterName) throws SQLException;
+ BigDecimal getBigDecimal(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Object</code> using the specified mapping for conversion from
+ * SQL to Java types.
+ *
+ * @param name The name of the parameter to return.
+ * @param map The mapping to use for conversion from SQL to Java types.
+ * @return The parameter value as an <code>Object</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Object getObject(String parameterName, Map<String, Class<?>> map)
- throws SQLException;
+ Object getObject(String name, Map<String, Class<?>> map) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Ref</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>Ref</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Ref getRef(String parameterName) throws SQLException;
+ Ref getRef(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Blob</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>Blob</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Blob getBlob(String parameterName) throws SQLException;
+ Blob getBlob(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Clob</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>Clob</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Clob getClob(String parameterName) throws SQLException;
+ Clob getClob(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>Array</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>Array</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Array getArray(String parameterName) throws SQLException;
+ Array getArray(String name) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Date</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @return The parameter value as a <code>java.sql.Date</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Date getDate(String parameterName, Calendar cal) throws SQLException;
+ Date getDate(String name, Calendar cal) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Time</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @return The parameter value as a <code>java.sql.Time</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Time getTime(String parameterName, Calendar cal) throws SQLException;
+ Time getTime(String name, Calendar cal) throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.sql.Timestamp</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
+ * @return The parameter value as a <code>java.sql.Timestamp</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Timestamp getTimestamp(String parameterName, Calendar cal)
+ Timestamp getTimestamp(String name, Calendar cal)
throws SQLException;
/**
+ * This method returns the value of the specified parameter as a Java
+ * <code>java.net.URL</code>.
+ *
+ * @param name The name of the parameter to return.
+ * @return The parameter value as a <code>java.net.URL</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- URL getURL(String parameterName) throws SQLException;
+ URL getURL(String name) throws SQLException;
}
diff --git a/java/sql/Clob.java b/java/sql/Clob.java
index 8789da596..53bf6393c 100644
--- a/java/sql/Clob.java
+++ b/java/sql/Clob.java
@@ -1,5 +1,5 @@
/* Clob.java -- Access Character Large OBjects
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,6 +35,7 @@ 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 java.sql;
import java.io.InputStream;
@@ -43,110 +44,144 @@ import java.io.Reader;
import java.io.Writer;
/**
- * This interface contains methods for accessing a SQL CLOB (Character
- * Large OBject) type.
- *
+ * This interface contains methods for accessing a SQL CLOB (Character Large
+ * OBject) type.
+ *
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
-public interface Clob
+public interface Clob
{
- /**
- * This method returns the number of characters in the CLOB.
- *
- * @return The number of characters in the CLOB.
- * @exception SQLException If an error occurs.
- * @since 1.2
- */
+ /**
+ * This method returns the number of characters in this <code>Clob</code>.
+ *
+ * @return The number of characters in this <code>Clob</code>.
+ * @exception SQLException If an error occurs.
+ * @since 1.2
+ */
long length() throws SQLException;
/**
- * This method returns the specified portion of the CLOB as a
- * <code>String</code>.
- *
- * @param offset The index into the CLOB (index values start at 1) to
- * start returning characters from.
- * @param length The requested number of characters to return.
- * @return The requested CLOB section, as a <code>String</code>.
+ * This method returns the specified portion of this <code>Clob</code> as a
+ * <code>String</code>.
+ *
+ * @param start The index into this <code>Clob</code> (index values
+ * start at 1) to start returning characters from.
+ * @param count The requested number of characters to return.
+ * @return The requested <code>Clob</code> section, as a <code>String</code>.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- String getSubString(long pos, int length) throws SQLException;
+ String getSubString(long start, int count) throws SQLException;
/**
- * This method returns a character stream that reads the contents of the
- * CLOB.
- *
- * @return A character stream to read the CLOB's contents.
+ * This method returns a character stream that reads the contents of this
+ * <code>Clob</code>.
+ *
+ * @return A character stream to read this <code>Clob</code>'s contents.
* @exception SQLException If an error occurs.
* @since 1.2
*/
Reader getCharacterStream() throws SQLException;
/**
- * This method returns a byte stream that reads the contents of the
- * CLOB as a series of ASCII bytes.
- *
- * @return A stream to read the CLOB's contents.
+ * This method returns a byte stream that reads the contents of this
+ * <code>Clob</code> as a series of ASCII bytes.
+ *
+ * @return A stream to read this <code>Clob</code>'s contents.
* @exception SQLException If an error occurs.
* @since 1.2
*/
InputStream getAsciiStream() throws SQLException;
/**
- * This method returns the index into the CLOB of the first occurrence of
- * the specified character pattern (supplied by the caller as a
- * <code>String</code>). The search begins at the specified index.
- *
- * @param searchstr The character pattern to search for, passed as a
- * <code>String</code>.
- * @param start. The index into the CLOB to start search (indexes start
- * at 1).
- * @return The index at which the pattern was found (indexes start at 1),
- * or -1 if the pattern was not found.
+ * This method returns the index into this <code>Clob</code> of the first
+ * occurrence of the specified character pattern (supplied by the caller as a
+ * <code>String</code>). The search begins at the specified index.
+ *
+ * @param pattern The character pattern to search for, passed as a
+ * <code>String</code>.
+ * @param start The index into this <code>Clob</code> to start searching
+ * (indices start at 1).
+ * @return The index at which the pattern was found (indices start at 1), or
+ * -1 if the pattern was not found.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- long position(String searchstr, long start) throws SQLException;
+ long position(String pattern, long start) throws SQLException;
/**
- * This method returns the index into the CLOB of the first occurrence of
- * the specified character pattern (supplied by the caller as a
- * <code>Clob</code>). The search begins at the specified index.
- *
- * @param searchstr The character pattern to search for, passed as a
- * <code>Clob</code>.
- * @param start. The index into the CLOB to start search (indexes start
- * at 1).
- * @return The index at which the pattern was found (indexes start at 1),
- * or -1 if the pattern was not found.
+ * This method returns the index into this <code>Clob</code> of the first
+ * occurrence of the specified character pattern (supplied by the caller as a
+ * <code>Clob</code>). The search begins at the specified index.
+ *
+ * @param pattern The character pattern to search for, passed as a
+ * <code>Clob</code>.
+ * @param start The index into this <code>Clob</code> to start searching
+ * (indices start at 1).
+ * @return The index at which the pattern was found (indices start at 1), or
+ * -1 if the pattern was not found.
* @exception SQLException If an error occurs.
* @since 1.2
*/
- long position(Clob searchstr, long start) throws SQLException;
+ long position(Clob pattern, long start) throws SQLException;
/**
+ * Writes the specified string into this <code>Clob</code>, starting at the
+ * specified index.
+ *
+ * @param start The index at which the writing starts.
+ * @param value The string to write.
+ * @return The number of characters written.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- int setString(long pos, String str) throws SQLException;
+ int setString(long start, String value) throws SQLException;
/**
+ * Writes the specified portion of a string into this <code>Clob</code>,
+ * starting at the specified index.
+ *
+ * @param startWrite The index at which the writing starts.
+ * @param value The string to write a portion of.
+ * @param startRead The offset into the string where the portion to copy
+ * starts.
+ * @param count The number of characters to write.
+ * @return The number of characters written.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- int setString(long pos, String str, int offset, int len)
- throws SQLException;
+ int setString(long startWrite, String value, int startRead, int count)
+ throws SQLException;
/**
+ * Returns an ASCII text stream that writes into this <code>Clob</code>,
+ * starting at the specified index.
+ *
+ * @param start The index at which the writing starts.
+ * @return An ASCII text stream to write into this <code>Clob</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- OutputStream setAsciiStream(long pos) throws SQLException;
+ OutputStream setAsciiStream(long start) throws SQLException;
/**
+ * Returns a character stream that writes into this <code>Clob</code>,
+ * starting at the specified index.
+ *
+ * @param start The index at which the writing starts.
+ * @return A character stream to write into this <code>Clob</code>.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- Writer setCharacterStream(long pos) throws SQLException;
+ Writer setCharacterStream(long start) throws SQLException;
/**
+ * Truncates this <code>Clob</code> to be at most the specified number of
+ * characters long.
+ *
+ * @param count The length this <code>Clob</code> is truncated to.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void truncate(long len) throws SQLException;
+ void truncate(long count) throws SQLException;
}
diff --git a/java/sql/Connection.java b/java/sql/Connection.java
index aeecdb127..8dc7544c7 100644
--- a/java/sql/Connection.java
+++ b/java/sql/Connection.java
@@ -1,5 +1,5 @@
/* Connection.java -- Manage a database connection.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -61,7 +61,7 @@ public interface Connection
int TRANSACTION_READ_UNCOMMITTED = 1;
/**
- * This transaction isolation leve indicates that only committed data from
+ * This transaction isolation level indicates that only committed data from
* other transactions will be read. If a transaction reads a row, then
* another transaction commits a change to that row, the first transaction
* would retrieve the changed row on subsequent reads of the same row.
@@ -101,8 +101,8 @@ public interface Connection
* SQL string. This method is designed for use with parameterized
* statements. The default result set type and concurrency will be used.
*
- * @param The SQL statement to use in creating this
- * <code>PreparedStatement</code>.
+ * @param sql The SQL statement to use in creating this
+ * <code>PreparedStatement</code>.
* @return A new <code>PreparedStatement</code>.
* @exception SQLException If an error occurs.
* @see PreparedStatement
@@ -115,8 +115,8 @@ public interface Connection
* stored procedures. The default result set type and concurrency
* will be used.
*
- * @param The SQL statement to use in creating this
- * <code>CallableStatement</code>.
+ * @param sql The SQL statement to use in creating this
+ * <code>CallableStatement</code>.
* @return A new <code>CallableStatement</code>.
* @exception SQLException If an error occurs.
* @see CallableStatement
@@ -127,7 +127,7 @@ public interface Connection
* This method converts the specified generic SQL statement into the
* native grammer of the database this object is connected to.
*
- * @param The JDBC generic SQL statement.
+ * @param sql The JDBC generic SQL statement.
* @return The native SQL statement.
* @exception SQLException If an error occurs.
*/
@@ -139,10 +139,10 @@ public interface Connection
* transaction must be explicitly committed or rolled back.
*
* @param autoCommit <code>true</code> to enable auto commit mode,
- * <code>false</code> to disable it.
+ * <code>false</code> to disable it.
* @exception SQLException If an error occurs.
- * @see commit
- * @see rollback
+ * @see #commit()
+ * @see #rollback()
*/
void setAutoCommit(boolean autoCommit) throws SQLException;
@@ -152,12 +152,10 @@ public interface Connection
* Otherwise a transaction must be explicitly committed or rolled back.
*
* @return <code>true</code> if auto commit mode is enabled,
- * <code>false</code> otherwise.
- *
+ * <code>false</code> otherwise.
* @exception SQLException If an error occurs.
- *
- * @see commit
- * @see rollback
+ * @see #commit()
+ * @see #rollback()
*/
boolean getAutoCommit() throws SQLException;
@@ -207,7 +205,7 @@ public interface Connection
* a transaction is in progress.
*
* @param readOnly <code>true</code> if this connection is read only,
- * <code>false</code> otherwise.
+ * <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
void setReadOnly(boolean readOnly) throws SQLException;
@@ -235,8 +233,8 @@ public interface Connection
* This method returns the name of the catalog in use by this connection,
* if any.
*
- * @return The name of the catalog, or <code>null</code> if one does not
- * exist or catalogs are not supported by this database.
+ * @return The name of the catalog, or <code>null</code> if none
+ * exists or catalogs are not supported by this database.
* @exception SQLException If an error occurs.
*/
String getCatalog() throws SQLException;
@@ -283,8 +281,8 @@ public interface Connection
* <code>ResultSet</code> class.
*
* @param resultSetType The type of result set to use for this statement.
- * @param resultSetConcurrency. The type of concurrency to be used in
- * the result set for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
* @return A new <code>Statement</code> object.
* @exception SQLException If an error occurs.
* @see Statement
@@ -300,11 +298,11 @@ public interface Connection
* Valid values for these parameters are specified in the
* <code>ResultSet</code> class.
*
- * @param The SQL statement to use in creating this
- * <code>PreparedStatement</code>.
+ * @param sql The SQL statement to use in creating this
+ * <code>PreparedStatement</code>.
* @param resultSetType The type of result set to use for this statement.
- * @param resultSetConcurrency. The type of concurrency to be used in
- * the result set for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
* @return A new <code>PreparedStatement</code>.
* @exception SQLException If an error occurs.
* @see PreparedStatement
@@ -320,11 +318,11 @@ public interface Connection
* will be used. Valid values for these parameters are specified in the
* <code>ResultSet</code> class.
*
- * @param The SQL statement to use in creating this
- * <code>PreparedStatement</code>.
+ * @param sql The SQL statement to use in creating this
+ * <code>PreparedStatement</code>.
* @param resultSetType The type of result set to use for this statement.
- * @param resultSetConcurrency. The type of concurrency to be used in
- * the result set for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
* @return A new <code>CallableStatement</code>.
* @exception SQLException If an error occurs.
* @see CallableStatement
@@ -353,48 +351,130 @@ public interface Connection
void setTypeMap(Map<String, Class<?>> map) throws SQLException;
/**
+ * Sets the default holdability of <code>ResultSet</code>S that are created
+ * from <code>Statement</code>S using this <code>Connection</code>.
+ *
+ * @param holdability The default holdability value to set, this must be one
+ * of <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+ * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+ * @exception SQLException If an error occurs.
+ * @see ResultSet
* @since 1.4
*/
void setHoldability(int holdability) throws SQLException;
/**
+ * Gets the default holdability of <code>ResultSet</code>S that are created
+ * from <code>Statement</code>S using this <code>Connection</code>.
+ *
+ * @return The current default holdability value, this must be one of
+ * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
+ * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+ * @exception SQLException If an error occurs.
+ * @see ResultSet
* @since 1.4
*/
int getHoldability() throws SQLException;
/**
+ * Creates a new unnamed savepoint for this <code>Connection</code>
+ *
+ * @return The <code>Savepoint</code> object representing the savepoint.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
Savepoint setSavepoint() throws SQLException;
/**
+ * Creates a new savepoint with the specifiend name for this
+ * <code>Connection</code>.
+ *
+ * @param name The name of the savepoint.
+ * @return The <code>Savepoint</code> object representing the savepoint.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
Savepoint setSavepoint(String name) throws SQLException;
/**
+ * Undoes all changes made after the specified savepoint was set.
+ *
+ * @param savepoint The safepoint to roll back to.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
void rollback(Savepoint savepoint) throws SQLException;
/**
+ * Removes the specified savepoint from this <code>Connection</code>.
+ * Refering to a savepoint after it was removed is an error and will throw an
+ * SQLException.
+ *
+ * @param savepoint The savepoint to release.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
void releaseSavepoint(Savepoint savepoint) throws SQLException;
/**
+ * This method creates a new SQL statement with the specified type,
+ * concurrency and holdability, instead of using the defaults. Valid values
+ * for these parameters are specified in the <code>ResultSet</code> class.
+ *
+ * @param resultSetType The type of result set to use for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
+ * @param resultSetHoldability The type of holdability to be usd in the
+ * result set for this statement.
+ * @return A new <code>Statement</code>
+ * @exception SQLException If an error occurs.
+ * @see ResultSet
* @since 1.4
*/
Statement createStatement(int resultSetType, int
resultSetConcurrency, int resultSetHoldability) throws SQLException;
/**
+ * This method creates a new <code>PreparedStatement</code> for the specified
+ * SQL string. This method is designed for use with parameterized
+ * statements. The specified result set type, concurrency and holdability
+ * will be used. Valid values for these parameters are specified in the
+ * <code>ResultSet</code> class.
+ *
+ * @param sql The SQL statement to use in creating this
+ * <code>PreparedStatement</code>.
+ * @param resultSetType The type of result set to use for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
+ * @param resultSetHoldability The type of holdability to be usd in the
+ * result set for this statement.
+ * @return A new <code>PreparedStatement</code>.
+ * @exception SQLException If an error occurs.
+ * @see PreparedStatement
+ * @see ResultSet
* @since 1.4
*/
PreparedStatement prepareStatement(String sql, int resultSetType, int
resultSetConcurrency, int resultSetHoldability) throws SQLException;
/**
+ * This method creates a new <code>CallableStatement</code> for the
+ * specified SQL string. Thie method is designed to be used with
+ * stored procedures. The specified result set type, concurrency and
+ * holdability will be used. Valid values for these parameters are specified
+ * in the <code>ResultSet</code> class.
+ *
+ * @param sql The SQL statement to use in creating this
+ * <code>PreparedStatement</code>.
+ * @param resultSetType The type of result set to use for this statement.
+ * @param resultSetConcurrency The type of concurrency to be used in
+ * the result set for this statement.
+ * @param resultSetHoldability The type of holdability to be used in the
+ * result set for this statement.
+ * @return A new <code>CallableStatement</code>.
+ * @exception SQLException If an error occurs.
+ * @see CallableStatement
+ * @see ResultSet
* @since 1.4
*/
CallableStatement prepareCall(String sql, int resultSetType, int
diff --git a/java/sql/DatabaseMetaData.java b/java/sql/DatabaseMetaData.java
index d34c4e2f9..48c2d9afc 100644
--- a/java/sql/DatabaseMetaData.java
+++ b/java/sql/DatabaseMetaData.java
@@ -1,5 +1,5 @@
/* DatabaseMetaData.java -- Information about the database itself.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -256,10 +256,19 @@ public interface DatabaseMetaData
*/
short tableIndexOther = 3;
+ /**
+ * A NULL value is not allowed for this attribute.
+ */
short attributeNoNulls = 0;
+ /**
+ * A NULL value is allowed for this attribute.
+ */
short attributeNullable = 1;
+ /**
+ * It is unknown whether or not NULL values are allowed for this attribute.
+ */
short attributeNullableUnknown = 2;
int sqlStateXOpen = 1;
@@ -1395,12 +1404,12 @@ public interface DatabaseMetaData
* or "" to return procedures from all catalogs.
* @param schemaPattern A schema pattern for the schemas to return stored
* procedures from, or "" to return procedures from all schemas.
- * @param namePattern The pattern of procedures names to return.
+ * @param procedurePattern The pattern of procedure names to return.
* @returns A <code>ResultSet</code> with all the requested procedures.
* @exception SQLException If an error occurs.
*/
ResultSet getProcedures(String catalog, String schemaPattern, String
- procedureNamePattern) throws SQLException;
+ procedurePattern) throws SQLException;
/**
* This method returns a list of the parameter and result columns for
@@ -1436,13 +1445,13 @@ public interface DatabaseMetaData
* or "" to return procedures from all catalogs.
* @param schemaPattern A schema pattern for the schemas to return stored
* procedures from, or "" to return procedures from all schemas.
- * @param namePattern The pattern of procedures names to return.
+ * @param procedurePattern The pattern of procedures names to return.
* @param columnPattern The pattern of column names to return.
* @returns A <code>ResultSet</code> with all the requested procedures.
* @exception SQLException If an error occurs.
*/
ResultSet getProcedureColumns(String catalog, String schemaPattern,
- String procedureNamePattern, String columnNamePattern) throws
+ String procedurePattern, String columnPattern) throws
SQLException;
/**
@@ -1462,13 +1471,13 @@ public interface DatabaseMetaData
* or "" to return tables from all catalogs.
* @param schemaPattern A schema pattern for the schemas to return tables
* from, or "" to return tables from all schemas.
- * @param namePattern The pattern of table names to return.
+ * @param tablePattern The pattern of table names to return.
* @param types The list of table types to include; null returns all types.
* @returns A <code>ResultSet</code> with all the requested tables.
* @exception SQLException If an error occurs.
*/
ResultSet getTables(String catalog, String schemaPattern, String
- tableNamePattern, String[] types) throws SQLException;
+ tablePattern, String[] types) throws SQLException;
/**
* This method returns the list of database schemas as a
@@ -1536,13 +1545,13 @@ public interface DatabaseMetaData
* or "" to return tables from all catalogs.
* @param schemaPattern A schema pattern for the schemas to return
* tables from, or "" to return tables from all schemas.
- * @param namePattern The pattern of tables names to return.
+ * @param tablePattern The pattern of table names to return.
* @param columnPattern The pattern of column names to return.
* @returns A <code>ResultSet</code> with all the requested tables.
* @exception SQLException If an error occurs.
*/
ResultSet getColumns(String catalog, String schemaPattern, String
- tableNamePattern, String columnNamePattern) throws SQLException;
+ tablePattern, String columnPattern) throws SQLException;
/**
* This method returns the access rights that have been granted to the
@@ -1568,13 +1577,13 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
+ * @param tableName The table name to return information for.
* @param columnPattern A pattern of column names to return information for.
* @return A <code>ResultSet</code> with all the requested privileges.
* @exception SQLException If an error occurs.
*/
ResultSet getColumnPrivileges(String catalog, String schema, String
- table, String columnNamePattern) throws SQLException;
+ tableName, String columnPattern) throws SQLException;
/**
* This method returns the access rights that have been granted to the
@@ -1597,7 +1606,7 @@ public interface DatabaseMetaData
* @param catalog The catalog to retrieve information from, or the empty string
* to return entities not associated with a catalog, or <code>null</code>
* to return information from all catalogs.
- * @param schema The schema to retrieve information from, or the empty string
+ * @param schemaPattern The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
* @param tablePattern The table name pattern of tables to return
* information for.
@@ -1605,7 +1614,7 @@ public interface DatabaseMetaData
* @exception SQLException If an error occurs.
*/
ResultSet getTablePrivileges(String catalog, String schemaPattern,
- String tableNamePattern) throws SQLException;
+ String tablePattern) throws SQLException;
/**
* This method returns the best set of columns for uniquely identifying
@@ -1634,8 +1643,7 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
- * @param columnPattern A pattern of column names to return information for.
+ * @param tableName The table name to return information for.
* @param scope One of the best row id scope constants from this class.
* @param nullable <code>true</code> to include columns that are nullable,
* <code>false</code> otherwise.
@@ -1643,7 +1651,7 @@ public interface DatabaseMetaData
* @exception SQLException If an error occurs.
*/
ResultSet getBestRowIdentifier(String catalog, String schema,
- String table, int scope, boolean nullable) throws SQLException;
+ String tableName, int scope, boolean nullable) throws SQLException;
/**
* This method returns the set of columns that are automatically updated
@@ -1670,13 +1678,12 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
- * @param columnPattern A pattern of column names to return information for.
+ * @param tableName The table name to return information for
* @return A <code>ResultSet</code> with the version columns.
* @exception SQLException If an error occurs.
*/
ResultSet getVersionColumns(String catalog, String schema,
- String table) throws SQLException;
+ String tableName) throws SQLException;
/**
* This method returns a list of a table's primary key columns. These
@@ -1696,12 +1703,11 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
- * @param columnPattern A pattern of column names to return information for.
+ * @param tableName The table name to return information for.
* @return A <code>ResultSet</code> with the primary key columns.
* @exception SQLException If an error occurs.
*/
- ResultSet getPrimaryKeys(String catalog, String schema, String table)
+ ResultSet getPrimaryKeys(String catalog, String schema, String tableName)
throws SQLException;
/**
@@ -1740,14 +1746,12 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
- *
+ * @param tableName The table name to return information for.
* @return A <code>ResultSet</code> with the foreign key columns.
- *
* @exception SQLException If an error occurs.
*/
ResultSet getImportedKeys(String catalog, String schema,
- String table) throws SQLException;
+ String tableName) throws SQLException;
/**
* This method returns a list of the table's which use this table's
@@ -1786,12 +1790,12 @@ public interface DatabaseMetaData
* to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
+ * @param tableName The table name to return information for.
* @return A <code>ResultSet</code> with the requested information
* @exception SQLException If an error occurs.
*/
ResultSet getExportedKeys(String catalog, String schema,
- String table) throws SQLException;
+ String tableName) throws SQLException;
/**
* This method returns a description of how one table imports another
@@ -1825,26 +1829,30 @@ public interface DatabaseMetaData
* <code>importedKeyNotDeferrable</code>).</li>
* </ol>
*
- * @param primCatalog The catalog to retrieve information from, or the empty string
- * to return entities not associated with a catalog, or <code>null</code>
- * to return information from all catalogs, on the exporting side.
- * @param primSchema The schema to retrieve information from, or the empty string
- * to return entities not associated with a schema, on the exporting side.
- * @param primTable The table name to return information for, on the exporting
- * side.
- * @param forCatalog The catalog to retrieve information from, or the empty string
- * to return entities not associated with a catalog, or <code>null</code>
- * to return information from all catalogs, on the importing side.
- * @param forSchema The schema to retrieve information from, or the empty string
- * to return entities not associated with a schema on the importing side.
- * @param forTable The table name to return information for on the importing
- * side.
+ * @param primaryCatalog The catalog to retrieve information from, or the
+ * empty string to return entities not associated with a catalog, or
+ * <code>null</code> to return information from all catalogs, on the
+ * exporting side.
+ * @param primarySchema The schema to retrieve information from, or the empty
+ * string to return entities not associated with a schema, on the
+ * exporting side.
+ * @param primaryTableName The table name to return information for, on the
+ * exporting side.
+ * @param foreignCatalog The catalog to retrieve information from, or the
+ * empty string to return entities not associated with a catalog,
+ * or <code>null</code> to return information from all catalogs, on
+ * the importing side.
+ * @param foreignSchema The schema to retrieve information from, or the
+ * empty string to return entities not associated with a schema on
+ * the importing side.
+ * @param foreignTableName The table name to return information for on the
+ * importing side.
* @return A <code>ResultSet</code> with the requested information
* @exception SQLException If an error occurs.
*/
ResultSet getCrossReference(String primaryCatalog, String
- primarySchema, String primaryTable, String foreignCatalog, String
- foreignSchema, String foreignTable) throws SQLException;
+ primarySchema, String primaryTableName, String foreignCatalog, String
+ foreignSchema, String foreignTableName) throws SQLException;
/**
* This method returns a list of the SQL types supported by this
@@ -1921,15 +1929,15 @@ public interface DatabaseMetaData
* <code>null</code> to return information from all catalogs.
* @param schema The schema to retrieve information from, or the empty string
* to return entities not associated with a schema.
- * @param table The table name to return information for.
+ * @param tableName The table name to return information for.
* @param unique <code>true</code> to return only unique indexes,
* <code>false</code> otherwise.
- * @param approx <code>true</code> if data values can be approximations,
+ * @param approximate <code>true</code> if data values can be approximations,
* <code>false</code> otherwise.
* @return A <code>ResultSet</code> with the requested index information
* @exception SQLException If an error occurs.
*/
- ResultSet getIndexInfo(String catalog, String schema, String table,
+ ResultSet getIndexInfo(String catalog, String schema, String tableName,
boolean unique, boolean approximate) throws SQLException;
/**
@@ -1954,8 +1962,8 @@ public interface DatabaseMetaData
*
* @param type The desired result type, which is one of the constants
* defined in <code>ResultSet</code>.
- * @param concur The desired concurrency type, which is one of the constants
- * defined in <code>ResultSet</code>.
+ * @param concurrency The desired concurrency type, which is one of the
+ * constants defined in <code>ResultSet</code>.
* @return <code>true</code> if the result set type is supported,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
@@ -2108,8 +2116,8 @@ public interface DatabaseMetaData
* @param catalog The catalog to retrieve information from, or the empty string
* to return entities not associated with a catalog, or <code>null</code>
* to return information from all catalogs.
- * @param schema The schema to retrieve information from, or the empty string
- * to return entities not associated with a schema.
+ * @param schemaPattern The schema to retrieve information from, or the
+ * empty string to return entities not associated with a schema.
* @param typePattern The type name pattern to match.
* @param types The type identifier patterns (from <code>Types</code>) to
* match.
@@ -2117,7 +2125,7 @@ public interface DatabaseMetaData
* @exception SQLException If an error occurs.
*/
ResultSet getUDTs(String catalog, String schemaPattern, String
- typeNamePattern, int[] types) throws SQLException;
+ typePattern, int[] types) throws SQLException;
/**
* This method returns the <code>Connection</code> object that was used
@@ -2129,16 +2137,33 @@ public interface DatabaseMetaData
Connection getConnection() throws SQLException;
/**
+ * This method tests whether the databse supports savepoints.
+ *
+ * @return <code>true</code> if the database supports savepoints,
+ * <code>false</code> if it does not.
+ * @exception SQLException If an error occurs.
+ * @see Savepoint
* @since 1.4
*/
boolean supportsSavepoints() throws SQLException;
/**
+ * This method tests whether the database supports named parameters.
+ *
+ * @return <code>true</code> if the database supports named parameters,
+ * <code>false</code> if it does not.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
boolean supportsNamedParameters() throws SQLException;
/**
+ * This method tests whether the database supports returning multiple
+ * <code>ResultSet</code>S from a <code>CallableStatement</code> at once.
+ *
+ * @return <code>true</code> if the database supports returnig multiple
+ * results at once, <code>false</code> if it does not.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
boolean supportsMultipleOpenResults() throws SQLException;
@@ -2152,47 +2177,78 @@ public interface DatabaseMetaData
* @since 1.4
*/
ResultSet getSuperTypes(String catalog, String schemaPattern,
- String typeNamePattern) throws SQLException;
+ String typePattern) throws SQLException;
/**
* @since 1.4
*/
ResultSet getSuperTables(String catalog, String schemaPattern,
- String tableNamePattern) throws SQLException;
+ String tablePattern) throws SQLException;
/**
* @since 1.4
*/
ResultSet getAttributes(String catalog, String schemaPattern, String
- typeNamePattern, String attributeNamePattern) throws SQLException;
+ typePattern, String attributePattern) throws SQLException;
/**
+ * This method tests if the database supports the specified holdability type.
+ * Valid values for this parameter are specified in the
+ * <code>ResultSet</code> class.
+ *
+ * @param holdability The holdability type to test.
+ * @return <code>true</code> if the database supports the holdability type,
+ * <code>false</code> if it does not.
+ * @exception SQLException If an error occurs.
+ * @see ResultSet
* @since 1.4
*/
boolean supportsResultSetHoldability(int holdability)
throws SQLException;
/**
+ * This method returns the default holdability type of <code>ResultSet</code>S
+ * retrieved from this database. The possible values are specified in the
+ * <code>ResultSet</code> class.
+ *
+ * @return The default holdability type.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
int getResultSetHoldability() throws SQLException;
/**
+ * This method returns the major version number of the database.
+ *
+ * @return The major version number of the database.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
int getDatabaseMajorVersion() throws SQLException;
/**
+ * This method returns the minor version number of the database.
+ *
+ * @return The minor version number of the database.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
int getDatabaseMinorVersion() throws SQLException;
/**
+ * This method returns the major version number of the JDBC driver.
+ *
+ * @return The major version number of the JDBC driver.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
int getJDBCMajorVersion() throws SQLException;
/**
+ * This method returns the minor version number of the JDBC driver.
+ *
+ * @return The minor version number of the database.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
int getJDBCMinorVersion() throws SQLException;
diff --git a/java/sql/Date.java b/java/sql/Date.java
index d429cc826..f4c330709 100644
--- a/java/sql/Date.java
+++ b/java/sql/Date.java
@@ -1,5 +1,5 @@
/* Date.java -- Wrapper around java.util.Date
- Copyright (C) 1999, 2000, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -72,10 +72,10 @@ public class Date extends java.util.Date
/**
* This method initializes a new instance of this class with the
- * specified time value representing the number of seconds since
+ * specified time value representing the number of milliseconds since
* Jan 1, 1970 at 12:00 midnight GMT.
*
- * @param time The time value to intialize this date to.
+ * @param date The time value to intialize this date to.
*/
public Date(long date)
{
diff --git a/java/sql/Driver.java b/java/sql/Driver.java
index 10f83ef2f..277dd1713 100644
--- a/java/sql/Driver.java
+++ b/java/sql/Driver.java
@@ -1,5 +1,5 @@
/* Driver.java -- A JDBC driver
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -68,7 +68,7 @@ public interface Driver
* connection, or <code>null</code> if the URL is not understood.
* @exception SQLException If an error occurs.
*/
- Connection connect(String url, Properties info) throws SQLException;
+ Connection connect(String url, Properties properties) throws SQLException;
/**
* This method tests whether or not the driver believes it can connect to
@@ -76,7 +76,7 @@ public interface Driver
* understands and accepts the URL. It should not necessarily attempt to
* probe the database for a connection.
*
- * @param The database URL string.
+ * @param url The database URL string.
* @return <code>true</code> if the drivers can connect to the database,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
diff --git a/java/sql/DriverManager.java b/java/sql/DriverManager.java
index 5cba6f4bc..7d1ef07c1 100644
--- a/java/sql/DriverManager.java
+++ b/java/sql/DriverManager.java
@@ -1,5 +1,6 @@
/* DriverManager.java -- Manage JDBC drivers
- Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003, 2004, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -292,11 +293,11 @@ public class DriverManager
* This method set the login timeout used by JDBC drivers. This is a
* system-wide parameter that applies to all drivers.
*
- * @param login_timeout The new login timeout value.
+ * @param seconds The new login timeout value.
*/
public static void setLoginTimeout(int seconds)
{
- DriverManager.login_timeout = login_timeout;
+ DriverManager.login_timeout = seconds;
}
/**
@@ -312,20 +313,18 @@ public class DriverManager
/**
* This method sets the log stream in use by JDBC.
*
- * @param log_stream The log stream in use by JDBC.
- *
+ * @param stream The log stream in use by JDBC.
* @deprecated Use <code>setLogWriter</code> instead.
*/
- public static void setLogStream(PrintStream out)
+ public static void setLogStream(PrintStream stream)
{
- DriverManager.log_stream = log_stream;
+ DriverManager.log_stream = stream;
}
/**
* This method returns the log stream in use by JDBC.
*
* @return The log stream in use by JDBC.
- *
* @deprecated Use <code>getLogWriter()</code> instead.
*/
public static PrintStream getLogStream()
@@ -336,7 +335,7 @@ public class DriverManager
/**
* This method prints the specified line to the log stream.
*
- * @param str The string to write to the log stream.
+ * @param message The string to write to the log stream.
*/
public static void println(String message)
{
diff --git a/java/sql/PreparedStatement.java b/java/sql/PreparedStatement.java
index 3aedbc593..ca7eb2c5d 100644
--- a/java/sql/PreparedStatement.java
+++ b/java/sql/PreparedStatement.java
@@ -1,5 +1,5 @@
/* PreparedStatement.java -- Interface for pre-compiled statements.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,6 +48,8 @@ import java.util.Calendar;
* statements. This provides greater efficiency when calling the same
* statement multiple times. Parameters are allowed in a statement,
* providings for maximum reusability.
+ *
+ * <p> Note that in this class parameter indices start at 1, not 0.</p>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
@@ -76,11 +78,12 @@ public interface PreparedStatement extends Statement
* for the specified type.
*
* @param index The index of the parameter to set.
- * @param type The SQL type identifier of the parameter from <code>Types</code>
+ * @param sqlType The SQL type identifier of the parameter from
+ * <code>Types</code>
*
* @exception SQLException If an error occurs.
*/
- void setNull(int parameterIndex, int sqlType) throws SQLException;
+ void setNull(int index, int sqlType) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -90,7 +93,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setBoolean(int parameterIndex, boolean x) throws SQLException;
+ void setBoolean(int index, boolean value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -100,7 +103,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setByte(int parameterIndex, byte x) throws SQLException;
+ void setByte(int index, byte value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -110,7 +113,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setShort(int parameterIndex, short x) throws SQLException;
+ void setShort(int index, short value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -120,7 +123,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setInt(int parameterIndex, int x) throws SQLException;
+ void setInt(int index, int value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -130,7 +133,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setLong(int parameterIndex, long x) throws SQLException;
+ void setLong(int index, long value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -140,7 +143,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setFloat(int parameterIndex, float x) throws SQLException;
+ void setFloat(int index, float value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -150,7 +153,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setDouble(int parameterIndex, double x) throws SQLException;
+ void setDouble(int index, double value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -160,7 +163,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setBigDecimal(int parameterIndex, BigDecimal x) throws
+ void setBigDecimal(int index, BigDecimal value) throws
SQLException;
/**
@@ -171,7 +174,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setString(int parameterIndex, String x) throws SQLException;
+ void setString(int index, String value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -181,7 +184,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setBytes(int parameterIndex, byte[] x) throws SQLException;
+ void setBytes(int index, byte[] value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -191,7 +194,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setDate(int parameterIndex, Date x) throws SQLException;
+ void setDate(int index, Date value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -201,7 +204,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setTime(int parameterIndex, Time x) throws SQLException;
+ void setTime(int index, Time value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -211,7 +214,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setTimestamp(int parameterIndex, Timestamp x)
+ void setTimestamp(int index, Timestamp value)
throws SQLException;
/**
@@ -219,11 +222,11 @@ public interface PreparedStatement extends Statement
* ASCII <code>InputStream</code> value.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
- * @param length The number of bytes in the stream.
+ * @param stream The stream from which the parameter value is read.
+ * @param count The number of bytes in the stream.
* @exception SQLException If an error occurs.
*/
- void setAsciiStream(int parameterIndex, InputStream x, int length)
+ void setAsciiStream(int index, InputStream stream, int count)
throws SQLException;
/**
@@ -231,12 +234,12 @@ public interface PreparedStatement extends Statement
* Unicode UTF-8 <code>InputStream</code> value.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
- * @param length The number of bytes in the stream.
+ * @param stream The stream from which the parameter value is read.
+ * @param count The number of bytes in the stream.
* @exception SQLException If an error occurs.
* @deprecated
*/
- void setUnicodeStream(int parameterIndex, InputStream x, int length)
+ void setUnicodeStream(int index, InputStream stream, int count)
throws SQLException;
/**
@@ -244,11 +247,11 @@ public interface PreparedStatement extends Statement
* binary <code>InputStream</code> value.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
- * @param length The number of bytes in the stream.
+ * @param stream The stream from which the parameter value is read.
+ * @param count The number of bytes in the stream.
* @exception SQLException If an error occurs.
*/
- void setBinaryStream(int parameterIndex, InputStream x, int length)
+ void setBinaryStream(int index, InputStream stream, int count)
throws SQLException;
/**
@@ -265,13 +268,14 @@ public interface PreparedStatement extends Statement
*
* @param index The index of the parameter value to set.
* @param value The value of the parameter.
- * @param type The SQL type to use for the parameter, from <code>Types</code>
+ * @param sqlType The SQL type to use for the parameter, from
+ * <code>Types</code>
* @param scale The scale of the value, for numeric values only.
* @exception SQLException If an error occurs.
* @see Types
*/
- void setObject(int parameterIndex, Object x, int targetSqlType,
- int scale) throws SQLException;
+ void setObject(int index, Object value, int sqlType, int scale)
+ throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -279,11 +283,12 @@ public interface PreparedStatement extends Statement
*
* @param index The index of the parameter value to set.
* @param value The value of the parameter.
- * @param type The SQL type to use for the parameter, from <code>Types</code>
+ * @param sqlType The SQL type to use for the parameter, from
+ * <code>Types</code>
* @exception SQLException If an error occurs.
* @see Types
*/
- void setObject(int parameterIndex, Object x, int targetSqlType)
+ void setObject(int index, Object value, int sqlType)
throws SQLException;
/**
@@ -295,7 +300,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setObject(int parameterIndex, Object x) throws SQLException;
+ void setObject(int index, Object value) throws SQLException;
/**
* This method executes a prepared SQL query.
@@ -319,12 +324,12 @@ public interface PreparedStatement extends Statement
* character <code>Reader</code> value.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
- * @param length The number of bytes in the stream.
+ * @param reader The reader from which the parameter value is read.
+ * @param count The number of characters in the stream.
* @exception SQLException If an error occurs.
*/
- void setCharacterStream(int parameterIndex, Reader reader,
- int length) throws SQLException;
+ void setCharacterStream(int index, Reader reader, int count)
+ throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -332,10 +337,10 @@ public interface PreparedStatement extends Statement
* will be used.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
+ * @param value The <code>Ref</code> used to set the value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setRef(int i, Ref x) throws SQLException;
+ void setRef(int index, Ref value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -343,10 +348,11 @@ public interface PreparedStatement extends Statement
* will be used.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
+ * @param value The <code>Blob</code> used to set the
+ * value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setBlob(int i, Blob x) throws SQLException;
+ void setBlob(int index, Blob value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -354,10 +360,11 @@ public interface PreparedStatement extends Statement
* will be used.
*
* @param index The index of the parameter value to set.
- * @param value The value of the parameter.
+ * @param value The <code>Clob</code> used to set the
+ * value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setClob(int i, Clob x) throws SQLException;
+ void setClob(int index, Clob value) throws SQLException;
/**
* This method sets the specified parameter from the given Java
@@ -368,7 +375,7 @@ public interface PreparedStatement extends Statement
* @param value The value of the parameter.
* @exception SQLException If an error occurs.
*/
- void setArray(int i, Array x) throws SQLException;
+ void setArray(int index, Array value) throws SQLException;
/**
* This method returns meta data for the result set from this statement.
@@ -384,10 +391,10 @@ public interface PreparedStatement extends Statement
*
* @param index The index of the parameter value to set.
* @param value The value of the parameter.
- * @param calendar The <code>Calendar</code> to use for timezone and locale.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
* @exception SQLException If an error occurs.
*/
- void setDate(int parameterIndex, Date x, Calendar cal)
+ void setDate(int index, Date value, Calendar cal)
throws SQLException;
/**
@@ -396,10 +403,10 @@ public interface PreparedStatement extends Statement
*
* @param index The index of the parameter value to set.
* @param value The value of the parameter.
- * @param calendar The <code>Calendar</code> to use for timezone and locale.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
* @exception SQLException If an error occurs.
*/
- void setTime(int parameterIndex, Time x, Calendar cal)
+ void setTime(int index, Time value, Calendar cal)
throws SQLException;
/**
@@ -408,10 +415,10 @@ public interface PreparedStatement extends Statement
*
* @param index The index of the parameter value to set.
* @param value The value of the parameter.
- * @param calendar The <code>Calendar</code> to use for timezone and locale.
+ * @param cal The <code>Calendar</code> to use for timezone and locale.
* @exception SQLException If an error occurs.
*/
- void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+ void setTimestamp(int index, Timestamp value, Calendar cal)
throws SQLException;
/**
@@ -419,19 +426,32 @@ public interface PreparedStatement extends Statement
* for the specified type.
*
* @param index The index of the parameter to set.
- * @param type The SQL type identifier of the parameter from <code>Types</code>
- * @param name The name of the data type, for user defined types.
+ * @param sqlType The SQL type identifier of the parameter from
+ * <code>Types</code>
+ * @param typeName The name of the data type, for user defined types.
* @exception SQLException If an error occurs.
*/
- void setNull(int paramIndex, int sqlType, String typeName)
+ void setNull(int index, int sqlType, String typeName)
throws SQLException;
/**
+ * This method sets the specified parameter from the given Java
+ * <code>java.net.URL</code> value.
+ *
+ * @param index The index of the parameter to set.
+ * @param value The value of the parameter.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void setURL(int parameterIndex, URL x) throws SQLException;
+ void setURL(int index, URL value) throws SQLException;
/**
+ * Returns information about the parameters set on this
+ * <code>PreparedStatement</code> (see {@link ParameterMetaData} for a
+ * detailed description of the provided information).
+ *
+ * @return Meta data for the parameters of this statement.
+ * @see ParameterMetaData
* @since 1.4
*/
ParameterMetaData getParameterMetaData() throws SQLException;
diff --git a/java/sql/ResultSet.java b/java/sql/ResultSet.java
index 442be404e..573deb3e1 100644
--- a/java/sql/ResultSet.java
+++ b/java/sql/ResultSet.java
@@ -1,5 +1,5 @@
/* ResultSet.java -- A SQL statement result set.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -138,7 +138,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>String</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>String</code>.
* @exception SQLException If an error occurs.
*/
@@ -148,7 +148,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>boolean</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>boolean</code>.
* @exception SQLException If an error occurs.
*/
@@ -158,7 +158,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>byte</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>byte</code>.
* @exception SQLException If an error occurs.
*/
@@ -168,7 +168,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>short</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>short</code>.
* @exception SQLException If an error occurs.
*/
@@ -178,7 +178,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>int</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>int</code>.
* @exception SQLException If an error occurs.
*/
@@ -188,7 +188,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>long</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>long</code>.
* @exception SQLException If an error occurs.
*/
@@ -198,7 +198,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>float</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>float</code>.
* @exception SQLException If an error occurs.
*/
@@ -208,7 +208,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>double</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>double</code>.
* @exception SQLException If an error occurs.
*/
@@ -218,7 +218,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>BigDecimal</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @param scale The number of digits to the right of the decimal to return.
* @return The column value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
@@ -231,7 +231,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* byte array.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a byte array
* @exception SQLException If an error occurs.
*/
@@ -241,7 +241,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Date</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
*/
@@ -251,7 +251,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Time</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
*/
@@ -261,7 +261,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Timestamp</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>java.sql.Timestamp</code>.
* @exception SQLException If an error occurs.
*/
@@ -274,7 +274,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as an ASCII <code>InputStream</code>.
* @exception SQLException If an error occurs.
*/
@@ -287,7 +287,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a Unicode UTF-8 <code>InputStream</code>.
* @exception SQLException If an error occurs.
* @deprecated Use getCharacterStream instead.
@@ -301,7 +301,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a raw byte <code>InputStream</code>.
* @exception SQLException If an error occurs.
*/
@@ -311,7 +311,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>String</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>String</code>.
* @exception SQLException If an error occurs.
*/
@@ -321,7 +321,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>boolean</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>boolean</code>.
* @exception SQLException If an error occurs.
*/
@@ -331,7 +331,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>byte</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>byte</code>.
* @exception SQLException If an error occurs.
*/
@@ -341,7 +341,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>short</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>short</code>.
* @exception SQLException If an error occurs.
*/
@@ -351,7 +351,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>int</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>int</code>.
* @exception SQLException If an error occurs.
*/
@@ -361,7 +361,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>long</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>long</code>.
* @exception SQLException If an error occurs.
*/
@@ -371,7 +371,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>float</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>float</code>.
* @exception SQLException If an error occurs.
*/
@@ -381,7 +381,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>double</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>double</code>.
* @exception SQLException If an error occurs.
*/
@@ -391,7 +391,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>BigDecimal</code>.
*
- * @param index The index of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
* @deprecated
@@ -403,7 +403,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* byte array.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a byte array
* @exception SQLException If an error occurs.
*/
@@ -413,7 +413,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Date</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
*/
@@ -423,7 +423,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Time</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
*/
@@ -433,7 +433,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>java.sql.Timestamp</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>java.sql.Timestamp</code>.
* @exception SQLException If an error occurs.
*/
@@ -446,7 +446,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as an ASCII <code>InputStream</code>.
* @exception SQLException If an error occurs.
*/
@@ -459,7 +459,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a Unicode UTF-8 <code>InputStream</code>.
* @exception SQLException If an error occurs.
* @deprecated Use getCharacterStream instead.
@@ -473,7 +473,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a raw byte <code>InputStream</code>.
* @exception SQLException If an error occurs.
*/
@@ -518,7 +518,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>Object</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as an <code>Object</code>.
* @exception SQLException If an error occurs.
*/
@@ -528,7 +528,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>Object</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as an <code>Object</code>.
* @exception SQLException If an error occurs.
*/
@@ -537,7 +537,7 @@ public interface ResultSet
/**
* This method returns the column index of the specified named column.
*
- * @param column The name of the column.
+ * @param columnName The name of the column.
* @return The index of the column.
* @exception SQLException If an error occurs.
*/
@@ -550,7 +550,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as an character <code>Reader</code>.
* @exception SQLException If an error occurs.
*/
@@ -563,7 +563,7 @@ public interface ResultSet
* calling <code>next()</code> or <code>close()</code> on this result set
* will close this stream as well.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as an character <code>Reader</code>.
* @exception SQLException If an error occurs.
*/
@@ -573,7 +573,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>BigDecimal</code>.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return The column value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
*/
@@ -583,7 +583,7 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>BigDecimal</code>.
*
- * @param column The name of the column to return.
+ * @param columnName The name of the column to return.
* @return The column value as a <code>BigDecimal</code>.
* @exception SQLException If an error occurs.
*/
@@ -692,7 +692,7 @@ public interface ResultSet
* This method moves the result set position relative to the current row.
* The offset can be positive or negative.
*
- * @param row The relative row position to move to.
+ * @param rows The number of row positions to move.
* @return <code>true</code> if the current position was changed,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
@@ -713,7 +713,9 @@ public interface ResultSet
* This method provides a hint to the driver about which direction the
* result set will be processed in.
*
- * @param direction The direction in which rows will be processed. (Values?)
+ * @param direction The direction in which rows will be processed. The
+ * allowed values are the <code>FETCH_*</code> constants
+ * defined in this interface.
* @exception SQLException If an error occurs.
*/
void setFetchDirection(int direction) throws SQLException;
@@ -746,7 +748,7 @@ public interface ResultSet
/**
* This method returns the result set type of this result set. This will
- * be one of the TYPE_* constants defined in this interface.
+ * be one of the <code>TYPE_*</code> constants defined in this interface.
*
* @return The result set type.
* @exception SQLException If an error occurs.
@@ -755,7 +757,7 @@ public interface ResultSet
/**
* This method returns the concurrency type of this result set. This will
- * be one of the CONCUR_* constants defined in this interface.
+ * be one of the <code>CONCUR_*</code> constants defined in this interface.
*
* @return The result set concurrency type.
* @exception SQLException If an error occurs.
@@ -800,7 +802,7 @@ public interface ResultSet
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @return index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @exception SQLException If an error occurs.
*/
void updateNull(int columnIndex) throws SQLException;
@@ -810,88 +812,88 @@ public interface ResultSet
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBoolean(int columnIndex, boolean x) throws SQLException;
+ void updateBoolean(int columnIndex, boolean value) throws SQLException;
/**
* This method updates the specified column to have a byte value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateByte(int columnIndex, byte x) throws SQLException;
+ void updateByte(int columnIndex, byte value) throws SQLException;
/**
* This method updates the specified column to have a short value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateShort(int columnIndex, short x) throws SQLException;
+ void updateShort(int columnIndex, short value) throws SQLException;
/**
* This method updates the specified column to have an int value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateInt(int columnIndex, int x) throws SQLException;
+ void updateInt(int columnIndex, int value) throws SQLException;
/**
* This method updates the specified column to have a long value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateLong(int columnIndex, long x) throws SQLException;
+ void updateLong(int columnIndex, long value) throws SQLException;
/**
* This method updates the specified column to have a float value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateFloat(int columnIndex, float x) throws SQLException;
+ void updateFloat(int columnIndex, float value) throws SQLException;
/**
* This method updates the specified column to have a double value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateDouble(int columnIndex, double x) throws SQLException;
+ void updateDouble(int columnIndex, double value) throws SQLException;
/**
* This method updates the specified column to have a BigDecimal value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBigDecimal(int columnIndex, BigDecimal x)
+ void updateBigDecimal(int columnIndex, BigDecimal value)
throws SQLException;
/**
@@ -899,55 +901,55 @@ public interface ResultSet
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateString(int columnIndex, String x) throws SQLException;
+ void updateString(int columnIndex, String value) throws SQLException;
/**
* This method updates the specified column to have a byte array value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBytes(int columnIndex, byte[] x) throws SQLException;
+ void updateBytes(int columnIndex, byte[] value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Date value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateDate(int columnIndex, Date x) throws SQLException;
+ void updateDate(int columnIndex, Date value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Time value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateTime(int columnIndex, Time x) throws SQLException;
+ void updateTime(int columnIndex, Time value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Timestamp value.
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateTimestamp(int columnIndex, Timestamp x)
+ void updateTimestamp(int columnIndex, Timestamp value)
throws SQLException;
/**
@@ -955,12 +957,12 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
+ * @param columnIndex The index of the column to update.
+ * @param stream The stream from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateAsciiStream(int columnIndex, InputStream x, int length)
+ void updateAsciiStream(int columnIndex, InputStream stream, int count)
throws SQLException;
/**
@@ -968,12 +970,12 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
+ * @param columnIndex The index of the column to update.
+ * @param stream The stream from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateBinaryStream(int columnIndex, InputStream x, int length)
+ void updateBinaryStream(int columnIndex, InputStream stream, int count)
throws SQLException;
/**
@@ -981,12 +983,12 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
+ * @param columnIndex The index of the column to update.
+ * @param reader The reader from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateCharacterStream(int columnIndex, Reader x, int length)
+ void updateCharacterStream(int columnIndex, Reader reader, int count)
throws SQLException;
/**
@@ -994,12 +996,13 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
- *
+ * @param scale The scale of the object in question, which is used only
+ * for numeric type objects.
* @exception SQLException If an error occurs.
*/
- void updateObject(int columnIndex, Object x, int scale)
+ void updateObject(int columnIndex, Object value, int scale)
throws SQLException;
/**
@@ -1007,20 +1010,18 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param index The index of the column to update.
+ * @param columnIndex The index of the column to update.
* @param value The new value of the column.
- * @param scale The scale of the object in question, which is used only
- * for numeric type objects.
* @exception SQLException If an error occurs.
*/
- void updateObject(int columnIndex, Object x) throws SQLException;
+ void updateObject(int columnIndex, Object value) throws SQLException;
/**
* This method updates the specified column to have a NULL value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @return name The name of the column to update.
+ * @param columnName The name of the column to update.
* @exception SQLException If an error occurs.
*/
void updateNull(String columnName) throws SQLException;
@@ -1030,88 +1031,88 @@ public interface ResultSet
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBoolean(String columnName, boolean x) throws SQLException;
+ void updateBoolean(String columnName, boolean value) throws SQLException;
/**
* This method updates the specified column to have a byte value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateByte(String columnName, byte x) throws SQLException;
+ void updateByte(String columnName, byte value) throws SQLException;
/**
* This method updates the specified column to have a short value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateShort(String columnName, short x) throws SQLException;
+ void updateShort(String columnName, short value) throws SQLException;
/**
* This method updates the specified column to have an int value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateInt(String columnName, int x) throws SQLException;
+ void updateInt(String columnName, int value) throws SQLException;
/**
* This method updates the specified column to have a long value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateLong(String columnName, long x) throws SQLException;
+ void updateLong(String columnName, long value) throws SQLException;
/**
* This method updates the specified column to have a float value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateFloat(String columnName, float x) throws SQLException;
+ void updateFloat(String columnName, float value) throws SQLException;
/**
* This method updates the specified column to have a double value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateDouble(String columnName, double x) throws SQLException;
+ void updateDouble(String columnName, double value) throws SQLException;
/**
* This method updates the specified column to have a BigDecimal value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBigDecimal(String columnName, BigDecimal x)
+ void updateBigDecimal(String columnName, BigDecimal value)
throws SQLException;
/**
@@ -1119,55 +1120,55 @@ public interface ResultSet
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateString(String columnName, String x) throws SQLException;
+ void updateString(String columnName, String value) throws SQLException;
/**
* This method updates the specified column to have a byte array value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateBytes(String columnName, byte[] x) throws SQLException;
+ void updateBytes(String columnName, byte[] value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Date value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateDate(String columnName, Date x) throws SQLException;
+ void updateDate(String columnName, Date value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Time value. This
* does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateTime(String columnName, Time x) throws SQLException;
+ void updateTime(String columnName, Time value) throws SQLException;
/**
* This method updates the specified column to have a java.sql.Timestamp value.
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
* @exception SQLException If an error occurs.
*/
- void updateTimestamp(String columnName, Timestamp x)
+ void updateTimestamp(String columnName, Timestamp value)
throws SQLException;
/**
@@ -1175,12 +1176,12 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
+ * @param columnName The name of the column to update.
+ * @param stream The stream from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateAsciiStream(String columnName, InputStream x, int length)
+ void updateAsciiStream(String columnName, InputStream stream, int count)
throws SQLException;
/**
@@ -1188,12 +1189,12 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
+ * @param columnName The name of the column to update.
+ * @param stream The stream from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateBinaryStream(String columnName, InputStream x, int length)
+ void updateBinaryStream(String columnName, InputStream stream, int count)
throws SQLException;
/**
@@ -1201,25 +1202,26 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
- * @param value The new value of the column.
- * @param length The length of the stream.
- *
+ * @param columnName The name of the column to update.
+ * @param reader The reader from which the column value is updated.
+ * @param count The length of the stream.
* @exception SQLException If an error occurs.
*/
- void updateCharacterStream(String columnName, Reader reader,
- int length) throws SQLException;
+ void updateCharacterStream(String columnName, Reader reader, int count)
+ throws SQLException;
/**
* This method updates the specified column to have an Object value.
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
+ * @param scale The scale of the object in question, which is used only
+ * for numeric type objects.
* @exception SQLException If an error occurs.
*/
- void updateObject(String columnName, Object x, int scale)
+ void updateObject(String columnName, Object value, int scale)
throws SQLException;
/**
@@ -1227,13 +1229,11 @@ public interface ResultSet
* This does not update the actual database. <code>updateRow</code> must be
* called in order to do that.
*
- * @param name The name of the column to update.
+ * @param columnName The name of the column to update.
* @param value The new value of the column.
- * @param scale The scale of the object in question, which is used only
- * for numeric type objects.
* @exception SQLException If an error occurs.
*/
- void updateObject(String columnName, Object x) throws SQLException;
+ void updateObject(String columnName, Object value) throws SQLException;
/**
* This method inserts the current row into the database. The result set
@@ -1304,98 +1304,99 @@ public interface ResultSet
* This method returns the value of the specified column as a Java
* <code>Object</code> using the specified SQL type to Java type map.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @param map The SQL type to Java type map to use.
* @return The value of the column as an <code>Object</code>.
* @exception SQLException If an error occurs.
*/
- Object getObject(int i, Map<String, Class<?>> map) throws SQLException;
+ Object getObject(int columnIndex, Map<String, Class<?>> map)
+ throws SQLException;
/**
* This method returns a <code>Ref</code> for the specified column which
* represents the structured type for the column.
*
- * @param index The index of the column to return.
+ * @param columnIndex The index of the column to return.
* @return A <code>Ref</code> object for the column
* @exception SQLException If an error occurs.
*/
- Ref getRef(int i) throws SQLException;
+ Ref getRef(int columnIndex) throws SQLException;
/**
* This method returns the specified column value as a BLOB.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @return The value of the column as a BLOB.
* @exception SQLException If an error occurs.
*/
- Blob getBlob(int i) throws SQLException;
+ Blob getBlob(int columnIndex) throws SQLException;
/**
* This method returns the specified column value as a CLOB.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @return The value of the column as a CLOB.
* @exception SQLException If an error occurs.
*/
- Clob getClob(int i) throws SQLException;
+ Clob getClob(int columnIndex) throws SQLException;
/**
* This method returns the specified column value as an <code>Array</code>.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @return The value of the column as an <code>Array</code>.
* @exception SQLException If an error occurs.
*/
- Array getArray(int i) throws SQLException;
+ Array getArray(int columnIndex) throws SQLException;
/**
* This method returns the value of the specified column as a Java
* <code>Object</code> using the specified SQL type to Java type map.
*
- * @param name The name of the column to return.
+ * @param columnName The name of the column to return.
* @param map The SQL type to Java type map to use.
* @return The value of the column as an <code>Object</code>.
* @exception SQLException If an error occurs.
*/
- Object getObject(String colName, Map<String, Class<?>> map)
+ Object getObject(String columnName, Map<String, Class<?>> map)
throws SQLException;
/**
* This method returns a <code>Ref</code> for the specified column which
* represents the structured type for the column.
*
- * @param index The index of the column to return.
+ * @param columnName The name of the column to return.
* @return A <code>Ref</code> object for the column
* @exception SQLException If an error occurs.
*/
- Ref getRef(String colName) throws SQLException;
+ Ref getRef(String columnName) throws SQLException;
/**
* This method returns the specified column value as a BLOB.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @return The value of the column as a BLOB.
* @exception SQLException If an error occurs.
*/
- Blob getBlob(String colName) throws SQLException;
+ Blob getBlob(String columnName) throws SQLException;
/**
* This method returns the specified column value as a CLOB.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @return The value of the column as a CLOB.
* @exception SQLException If an error occurs.
*/
- Clob getClob(String colName) throws SQLException;
+ Clob getClob(String columnName) throws SQLException;
/**
* This method returns the specified column value as an <code>Array</code>.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @return The value of the column as an <code>Array</code>.
* @exception SQLException If an error occurs.
*/
- Array getArray(String colName) throws SQLException;
+ Array getArray(String columnName) throws SQLException;
/**
* This method returns the specified column value as a
@@ -1403,7 +1404,7 @@ public interface ResultSet
* to generate a value for the date if the database does not support
* timezones.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
* @return The value of the column as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
@@ -1416,7 +1417,7 @@ public interface ResultSet
* to generate a value for the date if the database does not support
* timezones.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
* @return The value of the column as a <code>java.sql.Date</code>.
* @exception SQLException If an error occurs.
@@ -1429,7 +1430,7 @@ public interface ResultSet
* to generate a value for the time if the database does not support
* timezones.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
* @return The value of the column as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
@@ -1442,7 +1443,7 @@ public interface ResultSet
* to generate a value for the time if the database does not support
* timezones.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
* @return The value of the column as a <code>java.sql.Time</code>.
* @exception SQLException If an error occurs.
@@ -1455,7 +1456,7 @@ public interface ResultSet
* to generate a value for the timestamp if the database does not support
* timezones.
*
- * @param index The index of the column value to return.
+ * @param columnIndex The index of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
* @return The value of the column as a <code>java.sql.Timestamp</code>.
* @exception SQLException If an error occurs.
@@ -1469,7 +1470,7 @@ public interface ResultSet
* to generate a value for the timestamp if the database does not support
* timezones.
*
- * @param name The name of the column value to return.
+ * @param columnName The name of the column value to return.
* @param cal The <code>Calendar</code> to use for calculating timezones.
*
* @return The value of the column as a <code>java.sql.Timestamp</code>.
@@ -1480,52 +1481,132 @@ public interface ResultSet
throws SQLException;
/**
+ * This method returns the specified column value as a
+ * <code>java.net.URL</code>.
+ *
+ * @param columnIndex The index of the column value to return.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
URL getURL(int columnIndex) throws SQLException;
/**
+ * This method returns the specified column value as a
+ * <code>java.net.URL</code>.
+ *
+ * @param columnName The name of the column value to return.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
URL getURL(String columnName) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Ref</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnIndex The index of the column value to update.
+ * @parm value The <code>java.sql.Ref</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateRef(int columnIndex, Ref x) throws SQLException;
+ void updateRef(int columnIndex, Ref value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Ref</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnName The name of the column value to update.
+ * @parm value The <code>java.sql.Ref</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateRef(String columnName, Ref x) throws SQLException;
+ void updateRef(String columnName, Ref value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Blob</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnIndex The index of the column value to update.
+ * @parm value The <code>java.sql.Blob</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateBlob(int columnIndex, Blob x) throws SQLException;
+ void updateBlob(int columnIndex, Blob value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Blob</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnName The name of the column value to update.
+ * @parm value The <code>java.sql.Blob</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateBlob(String columnName, Blob x) throws SQLException;
+ void updateBlob(String columnName, Blob value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Clob</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnIndex The index of the column value to update.
+ * @parm value The <code>java.sql.Clob</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateClob(int columnIndex, Clob x) throws SQLException;
+ void updateClob(int columnIndex, Clob value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sql.Clob</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnName The name of the column value to update.
+ * @parm value The <code>java.sql.Clob</code> used to set the new value
+ * of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateClob(String columnName, Clob x) throws SQLException;
+ void updateClob(String columnName, Clob value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sqlArray</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnIndex The index of the column value to update.
+ * @parm value The new value of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateArray(int columnIndex, Array x) throws SQLException;
+ void updateArray(int columnIndex, Array value) throws SQLException;
/**
+ * This method updates the specified column to have a
+ * <code>java.sqlArray</code> value.
+ * This does not update the actual database. <code>updateRow</code> must be
+ * called in order to do that.
+ *
+ * @parm columnName The name of the column value to update.
+ * @parm value The new value of the column.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void updateArray(String columnName, Array x) throws SQLException;
+ void updateArray(String columnName, Array value) throws SQLException;
}
diff --git a/java/sql/ResultSetMetaData.java b/java/sql/ResultSetMetaData.java
index 0086677ee..5a62c549e 100644
--- a/java/sql/ResultSetMetaData.java
+++ b/java/sql/ResultSetMetaData.java
@@ -1,5 +1,5 @@
/* ResultSetMetaData.java -- Returns information about the ResultSet
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,8 +41,8 @@ package java.sql;
/**
* This interface provides a mechanism for obtaining information about
* the columns that are present in a <code>ResultSet</code>.
- * <p>
- * Note that in this class column indexes start at 1, not 0.
+ *
+ * <p> Note that in this class column indices start at 1, not 0.</p>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
@@ -75,207 +75,207 @@ public interface ResultSetMetaData
* This method test whether or not the column is an auto-increment column.
* Auto-increment columns are read-only.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return <code>true</code> if the column is auto-increment, <code>false</code>
* otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isAutoIncrement(int column) throws SQLException;
+ boolean isAutoIncrement(int columnIndex) throws SQLException;
/**
* This method tests whether or not a column is case sensitive in its values.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return <code>true</code> if the column value is case sensitive,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isCaseSensitive(int column) throws SQLException;
+ boolean isCaseSensitive(int columnIndex) throws SQLException;
/**
* This method tests whether not the specified column can be used in
* a WHERE clause.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return <code>true</code> if the column may be used in a WHERE clause,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isSearchable(int column) throws SQLException;
+ boolean isSearchable(int columnIndex) throws SQLException;
/**
* This method tests whether or not the column stores a monetary value.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return <code>true</code> if the column contains a monetary value,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isCurrency(int column) throws SQLException;
+ boolean isCurrency(int columnIndex) throws SQLException;
/**
* This method returns a value indicating whether or not the specified
* column may contain a NULL value.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return A constant indicating whether or not the column can contain NULL,
* which will be one of <code>columnNoNulls</code>,
* <code>columnNullable</code>, or <code>columnNullableUnknown</code>.
* @exception SQLException If an error occurs.
*/
- int isNullable(int column) throws SQLException;
+ int isNullable(int columnIndex) throws SQLException;
/**
* This method tests whether or not the value of the specified column
* is signed or unsigned.
*
- * @param index The index of the column to test.
+ * @param columnIndex The index of the column to test.
* @return <code>true</code> if the column value is signed, <code>false</code>
* otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isSigned(int column) throws SQLException;
+ boolean isSigned(int columnIndex) throws SQLException;
/**
* This method returns the maximum number of characters that can be used
* to display a value in this column.
*
- * @param index The index of the column to check.
+ * @param columnIndex The index of the column to check.
* @return The maximum number of characters that can be used to display a
* value for this column.
* @exception SQLException If an error occurs.
*/
- int getColumnDisplaySize(int column) throws SQLException;
+ int getColumnDisplaySize(int columnIndex) throws SQLException;
/**
* This method returns a string that should be used as a caption for this
* column for user display purposes.
*
- * @param index The index of the column to check.
+ * @param columnIndex The index of the column to check.
* @return A display string for the column.
* @exception SQLException If an error occurs.
*/
- String getColumnLabel(int column) throws SQLException;
+ String getColumnLabel(int columnIndex) throws SQLException;
/**
* This method returns the name of the specified column.
*
- * @param index The index of the column to return the name of.
+ * @param columnIndex The index of the column to return the name of.
* @return The name of the column.
* @exception SQLException If an error occurs.
*/
- String getColumnName(int column) throws SQLException;
+ String getColumnName(int columnIndex) throws SQLException;
/**
* This method returns the name of the schema that contains the specified
* column.
*
- * @param index The index of the column to check the schema name for.
+ * @param columnIndex The index of the column to check the schema name for.
* @return The name of the schema that contains the column.
* @exception SQLException If an error occurs.
*/
- String getSchemaName(int column) throws SQLException;
+ String getSchemaName(int columnIndex) throws SQLException;
/**
* This method returns the precision of the specified column, which is the
* number of decimal digits it contains.
*
- * @param index The index of the column to check the precision on.
+ * @param columnIndex The index of the column to check the precision on.
* @return The precision of the specified column.
* @exception SQLException If an error occurs.
*/
- int getPrecision(int column) throws SQLException;
+ int getPrecision(int columnIndex) throws SQLException;
/**
* This method returns the scale of the specified column, which is the
* number of digits to the right of the decimal point.
*
- * @param index The index column to check the scale of.
+ * @param columnIndex The index column to check the scale of.
* @return The scale of the column.
* @exception SQLException If an error occurs.
*/
- int getScale(int column) throws SQLException;
+ int getScale(int columnIndex) throws SQLException;
/**
* This method returns the name of the table containing the specified
* column.
*
- * @param index The index of the column to check the table name for.
+ * @param columnIndex The index of the column to check the table name for.
* @return The name of the table containing the column.
* @exception SQLException If an error occurs.
*/
- String getTableName(int column) throws SQLException;
+ String getTableName(int columnIndex) throws SQLException;
/**
* This method returns the name of the catalog containing the specified
* column.
*
- * @param index The index of the column to check the catalog name for.
+ * @param columnIndex The index of the column to check the catalog name for.
* @return The name of the catalog containing the column.
* @exception SQLException If an error occurs.
*/
- String getCatalogName(int column) throws SQLException;
+ String getCatalogName(int columnIndex) throws SQLException;
/**
* This method returns the SQL type of the specified column. This will
* be one of the constants from <code>Types</code>.
*
- * @param index The index of the column to check the SQL type of.
+ * @param columnIndex The index of the column to check the SQL type of.
* @return The SQL type for this column.
* @exception SQLException If an error occurs.
* @see Types
*/
- int getColumnType(int column) throws SQLException;
+ int getColumnType(int columnIndex) throws SQLException;
/**
* This method returns the name of the SQL type for this column.
*
- * @param index The index of the column to check the SQL type name for.
+ * @param columnIndex The index of the column to check the SQL type name for.
* @return The name of the SQL type for this column.
* @exception SQLException If an error occurs.
*/
- String getColumnTypeName(int column) throws SQLException;
+ String getColumnTypeName(int columnIndex) throws SQLException;
/**
* This method tests whether or not the specified column is read only.
*
- * @param index The index of the column to check.
+ * @param columnIndex The index of the column to check.
* @return <code>true</code> if the column is read only, <code>false</code>
* otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isReadOnly(int column) throws SQLException;
+ boolean isReadOnly(int columnIndex) throws SQLException;
/**
* This method tests whether or not the column may be writable. This
* does not guarantee that a write will be successful.
*
- * @param index The index of the column to check for writability.
+ * @param columnIndex The index of the column to check for writability.
* @return <code>true</code> if the column may be writable,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isWritable(int column) throws SQLException;
+ boolean isWritable(int columnIndex) throws SQLException;
/**
* This method tests whether or not the column is writable. This
* does guarantee that a write will be successful.
*
- * @param index The index of the column to check for writability.
+ * @param columnIndex The index of the column to check for writability.
* @return <code>true</code> if the column is writable,
* <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
- boolean isDefinitelyWritable(int column) throws SQLException;
+ boolean isDefinitelyWritable(int columnIndex) throws SQLException;
/**
* This method returns the name of the Java class which will be used to
* create objects representing the data in this column.
*
- * @param index The index of the column to check.
+ * @param columnIndex The index of the column to check.
* @return The name of the Java class that will be used for values in
* this column.
* @exception SQLException If an error occurs.
*/
- String getColumnClassName(int column) throws SQLException;
+ String getColumnClassName(int columnIndex) throws SQLException;
}
diff --git a/java/sql/SQLData.java b/java/sql/SQLData.java
index 2ba1fb18d..cf006e15a 100644
--- a/java/sql/SQLData.java
+++ b/java/sql/SQLData.java
@@ -1,5 +1,5 @@
/* SQLData.java -- Custom mapping for a user defined datatype
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,7 +57,7 @@ public interface SQLData
* This method populates the data in the object from the specified stream.
*
* @param stream The stream to read the data from.
- * @param name The data type name of the data on the stream.
+ * @param typeName The data type name of the data on the stream.
* @exception SQLException If an error occurs.
*/
void readSQL(SQLInput stream, String typeName) throws SQLException;
diff --git a/java/sql/SQLOutput.java b/java/sql/SQLOutput.java
index 8e6c88f8c..e210258fa 100644
--- a/java/sql/SQLOutput.java
+++ b/java/sql/SQLOutput.java
@@ -1,5 +1,5 @@
/* SQLOutput.java -- Write SQL values to a stream
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -59,7 +59,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeString(String x) throws SQLException;
+ void writeString(String value) throws SQLException;
/**
* This method writes the specified Java <code>boolean</code>
@@ -68,7 +68,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeBoolean(boolean x) throws SQLException;
+ void writeBoolean(boolean value) throws SQLException;
/**
* This method writes the specified Java <code>byte</code>
@@ -77,7 +77,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeByte(byte x) throws SQLException;
+ void writeByte(byte value) throws SQLException;
/**
* This method writes the specified Java <code>short</code>
@@ -86,7 +86,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeShort(short x) throws SQLException;
+ void writeShort(short value) throws SQLException;
/**
* This method writes the specified Java <code>int</code>
@@ -95,7 +95,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeInt(int x) throws SQLException;
+ void writeInt(int value) throws SQLException;
/**
* This method writes the specified Java <code>long</code>
@@ -104,7 +104,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeLong(long x) throws SQLException;
+ void writeLong(long value) throws SQLException;
/**
* This method writes the specified Java <code>float</code>
@@ -113,7 +113,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeFloat(float x) throws SQLException;
+ void writeFloat(float value) throws SQLException;
/**
* This method writes the specified Java <code>double</code>
@@ -122,7 +122,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeDouble(double x) throws SQLException;
+ void writeDouble(double value) throws SQLException;
/**
* This method writes the specified Java <code>BigDecimal</code>
@@ -131,7 +131,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeBigDecimal(BigDecimal x) throws SQLException;
+ void writeBigDecimal(BigDecimal value) throws SQLException;
/**
* This method writes the specified Java <code>byte</code> array
@@ -140,7 +140,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeBytes(byte[] x) throws SQLException;
+ void writeBytes(byte[] value) throws SQLException;
/**
* This method writes the specified Java <code>java.sql.Date</code>
@@ -149,7 +149,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeDate(Date x) throws SQLException;
+ void writeDate(Date value) throws SQLException;
/**
* This method writes the specified Java <code>java.sql.Time</code>
@@ -158,7 +158,7 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeTime(Time x) throws SQLException;
+ void writeTime(Time value) throws SQLException;
/**
* This method writes the specified Java <code>java.sql.Timestamp</code>
@@ -167,34 +167,34 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeTimestamp(Timestamp x) throws SQLException;
+ void writeTimestamp(Timestamp value) throws SQLException;
/**
* This method writes the specified Java character stream
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param stream The stream that holds the character data to write.
* @exception SQLException If an error occurs.
*/
- void writeCharacterStream(Reader x) throws SQLException;
+ void writeCharacterStream(Reader stream) throws SQLException;
/**
* This method writes the specified ASCII text stream
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param stream The stream that holds the ASCII data to write.
* @exception SQLException If an error occurs.
*/
- void writeAsciiStream(InputStream x) throws SQLException;
+ void writeAsciiStream(InputStream stream) throws SQLException;
/**
* This method writes the specified uninterpreted binary byte stream
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param stream The stream that holds the binary data to write.
* @exception SQLException If an error occurs.
*/
- void writeBinaryStream(InputStream x) throws SQLException;
+ void writeBinaryStream(InputStream stream) throws SQLException;
/**
* This method writes the specified Java <code>SQLData</code> object
@@ -203,43 +203,48 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeObject(SQLData x) throws SQLException;
+ void writeObject(SQLData value) throws SQLException;
/**
* This method writes the specified Java SQL <code>Ref</code> object
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param value The <code>Ref</code> object to write to the stream.
* @exception SQLException If an error occurs.
+ * @see Ref
*/
- void writeRef(Ref x) throws SQLException;
+ void writeRef(Ref value) throws SQLException;
+
/**
* This method writes the specified Java SQL <code>Blob</code> object
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param value The <code>Blob</code> object to write to the stream.
* @exception SQLException If an error occurs.
+ * @see Blob
*/
- void writeBlob(Blob x) throws SQLException;
+ void writeBlob(Blob value) throws SQLException;
/**
* This method writes the specified Java SQL <code>Clob</code> object
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param value The <code>Clob</code> object to write to the stream.
* @exception SQLException If an error occurs.
+ * @see Clob
*/
- void writeClob(Clob x) throws SQLException;
+ void writeClob(Clob value) throws SQLException;
/**
* This method writes the specified Java SQL <code>Struct</code> object
* to the SQL stream.
*
- * @param value The value to write to the stream.
+ * @param value The <code>Struct</code> object to write to the stream.
* @exception SQLException If an error occurs.
+ * @see Struct
*/
- void writeStruct(Struct x) throws SQLException;
+ void writeStruct(Struct value) throws SQLException;
/**
* This method writes the specified Java SQL <code>Array</code> object
@@ -248,10 +253,15 @@ public interface SQLOutput
* @param value The value to write to the stream.
* @exception SQLException If an error occurs.
*/
- void writeArray(Array x) throws SQLException;
+ void writeArray(Array value) throws SQLException;
/**
+ * This method writes the specified <code>java.net.URL</code> object to the
+ * SQL stream.
+ *
+ * @param value The value to write to the stream.
+ * @exception SQLException If an error occurs.
* @since 1.4
*/
- void writeURL(URL x) throws SQLException;
+ void writeURL(URL value) throws SQLException;
}
diff --git a/java/sql/SQLWarning.java b/java/sql/SQLWarning.java
index 841d137e1..d9c7e354e 100644
--- a/java/sql/SQLWarning.java
+++ b/java/sql/SQLWarning.java
@@ -1,5 +1,5 @@
/* SQLWarning.java -- Database access warnings.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -56,9 +56,9 @@ public class SQLWarning extends SQLException
* @param SQLState A string containing the SQL state of the error.
* @param vendorCode The vendor error code associated with this error.
*/
- public SQLWarning(String reason, String SQLState, int vendorCode)
+ public SQLWarning(String message, String SQLState, int vendorCode)
{
- super(reason, SQLState, vendorCode);
+ super(message, SQLState, vendorCode);
}
/**
diff --git a/java/sql/Statement.java b/java/sql/Statement.java
index 42e8e8e88..195600eaa 100644
--- a/java/sql/Statement.java
+++ b/java/sql/Statement.java
@@ -1,5 +1,5 @@
/* Statement.java -- Interface for executing SQL statements.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -91,10 +91,10 @@ public interface Statement
/**
* This method sets the limit for the maximum length of any column in bytes.
*
- * @param maxsize The new maximum length of any column in bytes.
+ * @param maxSize The new maximum length of any column in bytes.
* @exception SQLException If an error occurs.
*/
- void setMaxFieldSize(int max) throws SQLException;
+ void setMaxFieldSize(int maxSize) throws SQLException;
/**
* This method returns the maximum possible number of rows in a result set.
@@ -108,20 +108,20 @@ public interface Statement
* This method sets the maximum number of rows that can be present in a
* result set.
*
- * @param maxrows The maximum possible number of rows in a result set.
+ * @param maxRows The maximum possible number of rows in a result set.
* @exception SQLException If an error occurs.
*/
- void setMaxRows(int max) throws SQLException;
+ void setMaxRows(int maxRows) throws SQLException;
/**
* This method sets the local escape processing mode on or off. The
* default value is on.
*
* @param escape <code>true</code> to enable local escape processing,
- * <code>false</code> to disable it.
+ * <code>false</code> to disable it.
* @exception SQLException If an error occurs.
*/
- void setEscapeProcessing(boolean enable) throws SQLException;
+ void setEscapeProcessing(boolean escape) throws SQLException;
/**
* The method returns the number of seconds a statement may be in process
@@ -136,7 +136,7 @@ public interface Statement
* This method sets the number of seconds a statement may be in process
* before timing out. A value of 0 means there is no timeout.
*
- * @param timeout The new SQL statement timeout value.
+ * @param seconds The new SQL statement timeout value.
* @exception SQLException If an error occurs.
*/
void setQueryTimeout(int seconds) throws SQLException;
@@ -192,7 +192,10 @@ public interface Statement
* @return The result set of the query, or <code>null</code> if there was
* no result set (for example, if the statement was an UPDATE).
* @exception SQLException If an error occurs.
- * @see execute
+ * @see #execute(String)
+ * @see #execute(String, int)
+ * @see #execute(String, int[])
+ * @see #execute(String, String[])
*/
ResultSet getResultSet() throws SQLException;
@@ -203,7 +206,10 @@ public interface Statement
* @return The update count of the query, or -1 if there was no update
* count (for example, if the statement was a SELECT).
* @exception SQLException If an error occurs.
- * @see execute
+ * @see #execute(String)
+ * @see #execute(String, int)
+ * @see #execute(String, int[])
+ * @see #execute(String, String[])
*/
int getUpdateCount() throws SQLException;
@@ -215,7 +221,10 @@ public interface Statement
* <code>false</code> otherwise (for example, the next result is an
* update count).
* @exception SQLException If an error occurs.
- * @see execute
+ * @see #execute(String)
+ * @see #execute(String, int)
+ * @see #execute(String, int[])
+ * @see #execute(String, String[])
*/
boolean getMoreResults() throws SQLException;
@@ -241,11 +250,11 @@ public interface Statement
* This method informs the driver how many rows it should fetch from the
* database at a time.
*
- * @param numrows The number of rows the driver should fetch at a time
- * to populate the result set.
+ * @param numRows The number of rows the driver should fetch at a time
+ * to populate the result set.
* @exception SQLException If an error occurs.
*/
- void setFetchSize(int rows) throws SQLException;
+ void setFetchSize(int numRows) throws SQLException;
/**
* This method returns the number of rows the driver believes should be
diff --git a/java/sql/Time.java b/java/sql/Time.java
index 57551528b..2d1a433fa 100644
--- a/java/sql/Time.java
+++ b/java/sql/Time.java
@@ -1,5 +1,6 @@
/* Time.java -- Wrapper around java.util.Date
- Copyright (C) 1999, 2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -177,10 +178,10 @@ public class Time extends java.util.Date
/**
* This method initializes a new instance of this class with the
- * specified time value representing the number of seconds since
+ * specified time value representing the number of milliseconds since
* Jan 1, 1970 at 12:00 midnight GMT.
*
- * @param time The time value to intialize this <code>Time</code> to.
+ * @param date The time value to intialize this <code>Time</code> to.
*/
public Time(long date)
{
diff --git a/java/sql/Timestamp.java b/java/sql/Timestamp.java
index 66f8259f2..18ccda557 100644
--- a/java/sql/Timestamp.java
+++ b/java/sql/Timestamp.java
@@ -143,7 +143,7 @@ public class Timestamp extends java.util.Date
* specified time value representing the number of milliseconds since
* Jan 1, 1970 at 12:00 midnight GMT.
*
- * @param time The time value to intialize this <code>Time</code> to.
+ * @param date The time value to intialize this <code>Time</code> to.
*/
public Timestamp(long date)
{
@@ -279,12 +279,13 @@ public class Timestamp extends java.util.Date
}
/**
- * Compare two Timestamp
- * @param when the other Timestamp.
- * @return 0, if the date represented
- * by obj is exactly the same as the time represented by this
- * object, a negative if this Timestamp is before the other Timestamp, and
- * a positive value otherwise.
+ * Compares this <code>Timestamp</code> to another one.
+ *
+ * @param ts The other Timestamp.
+ * @return <code>0</code>, if both <code>Timestamp</code>'s represent exactly
+ * the same date, a negative value if this <code>Timestamp</code> is
+ * before the specified <code>Timestamp</code> and a positive value
+ * otherwise.
* @since 1.2
*/
public int compareTo(Timestamp ts)
@@ -297,15 +298,18 @@ public class Timestamp extends java.util.Date
}
/**
- * Compares this Timestamp to another. This behaves like
+ * Compares this <code>Timestamp</code> to another one. This behaves like
* <code>compareTo(Timestamp)</code>, but it may throw a
- * <code>ClassCastException</code>
- * @param obj the other Timestamp.
- * @return 0, if the Timestamp represented
- * by obj is exactly the same as the time represented by this
- * object, a negative if this Timestamp is before the other Timestamp, and
- * a positive value otherwise.
+ * <code>ClassCastException</code>, if the specified object is not of type
+ * <code>Timestamp</code>.
+ *
+ * @param obj The object to compare with.
+ * @return <code>0</code>, if both <code>Timestamp</code>'s represent exactly
+ * the same date, a negative value if this <code>Timestamp</code> is
+ * before the specified <code>Timestamp</code> and a positive value
+ * otherwise.
* @exception ClassCastException if obj is not of type Timestamp.
+ * @see #compareTo(Timestamp)
* @since 1.2
*/
public int compareTo(java.util.Date obj)
diff --git a/java/text/SimpleDateFormat.java b/java/text/SimpleDateFormat.java
index c0c4cf68c..00c08507e 100644
--- a/java/text/SimpleDateFormat.java
+++ b/java/text/SimpleDateFormat.java
@@ -805,7 +805,8 @@ public class SimpleDateFormat extends DateFormat
buffer.setDefaultAttribute(DateFormat.Field.RFC822_TIME_ZONE);
int pureMinutes = (calendar.get(Calendar.ZONE_OFFSET) +
calendar.get(Calendar.DST_OFFSET)) / (1000 * 60);
- String sign = (pureMinutes < 0) ? "-" : "+";
+ String sign = (pureMinutes < 0) ? "-" : "+";
+ pureMinutes = Math.abs(pureMinutes);
int hours = pureMinutes / 60;
int minutes = pureMinutes % 60;
buffer.append(sign);
diff --git a/java/util/Locale.java b/java/util/Locale.java
index e1b1bdfbb..d2aead43c 100644
--- a/java/util/Locale.java
+++ b/java/util/Locale.java
@@ -66,11 +66,12 @@ import java.io.Serializable;
* be separated by an underscore (U+005F).
*
* <p>The default locale is determined by the values of the system properties
- * user.language, user.region, and user.variant, defaulting to "en". Note that
- * the locale does NOT contain the conversion and formatting capabilities (for
- * that, use ResourceBundle and java.text). Rather, it is an immutable tag
- * object for identifying a given locale, which is referenced by these other
- * classes when they must make locale-dependent decisions.
+ * user.language, user.country (or user.region), and user.variant, defaulting
+ * to "en_US". Note that the locale does NOT contain the conversion and
+ * formatting capabilities (for that, use ResourceBundle and java.text).
+ * Rather, it is an immutable tag object for identifying a given locale, which
+ * is referenced by these other classes when they must make locale-dependent
+ * decisions.
*
* @see ResourceBundle
* @see java.text.Format
@@ -210,10 +211,18 @@ public final class Locale implements Serializable, Cloneable
* null. Note the logic in the main constructor, to detect when
* bootstrapping has completed.
*/
- private static Locale defaultLocale =
- getLocale(SystemProperties.getProperty("user.language", "en"),
- SystemProperties.getProperty("user.region", ""),
- SystemProperties.getProperty("user.variant", ""));
+ private static Locale defaultLocale;
+
+ static {
+ String language = SystemProperties.getProperty("user.language", "en");
+ String country = SystemProperties.getProperty("user.country", "US");
+ String region = SystemProperties.getProperty("user.region", null);
+ String variant = SystemProperties.getProperty("user.variant", "");
+
+ defaultLocale = getLocale(language,
+ (region != null) ? region : country,
+ variant);
+ }
/**
* Array storing all the available two-letter ISO639 languages.
@@ -237,38 +246,38 @@ public final class Locale implements Serializable, Cloneable
}
/**
- * Retrieves the locale with the specified language and region
+ * Retrieves the locale with the specified language and country
* from the cache.
*
* @param language the language of the locale to retrieve.
- * @param region the region of the locale to retrieve.
+ * @param country the country of the locale to retrieve.
* @return the locale.
*/
- private static Locale getLocale(String language, String region)
+ private static Locale getLocale(String language, String country)
{
- return getLocale(language, region, "");
+ return getLocale(language, country, "");
}
/**
- * Retrieves the locale with the specified language, region
+ * Retrieves the locale with the specified language, country
* and variant from the cache.
*
* @param language the language of the locale to retrieve.
- * @param region the region of the locale to retrieve.
+ * @param country the country of the locale to retrieve.
* @param variant the variant of the locale to retrieve.
* @return the locale.
*/
- private static Locale getLocale(String language, String region, String variant)
+ private static Locale getLocale(String language, String country, String variant)
{
if (localeMap == null)
localeMap = new HashMap(256);
- String name = language + "_" + region + "_" + variant;
+ String name = language + "_" + country + "_" + variant;
Locale locale = (Locale) localeMap.get(name);
if (locale == null)
{
- locale = new Locale(language, region, variant);
+ locale = new Locale(language, country, variant);
localeMap.put(name, locale);
}
@@ -391,23 +400,23 @@ public final class Locale implements Serializable, Cloneable
for (int i = 0; i < len; i++)
{
String language;
- String region = "";
+ String country = "";
String variant = "";
String name = LocaleHelper.getLocaleName(i);
language = name.substring(0, 2);
if (name.length() > 2)
- region = name.substring(3);
+ country = name.substring(3);
- int index = region.indexOf("_");
+ int index = country.indexOf("_");
if (index > 0)
{
- variant = region.substring(index + 1);
- region = region.substring(0, index - 1);
+ variant = country.substring(index + 1);
+ country = country.substring(0, index - 1);
}
- availableLocales[i] = getLocale(language, region, variant);
+ availableLocales[i] = getLocale(language, country, variant);
}
}
diff --git a/java/util/jar/JarFile.java b/java/util/jar/JarFile.java
index ac5609b14..003d9cb5e 100644
--- a/java/util/jar/JarFile.java
+++ b/java/util/jar/JarFile.java
@@ -110,8 +110,9 @@ public class JarFile extends ZipFile
* The security provider to use for signature verification.
* We need a known fallback to be able to read any signed jar file
* (which might contain the user selected security provider).
+ * This is package-private to avoid accessor methods for inner classes.
*/
- private static final Gnu provider = new Gnu();
+ static final Gnu provider = new Gnu();
// Signature OIDs.
private static final OID MD2_OID = new OID("1.2.840.113549.2.2");
diff --git a/javax/accessibility/AccessibleAction.java b/javax/accessibility/AccessibleAction.java
index 2ca683e45..a7cf05e4a 100644
--- a/javax/accessibility/AccessibleAction.java
+++ b/javax/accessibility/AccessibleAction.java
@@ -55,6 +55,28 @@ package javax.accessibility;
*/
public interface AccessibleAction
{
+
+ /**
+ * The name of an action which decrements a value.
+ *
+ * @since 1.5
+ */
+ static final String DECREMENT = "decrement";
+
+ /**
+ * The name of an action which increments a value.
+ *
+ * @since 1.5
+ */
+ static final String INCREMENT = "increment";
+
+ /**
+ * The name of an action which toggles the expansion of a tree node.
+ *
+ * @since 1.5
+ */
+ static final String TOGGLE_EXPAND = "toggle expand";
+
/**
* Get the number possible actions for this object, with the zeroth
* representing the default action.
diff --git a/javax/accessibility/AccessibleRole.java b/javax/accessibility/AccessibleRole.java
index f386ad0e9..a5396f147 100644
--- a/javax/accessibility/AccessibleRole.java
+++ b/javax/accessibility/AccessibleRole.java
@@ -467,6 +467,56 @@ public class AccessibleRole extends AccessibleBundle
= new AccessibleRole("groupbox");
/**
+ * A formula for creating a value.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole EDITBAR
+ = new AccessibleRole("editbar");
+
+ /**
+ * A text-based footer.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole FOOTER
+ = new AccessibleRole("footer");
+
+ /**
+ * A text-based header.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole HEADER
+ = new AccessibleRole("header");
+
+
+ /**
+ * A text-based paragraph.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole PARAGRAPH
+ = new AccessibleRole("paragraph");
+
+ /**
+ * Represents the current level of progress on a particular task.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole PROGRESS_MONITOR
+ = new AccessibleRole("progress monitor");
+
+ /**
+ * A ruler is a method of measuring the distance between two
+ * points.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleRole RULER
+ = new AccessibleRole("ruler");
+
+ /**
* Create a new constant with a locale independent key. Follow the example,
* keep the constructor private and make public constants instead.
*
diff --git a/javax/accessibility/AccessibleState.java b/javax/accessibility/AccessibleState.java
index a630354b0..e4d00bd70 100644
--- a/javax/accessibility/AccessibleState.java
+++ b/javax/accessibility/AccessibleState.java
@@ -177,6 +177,28 @@ public class AccessibleState extends AccessibleBundle
= new AccessibleState("iconified");
/**
+ * Indicates that the state of this particular object is
+ * indeterminate. This commonly occurs when an object is incapable
+ * of representing the state by a single value.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState INDETERMINATE
+ = new AccessibleState("indeterminate");
+
+ /**
+ * Indicates that this particular object manages a number of
+ * subcomponents. This is a common property of structures such as
+ * trees and tables, which have a number of sub-elements such as
+ * rows and columns. The subcomponents should be left to the
+ * object, and not managed by the application.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState MANAGES_DESCENDANTS
+ = new AccessibleState("manages descendants");
+
+ /**
* Indicates that something must be done in the current object before
* interaction is allowed on other windows, usually for dialogs.
*
@@ -250,6 +272,15 @@ public class AccessibleState extends AccessibleBundle
= new AccessibleState("showing");
/**
+ * Indicates that this particular object is truncated when displayed
+ * visually.
+ *
+ * @since 1.5
+ */
+ public static final AccessibleState TRUNCATED
+ = new AccessibleState("truncated");
+
+ /**
* Indicates that this object intends to be visible. However, if its
* parent is invisible, this object is as well.
*
diff --git a/javax/net/ssl/HttpsURLConnection.java b/javax/net/ssl/HttpsURLConnection.java
index 4c73edbcd..3f30dc1b8 100644
--- a/javax/net/ssl/HttpsURLConnection.java
+++ b/javax/net/ssl/HttpsURLConnection.java
@@ -1,5 +1,5 @@
/* HttpsURLConnection.java -- an HTTPS connection.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.net.ssl;
-import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.Certificate;
@@ -90,9 +89,10 @@ public abstract class HttpsURLConnection extends HttpURLConnection
* Creates a new HTTPS URL connection.
*
* @param url The URL of the connection being established.
- * @throws IOException If the connection cannot be established.
+ * @specnote This was marked as throwing IOException in 1.4,
+ * but this was removed in 1.5.
*/
- protected HttpsURLConnection(URL url) throws IOException
+ protected HttpsURLConnection(URL url)
{
super(url);
}
diff --git a/javax/swing/ActionMap.java b/javax/swing/ActionMap.java
index 2a8c78d66..0d6706c3b 100644
--- a/javax/swing/ActionMap.java
+++ b/javax/swing/ActionMap.java
@@ -1,5 +1,5 @@
/* ActionMap.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,9 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/javax/swing/DefaultListSelectionModel.java b/javax/swing/DefaultListSelectionModel.java
index 003513a23..b6d3e079e 100644
--- a/javax/swing/DefaultListSelectionModel.java
+++ b/javax/swing/DefaultListSelectionModel.java
@@ -162,11 +162,14 @@ public class DefaultListSelectionModel implements Cloneable,
/**
* Sets the value of the {@link #selectionMode} property.
*
- * @param a The new value of the property
+ * @param mode The new value of the property
*/
- public void setSelectionMode(int a)
+ public void setSelectionMode(int mode)
{
- selectionMode = a;
+ if (mode < ListSelectionModel.SINGLE_SELECTION
+ || mode > ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+ throw new IllegalArgumentException("Unrecognised mode: " + mode);
+ selectionMode = mode;
}
/**
@@ -552,9 +555,10 @@ public class DefaultListSelectionModel implements Cloneable,
int i;
- Up: for (i = from; i>=0; i=sel.nextSetBit(i+1))
+ for (i = from; i>=0; i=sel.nextSetBit(i+1))
to = i;
+ sel.clear();
fireValueChanged(from, to, valueIsAdjusting);
}
@@ -776,6 +780,7 @@ public class DefaultListSelectionModel implements Cloneable,
DefaultListSelectionModel model =
(DefaultListSelectionModel) super.clone();
model.sel = (BitSet) sel.clone();
+ model.listenerList = new EventListenerList();
return model;
}
}
diff --git a/javax/swing/ImageIcon.java b/javax/swing/ImageIcon.java
index 0baaf6f60..7347985eb 100644
--- a/javax/swing/ImageIcon.java
+++ b/javax/swing/ImageIcon.java
@@ -1,5 +1,5 @@
/* ImageIcon.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package javax.swing;
import java.awt.Component;
import java.awt.Graphics;
+import java.awt.IllegalComponentStateException;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
@@ -60,7 +61,8 @@ public class ImageIcon
implements Icon, Serializable, Accessible
{
/**
- * Accessibility support for ImageIcon.
+ * Provides the accessibility features for the <code>ImageIcon</code>
+ * class.
*/
protected class AccessibleImageIcon
extends AccessibleContext
@@ -69,7 +71,7 @@ public class ImageIcon
private static final long serialVersionUID = 2113430526551336564L;
/**
- * Creates a new instance of AccessibleImageIcon.
+ * Creates a new instance of <code>AccessibleImageIcon</code>.
*/
protected AccessibleImageIcon()
{
@@ -77,10 +79,9 @@ public class ImageIcon
}
/**
- * Returns the AccessibleRole of ImageIcon, which is
- * {@link AccessibleRole#ICON}.
+ * Returns the accessible role for the <code>ImageIcon</code>.
*
- * @return {@link AccessibleRole#ICON}
+ * @return {@link AccessibleRole#ICON}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -88,45 +89,47 @@ public class ImageIcon
}
/**
- * Returns the accessible state of this ImageIcon.
+ * Returns the accessible state for the <code>ImageIcon</code>. To
+ * match the reference implementation, this method always returns
+ * <code>null</code>.
*
- * @return the accessible state of this ImageIcon
+ * @return <code>null</code>.
*/
public AccessibleStateSet getAccessibleStateSet()
{
- // TODO: which state information from ImageIcon is returned here??
- return new AccessibleStateSet();
+ // refer to Sun's bug report 4269253
+ return null;
}
/**
- * Returns the accessible parent of this object, which is <code>null</code>
- * in this case, because ImageIcons have no parent.
+ * Returns the accessible parent of this object. To match the reference
+ * implementation, this method always returns <code>null</code>.
*
- * @return <code>null</code>, because ImageIcons have no parent
+ * @return <code>null</code>.
*/
public Accessible getAccessibleParent()
{
- // TODO: ImageIcons have no parent, have they ??
+ // refer to Sun's bug report 4269253
return null;
}
/**
- * Returns the index of this object in its accessible parent, which is
- * -1 here, because ImageIcons have no accessible parent.
+ * Returns the index of this object in its accessible parent. To match
+ * the reference implementation, this method always returns <code>-1</code>.
*
- * @return -1 because ImageIcons have no parent
+ * @return <code>-1</code>.
*/
public int getAccessibleIndexInParent()
{
- // TODO: do ImageIcons have parents??
+ // refer to Sun's bug report 4269253
return -1;
}
/**
* Returns the number of accessible children of this component,
- * which is 0, because ImageIcons have no children.
+ * which is 0, because an {@link ImageIcon} has no children.
*
- * @return 0 because ImageIcons have no children
+ * @return <code>0</code>.
*/
public int getAccessibleChildrenCount()
{
@@ -135,11 +138,12 @@ public class ImageIcon
/**
* Returns the accessible child at index <code>i</code>, which is
- * <code>null</code> in this case because ImageIcons have no children.
+ * <code>null</code> in this case because an {@link ImageIcon} has no
+ * children.
*
* @param i the index of the child to be fetched
*
- * @return <code>null</code> because ImageIcons have no children
+ * @return <code>null</code>.
*/
public Accessible getAccessibleChild(int i)
{
@@ -147,21 +151,25 @@ public class ImageIcon
}
/**
- * Returns the locale of this object. This returns the default locale
- * that is set for the current VM.
+ * Returns the locale of this object. To match the reference
+ * implementation, this method always returns <code>null</code>.
*
- * @return the locale of this object
+ * @return <code>null</code>.
*/
- public Locale getLocale()
+ public Locale getLocale()
+ throws IllegalComponentStateException
{
- return Locale.getDefault();
+ // refer to Sun's bug report 4269253
+ return null;
}
/**
- * Returns the accessible Icon description. This returns the
- * actual 'description' property of the ImageIcon.
+ * Returns the accessible icon description. This returns the
+ * <code>description</code> property of the underlying {@link ImageIcon}.
*
- * @return the accessible Icon description
+ * @return The description (possibly <code>null</code>).
+ *
+ * @see #setAccessibleIconDescription(String)
*/
public String getAccessibleIconDescription()
{
@@ -169,10 +177,12 @@ public class ImageIcon
}
/**
- * Sets the accessible Icon description. This sets the
- * actual 'description' property of the ImageIcon.
+ * Sets the accessible icon description. This sets the
+ * <code>description</code> property of the underlying {@link ImageIcon}.
*
- * @param newDescr the description to be set
+ * @param newDescr the description (<code>null</code> permitted).
+ *
+ * @see #getAccessibleIconDescription()
*/
public void setAccessibleIconDescription(String newDescr)
{
@@ -180,10 +190,10 @@ public class ImageIcon
}
/**
- * Returns the icon height. This returns the iconHeight property of
- * the underlying Icon.
+ * Returns the icon height. This returns the <code>iconHeight</code>
+ * property of the underlying {@link ImageIcon}.
*
- * @return the icon height
+ * @return The icon height.
*/
public int getAccessibleIconHeight()
{
@@ -191,10 +201,10 @@ public class ImageIcon
}
/**
- * Returns the icon width. This returns the iconWidth property of
- * the underlying Icon.
+ * Returns the icon width. This returns the <code>iconWidth</code> property
+ * of the underlying {@link ImageIcon}.
*
- * @return the icon width
+ * @return The icon width.
*/
public int getAccessibleIconWidth()
{
@@ -446,9 +456,11 @@ public class ImageIcon
}
/**
- * Returns the AccessibleContext for this ImageIcon.
+ * Returns the object that provides accessibility features for this
+ * <code>ImageIcon</code> instance.
*
- * @return the AccessibleContext for this ImageIcon
+ * @return The accessible context (an instance of
+ * {@link AccessibleImageIcon}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JButton.java b/javax/swing/JButton.java
index c1340bbc2..787adb87c 100644
--- a/javax/swing/JButton.java
+++ b/javax/swing/JButton.java
@@ -1,5 +1,5 @@
/* JButton.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -78,27 +78,57 @@ public class JButton extends AbstractButton
*/
private boolean defaultCapable;
+ /**
+ * Creates a new button with an empty string for the button text and no
+ * icon.
+ */
public JButton()
{
this(null, null);
}
+ /**
+ * Creates a new button from the specified action.
+ *
+ * @param a the action (<code>null</code> permitted).
+ *
+ * @see AbstractButton#setAction(Action)
+ */
public JButton(Action a)
{
this();
setAction(a);
}
+ /**
+ * Creates a new button with the specified icon (and an empty string for
+ * the button text).
+ *
+ * @param icon the icon (<code>null</code> permitted).
+ */
public JButton(Icon icon)
{
this(null, icon);
}
+ /**
+ * Creates a new button with the specified text and no icon.
+ *
+ * @param text the button text (<code>null</code> permitted, will be
+ * substituted by an empty string).
+ */
public JButton(String text)
{
this(text, null);
}
+ /**
+ * Creates a new button with the specified text and icon.
+ *
+ * @param text the button text (<code>null</code> permitted, will be
+ * substituted by an empty string).
+ * @param icon the icon (<code>null</code> permitted).
+ */
public JButton(String text, Icon icon)
{
super();
@@ -108,12 +138,16 @@ public class JButton extends AbstractButton
}
protected void configurePropertiesFromAction(Action a)
- {
- // Factory method which sets the AbstractButton's properties according to
- // values from the Action instance.
+ {
super.configurePropertiesFromAction(a);
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JButton</code> component.
+ *
+ * @return The accessible context (an instance of {@link AccessibleJButton}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -121,6 +155,13 @@ public class JButton extends AbstractButton
return accessibleContext;
}
+ /**
+ * Returns the suffix (<code>"ButtonUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JButton</code>.
+ *
+ * @return <code>"ButtonUI"</code>.
+ */
public String getUIClassID()
{
// Returns a string that specifies the name of the L&F class that renders
@@ -138,7 +179,7 @@ public class JButton extends AbstractButton
* its <code>JRootPane</code>
*
* @see #isDefaultCapable()
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
*/
@@ -160,7 +201,7 @@ public class JButton extends AbstractButton
*
* @return <code>true</code> if this button can act as the default button
*
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see #isDefaultButton()
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
@@ -172,6 +213,13 @@ public class JButton extends AbstractButton
return defaultCapable;
}
+ /**
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JButton</code>.
+ *
+ * @return A string describing the attributes of this <code>JButton</code>
+ * (never <code>null</code>).
+ */
protected String paramString()
{
String superParam = super.paramString();
@@ -205,7 +253,7 @@ public class JButton extends AbstractButton
* @param defaultCapable <code>true</code> if this button can become the
* default button in its JRootPane, <code>false</code> otherwise
*
- * @see #setDefaultCapable()
+ * @see #setDefaultCapable(boolean)
* @see #isDefaultButton()
* @see JRootPane#getDefaultButton()
* @see JRootPane#setDefaultButton(JButton)
@@ -215,6 +263,10 @@ public class JButton extends AbstractButton
this.defaultCapable = defaultCapable;
}
+ /**
+ * Sets this button's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
+ */
public void updateUI()
{
setUI((ButtonUI) UIManager.getUI(this));
diff --git a/javax/swing/JComboBox.java b/javax/swing/JComboBox.java
index f995e114a..17bcf1f99 100644
--- a/javax/swing/JComboBox.java
+++ b/javax/swing/JComboBox.java
@@ -1,5 +1,5 @@
/* JComboBox.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -1102,15 +1102,33 @@ public class JComboBox extends JComponent implements ItemSelectable,
}
/**
- * A string that describes this JComboBox. Normally only used for debugging.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JComboBox</code>.
*
- * @return A string describing this JComboBox
+ * @return A string describing the attributes of this <code>JComboBox</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JComboBox";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isEditable=").append(isEditable());
+ sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled());
+ sb.append(",maximumRowCount=").append(getMaximumRowCount());
+
+ sb.append(",selectedItemReminder=");
+ if (selectedItemReminder != null)
+ sb.append(selectedItemReminder);
+ return superParamStr + sb.toString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JComboBox</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJComboBox}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -1219,6 +1237,10 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
private static final long serialVersionUID = 8217828307256675666L;
+ /**
+ * @specnote This constructor was protected in 1.4, but made public
+ * in 1.5.
+ */
public AccessibleJComboBox()
{
// Nothing to do here.
@@ -1254,6 +1276,11 @@ public class JComboBox extends JComponent implements ItemSelectable,
return false;
}
+ /**
+ * Returns the accessible role for the <code>JComboBox</code> component.
+ *
+ * @return {@link AccessibleRole#COMBO_BOX}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.COMBO_BOX;
diff --git a/javax/swing/JComponent.java b/javax/swing/JComponent.java
index eba05d03c..8838dda0a 100644
--- a/javax/swing/JComponent.java
+++ b/javax/swing/JComponent.java
@@ -1862,8 +1862,8 @@ public abstract class JComponent extends Container implements Serializable
// Go through children from top to bottom and find out their paint
// rectangles.
- int index = 0;
- while (paintRectangles.size() > 0 && index < children.length)
+ for (int index = 0; paintRectangles.size() > 0 &&
+ index < children.length; index++)
{
Component comp = children[index];
if (! comp.isVisible())
@@ -1936,6 +1936,12 @@ public abstract class JComponent extends Container implements Serializable
newPaintRects.add(rect);
}
}
+ else
+ {
+ // Not opaque, need to reuse the current paint rectangles
+ // for the next component.
+ newPaintRects.add(r);
+ }
}
else
@@ -1958,8 +1964,6 @@ public abstract class JComponent extends Container implements Serializable
paintRegions.add(componentRectangles);
componentRectangles = new ArrayList();
}
-
- index++;
}
// paintingTile becomes true just before we start painting the component's
@@ -2024,34 +2028,10 @@ public abstract class JComponent extends Container implements Serializable
g.clipRect(inner.x, inner.y, inner.width, inner.height);
Component[] children = getComponents();
- // Find the bottommost component that needs to be painted. This is the
- // component that - together with the rectangles of the components that
- // are painted above it - covers the whole clip area.
- Rectangle rect = new Rectangle();
- int startIndex = children.length - 1;
- for (int i = 0; i < children.length; i++)
- {
- Rectangle b = children[i].getBounds();
- if (children[i].isOpaque() && children[i].isVisible()
- && g.hitClip(b.x, b.y, b.width, b.height))
- {
- if (rect.isEmpty())
- rect.setBounds(b);
- else
- SwingUtilities.computeUnion(b.x, b.y, b.width, b.height, rect);
-
- if (SwingUtilities.isRectangleContainingRectangle(rect, inner))
- {
- startIndex = i;
- break;
- }
- }
- }
-
// paintingTile becomes true just before we start painting the component's
// children.
paintingTile = true;
- for (int i = startIndex; i >= 0; i--) //children.length; i++)
+ for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
{
// paintingTile must be set to false before we begin to start painting
// the last tile.
@@ -2942,9 +2922,12 @@ public abstract class JComponent extends Container implements Serializable
}
/**
- * Set the value of the {@link #opaque} property.
+ * Set if the component should paint all pixels withing its bounds.
+ * If this property is set to false, the component expects the cleared
+ * background.
*
- * @param isOpaque The new value of the property
+ * @param isOpaque if true, paint all pixels. If false, expect the clean
+ * background.
*
* @see ComponentUI#update
*/
diff --git a/javax/swing/JDesktopPane.java b/javax/swing/JDesktopPane.java
index 92b25f979..454870ea6 100644
--- a/javax/swing/JDesktopPane.java
+++ b/javax/swing/JDesktopPane.java
@@ -56,7 +56,6 @@ import javax.swing.plaf.DesktopPaneUI;
*/
public class JDesktopPane extends JLayeredPane implements Accessible
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = 766333777224038726L;
/**
@@ -94,15 +93,15 @@ public class JDesktopPane extends JLayeredPane implements Accessible
private boolean clientDragModeSet = false;
/**
- * AccessibleJDesktopPane
+ * Provides the accessibility features for the <code>JDesktopPane</code>
+ * component.
*/
protected class AccessibleJDesktopPane extends AccessibleJComponent
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = 6079388927946077570L;
/**
- * Constructor AccessibleJDesktopPane
+ * Creates a new <code>AccessibleJDesktopPane</code> instance.
*/
protected AccessibleJDesktopPane()
{
@@ -110,9 +109,9 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JSlider</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#DESKTOP_PANE}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -298,13 +297,22 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * This method returns a String that describes the JDesktopPane.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JDesktopPane</code>.
*
- * @return A String that describes the JDesktopPane.
+ * @return A string describing the attributes of this <code>JDesktopPane</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JDesktopPane";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isOptimizedDrawingPossible=");
+ sb.append(isOptimizedDrawingEnabled());
+ sb.append(",desktopManager=");
+ if (desktopManager != null)
+ sb.append(desktopManager);
+ return superParamStr + sb.toString();
}
/**
@@ -330,9 +338,11 @@ public class JDesktopPane extends JLayeredPane implements Accessible
}
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JDesktopPane</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of
+ * {@link AccessibleJDesktopPane}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JInternalFrame.java b/javax/swing/JInternalFrame.java
index 937212562..79dcc7326 100644
--- a/javax/swing/JInternalFrame.java
+++ b/javax/swing/JInternalFrame.java
@@ -280,15 +280,17 @@ public class JInternalFrame extends JComponent implements Accessible,
updateUI();
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JDesktopIcon</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJDesktopIcon}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
- accessibleContext = new AccessibleJDesktopIcon();
+ accessibleContext = new AccessibleJDesktopIcon();
return accessibleContext;
}
@@ -773,10 +775,16 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method returns the default action taken when this JInternalFrame is
- * closed.
+ * Returns a code for the default action taken when this
+ * <code>JInternalFrame</code> is closed.
*
- * @return The default action taken when this JInternalFrame is closed.
+ * @return The action code (usually one of
+ * {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE}, or
+ * {@link WindowConstants#DISPOSE_ON_CLOSE}).
+ *
+ * @see #setDefaultCloseOperation(int)
+ * @see #doDefaultCloseAction()
*/
public int getDefaultCloseOperation()
{
@@ -1202,13 +1210,15 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method returns a String describing this JInternalFrame.
+ * An implementation dependent string describing the current state of this
+ * <code>JInternalFrame</code> instance.
*
- * @return A String describing this JInternalFrame.
+ * @return A string describing the current state of this
+ * <code>JInternalFrame</code> instance.
*/
protected String paramString()
{
- return super.paramString();
+ return super.paramString() + ",title=" + getTitle();
}
/**
@@ -1322,12 +1332,17 @@ public class JInternalFrame extends JComponent implements Accessible,
}
/**
- * This method sets the action taken when this JInternalFrame is closed.
- *
- * @param operation One of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE or
- * DISPOSE_ON_CLOSE.
+ * Sets a code for the action to be taken when this
+ * <code>JInternalFrame</code> is closed. Note that no validation is
+ * performed on the <code>operation</code> code, any integer will be
+ * accepted (nevertheless, you should pass in one of the listed values).
*
- * @throws Error If the given operation is not one of the allowed modes.
+ * @param operation one of {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE} or
+ * {@link WindowConstants#DISPOSE_ON_CLOSE}.
+ *
+ * @see #getDefaultCloseOperation()
+ * @see #doDefaultCloseAction()
*/
public void setDefaultCloseOperation(int operation)
{
diff --git a/javax/swing/JLabel.java b/javax/swing/JLabel.java
index 7c552469e..65b1e6fcd 100644
--- a/javax/swing/JLabel.java
+++ b/javax/swing/JLabel.java
@@ -512,6 +512,7 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
Icon oldIcon = icon;
icon = newIcon;
firePropertyChange("icon", oldIcon, newIcon);
+ repaint();
}
}
diff --git a/javax/swing/JList.java b/javax/swing/JList.java
index 04f658361..04f3881a2 100644
--- a/javax/swing/JList.java
+++ b/javax/swing/JList.java
@@ -1,5 +1,5 @@
/* JList.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -1022,48 +1022,56 @@ public class JList extends JComponent implements Accessible, Scrollable
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*/
public JList()
{
- init();
+ init(new DefaultListModel());
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param items the initial list items.
*/
- public JList(Object[] listData)
+ public JList(Object[] items)
{
- init();
- setListData(listData);
+ init(createListModel(items));
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param items the initial list items.
*/
- public JList(Vector<?> listData)
+ public JList(Vector<?> items)
{
- init();
- setListData(listData);
+ init(createListModel(items));
}
/**
- * Creates a new JList object.
+ * Creates a new <code>JList</code> object.
*
- * @param listData Initial data to populate the list with
+ * @param model a model containing the list items (<code>null</code> not
+ * permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
*/
- public JList(ListModel listData)
+ public JList(ListModel model)
{
- init();
- setModel(listData);
+ init(model);
}
- void init()
+ /**
+ * Initializes the list.
+ *
+ * @param m the list model (<code>null</code> not permitted).
+ */
+ private void init(ListModel m)
{
+ if (m == null)
+ throw new IllegalArgumentException("Null model not permitted.");
dragEnabled = false;
fixedCellHeight = -1;
fixedCellWidth = -1;
@@ -1075,9 +1083,17 @@ public class JList extends JComponent implements Accessible, Scrollable
cellRenderer = new DefaultListCellRenderer();
listListener = new ListListener();
- setModel(new DefaultListModel());
- setSelectionModel(createSelectionModel());
- setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ model = m;
+ if (model != null)
+ model.addListDataListener(listListener);
+
+ selectionModel = createSelectionModel();
+ if (selectionModel != null)
+ {
+ selectionModel.addListSelectionListener(listListener);
+ selectionModel.setSelectionMode
+ (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ }
setLayout(null);
updateUI();
@@ -1117,6 +1133,8 @@ public class JList extends JComponent implements Accessible, Scrollable
* #prototypeCellValue} property is set, but setting it explicitly
* overrides the height computed from {@link #prototypeCellValue}.
*
+ * @param h the height.
+ *
* @see #getFixedCellHeight
* @see #getPrototypeCellValue
*/
@@ -1127,7 +1145,7 @@ public class JList extends JComponent implements Accessible, Scrollable
int old = fixedCellHeight;
fixedCellHeight = h;
- firePropertyChange("fixedCellWidth", old, h);
+ firePropertyChange("fixedCellHeight", old, h);
}
@@ -1549,20 +1567,39 @@ public class JList extends JComponent implements Accessible, Scrollable
* @param listData The object array to build a new list model on
* @see #setModel
*/
- public void setListData(final Object[] listData)
+ public void setListData(Object[] listData)
{
- setModel(new AbstractListModel()
- {
- public int getSize()
- {
- return listData.length;
- }
+ setModel(createListModel(listData));
+ }
- public Object getElementAt(int i)
- {
- return listData[i];
- }
- });
+ private ListModel createListModel(final Object[] items)
+ {
+ return new AbstractListModel()
+ {
+ public int getSize()
+ {
+ return items.length;
+ }
+ public Object getElementAt(int i)
+ {
+ return items[i];
+ }
+ };
+ }
+
+ private ListModel createListModel(final Vector items)
+ {
+ return new AbstractListModel()
+ {
+ public int getSize()
+ {
+ return items.size();
+ }
+ public Object getElementAt(int i)
+ {
+ return items.get(i);
+ }
+ };
}
/**
@@ -1576,17 +1613,17 @@ public class JList extends JComponent implements Accessible, Scrollable
public void setListData(final Vector<?> listData)
{
setModel(new AbstractListModel()
- {
- public int getSize()
- {
- return listData.size();
- }
-
- public Object getElementAt(int i)
- {
- return listData.elementAt(i);
- }
- });
+ {
+ public int getSize()
+ {
+ return listData.size();
+ }
+
+ public Object getElementAt(int i)
+ {
+ return listData.elementAt(i);
+ }
+ });
}
/**
@@ -2022,11 +2059,27 @@ public class JList extends JComponent implements Accessible, Scrollable
return selectionModel.getLeadSelectionIndex();
}
+ /**
+ * Returns the lowest item index in the current selection, or <code>-1</code>
+ * if there is no selection.
+ *
+ * @return The index.
+ *
+ * @see #getMaxSelectionIndex()
+ */
public int getMinSelectionIndex()
{
- return selectionModel.getMaxSelectionIndex();
+ return selectionModel.getMinSelectionIndex();
}
+ /**
+ * Returns the highest item index in the current selection, or
+ * <code>-1</code> if there is no selection.
+ *
+ * @return The index.
+ *
+ * @see #getMinSelectionIndex()
+ */
public int getMaxSelectionIndex()
{
return selectionModel.getMaxSelectionIndex();
@@ -2140,7 +2193,14 @@ public class JList extends JComponent implements Accessible, Scrollable
*/
public Rectangle getCellBounds(int index0, int index1)
{
- return getUI().getCellBounds(this, index0, index1);
+ ListUI ui = getUI();
+ Rectangle bounds = null;
+ if (ui != null)
+ {
+ bounds = ui.getCellBounds(this, index0, index1);
+ }
+ // When the UI is null, this method also returns null in the RI.
+ return bounds;
}
/**
@@ -2203,4 +2263,28 @@ public class JList extends JComponent implements Accessible, Scrollable
}
return index;
}
+
+ /**
+ * Returns a string describing the attributes for the <code>JList</code>
+ * component, for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format of the string may vary between
+ * implementations.
+ *
+ * @return A string describing the attributes of the <code>JList</code>.
+ */
+ protected String paramString()
+ {
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",fixedCellHeight=").append(getFixedCellHeight());
+ sb.append(",fixedCellWidth=").append(getFixedCellWidth());
+ sb.append(",selectionBackground=");
+ if (getSelectionBackground() != null)
+ sb.append(getSelectionBackground());
+ sb.append(",selectionForeground=");
+ if (getSelectionForeground() != null)
+ sb.append(getSelectionForeground());
+ sb.append(",visibleRowCount=").append(getVisibleRowCount());
+ sb.append(",layoutOrientation=").append(getLayoutOrientation());
+ return sb.toString();
+ }
}
diff --git a/javax/swing/JMenu.java b/javax/swing/JMenu.java
index 438fc49f1..37ed14854 100644
--- a/javax/swing/JMenu.java
+++ b/javax/swing/JMenu.java
@@ -1,5 +1,5 @@
/* JMenu.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Point;
import java.awt.event.KeyEvent;
@@ -821,26 +823,31 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
}
public int getAccessibleChildrenCount()
+ throws NotImplementedException
{
return 0;
}
public Accessible getAccessibleChild(int value0)
+ throws NotImplementedException
{
return null;
}
public AccessibleSelection getAccessibleSelection()
+ throws NotImplementedException
{
return null;
}
public Accessible getAccessibleSelection(int value0)
+ throws NotImplementedException
{
return null;
}
public boolean isAccessibleChildSelected(int value0)
+ throws NotImplementedException
{
return false;
}
@@ -851,26 +858,31 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
}
public int getAccessibleSelectionCount()
+ throws NotImplementedException
{
return 0;
}
public void addAccessibleSelection(int value0)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void removeAccessibleSelection(int value0)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void clearAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
public void selectAllAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/JMenuItem.java b/javax/swing/JMenuItem.java
index 643fe8fd5..272c1cfe6 100644
--- a/javax/swing/JMenuItem.java
+++ b/javax/swing/JMenuItem.java
@@ -1,5 +1,5 @@
/* JMenuItem.java --
- Copyright (C) 2002, 2004, 2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -671,16 +673,26 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
/**
- * A string that describes this JMenuItem. Normally only used
- * for debugging.
+ * Returns a string describing the attributes for the <code>JToolTip</code>
+ * component, for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format of the string may vary between
+ * implementations.
*
- * @return A string describing this JMenuItem
+ * @return A string describing the attributes of the <code>JMenuItem</code>.
*/
protected String paramString()
{
+ // calling super seems to be sufficient here...
return super.paramString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JMenuItem</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJMenuItem}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -689,13 +701,19 @@ public class JMenuItem extends AbstractButton implements Accessible,
return accessibleContext;
}
+ /**
+ * Provides the accessibility features for the <code>JMenuItem</code>
+ * component.
+ *
+ * @see JMenuItem#getAccessibleContext()
+ */
protected class AccessibleJMenuItem extends AccessibleAbstractButton
implements ChangeListener
{
private static final long serialVersionUID = 6748924232082076534L;
/**
- * Creates a new AccessibleJMenuItem object.
+ * Creates a new <code>AccessibleJMenuItem</code> instance.
*/
AccessibleJMenuItem()
{
@@ -703,10 +721,16 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
public void stateChanged(ChangeEvent event)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
+ /**
+ * Returns the accessible role for the <code>JMenuItem</code> component.
+ *
+ * @return {@link AccessibleRole#MENU_ITEM}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.MENU_ITEM;
diff --git a/javax/swing/JPanel.java b/javax/swing/JPanel.java
index 815e452dc..3bd71d1c2 100644
--- a/javax/swing/JPanel.java
+++ b/javax/swing/JPanel.java
@@ -1,5 +1,5 @@
/* JPanel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -80,54 +80,108 @@ public class JPanel extends JComponent implements Accessible
}
}
+ /**
+ * Creates a new panel with a new instance of {@link FlowLayout} as the
+ * layout manager and double-buffering enabled.
+ */
public JPanel()
{
this(new FlowLayout(), true);
}
- public JPanel(boolean double_buffered)
+ /**
+ * Creates a new panel with double-buffering enabled or disabled as
+ * specified. The default layout manager is an instance of
+ * {@link FlowLayout}.
+ *
+ * @param isDoubleBuffered a flag that controls whether or not
+ * double-buffering is enabled.
+ */
+ public JPanel(boolean isDoubleBuffered)
{
- this(new FlowLayout(), double_buffered);
+ this(new FlowLayout(), isDoubleBuffered);
}
+ /**
+ * Creates a new panel with the specified layout manager. Double-buffering
+ * is enabled by default.
+ *
+ * @param layout the layout manager (<code>null</code> permitted).
+ */
public JPanel(LayoutManager layout)
{
this(layout, true);
}
+ /**
+ * Creates a new panel with the specified layout manager and
+ * double-buffering.
+ *
+ * @param layout the layout manager (<code>null</code> permitted).
+ * @param isDoubleBuffered a flag that controls whether or not
+ * double-buffering is enabled.
+ */
public JPanel(LayoutManager layout, boolean isDoubleBuffered)
{
- if (layout == null)
- {
- // TODO: Is this correct? Or should we throw a NPE?
- layout = new FlowLayout();
- }
setLayout(layout);
- setOpaque(true);
-
+ setOpaque(true);
+ setDoubleBuffered(isDoubleBuffered);
updateUI();
}
+ /**
+ * Returns the suffix (<code>"PanelUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JPanel</code>.
+ *
+ * @return <code>"PanelUI"</code>.
+ */
public String getUIClassID()
{
return "PanelUI";
}
+ /**
+ * Sets the UI delegate for the <code>JPanel</code> component.
+ *
+ * @param ui the UI delegate.
+ *
+ * @since 1.4
+ * @see #getUI()
+ */
public void setUI(PanelUI ui)
{
super.setUI(ui);
}
+ /**
+ * Returns the UI delegate for the <code>JPanel</code> component.
+ *
+ * @return The UI delegate.
+ *
+ * @since 1.4
+ * @see #setUI(PanelUI)
+ */
public PanelUI getUI()
{
return (PanelUI) ui;
}
+ /**
+ * Sets this panel's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
+ */
public void updateUI()
{
setUI((PanelUI) UIManager.getUI(this));
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JPanel</code> component.
+ *
+ * @return The accessible context (an instance of {@link AccessibleJPanel}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -135,7 +189,14 @@ public class JPanel extends JComponent implements Accessible
return accessibleContext;
}
- protected String paramString()
+ /**
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JPanel</code>.
+ *
+ * @return A string describing the attributes of this <code>JPanel</code>
+ * (never <code>null</code>).
+ */
+ protected String paramString()
{
return super.paramString();
}
diff --git a/javax/swing/JProgressBar.java b/javax/swing/JProgressBar.java
index 2f61ac305..db936f64a 100644
--- a/javax/swing/JProgressBar.java
+++ b/javax/swing/JProgressBar.java
@@ -634,15 +634,28 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns a string that can be used to
- * describe this JProgressBar. This method is usually
- * only used for debugging purposes.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JProgressBar</code>.
*
- * @return A string that describes this JProgressBar.
+ * @return A string describing the attributes of this
+ * <code>JProgressBar</code> (never <code>null</code>).
*/
protected String paramString()
{
- return "JProgressBar";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL)
+ sb.append("HORIZONTAL");
+ else
+ sb.append("VERTICAL");
+ sb.append(",paintBorder=").append(isBorderPainted());
+ sb.append(",paintString=").append(isStringPainted());
+ sb.append(",progressString=");
+ if (progressString != null)
+ sb.append(progressString);
+ sb.append(",indeterminateString=").append(isIndeterminate());
+ return superParamStr + sb.toString();
}
/**
diff --git a/javax/swing/JRadioButtonMenuItem.java b/javax/swing/JRadioButtonMenuItem.java
index 61a8dbab3..0d7c1d105 100644
--- a/javax/swing/JRadioButtonMenuItem.java
+++ b/javax/swing/JRadioButtonMenuItem.java
@@ -1,5 +1,5 @@
/* JRadioButtonMenuItem.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -168,16 +168,27 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
}
/**
- * A string that describes this JRadioButtonMenuItem. Normally only used
- * for debugging.
+ * Returns a string describing the attributes for the
+ * <code>JRadioButtonMenuItem</code> component, for use in debugging. The
+ * return value is guaranteed to be non-<code>null</code>, but the format of
+ * the string may vary between implementations.
*
- * @return A string describing this JRadioButtonMenuItem
+ * @return A string describing the attributes of the
+ * <code>JRadioButtonMenuItem</code>.
*/
protected String paramString()
{
- return "JRadioButtonMenuItem";
+ // calling super seems to be sufficient here...
+ return super.paramString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JRadioButtonMenuItem</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJRadioButtonMenuItem}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -186,18 +197,30 @@ public class JRadioButtonMenuItem extends JMenuItem implements Accessible
return accessibleContext;
}
+ /**
+ * Provides the accessibility features for the
+ * <code>JRadioButtonMenuItem</code> component.
+ *
+ * @see JRadioButtonMenuItem#getAccessibleContext()
+ */
protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem
{
private static final long serialVersionUID = 4381471510145292179L;
/**
- * Creates a new AccessibleJRadioButtonMenuItem object.
+ * Creates a new <code>AccessibleJRadioButtonMenuItem</code> instance.
*/
protected AccessibleJRadioButtonMenuItem()
{
// Nothing to do here.
}
+ /**
+ * Returns the accessible role for the <code>JRadioButtonMenuItem</code>
+ * component.
+ *
+ * @return {@link AccessibleRole#RADIO_BUTTON}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.RADIO_BUTTON;
diff --git a/javax/swing/JScrollPane.java b/javax/swing/JScrollPane.java
index b1e16a681..09e37378b 100644
--- a/javax/swing/JScrollPane.java
+++ b/javax/swing/JScrollPane.java
@@ -51,7 +51,6 @@ import javax.accessibility.AccessibleContext;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.plaf.ScrollBarUI;
import javax.swing.plaf.ScrollPaneUI;
import javax.swing.plaf.UIResource;
diff --git a/javax/swing/JSeparator.java b/javax/swing/JSeparator.java
index 602af6a38..c87783b73 100644
--- a/javax/swing/JSeparator.java
+++ b/javax/swing/JSeparator.java
@@ -37,12 +37,13 @@ exception statement from your version. */
package javax.swing;
+import java.beans.PropertyChangeEvent;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.plaf.SeparatorUI;
-
/**
* The JSeparator. It is mostly used to divide/space out
* components.
@@ -51,14 +52,15 @@ public class JSeparator extends JComponent implements SwingConstants,
Accessible
{
/**
- * AccessibleJSeparator
+ * Provides the accessibility features for the <code>JSeparator</code>
+ * component.
*/
protected class AccessibleJSeparator extends AccessibleJComponent
{
private static final long serialVersionUID = 916332890553201095L;
/**
- * Constructor AccessibleJSeparator
+ * Creates a new <code>AccessibleJSeparator</code> instance.
*/
protected AccessibleJSeparator()
{
@@ -66,9 +68,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JSeparator</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#SEPARATOR}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -82,7 +84,7 @@ public class JSeparator extends JComponent implements SwingConstants,
private transient int orientation = HORIZONTAL;
/**
- * Creates a new horizontal JSeparator object.
+ * Creates a new horizontal <code>JSeparator</code> object.
*/
public JSeparator()
{
@@ -90,9 +92,13 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * Creates a new JSeparator object with the given orientation.
+ * Creates a new <code>JSeparator</code> object with the given orientation.
*
- * @param orientation The orientation of the JSeparator.
+ * @param orientation the orientation (either {@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if <code>orientation</code> is not
+ * one of the specified values.
*/
public JSeparator(int orientation)
{
@@ -104,10 +110,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the UI delegate being
- * used with the JSeparator.
+ * Returns the UI delegate being used with the <code>JSeparator</code>.
*
- * @return SeparatorUI The JSeparator's UI delegate.
+ * @return The JSeparator's UI delegate.
*/
public SeparatorUI getUI()
{
@@ -115,10 +120,9 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method sets the UI delegate to use
- * with the JSeparator.
+ * Sets the separator's UI delegate.
*
- * @param ui The UI delegate to use.
+ * @param ui the UI delegate.
*/
public void setUI(SeparatorUI ui)
{
@@ -126,8 +130,8 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method resets the UI delegate to the
- * default for the current look and feel.
+ * Sets this separator's UI delegate to the default (obtained from the
+ * {@link UIManager}) for the current look and feel.
*/
public void updateUI()
{
@@ -135,11 +139,11 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the identifier string
- * that is used to determine the UI delegate
- * from the current look and feel.
+ * Returns the suffix (<code>"SeparatorUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JSeparator</code>.
*
- * @return String The identifier string for the UI.
+ * @return <code>"SeparatorUI"</code>.
*/
public String getUIClassID()
{
@@ -147,9 +151,11 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method returns the JSeparator's orientation.
+ * Returns the orientation of the <code>JSeparator</code>.
*
- * @return int The JSeparator's orientation.
+ * @return The orientation (one of {@link #HORIZONTAL} and {@link #VERTICAL}).
+ *
+ * @see #setOrientation(int)
*/
public int getOrientation()
{
@@ -157,33 +163,50 @@ public class JSeparator extends JComponent implements SwingConstants,
}
/**
- * This method changes the JSeparator's orientation.
+ * Sets the orientation for the <code>JSeparator</code> and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * <code>orientation</code>) to all registered listeners.
*
- * @param orientation The JSeparator's orientation.
+ * @param orientation the orientation (either {@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if <code>orientation</code> is not
+ * one of the specified values.
+ *
+ * @see #getOrientation()
*/
public void setOrientation(int orientation)
{
if (orientation != HORIZONTAL && orientation != VERTICAL)
throw new IllegalArgumentException(orientation
+ " is not a valid orientation.");
+ int old = this.orientation;
this.orientation = orientation;
+ firePropertyChange("orientation", old, orientation);
}
/**
- * This method returns a string desribing the JSeparator.
- * Normally only used in debugging.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSeparator</code>.
*
- * @return String A string describing the JSeparator.
+ * @return A string describing the attributes of this <code>JSeparator</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSeparator";
+ String superParamStr = super.paramString();
+ if (orientation == HORIZONTAL)
+ return superParamStr + ",orientation=HORIZONTAL";
+ else
+ return superParamStr + ",orientation=VERTICAL";
}
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JSeparator</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of
+ * {@link AccessibleJSeparator}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JSlider.java b/javax/swing/JSlider.java
index f298cbebf..ed94c4ecc 100644
--- a/javax/swing/JSlider.java
+++ b/javax/swing/JSlider.java
@@ -1068,15 +1068,35 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
}
/**
- * Returns a string describing the attributes of this slider, for debugging
- * purposes. According to the specification, this method is implementation
- * specific, we just return "JSlider" at present.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSlider</code>.
*
- * @return Returns a string describing the attributes of this slider.
+ * @return A string describing the attributes of this <code>JSlider</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSlider";
+ String superParamStr = super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",isInverted=").append(getInverted());
+ sb.append(",majorTickSpacing=").append(getMajorTickSpacing());
+ sb.append(",minorTickSpacing=").append(getMinorTickSpacing());
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL)
+ sb.append("HORIZONTAL");
+ else
+ sb.append("VERTICAL");
+ sb.append(",paintLabels=").append(getPaintLabels());
+ sb.append(",paintTicks=").append(getPaintTicks());
+ sb.append(",paintTrack=").append(getPaintTrack());
+ sb.append(",snapToTicks=").append(getSnapToTicks());
+
+ // the following is output by the reference implementation. We don't
+ // strictly need to replicate this. Perhaps it has some meaning, but
+ // I couldn't determine it yet...
+ sb.append(",snapToValue=true");
+
+ return superParamStr + sb.toString();
}
/**
diff --git a/javax/swing/JSpinner.java b/javax/swing/JSpinner.java
index 882d216e1..70045ed53 100644
--- a/javax/swing/JSpinner.java
+++ b/javax/swing/JSpinner.java
@@ -106,6 +106,10 @@ public class JSpinner extends JComponent
add(ftf);
ftf.setValue(spinner.getValue());
ftf.addPropertyChangeListener(this);
+ if(getComponentOrientation().isLeftToRight())
+ ftf.setHorizontalAlignment(JTextField.RIGHT);
+ else
+ ftf.setHorizontalAlignment(JTextField.LEFT);
spinner.addChangeListener(this);
}
diff --git a/javax/swing/JSplitPane.java b/javax/swing/JSplitPane.java
index cb2640570..4e18b7cda 100644
--- a/javax/swing/JSplitPane.java
+++ b/javax/swing/JSplitPane.java
@@ -1,5 +1,5 @@
/* JSplitPane.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,10 +40,12 @@ package javax.swing;
import java.awt.Component;
import java.awt.Graphics;
+import java.beans.PropertyChangeEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
import javax.swing.plaf.SplitPaneUI;
@@ -56,18 +58,18 @@ import javax.swing.plaf.SplitPaneUI;
*/
public class JSplitPane extends JComponent implements Accessible
{
+
/**
- * DOCUMENT ME!
+ * Provides the accessibility features for the <code>JSplitPane</code>
+ * component.
*/
- // FIXME: This inner class is a complete stub and must be implemented
- // properly.
protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
implements AccessibleValue
{
private static final long serialVersionUID = -1788116871416305366L;
/**
- * Creates a new AccessibleJSplitPane object.
+ * Creates a new <code>AccessibleJSplitPane</code> instance.
*/
protected AccessibleJSplitPane()
{
@@ -75,75 +77,101 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns a set containing the current state of the {@link JSplitPane}
+ * component.
*
- * @return DOCUMENT ME!
+ * @return The accessible state set.
*/
public AccessibleStateSet getAccessibleStateSet()
{
- return null;
+ AccessibleStateSet result = super.getAccessibleStateSet();
+ if (getOrientation() == HORIZONTAL_SPLIT)
+ {
+ result.add(AccessibleState.HORIZONTAL);
+ }
+ else if (getOrientation() == VERTICAL_SPLIT)
+ {
+ result.add(AccessibleState.VERTICAL);
+ }
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns the accessible role for the <code>JSplitPane</code> component.
*
- * @return DOCUMENT ME!
+ * @return {@link AccessibleRole#SPLIT_PANE}.
*/
public AccessibleRole getAccessibleRole()
{
- return null;
+ return AccessibleRole.SPLIT_PANE;
}
/**
- * DOCUMENT ME!
+ * Returns an object that provides access to the current, minimum and
+ * maximum values for the {@link JSlider}. Since this class implements
+ * {@link AccessibleValue}, it returns itself.
*
- * @return DOCUMENT ME!
+ * @return The accessible value.
*/
public AccessibleValue getAccessibleValue()
{
- return null;
+ return this;
}
/**
- * DOCUMENT ME!
+ * Returns the current divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The current divider location.
*/
public Number getCurrentAccessibleValue()
{
- return null;
+ return new Integer(getDividerLocation());
}
/**
- * DOCUMENT ME!
+ * Sets the divider location for the {@link JSplitPane} component and sends
+ * a {@link PropertyChangeEvent} (with the property name
+ * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
+ * listeners. If the supplied value is <code>null</code>, this method
+ * does nothing and returns <code>false</code>.
*
- * @param value0 DOCUMENT ME!
+ * @param value the new slider value (<code>null</code> permitted).
*
- * @return DOCUMENT ME!
+ * @return <code>true</code> if the slider value is updated, and
+ * <code>false</code> otherwise.
*/
- public boolean setCurrentAccessibleValue(Number value0)
+ public boolean setCurrentAccessibleValue(Number value)
{
- return false;
+ if (value == null)
+ return false;
+ Number oldValue = getCurrentAccessibleValue();
+ setDividerLocation(value.intValue());
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue,
+ new Integer(value.intValue()));
+ return true;
}
/**
- * DOCUMENT ME!
+ * Returns the minimum divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The minimum divider location.
*/
public Number getMinimumAccessibleValue()
{
- return null;
+ return new Integer(getMinimumDividerLocation());
}
/**
- * DOCUMENT ME!
+ * Returns the maximum divider location for the {@link JSplitPane}
+ * component, as an {@link Integer}.
*
- * @return DOCUMENT ME!
+ * @return The maximum divider location.
*/
public Number getMaximumAccessibleValue()
{
- return null;
+ return new Integer(getMaximumDividerLocation());
}
}
@@ -371,9 +399,11 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns the object that provides accessibility features for this
+ * <code>JSplitPane</code> component.
*
- * @return DOCUMENT ME!
+ * @return The accessible context (an instance of
+ * {@link AccessibleJSplitPane}).
*/
public AccessibleContext getAccessibleContext()
{
@@ -559,14 +589,27 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * This method returns a String that describes this JSplitPane. The string
- * is primarily used for debugging purposes.
+ * Returns an implementation-dependent string describing the attributes of
+ * this <code>JSplitPane</code>.
*
- * @return A String used for debugging purposes.
+ * @return A string describing the attributes of this <code>JSplitPane</code>
+ * (never <code>null</code>).
*/
protected String paramString()
{
- return "JSplitPane";
+ // FIXME: the next line can be restored once PR27208 is fixed
+ String superParamStr = ""; //super.paramString();
+ StringBuffer sb = new StringBuffer();
+ sb.append(",continuousLayout=").append(isContinuousLayout());
+ sb.append(",dividerSize=").append(getDividerSize());
+ sb.append(",lastDividerLocation=").append(getLastDividerLocation());
+ sb.append(",oneTouchExpandable=").append(isOneTouchExpandable());
+ sb.append(",orientation=");
+ if (orientation == HORIZONTAL_SPLIT)
+ sb.append("HORIZONTAL_SPLIT");
+ else
+ sb.append("VERTICAL_SPLIT");
+ return superParamStr + sb.toString();
}
/**
@@ -753,11 +796,15 @@ public class JSplitPane extends JComponent implements Accessible
}
/**
- * This method sets the orientation of the JSplitPane.
+ * Sets the orientation for the <code>JSplitPane</code> and sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * {@link #ORIENTATION_PROPERTY}) to all registered listeners.
*
- * @param orientation The orientation of the JSplitPane.
+ * @param orientation the orientation (either {@link #HORIZONTAL_SPLIT}
+ * or {@link #VERTICAL_SPLIT}).
*
- * @throws IllegalArgumentException DOCUMENT ME!
+ * @throws IllegalArgumentException if <code>orientation</code> is not one of
+ * the listed values.
*/
public void setOrientation(int orientation)
{
@@ -784,7 +831,14 @@ public class JSplitPane extends JComponent implements Accessible
*/
public void setResizeWeight(double value)
{
- resizeWeight = value;
+ if (value < 0.0 || value > 1.0)
+ throw new IllegalArgumentException("Value outside permitted range.");
+ if (this.resizeWeight != value)
+ {
+ double old = resizeWeight;
+ resizeWeight = value;
+ firePropertyChange(RESIZE_WEIGHT_PROPERTY, old, value);
+ }
}
/**
diff --git a/javax/swing/JTabbedPane.java b/javax/swing/JTabbedPane.java
index 0c2180969..34ab8eeaa 100644
--- a/javax/swing/JTabbedPane.java
+++ b/javax/swing/JTabbedPane.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
@@ -102,6 +104,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param e the change event describing the change
*/
public void stateChanged(ChangeEvent e)
+ throws NotImplementedException
{
// Implement this properly.
}
@@ -113,6 +116,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the accessible role of the <code>JTabbedPane</code>
*/
public AccessibleRole getAccessibleRole()
+ throws NotImplementedException
{
return null;
}
@@ -125,6 +129,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* <code>JTabbedPane</code>
*/
public int getAccessibleChildrenCount()
+ throws NotImplementedException
{
return 0;
}
@@ -153,6 +158,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the current selection state of the <code>JTabbedPane</code>
*/
public AccessibleSelection getAccessibleSelection()
+ throws NotImplementedException
{
return null;
}
@@ -169,6 +175,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* this location
*/
public Accessible getAccessibleAt(Point p)
+ throws NotImplementedException
{
return null;
}
@@ -183,6 +190,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* <code>JTabbedPane</code>
*/
public int getAccessibleSelectionCount()
+ throws NotImplementedException
{
return 0;
}
@@ -195,6 +203,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return DOCUMENT ME!
*/
public Accessible getAccessibleSelection(int i)
+ throws NotImplementedException
{
return null;
}
@@ -207,6 +216,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return DOCUMENT ME!
*/
public boolean isAccessibleChildSelected(int i)
+ throws NotImplementedException
{
return false;
}
@@ -217,6 +227,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param i DOCUMENT ME!
*/
public void addAccessibleSelection(int i)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -227,6 +238,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* @param i DOCUMENT ME!
*/
public void removeAccessibleSelection(int i)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -235,6 +247,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* DOCUMENT ME!
*/
public void clearAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -243,6 +256,7 @@ public class JTabbedPane extends JComponent implements Serializable,
* DOCUMENT ME!
*/
public void selectAllAccessibleSelection()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -595,12 +609,14 @@ public class JTabbedPane extends JComponent implements Serializable,
}
public AccessibleStateSet getAccessibleStateSet()
+ throws NotImplementedException
{
// FIXME: Implement this properly.
return null;
}
public int getAccessibleIndexInParent()
+ throws NotImplementedException
{
// FIXME: Implement this properly.
return 0;
diff --git a/javax/swing/JTable.java b/javax/swing/JTable.java
index 89272451e..3463ac26f 100644
--- a/javax/swing/JTable.java
+++ b/javax/swing/JTable.java
@@ -2053,9 +2053,6 @@ public class JTable
int column,
boolean includeSpacing)
{
- // moveToCellBeingEdited expects the cached value and clones it.
- // If the caching would be removed later, uplate moveToCellBeingEdited
- // as well.
int height = getRowHeight(row);
int width = columnModel.getColumn(column).getWidth();
int x_gap = columnModel.getColumnMargin();
@@ -2069,12 +2066,14 @@ public class JTable
for (int i = 0; i < column; ++i)
x += columnModel.getColumn(i).getWidth();
+
+ Rectangle rect = new Rectangle();
if (includeSpacing)
- rectCache.setBounds(x, y, width, height +y_gap);
+ rect.setBounds(x, y, width, height +y_gap);
else
- rectCache.setBounds(x, y, width - x_gap, height);
- return rectCache;
+ rect.setBounds(x, y, width - x_gap, height);
+ return rect;
}
public void clearSelection()
@@ -2434,7 +2433,7 @@ public class JTable
/**
* Get the value of the <code>columnCount</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the columnCount property
*/
@@ -2445,7 +2444,7 @@ public class JTable
/**
* Get the value of the <code>rowCount</code> property by
- * delegation to the @{link #dataModel} field.
+ * delegation to the {@link #dataModel} field.
*
* @return The current value of the rowCount property
*/
@@ -2466,7 +2465,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumn</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumn property
*/
@@ -2535,7 +2534,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumnCount</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumnCount property
*/
@@ -2546,7 +2545,7 @@ public class JTable
/**
* Get the value of the <code>selectedColumns</code> property by
- * delegation to the @{link #columnModel} field.
+ * delegation to the {@link #columnModel} field.
*
* @return The current value of the selectedColumns property
*/
@@ -2567,7 +2566,7 @@ public class JTable
/**
* Get the value of the <code>selectedRowCount</code> property by
- * delegation to the @{link #selectionModel} field.
+ * delegation to the {@link #selectionModel} field.
*
* @return The current value of the selectedRowCount property
*/
@@ -2578,7 +2577,7 @@ public class JTable
/**
* Get the value of the <code>selectedRows</code> property by
- * delegation to the @{link #selectionModel} field.
+ * delegation to the {@link #selectionModel} field.
*
* @return The current value of the selectedRows property
*/
@@ -3722,8 +3721,7 @@ public class JTable
private void moveToCellBeingEdited(Component component)
{
Rectangle r = getCellRect(editingRow, editingColumn, true);
- // Clone rectangle as getCellRect returns the cached value.
- component.setBounds(new Rectangle(r));
+ component.setBounds(r);
}
/**
diff --git a/javax/swing/JToolBar.java b/javax/swing/JToolBar.java
index bc97f9ecd..b576b4f2a 100644
--- a/javax/swing/JToolBar.java
+++ b/javax/swing/JToolBar.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
@@ -67,17 +65,15 @@ import javax.swing.plaf.ToolBarUI;
public class JToolBar extends JComponent implements SwingConstants, Accessible
{
/**
- * AccessibleJToolBar
+ * Provides the accessibility features for the <code>JToolBar</code>
+ * component.
*/
- // FIXME: This inner class is a complete stub and must be implemented
- // properly.
protected class AccessibleJToolBar extends AccessibleJComponent
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = -5516888265903814215L;
/**
- * Constructor AccessibleJToolBar
+ * Creates a new <code>AccessibleJToolBar</code> instance.
*/
protected AccessibleJToolBar()
{
@@ -85,20 +81,23 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
}
/**
- * getAccessibleStateSet
+ * Returns a set containing the current state of the {@link JToolBar}
+ * component. The current implementation simply calls the superclass.
*
- * @return AccessibleStateSet
+ * @return The accessible state set.
*/
public AccessibleStateSet getAccessibleStateSet()
- throws NotImplementedException
{
- return null; // TODO
+ // running tests against the reference implementation, I was unable
+ // to find any state information that is set specifically by the
+ // tool bar...
+ return super.getAccessibleStateSet();
}
/**
- * getAccessibleRole
+ * Returns the accessible role for the <code>JToolBar</code> component.
*
- * @return AccessibleRole
+ * @return {@link AccessibleRole#TOOL_BAR}.
*/
public AccessibleRole getAccessibleRole()
{
@@ -768,9 +767,10 @@ public class JToolBar extends JComponent implements SwingConstants, Accessible
} // paramString()
/**
- * getAccessibleContext
+ * Returns the object that provides accessibility features for this
+ * <code>JToolBar</code> component.
*
- * @return AccessibleContext
+ * @return The accessible context (an instance of {@link AccessibleJToolBar}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JToolTip.java b/javax/swing/JToolTip.java
index 1a4a0f205..836c122c6 100644
--- a/javax/swing/JToolTip.java
+++ b/javax/swing/JToolTip.java
@@ -127,7 +127,7 @@ public class JToolTip extends JComponent implements Accessible
* Returns the object that provides accessibility features for this
* <code>JToolTip</code> component.
*
- * @return The accessible context (an instance of {@link AccessibleJToolTip}.
+ * @return The accessible context (an instance of {@link AccessibleJToolTip}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JTree.java b/javax/swing/JTree.java
index f4b37e106..eb54523e2 100644
--- a/javax/swing/JTree.java
+++ b/javax/swing/JTree.java
@@ -1276,10 +1276,16 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public void valueChanged(TreeSelectionEvent ev)
{
- TreeSelectionEvent rewritten =
+ TreeSelectionEvent rewritten =
(TreeSelectionEvent) ev.cloneWithSource(JTree.this);
fireValueChanged(rewritten);
- JTree.this.repaint();
+
+ // Only repaint the changed nodes.
+ TreePath[] changed = ev.getPaths();
+ for (int i = 0; i < changed.length; i++)
+ {
+ repaint(getPathBounds(changed[i]));
+ }
}
}
@@ -1396,8 +1402,6 @@ public class JTree extends JComponent implements Scrollable, Accessible
private TreePath anchorSelectionPath;
- private TreePath leadSelectionPath;
-
/**
* This contains the state of all nodes in the tree. Al/ entries map the
* TreePath of a note to to its state. Valid states are EXPANDED and
@@ -1504,8 +1508,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public JTree(TreeModel model)
{
- updateUI();
setRootVisible(true);
+ // The setModel also calls the updateUI
setModel(model);
setSelectionModel(new EmptySelectionModel());
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
@@ -1562,7 +1566,15 @@ public class JTree extends JComponent implements Scrollable, Accessible
TreeUI ui = getUI();
return ui != null ? ui.getPathForRow(this, row) : null;
}
-
+
+ /**
+ * Get the pathes that are displayes between the two given rows.
+ *
+ * @param index0 the starting row, inclusive
+ * @param index1 the ending row, inclusive
+ *
+ * @return the array of the tree pathes
+ */
protected TreePath[] getPathBetweenRows(int index0, int index1)
{
TreeUI ui = getUI();
@@ -1941,9 +1953,19 @@ public class JTree extends JComponent implements Scrollable, Accessible
if (rootVisible == flag)
return;
+ // If the root is currently selected, unselect it
+ if (rootVisible && !flag)
+ {
+ TreeSelectionModel model = getSelectionModel();
+ // The root is always shown in the first row
+ TreePath rootPath = getPathForRow(0);
+ model.removeSelectionPath(rootPath);
+ }
+
boolean oldValue = rootVisible;
rootVisible = flag;
firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
+
}
public boolean getShowsRootHandles()
@@ -2110,27 +2132,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
{
if (path == null)
return;
-
- Object[] oPath = path.getPath();
- TreePath temp = new TreePath(oPath[0]);
- boolean stop = false;
- int i = 1;
- while (!stop)
- {
- while (isVisible(temp))
- if (i < oPath.length)
- temp = temp.pathByAddingChild(oPath[i++]);
- else
- {
- stop = true;
- break;
- }
- makeVisible(temp);
- }
Rectangle rect = getPathBounds(path);
scrollRectToVisible(rect);
- revalidate();
- repaint();
}
public void scrollRowToVisible(int row)
@@ -2225,7 +2228,15 @@ public class JTree extends JComponent implements Scrollable, Accessible
addSelectionPaths(paths);
}
-
+
+ /**
+ * Select all rows between the two given indexes, inclusive. The method
+ * will not select the inner leaves and braches of the currently collapsed
+ * nodes in this interval.
+ *
+ * @param index0 the starting row, inclusive
+ * @param index1 the ending row, inclusive
+ */
public void addSelectionInterval(int index0, int index1)
{
TreePath[] paths = getPathBetweenRows(index0, index1);
@@ -2281,7 +2292,10 @@ public class JTree extends JComponent implements Scrollable, Accessible
public TreePath getLeadSelectionPath()
{
- return leadSelectionPath;
+ if (selectionModel == null)
+ return null;
+ else
+ return selectionModel.getLeadSelectionPath();
}
/**
@@ -2289,12 +2303,24 @@ public class JTree extends JComponent implements Scrollable, Accessible
*/
public void setLeadSelectionPath(TreePath path)
{
- if (leadSelectionPath == path)
- return;
-
- TreePath oldValue = leadSelectionPath;
- leadSelectionPath = path;
- firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
+ if (selectionModel != null)
+ {
+ TreePath oldValue = selectionModel.getLeadSelectionPath();
+ if (path.equals(oldValue))
+ return;
+
+ // Repaint the previous and current rows with the lead selection path.
+ if (path != null)
+ {
+ repaint(getPathBounds(path));
+ selectionModel.addSelectionPath(path);
+ }
+
+ if (oldValue!=null)
+ repaint(getPathBounds(oldValue));
+
+ firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
+ }
}
/**
@@ -2430,7 +2456,8 @@ public class JTree extends JComponent implements Scrollable, Accessible
public void expandPath(TreePath path)
{
// Don't expand if path is null
- if (path == null)
+ // or is already expanded.
+ if (path == null || isExpanded(path))
return;
try
@@ -2967,10 +2994,20 @@ public class JTree extends JComponent implements Scrollable, Accessible
}
/**
- * Sent when the tree has changed enough that we need to resize the bounds,
- * but not enough that we need to remove the expanded node set (e.g nodes
- * were expanded or collapsed, or nodes were inserted into the tree). You
- * should never have to invoke this, the UI will invoke this as it needs to.
+ * <p>
+ * Sent when the tree has changed enough that we need to resize the bounds,
+ * but not enough that we need to remove the expanded node set (e.g nodes were
+ * expanded or collapsed, or nodes were inserted into the tree). You should
+ * never have to invoke this, the UI will invoke this as it needs to.
+ * </p>
+ * <p>
+ * If the tree uses {@link DefaultTreeModel}, you must call
+ * {@link DefaultTreeModel#reload(TreeNode)} or
+ * {@link DefaultTreeModel#reload()} after adding or removing nodes. Following
+ * the official Java 1.5 API standard, just calling treeDidChange, repaint()
+ * or revalidate() does <i>not</i> update the tree appearance properly.
+ *
+ * @see DefaultTreeModel#reload()
*/
public void treeDidChange()
{
diff --git a/javax/swing/ProgressMonitor.java b/javax/swing/ProgressMonitor.java
index dc0c6434c..73e36b9ca 100644
--- a/javax/swing/ProgressMonitor.java
+++ b/javax/swing/ProgressMonitor.java
@@ -398,7 +398,11 @@ public class ProgressMonitor
if (( now - timestamp ) > millisToDecideToPopup )
{
first = false;
- long expected = ( now - timestamp ) * ( max - min ) / ( progress - min );
+
+
+ long expected = ( progress - min == 0 ) ?
+ ( now - timestamp ) * ( max - min ) :
+ ( now - timestamp ) * ( max - min ) / ( progress - min );
if ( expected > millisToPopup )
{
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index a5e0379f6..9e246ee1e 100644
--- a/javax/swing/RepaintManager.java
+++ b/javax/swing/RepaintManager.java
@@ -160,9 +160,9 @@ public class RepaintManager
if (o1 instanceof JComponent && o2 instanceof JComponent)
{
JComponent c1 = (JComponent) o1;
- Rectangle d1 = (Rectangle) dirtyComponents.get(c1);
+ Rectangle d1 = (Rectangle) dirtyComponentsWork.get(c1);
JComponent c2 = (JComponent) o2;
- Rectangle d2 = (Rectangle) dirtyComponents.get(c2);
+ Rectangle d2 = (Rectangle) dirtyComponentsWork.get(c2);
return d2.width * d2.height - d1.width * d1.height;
}
throw new ClassCastException("This comparator can only be used with "
@@ -188,6 +188,12 @@ public class RepaintManager
HashMap dirtyComponents;
/**
+ * The dirtyComponents which is used in paintDiryRegions to avoid unnecessary
+ * locking.
+ */
+ HashMap dirtyComponentsWork;
+
+ /**
* The comparator used for ordered inserting into the repaintOrder list.
*/
private transient Comparator comparator;
@@ -262,6 +268,7 @@ public class RepaintManager
public RepaintManager()
{
dirtyComponents = new HashMap();
+ dirtyComponentsWork = new HashMap();
invalidComponents = new ArrayList();
repaintWorker = new RepaintWorker();
doubleBufferMaximumSize = new Dimension(2000,2000);
@@ -554,31 +561,36 @@ public class RepaintManager
if (dirtyComponents.size() == 0)
return;
+ // Swap dirtyRegions with dirtyRegionsWork to avoid locking.
synchronized (dirtyComponents)
{
- // We sort the components by their size here. This way we have a good
- // chance that painting the bigger components also paints the smaller
- // components and we don't need to paint them twice.
- ArrayList repaintOrder = new ArrayList(dirtyComponents.size());
- repaintOrder.addAll(dirtyComponents.keySet());
- if (comparator == null)
- comparator = new ComponentComparator();
- Collections.sort(repaintOrder, comparator);
- repaintUnderway = true;
- for (Iterator i = repaintOrder.iterator(); i.hasNext();)
- {
- JComponent comp = (JComponent) i.next();
- // If a component is marked completely clean in the meantime, then skip
- // it.
- Rectangle damaged = (Rectangle) dirtyComponents.get(comp);
- if (damaged == null || damaged.isEmpty())
- continue;
- comp.paintImmediately(damaged);
- dirtyComponents.remove(comp);
- }
- repaintUnderway = false;
- commitRemainingBuffers();
+ HashMap swap = dirtyComponents;
+ dirtyComponents = dirtyComponentsWork;
+ dirtyComponentsWork = swap;
}
+
+ ArrayList repaintOrder = new ArrayList(dirtyComponentsWork.size());;
+ // We sort the components by their size here. This way we have a good
+ // chance that painting the bigger components also paints the smaller
+ // components and we don't need to paint them twice.
+ repaintOrder.addAll(dirtyComponentsWork.keySet());
+
+ if (comparator == null)
+ comparator = new ComponentComparator();
+ Collections.sort(repaintOrder, comparator);
+ repaintUnderway = true;
+ for (Iterator i = repaintOrder.iterator(); i.hasNext();)
+ {
+ JComponent comp = (JComponent) i.next();
+ // If a component is marked completely clean in the meantime, then skip
+ // it.
+ Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
+ if (damaged == null || damaged.isEmpty())
+ continue;
+ comp.paintImmediately(damaged);
+ }
+ repaintUnderway = false;
+ commitRemainingBuffers();
}
/**
diff --git a/javax/swing/ScrollPaneLayout.java b/javax/swing/ScrollPaneLayout.java
index 9f6829f4d..da8f03afb 100644
--- a/javax/swing/ScrollPaneLayout.java
+++ b/javax/swing/ScrollPaneLayout.java
@@ -328,7 +328,7 @@ public class ScrollPaneLayout
// parent is no JScrollPane, so do we.
JScrollPane sc = (JScrollPane) parent;
JViewport viewport = sc.getViewport();
- Dimension viewSize = viewport.getViewSize();
+ Dimension viewSize = viewport.getView().getPreferredSize();
int x1 = 0, x2 = 0, x3 = 0, x4 = 0;
int y1 = 0, y2 = 0, y3 = 0, y4 = 0;
diff --git a/javax/swing/SpinnerDateModel.java b/javax/swing/SpinnerDateModel.java
index a92f5a49e..e5ff76f1a 100644
--- a/javax/swing/SpinnerDateModel.java
+++ b/javax/swing/SpinnerDateModel.java
@@ -59,13 +59,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
private Calendar date;
/**
- * The start or earliest permitted date (<code>null</code> for no
- * minimum).
+ * A constraint on the start or earliest permitted date (<code>null</code>
+ * for no minimum).
*/
private Comparable start;
/**
- * The end or latest permitted date (<code>null</code> for no
+ * A constraint on the end or latest permitted date (<code>null</code> for no
* maximum).
*/
private Comparable end;
@@ -77,7 +77,6 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* For compatability with Sun's JDK
- * FIXME: Which fields should be serialized?
*/
private static final long serialVersionUID = -4802518107105940612L;
@@ -92,14 +91,21 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Constructs a SpinnerDateModel which spins a given calendar field,
- * using a given date and start and end date limits.
- * @param value - the initial Date value
- * @param start - start limit, as a Date object, or <code>null</code>
- * for no lower limit.
- * @param end - end limit, or <code>null</code> for no upper limit.
- * @param calendarField - the <code>Calendar</code> field to spin,
- * (Calendar.ZONE_OFFSET and Calendar.DST_OFFSET are invalid)
+ * Constructs a <code>SpinnerDateModel</code> with the specified value, lower
+ * and upper bounds, and which spins the specified calendar field.
+ * <p>
+ * The <code>start</code> and <code>end</code> limits must have a
+ * <code>compareTo</code> method that supports instances of {@link Date}, but
+ * do not themselves need to be instances of {@link Date} (although typically
+ * they are).
+ *
+ * @param value the initial value/date (<code>null</code> not permitted).
+ * @param start a constraint that specifies the earliest permitted date
+ * value, or <code>null</code> for no lower limit.
+ * @param end a constraint that specifies the latest permitted date value,
+ * or <code>null</code> for no upper limit.
+ * @param calendarField the <code>Calendar</code> field to spin,
+ * (Calendar.ZONE_OFFSET and Calendar.DST_OFFSET are invalid)
*/
public SpinnerDateModel(Date value, Comparable start, Comparable end,
int calendarField)
@@ -129,9 +135,11 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the current date.
+ * Returns the current date/time.
+ *
+ * @return The current date/time (never <code>null</code>).
*
- * @return The current date.
+ * @see #getValue()
*/
public Date getDate()
{
@@ -139,9 +147,12 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the start date, or <code>null</code> if there is no minimum date.
+ * Returns the lower limit on the date/time value, or <code>null</code> if
+ * there is no minimum date/time.
*
- * @return The start date.
+ * @return The lower limit.
+ *
+ * @see #setStart(Comparable)
*/
public Comparable getStart()
{
@@ -149,9 +160,12 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Returns the end date, or <code>null</code> if there is no maximum date.
+ * Returns the upper limit on the date/time value, or <code>null</code> if
+ * there is no maximum date/time.
+ *
+ * @return The upper limit.
*
- * @return The end date.
+ * @see #setEnd(Comparable)
*/
public Comparable getEnd()
{
@@ -160,9 +174,9 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the current date in the sequence (this method returns the same as
- * {@link #getDate()}.
+ * {@link #getDate()}).
*
- * @return The current date.
+ * @return The current date (never <code>null</code>).
*/
public Object getValue()
{
@@ -171,10 +185,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the next date in the sequence, or <code>null</code> if the
- * next date is after the end date. The current date is not changed.
+ * next date is past the upper limit (if one is specified). The current date
+ * is not changed.
*
* @return The next date, or <code>null</code> if the current value is
* the latest date represented by the model.
+ *
+ * @see #getEnd()
*/
public Object getNextValue()
{
@@ -190,11 +207,13 @@ public class SpinnerDateModel extends AbstractSpinnerModel
/**
* Returns the previous date in the sequence, or <code>null</code> if the
- * previous date is prior to the start date. The current date is not
- * changed.
+ * previous date is prior to the lower limit (if one is specified). The
+ * current date is not changed.
*
* @return The previous date, or <code>null</code> if the current value is
* the earliest date represented by the model.
+ *
+ * @see #getStart()
*/
public Object getPreviousValue()
{
@@ -233,14 +252,16 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Sets the start date and, if the new date is different to the old date,
- * sends a {@link ChangeEvent} to all registered listeners. A
- * <code>null</code> date is interpreted as "no start date". No check
- * is made to ensure that the new start date is on or before the current
- * date - the caller is responsible for ensuring that this relationship
- * holds.
+ * Sets the lower limit for the date/time value and, if the new limit is
+ * different to the old limit, sends a {@link ChangeEvent} to all registered
+ * listeners. A <code>null</code> value is interpreted as "no lower limit".
+ * No check is made to ensure that the current date/time is on or after the
+ * new lower limit - the caller is responsible for ensuring that this
+ * relationship holds. In addition, the caller should ensure that
+ * <code>start</code> is {@link Serializable}.
*
- * @param start the new start date (<code>null</code> permitted).
+ * @param start the new lower limit for the date/time value
+ * (<code>null</code> permitted).
*/
public void setStart(Comparable start)
{
@@ -252,13 +273,16 @@ public class SpinnerDateModel extends AbstractSpinnerModel
}
/**
- * Sets the end date and, if the new date is different to the old date,
- * sends a {@link ChangeEvent} to all registered listeners. A
- * <code>null</code> date is interpreted as "no end date". No check
- * is made to ensure that the new end date is on or after the current date -
- * the caller is responsible for ensuring that this relationship holds.
+ * Sets the upper limit for the date/time value and, if the new limit is
+ * different to the old limit, sends a {@link ChangeEvent} to all registered
+ * listeners. A <code>null</code> value is interpreted as "no upper limit".
+ * No check is made to ensure that the current date/time is on or before the
+ * new upper limit - the caller is responsible for ensuring that this
+ * relationship holds. In addition, the caller should ensure that
+ * <code>end</code> is {@link Serializable}.
*
- * @param end the new end date (<code>null</code> permitted).
+ * @param end the new upper limit for the date/time value (<code>null</code>
+ * permitted).
*/
public void setEnd(Comparable end)
{
diff --git a/javax/swing/SpinnerNumberModel.java b/javax/swing/SpinnerNumberModel.java
index 389c536e4..1abbbe377 100644
--- a/javax/swing/SpinnerNumberModel.java
+++ b/javax/swing/SpinnerNumberModel.java
@@ -110,12 +110,14 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
}
/**
- * Creates a <code>SpinnerNumberModel</code> with the given attributes.
+ * Creates a <code>SpinnerNumberModel</code> with the given attributes. The
+ * caller should ensure that both <code>minimum</code> and
+ * <code>maximum</code> are serializable.
*
- * @param value the initial value.
+ * @param value the initial value (<code>null</code> not permitted).
* @param minimum the minimum value (<code>null</code> permitted).
* @param maximum the maximum value (<code>null</code> permitted).
- * @param stepSize the step size.
+ * @param stepSize the step size (<code>null</code> not permitted).
*
* @throws IllegalArgumentException if minimum &lt;= value &lt;= maximum
* does not hold
@@ -171,9 +173,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
}
/**
- * Returns the current value.
+ * Returns the current value, which for this class is always an instance of
+ * {@link Number}.
*
* @return The current value.
+ *
+ * @see #getNumber()
*/
public Object getValue()
{
@@ -258,6 +263,8 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* Returns the minimum value, or <code>null</code> if there is no minimum.
*
* @return The minimum value.
+ *
+ * @see #setMinimum(Comparable)
*/
public Comparable getMinimum()
{
@@ -270,9 +277,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* <code>null</code> value is interpreted as "no minimum value". No check
* is made to ensure that the new minimum is less than or equal to the
* current value, the caller is responsible for ensuring that this
- * relationship holds.
+ * relationship holds. In addition, the caller should ensure that
+ * <code>newMinimum</code> is {@link Serializable}.
*
* @param newMinimum the new minimum value (<code>null</code> permitted).
+ *
+ * @see #getMinimum()
*/
public void setMinimum(Comparable newMinimum)
{
@@ -287,6 +297,9 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* Returns the maximum value, or <code>null</code> if there is no maximum.
*
* @return The maximum value.
+ *
+ * @see #getMinimum()
+ * @see #setMaximum(Comparable)
*/
public Comparable getMaximum()
{
@@ -299,9 +312,12 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
* <code>null</code> value is interpreted as "no maximum value". No check
* is made to ensure that the new maximum is greater than or equal to the
* current value, the caller is responsible for ensuring that this
- * relationship holds.
+ * relationship holds. In addition, the caller should ensure that
+ * <code>newMaximum</code> is {@link Serializable}.
*
* @param newMaximum the new maximum (<code>null</code> permitted).
+ *
+ * @see #getMaximum()
*/
public void setMaximum(Comparable newMaximum)
{
@@ -315,7 +331,7 @@ public class SpinnerNumberModel extends AbstractSpinnerModel
/**
* Returns the step size.
*
- * @return The step size.
+ * @return The step size (never <code>null</code>).
*/
public Number getStepSize()
{
diff --git a/javax/swing/UIManager.java b/javax/swing/UIManager.java
index 3b9166261..e1ee28b3f 100644
--- a/javax/swing/UIManager.java
+++ b/javax/swing/UIManager.java
@@ -1,5 +1,5 @@
/* UIManager.java --
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
diff --git a/javax/swing/ViewportLayout.java b/javax/swing/ViewportLayout.java
index 67b69eb28..b61834e9e 100644
--- a/javax/swing/ViewportLayout.java
+++ b/javax/swing/ViewportLayout.java
@@ -158,7 +158,7 @@ public class ViewportLayout implements LayoutManager, Serializable
// the viewport require inputs in view space.
Rectangle portBounds = port.getViewRect();
- Dimension viewPref = view.getPreferredSize();
+ Dimension viewPref = new Dimension(view.getPreferredSize());
Point portLowerRight = new Point(portBounds.x + portBounds.width,
portBounds.y + portBounds.height);
@@ -182,14 +182,10 @@ public class ViewportLayout implements LayoutManager, Serializable
}
}
- // The scroll pane manages the view size itself.
- if (! (port.getParent() instanceof JScrollPane) )
- {
- if (viewPref.width < portBounds.width)
- viewPref.width = portBounds.width;
- if (viewPref.height < portBounds.height)
- viewPref.height = portBounds.height;
- }
+ if (viewPref.width < portBounds.width)
+ viewPref.width = portBounds.width;
+ if (viewPref.height < portBounds.height)
+ viewPref.height = portBounds.height;
// If the view is larger than the port, the port is top and right
// aligned.
diff --git a/javax/swing/border/AbstractBorder.java b/javax/swing/border/AbstractBorder.java
index 7cbbcdaa8..c995de1c2 100644
--- a/javax/swing/border/AbstractBorder.java
+++ b/javax/swing/border/AbstractBorder.java
@@ -1,5 +1,5 @@
/* AbstractBorder.java --
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -68,7 +68,7 @@ public abstract class AbstractBorder implements Border, Serializable
* Performs nothing, because the default implementation provided by
* this class is an invisible, zero-width border. Subclasses will
* likely want to override this method, but they are not required
- * for doing so.
+ * to do so.
*
* @param c the component whose border is to be painted.
* @param g the graphics for painting.
@@ -87,9 +87,11 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Measures the width of this border.
+ * Returns the insets required for drawing this border around the specified
+ * component.
*
- * @param c the component whose border is to be measured.
+ * @param c the component that the border applies to (ignored here,
+ * subclasses may use it).
*
* @return an Insets object whose <code>left</code>, <code>right</code>,
* <code>top</code> and <code>bottom</code> fields indicate the
@@ -104,16 +106,23 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Determines the insets of this border. The implementation provided
- * by AbstractButton sets the <code>left</code>, <code>right</code>,
- * <code>top</code> and <code>bottom</code> fields of the passed
- * <code>insets</code> parameter to zero.
+ * Returns the insets required for drawing this border around the specified
+ * component. The default implementation provided here sets the
+ * <code>left</code>, <code>right</code>, <code>top</code> and
+ * <code>bottom</code> fields of the passed <code>insets</code> parameter to
+ * zero.
*
- * @param c the component whose border is to be measured
+ * @param c the component that the border applies to (ignored here,
+ * subclasses may use it).
+ * @param insets an instance that will be overwritten and returned as the
+ * result (<code>null</code> not permitted).
*
- * @return the same object that was passed for <code>insets</code>
+ * @return The border insets (the same object that was passed as the
+ * <code>insets</code> argument).
*
* @see #getBorderInsets(Component)
+ *
+ * @throws NullPointerException if <code>insets</code> is <code>null</code>.
*/
public Insets getBorderInsets(Component c, Insets insets)
{
@@ -126,7 +135,7 @@ public abstract class AbstractBorder implements Border, Serializable
* fills every pixel in its area when painting. Partially
* translucent borders must return <code>false</code>, or ugly
* artifacts can appear on screen. The default implementation
- * provided by AbstractBorder always returns <code>false</code>.
+ * provided here always returns <code>false</code>.
*
* @return <code>false</code>.
*/
@@ -136,9 +145,9 @@ public abstract class AbstractBorder implements Border, Serializable
}
/**
- * Returns a rectangle that covers the specified area minus this
- * border. Components that wish to determine an area into which
- * they can safely draw without intersecting with a border might
+ * Returns a rectangle that covers the specified area minus the insets
+ * required to draw this border. Components that wish to determine an area
+ * into which they can safely draw without intersecting with a border might
* want to use this helper method.
*
* @param c the component in the center of this border.
@@ -146,24 +155,30 @@ public abstract class AbstractBorder implements Border, Serializable
* @param y the vertical position of the border.
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
+ *
+ * @return The interior rectangle.
*/
public Rectangle getInteriorRectangle(Component c, int x, int y, int width,
int height)
{
- return getInteriorRectangle (c, this, x, y, width, height);
+ return getInteriorRectangle(c, this, x, y, width, height);
}
/**
- * Returns a rectangle that covers the specified area minus a
- * border. Components that wish to determine an area into which
- * they can safely draw without intersecting with a border might
- * want to use this helper method.
+ * Returns a rectangle that covers the specified area minus the insets
+ * required to draw the specified border (if the border is <code>null</code>,
+ * zero insets are assumed). Components that wish to determine an area into
+ * which they can safely draw without intersecting with a border might want
+ * to use this helper method.
*
* @param c the component in the center of this border.
+ * @param b the border (<code>null</code> permitted).
* @param x the horizontal position of the border.
* @param y the vertical position of the border.
* @param width the width of the available area for the border.
* @param height the height of the available area for the border.
+ *
+ * @return The interior rectangle.
*/
public static Rectangle getInteriorRectangle(Component c, Border b, int x,
int y, int width, int height)
@@ -172,7 +187,7 @@ public abstract class AbstractBorder implements Border, Serializable
if (b != null)
{
- borderInsets = b.getBorderInsets (c);
+ borderInsets = b.getBorderInsets(c);
x += borderInsets.left;
y += borderInsets.top;
width -= borderInsets.left + borderInsets.right;
diff --git a/javax/swing/border/BevelBorder.java b/javax/swing/border/BevelBorder.java
index 45b758cae..403c35c04 100644
--- a/javax/swing/border/BevelBorder.java
+++ b/javax/swing/border/BevelBorder.java
@@ -305,6 +305,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see #getHighlightInnerColor(java.awt.Component)
* @see java.awt.Color#brighter()
*/
@@ -326,6 +328,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#brighter()
*/
@@ -347,6 +351,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#darker()
*/
@@ -367,6 +373,8 @@ public class BevelBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see #getShadowInnerColor(java.awt.Component)
* @see java.awt.Color#darker()
*/
@@ -384,6 +392,8 @@ public class BevelBorder extends AbstractBorder
* highlighted edges when painting the border, or <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getHighlightOuterColor()
{
@@ -396,6 +406,8 @@ public class BevelBorder extends AbstractBorder
* highlighted edges when painting the border, or <code>null</code>
* if that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getHighlightInnerColor()
{
@@ -408,6 +420,8 @@ public class BevelBorder extends AbstractBorder
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getShadowInnerColor()
{
@@ -420,6 +434,8 @@ public class BevelBorder extends AbstractBorder
* shadowed edges when painting the border, or <code>null</code> if
* that color will be derived from the background of the enclosed
* Component.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getShadowOuterColor()
{
@@ -430,6 +446,8 @@ public class BevelBorder extends AbstractBorder
/**
* Returns the appearance of this border, which is either {@link
* #RAISED} or {@link #LOWERED}.
+ *
+ * @return The bevel type ({@link #RAISED} or {@link #LOWERED}).
*/
public int getBevelType()
{
diff --git a/javax/swing/border/CompoundBorder.java b/javax/swing/border/CompoundBorder.java
index 998a9bab3..a69c5e20a 100644
--- a/javax/swing/border/CompoundBorder.java
+++ b/javax/swing/border/CompoundBorder.java
@@ -224,6 +224,8 @@ public class CompoundBorder extends AbstractBorder
* Returns the outside border, which is painted outside both the
* bordered Component and the inside border. It is valid for the
* result to be <code>null</code>.
+ *
+ * @return The outside border (possibly <code>null</code>).
*/
public Border getOutsideBorder()
{
@@ -234,6 +236,8 @@ public class CompoundBorder extends AbstractBorder
* Returns the inside border, which is painted between the bordered
* Component and the outside border. It is valid for the result to
* be <code>null</code>.
+ *
+ * @return The inside border (possibly <code>null</code>).
*/
public Border getInsideBorder ()
{
diff --git a/javax/swing/border/EtchedBorder.java b/javax/swing/border/EtchedBorder.java
index 22882b78c..cd48b18da 100644
--- a/javax/swing/border/EtchedBorder.java
+++ b/javax/swing/border/EtchedBorder.java
@@ -281,6 +281,8 @@ public class EtchedBorder extends AbstractBorder
/**
* Returns the appearance of this EtchedBorder, which is either
* {@link #RAISED} or {@link #LOWERED}.
+ *
+ * @return The type ({@link #RAISED} or {@link #LOWERED}).
*/
public int getEtchType()
{
@@ -297,6 +299,8 @@ public class EtchedBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#brighter()
*/
@@ -312,6 +316,8 @@ public class EtchedBorder extends AbstractBorder
* Returns the color that will be used for highlighted parts when
* painting the border, or <code>null</code> if that color will be
* derived from the background of the enclosed Component.
+ *
+ * @return The highlight color (possibly <code>null</code>).
*/
public Color getHighlightColor()
{
@@ -328,6 +334,8 @@ public class EtchedBorder extends AbstractBorder
*
* @param c the component enclosed by this border.
*
+ * @return The shadow color.
+ *
* @see java.awt.Component#getBackground()
* @see java.awt.Color#darker()
*/
@@ -344,6 +352,8 @@ public class EtchedBorder extends AbstractBorder
* Returns the color that will be used for shadowed parts when
* painting the border, or <code>null</code> if that color will be
* derived from the background of the enclosed Component.
+ *
+ * @return The shadow color (possibly <code>null</code>).
*/
public Color getShadowColor()
{
diff --git a/javax/swing/border/LineBorder.java b/javax/swing/border/LineBorder.java
index 36abddd91..31e19fe1f 100644
--- a/javax/swing/border/LineBorder.java
+++ b/javax/swing/border/LineBorder.java
@@ -162,8 +162,10 @@ public class LineBorder extends AbstractBorder
/**
- * Returns a black, one pixel thick, plain LineBorder. The method
- * may always return the same (singleton) LineBorder instance.
+ * Returns a black, one pixel thick, plain {@link LineBorder}. The method
+ * may always return the same (singleton) {@link LineBorder} instance.
+ *
+ * @return The border.
*/
public static Border createBlackLineBorder()
{
@@ -178,8 +180,10 @@ public class LineBorder extends AbstractBorder
/**
- * Returns a gray, one pixel thick, plain LineBorder. The method
- * may always return the same (singleton) LineBorder instance.
+ * Returns a gray, one pixel thick, plain {@link LineBorder}. The method
+ * may always return the same (singleton) {@link LineBorder} instance.
+ *
+ * @return The border.
*/
public static Border createGrayLineBorder()
{
@@ -295,6 +299,8 @@ public class LineBorder extends AbstractBorder
/**
* Returns the color of the line.
+ *
+ * @return The line color (never <code>null</code>).
*/
public Color getLineColor()
{
@@ -304,6 +310,8 @@ public class LineBorder extends AbstractBorder
/**
* Returns the thickness of the line in pixels.
+ *
+ * @return The line thickness (in pixels).
*/
public int getThickness()
{
diff --git a/javax/swing/border/MatteBorder.java b/javax/swing/border/MatteBorder.java
index 4d5b8c253..114cac623 100644
--- a/javax/swing/border/MatteBorder.java
+++ b/javax/swing/border/MatteBorder.java
@@ -299,6 +299,8 @@ public class MatteBorder extends EmptyBorder
* Returns the color that is used for filling the border, or
* <code>null</code> if the border is filled with repetitions of a
* tile icon.
+ *
+ * @return The color (possibly <code>null</code>).
*/
public Color getMatteColor()
{
@@ -310,6 +312,8 @@ public class MatteBorder extends EmptyBorder
* Returns the icon is used for tiling the border, or
* <code>null</code> if the border is filled with a color instead of
* an icon.
+ *
+ * @return The icon (possibly <code>null</code>).
*/
public Icon getTileIcon()
{
diff --git a/javax/swing/border/TitledBorder.java b/javax/swing/border/TitledBorder.java
index 8d3ee13d4..38b575423 100644
--- a/javax/swing/border/TitledBorder.java
+++ b/javax/swing/border/TitledBorder.java
@@ -912,8 +912,10 @@ public class TitledBorder extends AbstractBorder
* Calculates the minimum size needed for displaying the border
* and its title.
*
- * @param c the Component for which this TitledBorder consitutes
+ * @param c the Component for which this TitledBorder constitutes
* a border.
+ *
+ * @return The minimum size.
*/
public Dimension getMinimumSize(Component c)
{
@@ -980,6 +982,10 @@ public class TitledBorder extends AbstractBorder
/**
* Performs various measurements for the current state of this TitledBorder
* and the given Component.
+ *
+ * @param c the component (<code>null</code> not permitted).
+ *
+ * @return Various measurements.
*/
private Measurements getMeasurements(Component c)
{
@@ -1172,6 +1178,8 @@ public class TitledBorder extends AbstractBorder
/**
* Calculates the minimum size needed for displaying the border
* and its title. Used by {@link TitledBorder#getMinimumSize(Component)}.
+ *
+ * @return The minimum size.
*/
public Dimension getMinimumSize()
{
diff --git a/javax/swing/event/ChangeEvent.java b/javax/swing/event/ChangeEvent.java
index f75c15aac..8854282a9 100644
--- a/javax/swing/event/ChangeEvent.java
+++ b/javax/swing/event/ChangeEvent.java
@@ -1,5 +1,5 @@
/* ChangeEvent.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,23 +37,30 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventObject;
/**
- * ChangeEvent
+ * An event used to signal a state change for an object.
+ *
+ * @see ChangeListener
+ * @see CellEditorListener
+ * @see TableColumnModelListener
+ *
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public class ChangeEvent extends EventObject {
+public class ChangeEvent
+ extends EventObject
+{
- /**
- * ChangeEvent constructor
- * @param source Source object
- */
- public ChangeEvent(Object source) {
- super(source);
- } // ChangeEvent()
+ /**
+ * Creates a new <code>ChangeEvent</code> instance for the specified source.
+ *
+ * @param source the source for the event (<code>null</code> not permitted).
+ */
+ public ChangeEvent(Object source)
+ {
+ super(source);
+ }
-
-} // ChangeEvent
+}
diff --git a/javax/swing/event/ChangeListener.java b/javax/swing/event/ChangeListener.java
index 1e58b1d82..75809707b 100644
--- a/javax/swing/event/ChangeListener.java
+++ b/javax/swing/event/ChangeListener.java
@@ -1,5 +1,5 @@
/* ChangeListener.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,21 +37,27 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventListener;
/**
- * ChangeListener interface
+ * A <code>ChangeListener</code> can register with an object to receive
+ * notification of state changes (for objects that support this mechanism).
+ *
* @author Andrew Selkirk
* @author Ronald Veldema
*/
-public interface ChangeListener extends EventListener {
-
- /**
- * State changed
- * @param event Change Event
- */
- void stateChanged(ChangeEvent event);
-
-
-} // ChangeListener
+public interface ChangeListener
+ extends EventListener
+{
+
+ /**
+ * Called by an object to notify the listener that the object's state has
+ * changed. The incoming <code>event</code> identifies the
+ * <code>source</code> of the event, allowing the listener to differentiate
+ * when it is listening for changes in multiple sources.
+ *
+ * @param event the change event.
+ */
+ void stateChanged(ChangeEvent event);
+
+}
diff --git a/javax/swing/event/TableColumnModelListener.java b/javax/swing/event/TableColumnModelListener.java
index 90e1b29cc..522e0a8c6 100644
--- a/javax/swing/event/TableColumnModelListener.java
+++ b/javax/swing/event/TableColumnModelListener.java
@@ -1,5 +1,5 @@
/* TableColumnModelListener.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,44 +37,58 @@ exception statement from your version. */
package javax.swing.event;
-// Imports
import java.util.EventListener;
+import javax.swing.table.TableColumnModel;
+
/**
- * TableColumnModelListener public interface
+ * A <code>TableColumnModelListener</code> can register with a
+ * {@link TableColumnModel} to receive notification of changes to the model.
+ *
* @author Andrew Selkirk
*/
-public interface TableColumnModelListener extends EventListener {
-
- /**
- * Column added
- * @param event Table Column Model Event
- */
- void columnAdded(TableColumnModelEvent event);
-
- /**
- * Column margin changed
- * @param event Change Event
- */
- void columnMarginChanged(ChangeEvent event);
-
- /**
- * Column moved
- * @param event Table Column Model Event
- */
- void columnMoved(TableColumnModelEvent event);
-
- /**
- * Column removed
- * @param event Table Column Model Event
- */
- void columnRemoved(TableColumnModelEvent event);
-
- /**
- * Column selection changed
- * @param event List Selection Event
- */
- void columnSelectionChanged(ListSelectionEvent event);
-
-
-} // TableColumnModelListener
+public interface TableColumnModelListener
+ extends EventListener
+{
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * added to the model.
+ *
+ * @param event information about the column addition.
+ */
+ void columnAdded(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that the model's
+ * column margin has changed.
+ *
+ * @param event the event (identifies the source).
+ */
+ void columnMarginChanged(ChangeEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * moved.
+ *
+ * @param event information about the column move.
+ */
+ void columnMoved(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that a column has been
+ * removed from the model.
+ *
+ * @param event information about the column removal.
+ */
+ void columnRemoved(TableColumnModelEvent event);
+
+ /**
+ * Called by the {@link TableColumnModel} to indicate that the column
+ * selection state has changed.
+ *
+ * @param event information about the column selection state.
+ */
+ void columnSelectionChanged(ListSelectionEvent event);
+
+}
diff --git a/javax/swing/plaf/basic/BasicComboBoxUI.java b/javax/swing/plaf/basic/BasicComboBoxUI.java
index e62432f10..557eea93f 100644
--- a/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -972,6 +974,7 @@ public class BasicComboBoxUI extends ComboBoxUI
* by the look and feel.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement.
}
@@ -981,6 +984,7 @@ public class BasicComboBoxUI extends ComboBoxUI
* installed by in {@link #installListeners}.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement.
}
diff --git a/javax/swing/plaf/basic/BasicComboPopup.java b/javax/swing/plaf/basic/BasicComboPopup.java
index 90b0585c4..d4eabc602 100644
--- a/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/javax/swing/plaf/basic/BasicComboPopup.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
@@ -292,6 +294,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -559,6 +562,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
* DOCUMENT ME!
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicInternalFrameUI.java b/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 75aab2fe7..0a330e776 100644
--- a/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
@@ -1209,6 +1211,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method installs the keyboard actions for the JInternalFrame.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1291,6 +1294,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method uninstalls the keyboard actions for the JInternalFrame.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
diff --git a/javax/swing/plaf/basic/BasicLabelUI.java b/javax/swing/plaf/basic/BasicLabelUI.java
index d0964f473..60e3a9868 100644
--- a/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/javax/swing/plaf/basic/BasicLabelUI.java
@@ -37,6 +37,8 @@
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
@@ -372,6 +374,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param l The {@link JLabel} to install keyboard actions for.
*/
protected void installKeyboardActions(JLabel l)
+ throws NotImplementedException
{
//FIXME: implement.
}
@@ -382,6 +385,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
* @param l The {@link JLabel} to uninstall keyboard actions for.
*/
protected void uninstallKeyboardActions(JLabel l)
+ throws NotImplementedException
{
//FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicListUI.java b/javax/swing/plaf/basic/BasicListUI.java
index 6892833b2..e5dcd1c4f 100644
--- a/javax/swing/plaf/basic/BasicListUI.java
+++ b/javax/swing/plaf/basic/BasicListUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -1025,6 +1027,7 @@ public class BasicListUI extends ListUI
* Uninstalls keyboard actions for this UI in the {@link JList}.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicMenuBarUI.java b/javax/swing/plaf/basic/BasicMenuBarUI.java
index a21514467..f258ebe30 100644
--- a/javax/swing/plaf/basic/BasicMenuBarUI.java
+++ b/javax/swing/plaf/basic/BasicMenuBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Dimension;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
@@ -176,6 +178,7 @@ public class BasicMenuBarUI extends MenuBarUI
* This method installs the keyboard actions for the JMenuBar.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement
}
@@ -223,6 +226,7 @@ public class BasicMenuBarUI extends MenuBarUI
* This method reverses the work done in installKeyboardActions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicMenuUI.java b/javax/swing/plaf/basic/BasicMenuUI.java
index 4fb250d24..f8936be5b 100644
--- a/javax/swing/plaf/basic/BasicMenuUI.java
+++ b/javax/swing/plaf/basic/BasicMenuUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
@@ -218,6 +220,7 @@ public class BasicMenuUI extends BasicMenuItemUI
*
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -262,6 +265,7 @@ public class BasicMenuUI extends BasicMenuItemUI
* Basic look and feel's defaults.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicOptionPaneUI.java b/javax/swing/plaf/basic/BasicOptionPaneUI.java
index 005a3b394..88bca3b53 100644
--- a/javax/swing/plaf/basic/BasicOptionPaneUI.java
+++ b/javax/swing/plaf/basic/BasicOptionPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@@ -1204,6 +1206,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
* This method installs keyboard actions for the JOptionpane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1336,6 +1339,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
* This method uninstalls keyboard actions for the JOptionPane.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicPopupMenuUI.java b/javax/swing/plaf/basic/BasicPopupMenuUI.java
index 6ecd06b39..a26a5c7c4 100644
--- a/javax/swing/plaf/basic/BasicPopupMenuUI.java
+++ b/javax/swing/plaf/basic/BasicPopupMenuUI.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
@@ -137,6 +139,7 @@ public class BasicPopupMenuUI extends PopupMenuUI
* This method installs the keyboard actions for this {@link JPopupMenu}.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
@@ -179,6 +182,7 @@ public class BasicPopupMenuUI extends PopupMenuUI
* Uninstalls any keyboard actions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Need to implement
}
diff --git a/javax/swing/plaf/basic/BasicScrollBarUI.java b/javax/swing/plaf/basic/BasicScrollBarUI.java
index 0ab2914ea..f24485484 100644
--- a/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -763,6 +765,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
* This method installs the keyboard actions for the scrollbar.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1141,6 +1144,7 @@ public class BasicScrollBarUI extends ScrollBarUI implements LayoutManager,
* during install.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicScrollPaneUI.java b/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 1e982008f..e6a4eaf4f 100644
--- a/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -484,6 +486,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
* @param sp the scrollpane to install keyboard actions on
*/
protected void installKeyboardActions(JScrollPane sp)
+ throws NotImplementedException
{
// TODO: Is this only a hook method or should we actually do something
// here? If the latter, than figure out what and implement this.
@@ -579,6 +582,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
* @param sp the scrollpane to uninstall keyboard actions from
*/
protected void uninstallKeyboardActions(JScrollPane sp)
+ throws NotImplementedException
{
// TODO: Is this only a hook method or should we actually do something
// here? If the latter, than figure out what and implement this.
diff --git a/javax/swing/plaf/basic/BasicSliderUI.java b/javax/swing/plaf/basic/BasicSliderUI.java
index 9137ae9dc..137ab55a6 100644
--- a/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/javax/swing/plaf/basic/BasicSliderUI.java
@@ -63,7 +63,9 @@ import java.util.Dictionary;
import java.util.Enumeration;
import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
import javax.swing.BoundedRangeModel;
+import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
@@ -74,6 +76,7 @@ import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
+import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SliderUI;
@@ -871,9 +874,11 @@ public class BasicSliderUI extends SliderUI
* installed.
*/
protected void installKeyboardActions(JSlider slider)
- throws NotImplementedException
{
- // FIXME: implement.
+ InputMap keyMap = getInputMap(JComponent.WHEN_FOCUSED);
+ SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, keyMap);
+ ActionMap map = getActionMap();
+ SwingUtilities.replaceUIActionMap(slider, map);
}
/**
@@ -884,9 +889,9 @@ public class BasicSliderUI extends SliderUI
* uninstalled.
*/
protected void uninstallKeyboardActions(JSlider slider)
- throws NotImplementedException
{
- // FIXME: implement.
+ SwingUtilities.replaceUIActionMap(slider, null);
+ SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, null);
}
/* XXX: This is all after experimentation with SUN's implementation.
@@ -2073,18 +2078,22 @@ public class BasicSliderUI extends SliderUI
}
/**
- * This method is used to move the thumb one block in the direction
- * specified. If the slider snaps to ticks, this method is responsible for
- * snapping it to a tick after the thumb has been moved.
+ * Moves the thumb one block in the direction specified (a block is 1/10th
+ * of the slider range). If the slider snaps to ticks, this method is
+ * responsible for snapping it to a tick after the thumb has been moved.
*
- * @param direction The direction to move in.
+ * @param direction the direction (positive values increment the thumb
+ * position by one block, zero/negative values decrement the thumb position
+ * by one block).
*/
public void scrollByBlock(int direction)
{
- // The direction is -1 for backwards and 1 for forwards.
- int unit = direction * (slider.getMaximum() - slider.getMinimum()) / 10;
-
- int moveTo = slider.getValue() + unit;
+ int unit = (slider.getMaximum() - slider.getMinimum()) / 10;
+ int moveTo = slider.getValue();
+ if (direction > 0)
+ moveTo += unit;
+ else
+ moveTo -= unit;
if (slider.getSnapToTicks())
moveTo = findClosestTick(moveTo);
@@ -2093,16 +2102,21 @@ public class BasicSliderUI extends SliderUI
}
/**
- * This method is used to move the thumb one unit in the direction
- * specified. If the slider snaps to ticks, this method is responsible for
- * snapping it to a tick after the thumb has been moved.
+ * Moves the thumb one unit in the specified direction. If the slider snaps
+ * to ticks, this method is responsible for snapping it to a tick after the
+ * thumb has been moved.
*
- * @param direction The direction to move in.
+ * @param direction the direction (positive values increment the thumb
+ * position by one, zero/negative values decrement the thumb position by
+ * one).
*/
public void scrollByUnit(int direction)
{
- // The direction is -1 for backwards and 1 for forwards.
- int moveTo = slider.getValue() + direction;
+ int moveTo = slider.getValue();
+ if (direction > 0)
+ moveTo++;
+ else
+ moveTo--;
if (slider.getSnapToTicks())
moveTo = findClosestTick(moveTo);
@@ -2316,4 +2330,123 @@ public class BasicSliderUI extends SliderUI
else
return value + minor;
}
+
+ InputMap getInputMap(int condition)
+ {
+ if (condition == JComponent.WHEN_FOCUSED)
+ return (InputMap) UIManager.get("Slider.focusInputMap");
+ return null;
+ }
+
+ /**
+ * Returns the action map for the {@link JSlider}. All sliders share
+ * a single action map which is created the first time this method is
+ * called, then stored in the UIDefaults table for subsequent access.
+ *
+ * @return The shared action map.
+ */
+ ActionMap getActionMap()
+ {
+ ActionMap map = (ActionMap) UIManager.get("Slider.actionMap");
+
+ if (map == null) // first time here
+ {
+ map = createActionMap();
+ if (map != null)
+ UIManager.put("Slider.actionMap", map);
+ }
+ return map;
+ }
+
+ /**
+ * Creates the action map shared by all {@link JSlider} instances.
+ * This method is called once by {@link #getActionMap()} when it
+ * finds no action map in the UIDefaults table...after the map is
+ * created, it gets added to the defaults table so that subsequent
+ * calls to {@link #getActionMap()} will return the same shared
+ * instance.
+ *
+ * @return The action map.
+ */
+ ActionMap createActionMap()
+ {
+ ActionMap map = new ActionMapUIResource();
+ map.put("positiveUnitIncrement",
+ new AbstractAction("positiveUnitIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
+ else
+ ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
+ }
+ }
+ );
+ map.put("negativeUnitIncrement",
+ new AbstractAction("negativeUnitIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
+ else
+ ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
+ }
+ }
+ );
+ map.put("positiveBlockIncrement",
+ new AbstractAction("positiveBlockIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
+ else
+ ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
+ }
+ }
+ );
+ map.put("negativeBlockIncrement",
+ new AbstractAction("negativeBlockIncrement") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ BasicSliderUI ui = (BasicSliderUI) slider.getUI();
+ if (slider.getInverted())
+ ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
+ else
+ ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
+ }
+ }
+ );
+ map.put("minScroll",
+ new AbstractAction("minScroll") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ if (slider.getInverted())
+ slider.setValue(slider.getMaximum());
+ else
+ slider.setValue(slider.getMinimum());
+ }
+ }
+ );
+ map.put("maxScroll",
+ new AbstractAction("maxScroll") {
+ public void actionPerformed(ActionEvent event)
+ {
+ JSlider slider = (JSlider) event.getSource();
+ if (slider.getInverted())
+ slider.setValue(slider.getMinimum());
+ else
+ slider.setValue(slider.getMaximum());
+ }
+ }
+ );
+ return map;
+ }
}
diff --git a/javax/swing/plaf/basic/BasicSpinnerUI.java b/javax/swing/plaf/basic/BasicSpinnerUI.java
index 6f7a41a1d..465374bfd 100644
--- a/javax/swing/plaf/basic/BasicSpinnerUI.java
+++ b/javax/swing/plaf/basic/BasicSpinnerUI.java
@@ -41,7 +41,6 @@ package javax.swing.plaf.basic;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
-import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
@@ -365,9 +364,9 @@ public class BasicSpinnerUI extends SpinnerUI
private class DefaultLayoutManager implements LayoutManager
{
/**
- * DOCUMENT ME!
+ * Layout the spinners inner parts.
*
- * @param parent DOCUMENT ME!
+ * @param parent The parent container
*/
public void layoutContainer(Container parent)
{
@@ -385,12 +384,12 @@ public class BasicSpinnerUI extends SpinnerUI
Dimension e = prefSize(editor);
Dimension n = prefSize(next);
Dimension p = prefSize(previous);
- Dimension s = spinner.getPreferredSize();
+ Dimension s = parent.getSize();
int x = l2r ? i.left : i.right;
int y = i.top;
int w = Math.max(p.width, n.width);
- int h = e.height / 2;
+ int h = (s.height - i.bottom) / 2;
int e_width = s.width - w - i.left - i.right;
if (l2r)
diff --git a/javax/swing/plaf/basic/BasicSplitPaneUI.java b/javax/swing/plaf/basic/BasicSplitPaneUI.java
index 906acfe16..694baadda 100644
--- a/javax/swing/plaf/basic/BasicSplitPaneUI.java
+++ b/javax/swing/plaf/basic/BasicSplitPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
@@ -1047,6 +1049,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
* This method installs the keyboard actions for the JSplitPane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -1055,6 +1058,7 @@ public class BasicSplitPaneUI extends SplitPaneUI
* This method reverses the work done in installKeyboardActions.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index dd27b7d2d..6d9bed331 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -1734,6 +1736,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method installs keyboard actions for the JTabbedPane.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1742,6 +1745,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
* This method uninstalls keyboard actions for the JTabbedPane.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -1950,6 +1954,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
return;
}
+ int ascent = metrics.getAscent();
+
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex))
{
@@ -1966,10 +1972,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x,
- textRect.y
- + metrics.getAscent());
+ textRect.y + ascent);
else
- g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
+ g.drawString(title, textRect.x, textRect.y + ascent);
}
else
{
@@ -1977,17 +1982,19 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
g.setColor(bg.brighter());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
- textRect.x, textRect.y);
+ textRect.x, textRect.y
+ + ascent);
else
- g.drawString(title, textRect.x, textRect.y);
+ g.drawString(title, textRect.x, textRect.y + ascent);
g.setColor(bg.darker());
if (mnemIndex != -1)
BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
textRect.x + 1,
- textRect.y + 1);
+ textRect.y + 1
+ + ascent);
else
- g.drawString(title, textRect.x + 1, textRect.y + 1);
+ g.drawString(title, textRect.x + 1, textRect.y + 1 + ascent);
}
}
@@ -2552,10 +2559,23 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
*/
protected int lastTabInRun(int tabCount, int run)
{
- if (tabRuns[run] == 0)
- return tabCount - 1;
+ int lastTab;
+ if (runCount == 1)
+ lastTab = tabCount - 1;
else
- return tabRuns[run] - 1;
+ {
+ int nextRun;
+ if (run == runCount - 1)
+ nextRun = 0;
+ else
+ nextRun = run + 1;
+
+ if (tabRuns[nextRun] == 0)
+ lastTab = tabCount - 1;
+ else
+ lastTab = tabRuns[nextRun] - 1;
+ }
+ return lastTab;
}
/**
diff --git a/javax/swing/plaf/basic/BasicTableHeaderUI.java b/javax/swing/plaf/basic/BasicTableHeaderUI.java
index c6f9e37df..fbef6e69f 100644
--- a/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
@@ -415,6 +417,7 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void installKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -447,6 +450,7 @@ public class BasicTableHeaderUI extends TableHeaderUI
}
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicTableUI.java b/javax/swing/plaf/basic/BasicTableUI.java
index 9ddaeb2e9..0711ce385 100644
--- a/javax/swing/plaf/basic/BasicTableUI.java
+++ b/javax/swing/plaf/basic/BasicTableUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
@@ -1168,6 +1170,7 @@ public class BasicTableUI extends TableUI
}
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/plaf/basic/BasicTextAreaUI.java b/javax/swing/plaf/basic/BasicTextAreaUI.java
index e9f566e9a..93e119b31 100644
--- a/javax/swing/plaf/basic/BasicTextAreaUI.java
+++ b/javax/swing/plaf/basic/BasicTextAreaUI.java
@@ -1,5 +1,5 @@
/* BasicTextAreaUI.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,11 +45,9 @@ import javax.swing.JComponent;
import javax.swing.JTextArea;
import javax.swing.UIDefaults;
import javax.swing.plaf.ComponentUI;
-import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.PlainView;
import javax.swing.text.View;
-import javax.swing.text.ViewFactory;
import javax.swing.text.WrappedPlainView;
public class BasicTextAreaUI extends BasicTextUI
diff --git a/javax/swing/plaf/basic/BasicTextFieldUI.java b/javax/swing/plaf/basic/BasicTextFieldUI.java
index 4e2ca9f93..89c4e5a75 100644
--- a/javax/swing/plaf/basic/BasicTextFieldUI.java
+++ b/javax/swing/plaf/basic/BasicTextFieldUI.java
@@ -1,5 +1,5 @@
/* BasicTextFieldUI.java
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,7 @@ import java.beans.PropertyChangeEvent;
import javax.swing.JComponent;
import javax.swing.UIDefaults;
+import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.Element;
import javax.swing.text.FieldView;
@@ -83,6 +84,9 @@ public class BasicTextFieldUI extends BasicTextUI
* Receives notification whenever one of the text component's bound
* properties changes. Here we check for the editable and enabled
* properties and adjust the background color accordingly.
+ *
+ * <p>The colors are only changed if they are not a
+ * <code>ColorUIResource</code>.</p>
*
* @param event the property change event
*/
@@ -91,10 +95,11 @@ public class BasicTextFieldUI extends BasicTextUI
if (event.getPropertyName().equals("editable"))
{
boolean editable = ((Boolean) event.getNewValue()).booleanValue();
- if (editable)
- textComponent.setBackground(background);
- else
- textComponent.setBackground(inactiveBackground);
+
+ // Changing the color only if the current background is an instance of
+ // ColorUIResource is the behavior of the RI.
+ if (textComponent.getBackground() instanceof ColorUIResource)
+ textComponent.setBackground(editable ? background : inactiveBackground);
}
}
}
diff --git a/javax/swing/plaf/basic/BasicTextUI.java b/javax/swing/plaf/basic/BasicTextUI.java
index 6a45969cc..66c0da284 100644
--- a/javax/swing/plaf/basic/BasicTextUI.java
+++ b/javax/swing/plaf/basic/BasicTextUI.java
@@ -61,7 +61,6 @@ import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
-import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
@@ -69,7 +68,6 @@ import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ActionMapUIResource;
-import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TextUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.AbstractDocument;
@@ -824,6 +822,7 @@ public abstract class BasicTextUI extends TextUI
* this UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: Uninstall keyboard actions here.
}
@@ -1139,9 +1138,14 @@ public abstract class BasicTextUI extends TextUI
public int getNextVisualPositionFrom(JTextComponent t, int pos,
Position.Bias b, int direction,
Position.Bias[] biasRet)
- throws BadLocationException, NotImplementedException
+ throws BadLocationException
{
- return 0; // TODO: Implement me.
+ // A comment in the spec of NavigationFilter.getNextVisualPositionFrom()
+ // suggests that this method should be implemented by forwarding the call
+ // the root view.
+ return rootView.getNextVisualPositionFrom(pos, b,
+ getVisibleEditorRect(),
+ direction, biasRet);
}
/**
diff --git a/javax/swing/plaf/basic/BasicToolBarUI.java b/javax/swing/plaf/basic/BasicToolBarUI.java
index 5d718876f..80fec6a77 100644
--- a/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@@ -604,6 +606,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
* by the look and feel.
*/
protected void installKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
@@ -900,6 +903,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
+ throws NotImplementedException
{
// FIXME: implement.
}
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java
index 78d0a586a..fb09ac998 100644
--- a/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/javax/swing/plaf/basic/BasicTreeUI.java
@@ -1,5 +1,5 @@
/* BasicTreeUI.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,6 +57,7 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@@ -252,25 +253,25 @@ public class BasicTreeUI
int maxHeight = 0;
/** Listeners */
- private PropertyChangeListener propertyChangeListener;
+ PropertyChangeListener propertyChangeListener;
- private FocusListener focusListener;
+ FocusListener focusListener;
- private TreeSelectionListener treeSelectionListener;
+ TreeSelectionListener treeSelectionListener;
- private MouseListener mouseListener;
+ MouseListener mouseListener;
- private KeyListener keyListener;
+ KeyListener keyListener;
- private PropertyChangeListener selectionModelPropertyChangeListener;
+ PropertyChangeListener selectionModelPropertyChangeListener;
- private ComponentListener componentListener;
+ ComponentListener componentListener;
CellEditorListener cellEditorListener;
- private TreeExpansionListener treeExpansionListener;
+ TreeExpansionListener treeExpansionListener;
- private TreeModelListener treeModelListener;
+ TreeModelListener treeModelListener;
/**
* This timer fires the editing action after about 1200 ms if not reset during
@@ -668,7 +669,8 @@ public class BasicTreeUI
maxHeight = Math.max(maxHeight, iconHeight + gap);
}
-
+
+ treeState.setRowHeight(maxHeight);
return maxHeight;
}
@@ -1313,10 +1315,11 @@ public class BasicTreeUI
public void installUI(JComponent c)
{
tree = (JTree) c;
+ treeModel = tree.getModel();
+
prepareForUIInstall();
super.installUI(c);
installDefaults();
-
installComponents();
installKeyboardActions();
installListeners();
@@ -1384,25 +1387,11 @@ public class BasicTreeUI
int endIndex = tree.getClosestRowForLocation(clip.x + clip.width,
clip.y + clip.height);
- for (int i = startIndex; i <= endIndex; i++)
- {
- TreePath path = treeState.getPathForRow(i);
- boolean isLeaf = treeModel.isLeaf(path.getLastPathComponent());
- boolean isExpanded = tree.isExpanded(path);
-
- Rectangle bounds = getPathBounds(tree, path);
-
- paintHorizontalPartOfLeg(g, clip, insets, bounds, path, i,
- isExpanded, false, isLeaf);
- paintRow(g, clip, insets, bounds, path, i, isExpanded, false,
- isLeaf);
- if (isLastChild(path))
- paintVerticalPartOfLeg(g, clip, insets, path);
- }
-
// Also paint dashes to the invisible nodes below:
int rows = treeState.getRowCount();
+ // These should be painted first, otherwise they may cover
+ // the control icons.
if (endIndex < rows)
for (int i = endIndex + 1; i < rows; i++)
{
@@ -1410,6 +1399,37 @@ public class BasicTreeUI
if (isLastChild(path))
paintVerticalPartOfLeg(g, clip, insets, path);
}
+
+ // The two loops are required to ensure that the lines are not
+ // painted over the other tree components.
+
+ int n = endIndex - startIndex + 1;
+ Rectangle[] bounds = new Rectangle[n];
+ boolean[] isLeaf = new boolean[n];
+ boolean[] isExpanded = new boolean[n];
+ TreePath[] path = new TreePath[n];
+ int k;
+
+ k = 0;
+ for (int i = startIndex; i <= endIndex; i++, k++)
+ {
+ path[k] = treeState.getPathForRow(i);
+ isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
+ isExpanded[k] = tree.isExpanded(path[k]);
+ bounds[k] = getPathBounds(tree, path[k]);
+
+ paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k], i,
+ isExpanded[k], false, isLeaf[k]);
+ if (isLastChild(path[k]))
+ paintVerticalPartOfLeg(g, clip, insets, path[k]);
+ }
+
+ k = 0;
+ for (int i = startIndex; i <= endIndex; i++, k++)
+ {
+ paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
+ false, isLeaf[k]);
+ }
}
}
@@ -1508,8 +1528,9 @@ public class BasicTreeUI
{
if (! validCachedPreferredSize)
{
+ Rectangle size = tree.getBounds();
// Add the scrollbar dimensions to the preferred size.
- preferredSize = new Dimension(treeState.getPreferredWidth(null),
+ preferredSize = new Dimension(treeState.getPreferredWidth(size),
treeState.getPreferredHeight());
validCachedPreferredSize = true;
}
@@ -1598,12 +1619,6 @@ public class BasicTreeUI
*/
protected boolean startEditing(TreePath path, MouseEvent event)
{
- // Force to recalculate the maximal row height.
- maxHeight = 0;
-
- // Force to recalculate the cached preferred size.
- validCachedPreferredSize = false;
-
updateCellEditor();
TreeCellEditor ed = getCellEditor();
@@ -1720,7 +1735,10 @@ public class BasicTreeUI
/**
* Returning true signifies a mouse event on the node should toggle the
- * selection of only the row under the mouse.
+ * selection of only the row under the mouse. The BasisTreeUI treats the
+ * event as "toggle selection event" if the CTRL button was pressed while
+ * clicking. The event is not counted as toggle event if the associated
+ * tree does not support the multiple selection.
*
* @param event is the MouseEvent performed on the row.
* @return true signifies a mouse event on the node should toggle the
@@ -1728,12 +1746,18 @@ public class BasicTreeUI
*/
protected boolean isToggleSelectionEvent(MouseEvent event)
{
- return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION);
+ return
+ (tree.getSelectionModel().getSelectionMode() !=
+ TreeSelectionModel.SINGLE_TREE_SELECTION) &&
+ ((event.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0);
}
/**
* Returning true signifies a mouse event on the node should select from the
- * anchor point.
+ * anchor point. The BasisTreeUI treats the event as "multiple selection
+ * event" if the SHIFT button was pressed while clicking. The event is not
+ * counted as multiple selection event if the associated tree does not support
+ * the multiple selection.
*
* @param event is the MouseEvent performed on the node.
* @return true signifies a mouse event on the node should select from the
@@ -1741,7 +1765,10 @@ public class BasicTreeUI
*/
protected boolean isMultiSelectEvent(MouseEvent event)
{
- return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
+ return
+ (tree.getSelectionModel().getSelectionMode() !=
+ TreeSelectionModel.SINGLE_TREE_SELECTION) &&
+ ((event.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0);
}
/**
@@ -1763,15 +1790,19 @@ public class BasicTreeUI
* row. If the even is a toggle selection event, the row is either selected,
* or deselected. If the event identifies a multi selection event, the
* selection is updated from the anchor point. Otherwise, the row is selected,
- * and if the even specified a toggle event the row is expanded/collapsed.
+ * and the previous selection is cleared.</p>
*
* @param path is the path selected for an event
* @param event is the MouseEvent performed on the path.
+ *
+ * @see #isToggleSelectionEvent(MouseEvent)
+ * @see #isMultiSelectEvent(MouseEvent)
*/
protected void selectPathForEvent(TreePath path, MouseEvent event)
{
if (isToggleSelectionEvent(event))
{
+ // The event selects or unselects the clicked row.
if (tree.isPathSelected(path))
tree.removeSelectionPath(path);
else
@@ -1782,6 +1813,7 @@ public class BasicTreeUI
}
else if (isMultiSelectEvent(event))
{
+ // The event extends selection form anchor till the clicked row.
TreePath anchor = tree.getAnchorSelectionPath();
if (anchor != null)
{
@@ -1792,7 +1824,11 @@ public class BasicTreeUI
tree.addSelectionPath(path);
}
else
- tree.addSelectionPath(path);
+ {
+ // This is an ordinary event that just selects the clicked row.
+ tree.setSelectionPath(path);
+ tree.setAnchorSelectionPath(path);
+ }
}
/**
@@ -1865,7 +1901,7 @@ public class BasicTreeUI
if (tree.isEditing() && ! command.equals("startEditing"))
tree.stopEditing();
- tree.scrollPathToVisible(lead);
+ tree.scrollPathToVisible(tree.getLeadSelectionPath());
}
}
@@ -2017,24 +2053,38 @@ public class BasicTreeUI
/**
* Invoked when focus is activated on the tree we're in, redraws the lead
- * row. Invoked when a component gains the keyboard focus.
+ * row. Invoked when a component gains the keyboard focus. The method
+ * repaints the lead row that is shown differently when the tree is in
+ * focus.
*
* @param e is the focus event that is activated
*/
public void focusGained(FocusEvent e)
{
- // TODO: Implement this properly.
+ repaintLeadRow();
}
/**
* Invoked when focus is deactivated on the tree we're in, redraws the lead
- * row. Invoked when a component loses the keyboard focus.
+ * row. Invoked when a component loses the keyboard focus. The method
+ * repaints the lead row that is shown differently when the tree is in
+ * focus.
*
* @param e is the focus event that is deactivated
*/
public void focusLost(FocusEvent e)
{
- // TODO: Implement this properly.
+ repaintLeadRow();
+ }
+
+ /**
+ * Repaint the lead row.
+ */
+ void repaintLeadRow()
+ {
+ TreePath lead = tree.getLeadSelectionPath();
+ if (lead!=null)
+ tree.repaint(tree.getPathBounds(lead));
}
}
@@ -2131,6 +2181,11 @@ public class BasicTreeUI
{
Rectangle bounds = getPathBounds(tree, path);
int row = getRowForPath(tree, path);
+
+ // Cancel the editing session if clicked on the different row.
+ if (tree.isEditing() && row != editingRow)
+ cancelEditing(tree);
+
boolean cntlClick = isLocationInExpandControl(path, click.x, click.y);
boolean isLeaf = isLeaf(row);
@@ -2171,23 +2226,22 @@ public class BasicTreeUI
startEditTimer.stop();
startEditTimer = new Timer(WAIT_TILL_EDITING,
- new ActionListener()
- {
- public void actionPerformed(
- ActionEvent e)
- {
- startEditing(editPath,
- EDIT);
- }
- });
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ startEditing(editPath, EDIT);
+ }
+ });
startEditTimer.setRepeats(false);
startEditTimer.start();
}
else
{
- selectPath(tree, path);
if (e.getClickCount() == 2 && ! isLeaf(row))
toggleExpandState(path);
+ else
+ selectPathForEvent(path, e);
}
}
@@ -2410,12 +2464,13 @@ public class BasicTreeUI
*/
protected int getRowX(int row, int depth)
{
- return depth * rightChildIndent;
+ int iw = getCurrentControlIcon(null).getIconWidth();
+ return depth * (rightChildIndent + iw/2);
}
}// NodeDimensionsHandler
/**
- * PropertyChangeListener for the tree. Updates the appropriate varaible, or
+ * PropertyChangeListener for the tree. Updates the appropriate variable, or
* TreeState, based on what changes.
*/
public class PropertyChangeHandler
@@ -2438,12 +2493,23 @@ public class BasicTreeUI
*/
public void propertyChange(PropertyChangeEvent event)
{
- if ((event.getPropertyName()).equals("rootVisible"))
+ String property = event.getPropertyName();
+ if (property.equals(JTree.ROOT_VISIBLE_PROPERTY))
{
validCachedPreferredSize = false;
treeState.setRootVisible(tree.isRootVisible());
tree.repaint();
}
+ else if (property.equals(JTree.SELECTION_MODEL_PROPERTY))
+ {
+ treeSelectionModel = tree.getSelectionModel();
+ treeSelectionModel.setRowMapper(treeState);
+ }
+ else if (property.equals(JTree.TREE_MODEL_PROPERTY))
+ {
+ treeModel = tree.getModel();
+ treeModel.addTreeModelListener(treeModelListener);
+ }
}
}
@@ -2536,6 +2602,8 @@ public class BasicTreeUI
{
validCachedPreferredSize = false;
treeState.setExpandedState(event.getPath(), true);
+ tree.revalidate();
+ tree.repaint();
}
/**
@@ -2547,6 +2615,8 @@ public class BasicTreeUI
{
validCachedPreferredSize = false;
treeState.setExpandedState(event.getPath(), false);
+ tree.revalidate();
+ tree.repaint();
}
}// TreeExpansionHandler
@@ -2643,35 +2713,54 @@ public class BasicTreeUI
if (command.equals("selectPreviousChangeLead") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
+ tree.setAnchorSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectPreviousExtendSelection") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
+
+ // If the new path is already selected, the selection shrinks,
+ // unselecting the previously current path.
+ if (tree.isPathSelected(newPath))
+ tree.getSelectionModel().removeSelectionPath(currentPath);
+
+ // This must be called in any case because it updates the model
+ // lead selection index.
tree.addSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectPrevious") && hasPrev)
{
newPath = treeState.getPathForRow(prevRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
}
else if (command.equals("selectNext") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
}
else if (command.equals("selectNextExtendSelection") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
+
+ // If the new path is already selected, the selection shrinks,
+ // unselecting the previously current path.
+ if (tree.isPathSelected(newPath))
+ tree.getSelectionModel().removeSelectionPath(currentPath);
+
+ // This must be called in any case because it updates the model
+ // lead selection index.
tree.addSelectionPath(newPath);
+
tree.setLeadSelectionPath(newPath);
}
else if (command.equals("selectNextChangeLead") && hasNext)
{
newPath = treeState.getPathForRow(nextRow);
- selectPath(tree, newPath);
+ tree.setSelectionPath(newPath);
+ tree.setAnchorSelectionPath(newPath);
tree.setLeadSelectionPath(newPath);
}
}
@@ -2837,7 +2926,24 @@ public class BasicTreeUI
public void valueChanged(TreeSelectionEvent event)
{
if (tree.isEditing())
- tree.stopEditing();
+ tree.cancelEditing();
+
+ TreePath op = event.getOldLeadSelectionPath();
+ TreePath np = event.getNewLeadSelectionPath();
+
+ // Repaint of the changed lead selection path.
+ if (op != np)
+ {
+ Rectangle o = treeState.getBounds(event.getOldLeadSelectionPath(),
+ new Rectangle());
+ Rectangle n = treeState.getBounds(event.getNewLeadSelectionPath(),
+ new Rectangle());
+
+ if (o!=null)
+ tree.repaint(o);
+ if (n!=null)
+ tree.repaint(n);
+ }
}
}// TreeSelectionHandler
@@ -2913,16 +3019,41 @@ public class BasicTreeUI
return;
if (e.getActionCommand().equals("selectParent"))
- selectPath(tree, current.getParentPath());
+ {
+ if (current == null)
+ return;
+
+ if (tree.isExpanded(current))
+ {
+ tree.collapsePath(current);
+ }
+ else
+ {
+ // If the node is not expanded (also, if it is a leaf node),
+ // we just select the parent. We do not select the root if it
+ // is not visible.
+ TreePath parent = current.getParentPath();
+ if (parent != null &&
+ !(parent.getPathCount()==1 && !tree.isRootVisible()) )
+ tree.setSelectionPath(parent);
+ }
+ }
else if (e.getActionCommand().equals("selectChild"))
{
Object node = current.getLastPathComponent();
int nc = treeModel.getChildCount(node);
- if (nc > 0)
- node = treeModel.getChild(node, 0);
-
- TreePath path = current.pathByAddingChild(node);
- selectPath(tree, path);
+ if (nc == 0 || treeState.isExpanded(current))
+ {
+ // If the node is leaf or it is already expanded,
+ // we just select the next row.
+ int nextRow = tree.getLeadSelectionRow() + 1;
+ if (nextRow <= tree.getRowCount())
+ tree.setSelectionRow(nextRow);
+ }
+ else
+ {
+ tree.expandPath(current);
+ }
}
}
@@ -3018,23 +3149,9 @@ public class BasicTreeUI
{
if (path != null)
{
- if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION)
- {
- tree.getSelectionModel().clearSelection();
- tree.addSelectionPath(path);
- tree.setLeadSelectionPath(path);
- }
- else if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION)
- {
- // TODO
- }
- else
- {
- tree.addSelectionPath(path);
- tree.setLeadSelectionPath(path);
- tree.getSelectionModel().setSelectionMode(
- TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
- }
+ tree.setSelectionPath(path);
+ tree.setLeadSelectionPath(path);
+ tree.makeVisible(path);
tree.scrollPathToVisible(path);
}
}
@@ -3172,9 +3289,7 @@ public class BasicTreeUI
{
Icon icon = getCurrentControlIcon(path);
int iconW = icon.getIconWidth();
- int x = bounds.x - rightChildIndent + iconW / 2;
- if (x + iconW > bounds.x)
- x = bounds.x - rightChildIndent - gap;
+ int x = bounds.x - iconW - gap;
icon.paintIcon(tree, g, x, bounds.y + bounds.height / 2
- icon.getIconHeight() / 2);
}
@@ -3203,8 +3318,12 @@ public class BasicTreeUI
boolean isLeaf)
{
if (row != 0)
- paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, bounds.x - gap
- - 2, bounds.x);
+ {
+ Icon icon = getCurrentControlIcon(path);
+ int iconW = icon.getIconWidth();
+ paintHorizontalLine(g, tree, bounds.y + bounds.height / 2,
+ bounds.x - iconW/2 - gap, bounds.x - gap);
+ }
}
/**
@@ -3224,7 +3343,7 @@ public class BasicTreeUI
if (parent != null)
{
Rectangle parentBounds = getPathBounds(tree, parent);
- paintVerticalLine(g, tree, parentBounds.x + gap + 2,
+ paintVerticalLine(g, tree, parentBounds.x + 2* gap,
parentBounds.y + parentBounds.height / 2,
bounds.y + bounds.height / 2);
}
@@ -3260,9 +3379,15 @@ public class BasicTreeUI
if (dtcr == null)
dtcr = createDefaultCellRenderer();
+ boolean focused = false;
+ if (treeSelectionModel!= null)
+ focused = treeSelectionModel.getLeadSelectionRow() == row
+ && tree.isFocusOwner();
+
Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
isExpanded, isLeaf, row,
- tree.hasFocus());
+ focused);
+
rendererPane.paintComponent(g, c, c.getParent(), bounds);
}
@@ -3298,15 +3423,17 @@ public class BasicTreeUI
*/
void finish()
{
+ treeState.invalidatePathBounds(treeState.getPathForRow(editingRow));
editingPath = null;
editingRow = - 1;
stopEditingInCompleteEditing = false;
isEditing = false;
+ Rectangle bounds = editingComponent.getParent().getBounds();
tree.removeAll();
validCachedPreferredSize = false;
-
// Repaint the region, where was the editing component.
- tree.repaint(editingComponent.getParent().getBounds());
+ tree.repaint(bounds);
editingComponent = null;
+ tree.requestFocus();
}
} // BasicTreeUI
diff --git a/javax/swing/table/DefaultTableCellRenderer.java b/javax/swing/table/DefaultTableCellRenderer.java
index 0d9b62567..f56fd4f0e 100644
--- a/javax/swing/table/DefaultTableCellRenderer.java
+++ b/javax/swing/table/DefaultTableCellRenderer.java
@@ -1,5 +1,5 @@
/* DefaultTableCellRenderer.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -49,7 +49,6 @@ import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
-import javax.swing.JTextField;
/**
* Class to display every cells.
diff --git a/javax/swing/table/DefaultTableColumnModel.java b/javax/swing/table/DefaultTableColumnModel.java
index cd04a6979..6ed6331c2 100644
--- a/javax/swing/table/DefaultTableColumnModel.java
+++ b/javax/swing/table/DefaultTableColumnModel.java
@@ -1,5 +1,5 @@
/* DefaultTableColumnModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,6 +46,7 @@ import java.util.EventListener;
import java.util.Vector;
import javax.swing.DefaultListSelectionModel;
+import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
@@ -55,9 +56,11 @@ import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
/**
- * DefaultTableColumnModel
+ * A model that stores information about the columns used in a {@link JTable}.
+ *
+ * @see JTable#setColumnModel(TableColumnModel)
+ *
* @author Andrew Selkirk
- * @version 1.0
*/
public class DefaultTableColumnModel
implements TableColumnModel, PropertyChangeListener, ListSelectionListener,
@@ -66,88 +69,116 @@ public class DefaultTableColumnModel
private static final long serialVersionUID = 6580012493508960512L;
/**
- * Columns that this model keeps track of.
+ * Storage for the table columns.
*/
protected Vector<TableColumn> tableColumns;
/**
- * Selection Model that keeps track of columns selection
+ * A selection model that keeps track of column selections.
*/
protected ListSelectionModel selectionModel;
/**
- * Space between two columns. By default it is set to 1
+ * The space between the columns (the default value is <code>1</code>).
*/
protected int columnMargin;
/**
- * listenerList keeps track of all listeners registered with this model
+ * Storage for the listeners registered with the model.
*/
protected EventListenerList listenerList = new EventListenerList();
/**
- * changeEvent is fired when change occurs in one of the columns properties
+ * A change event used when notifying listeners of a change to the
+ * <code>columnMargin</code> field. This single event is reused for all
+ * notifications.
*/
+ // FIXME: use lazy instantiation
protected transient ChangeEvent changeEvent = new ChangeEvent(this);
/**
- * Indicates whether columns can be selected
+ * A flag that indicates whether or not columns can be selected.
*/
protected boolean columnSelectionAllowed;
/**
- * Total width of all the columns in this model
+ * The total width of all the columns in this model.
*/
protected int totalColumnWidth;
/**
- * Constructor DefaultTableColumnModel
+ * Creates a new table column model with zero columns. A default column
+ * selection model is created by calling {@link #createSelectionModel()}.
+ * The default value for <code>columnMargin</code> is <code>1</code> and
+ * the default value for <code>columnSelectionAllowed</code> is
+ * <code>false</code>.
*/
public DefaultTableColumnModel()
{
tableColumns = new Vector();
- setSelectionModel(createSelectionModel());
+ selectionModel = createSelectionModel();
+ selectionModel.addListSelectionListener(this);
columnMargin = 1;
columnSelectionAllowed = false;
}
/**
- * addColumn adds column to the model. This method fires ColumnAdded
- * event to model's registered TableColumnModelListeners.
+ * Adds a column to the model then calls
+ * {@link #fireColumnAdded(TableColumnModelEvent)} to notify the registered
+ * listeners. The model registers itself with the column as a
+ * {@link PropertyChangeListener} so that changes to the column width will
+ * invalidate the cached {@link #totalColumnWidth} value.
*
- * @param col column to add
+ * @param column the column (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>column</code> is
+ * <code>null</code>.
+ *
+ * @see #removeColumn(TableColumn)
*/
- public void addColumn(TableColumn col)
+ public void addColumn(TableColumn column)
{
- if (col == null)
+ if (column == null)
throw new IllegalArgumentException("Null 'col' argument.");
- tableColumns.add(col);
+ tableColumns.add(column);
+ column.addPropertyChangeListener(this);
invalidateWidthCache();
- fireColumnAdded(new TableColumnModelEvent(this, 0, tableColumns.size() - 1));
+ fireColumnAdded(new TableColumnModelEvent(this, 0,
+ tableColumns.size() - 1));
}
/**
- * removeColumn removes table column from the model. This method fires
- * ColumnRemoved event to model's registered TableColumnModelListeners.
+ * Removes a column from the model then calls
+ * {@link #fireColumnRemoved(TableColumnModelEvent)} to notify the registered
+ * listeners. If the specified column does not belong to the model, or is
+ * <code>null</code>, this method does nothing.
*
- * @param col column to be removed
+ * @param column the column to be removed (<code>null</code> permitted).
+ *
+ * @see #addColumn(TableColumn)
*/
- public void removeColumn(TableColumn col)
+ public void removeColumn(TableColumn column)
{
- int index = this.tableColumns.indexOf(col);
+ int index = this.tableColumns.indexOf(column);
if (index < 0)
return;
+ tableColumns.remove(column);
fireColumnRemoved(new TableColumnModelEvent(this, index, 0));
- tableColumns.remove(col);
+ column.removePropertyChangeListener(this);
invalidateWidthCache();
}
/**
- * moveColumn moves column at index i to index j. This method fires
- * ColumnMoved event to model's registered TableColumnModelListeners.
+ * Moves the column at index i to the position specified by index j, then
+ * calls {@link #fireColumnMoved(TableColumnModelEvent)} to notify registered
+ * listeners.
*
- * @param i index of the column that will be moved
- * @param j index of column's new location
+ * @param i index of the column that will be moved.
+ * @param j index of the column's new location.
+ *
+ * @throws IllegalArgumentException if <code>i</code> or <code>j</code> are
+ * outside the range <code>0</code> to <code>N-1</code>, where
+ * <code>N</code> is the column count.
*/
public void moveColumn(int i, int j)
{
@@ -158,22 +189,27 @@ public class DefaultTableColumnModel
throw new IllegalArgumentException("Index 'j' out of range.");
TableColumn column = tableColumns.remove(i);
tableColumns.add(j, column);
- fireColumnAdded(new TableColumnModelEvent(this, i, j));
+ fireColumnMoved(new TableColumnModelEvent(this, i, j));
}
/**
- * setColumnMargin sets margin of the columns.
- * @param m new column margin
+ * Sets the column margin then calls {@link #fireColumnMarginChanged()} to
+ * notify the registered listeners.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
*/
- public void setColumnMargin(int m)
+ public void setColumnMargin(int margin)
{
- columnMargin = m;
+ columnMargin = margin;
fireColumnMarginChanged();
}
/**
- * getColumnCount returns number of columns in the model
- * @return int number of columns in the model
+ * Returns the number of columns in the model.
+ *
+ * @return The column count.
*/
public int getColumnCount()
{
@@ -181,8 +217,9 @@ public class DefaultTableColumnModel
}
/**
- * getColumns
- * @return Enumeration
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
*/
public Enumeration<TableColumn> getColumns()
{
@@ -214,18 +251,28 @@ public class DefaultTableColumnModel
}
/**
- * getColumn returns column at the specified index
- * @param i index of the column
- * @return TableColumn column at the specified index
+ * Returns the column at the specified index.
+ *
+ * @param columnIndex the column index (in the range from <code>0</code> to
+ * <code>N-1</code>, where <code>N</code> is the number of columns in
+ * the model).
+ *
+ * @return The column at the specified index.
+ *
+ * @throws ArrayIndexOutOfBoundsException if <code>i</code> is not within
+ * the specified range.
*/
- public TableColumn getColumn(int i)
+ public TableColumn getColumn(int columnIndex)
{
- return (TableColumn) tableColumns.get(i);
+ return (TableColumn) tableColumns.get(columnIndex);
}
/**
- * getColumnMargin returns column margin
- * @return int column margin
+ * Returns the column margin.
+ *
+ * @return The column margin.
+ *
+ * @see #setColumnMargin(int)
*/
public int getColumnMargin()
{
@@ -233,16 +280,26 @@ public class DefaultTableColumnModel
}
/**
- * getColumnIndexAtX returns column that contains specified x-coordinate.
- * @param x x-coordinate that column should contain
- * @return int index of the column that contains specified x-coordinate relative
- * to this column model
+ * Returns the index of the column that contains the specified x-coordinate.
+ * This method assumes that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param x the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
*/
public int getColumnIndexAtX(int x)
{
for (int i = 0; i < tableColumns.size(); ++i)
{
- int w = ((TableColumn)tableColumns.get(i)).getWidth();
+ int w = ((TableColumn) tableColumns.get(i)).getWidth();
if (0 <= x && x < w)
return i;
else
@@ -252,10 +309,10 @@ public class DefaultTableColumnModel
}
/**
- * getTotalColumnWidth returns total width of all the columns including
- * column's margins.
+ * Returns total width of all the columns in the model, ignoring the
+ * {@link #columnMargin}.
*
- * @return total width of all the columns
+ * @return The total width of all the columns.
*/
public int getTotalColumnWidth()
{
@@ -265,24 +322,32 @@ public class DefaultTableColumnModel
}
/**
- * setSelectionModel sets selection model that will be used by this ColumnTableModel
- * to keep track of currently selected columns
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
*
- * @param model new selection model
- * @exception IllegalArgumentException if model is null
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
+ *
+ * @see #getSelectionModel()
*/
public void setSelectionModel(ListSelectionModel model)
{
if (model == null)
throw new IllegalArgumentException();
+ selectionModel.removeListSelectionListener(this);
selectionModel = model;
selectionModel.addListSelectionListener(this);
}
/**
- * getSelectionModel returns selection model
- * @return ListSelectionModel selection model
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
*/
public ListSelectionModel getSelectionModel()
{
@@ -290,10 +355,11 @@ public class DefaultTableColumnModel
}
/**
- * setColumnSelectionAllowed sets whether column selection is allowed
- * or not.
+ * Sets the flag that indicates whether or not column selection is allowed.
*
- * @param flag true if column selection is allowed and false otherwise
+ * @param flag the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
*/
public void setColumnSelectionAllowed(boolean flag)
{
@@ -301,10 +367,12 @@ public class DefaultTableColumnModel
}
/**
- * getColumnSelectionAllowed indicates whether column selection is
- * allowed or not.
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
*
- * @return boolean true if column selection is allowed and false otherwise.
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
*/
public boolean getColumnSelectionAllowed()
{
@@ -312,10 +380,9 @@ public class DefaultTableColumnModel
}
/**
- * getSelectedColumns returns array containing indexes of currently
- * selected columns
+ * Returns an array containing the indices of the selected columns.
*
- * @return int[] array containing indexes of currently selected columns
+ * @return An array containing the indices of the selected columns.
*/
public int[] getSelectedColumns()
{
@@ -356,8 +423,11 @@ public class DefaultTableColumnModel
}
/**
- * getSelectedColumnCount returns number of currently selected columns
- * @return int number of currently selected columns
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
*/
public int getSelectedColumnCount()
{
@@ -395,10 +465,10 @@ public class DefaultTableColumnModel
}
/**
- * addColumnModelListener adds specified listener to the model's
- * listener list
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
*
- * @param listener the listener to add
+ * @param listener the listener (<code>null</code> ignored).
*/
public void addColumnModelListener(TableColumnModelListener listener)
{
@@ -406,10 +476,10 @@ public class DefaultTableColumnModel
}
/**
- * removeColumnModelListener removes specified listener from the model's
- * listener list.
+ * Deregisters a listener so that it no longer receives notification of
+ * changes to this model.
*
- * @param listener the listener to remove
+ * @param listener the listener to remove
*/
public void removeColumnModelListener(TableColumnModelListener listener)
{
@@ -417,6 +487,13 @@ public class DefaultTableColumnModel
}
/**
+ * Returns an array containing the listeners that are registered with the
+ * model. If there are no listeners, an empty array is returned.
+ *
+ * @return An array containing the listeners that are registered with the
+ * model.
+ *
+ * @see #addColumnModelListener(TableColumnModelListener)
* @since 1.4
*/
public TableColumnModelListener[] getColumnModelListeners()
@@ -426,78 +503,97 @@ public class DefaultTableColumnModel
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was added
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been added to the model. The
+ * event's <code>toIndex</code> attribute should contain the index of the
+ * added column.
+ *
+ * @param e the event.
+ *
+ * @see #addColumn(TableColumn)
*/
protected void fireColumnAdded(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnAdded(e);
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was removed
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column has been removed from the model. The
+ * event's <code>fromIndex</code> attribute should contain the index of the
+ * removed column.
+ *
+ * @param e the event.
+ *
+ * @see #removeColumn(TableColumn)
*/
protected void fireColumnRemoved(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnRemoved(e);
}
/**
- * fireColumnAdded fires TableColumnModelEvent to registered
- * TableColumnModelListeners to indicate that column was moved
- *
- * @param e TableColumnModelEvent
+ * Sends the specified {@link TableColumnModelEvent} to all registered
+ * listeners, to indicate that a column in the model has been moved. The
+ * event's <code>fromIndex</code> attribute should contain the old column
+ * index, and the <code>toIndex</code> attribute should contain the new
+ * column index.
+ *
+ * @param e the event.
+ *
+ * @see #moveColumn(int, int)
*/
protected void fireColumnMoved(TableColumnModelEvent e)
{
TableColumnModelListener[] listeners = getColumnModelListeners();
- for (int i=0; i< listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].columnMoved(e);
}
/**
- * fireColumnSelectionChanged fires TableColumnModelEvent to model's
- * registered TableColumnModelListeners to indicate that different column
- * was selected.
+ * Sends the specified {@link ListSelectionEvent} to all registered listeners,
+ * to indicate that the column selections have changed.
*
- * @param evt ListSelectionEvent
+ * @param e the event.
+ *
+ * @see #valueChanged(ListSelectionEvent)
*/
- protected void fireColumnSelectionChanged(ListSelectionEvent evt)
+ protected void fireColumnSelectionChanged(ListSelectionEvent e)
{
EventListener [] listeners = getListeners(TableColumnModelListener.class);
for (int i = 0; i < listeners.length; ++i)
- ((TableColumnModelListener)listeners[i]).columnSelectionChanged(evt);
+ ((TableColumnModelListener) listeners[i]).columnSelectionChanged(e);
}
/**
- * fireColumnMarginChanged fires TableColumnModelEvent to model's
- * registered TableColumnModelListeners to indicate that column margin
- * was changed.
+ * Sends a {@link ChangeEvent} to the model's registered listeners to
+ * indicate that the column margin was changed.
+ *
+ * @see #setColumnMargin(int)
*/
protected void fireColumnMarginChanged()
{
EventListener [] listeners = getListeners(TableColumnModelListener.class);
for (int i = 0; i < listeners.length; ++i)
- ((TableColumnModelListener)listeners[i]).columnMarginChanged(changeEvent);
+ ((TableColumnModelListener) listeners[i]).columnMarginChanged(changeEvent);
}
/**
- * getListeners returns currently registered listeners with this model.
- * @param listenerType type of listeners to return
+ * Returns an array containing the listeners (of the specified type) that
+ * are registered with this model.
+ *
+ * @param listenerType the listener type (must indicate a subclass of
+ * {@link EventListener}, <code>null</code> not permitted).
*
- * @return EventListener[] array of model's listeners of the specified type
+ * @return An array containing the listeners (of the specified type) that
+ * are registered with this model.
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
@@ -505,20 +601,26 @@ public class DefaultTableColumnModel
}
/**
- * propertyChange handles changes occuring in the properties of the
- * model's columns.
+ * Receives notification of property changes for the columns in the model.
+ * If the <code>width</code> property for any column changes, we invalidate
+ * the {@link #totalColumnWidth} value here.
*
- * @param evt PropertyChangeEvent
+ * @param event the event.
*/
- public void propertyChange(PropertyChangeEvent evt)
+ public void propertyChange(PropertyChangeEvent event)
{
- if (evt.getPropertyName().equals(TableColumn.COLUMN_WIDTH_PROPERTY))
- invalidateWidthCache();
+ if (event.getPropertyName().equals("width"))
+ invalidateWidthCache();
}
/**
- * valueChanged handles changes in the selectionModel.
- * @param e ListSelectionEvent
+ * Receives notification of the change to the list selection model, and
+ * responds by calling
+ * {@link #fireColumnSelectionChanged(ListSelectionEvent)}.
+ *
+ * @param e the list selection event.
+ *
+ * @see #getSelectionModel()
*/
public void valueChanged(ListSelectionEvent e)
{
@@ -526,10 +628,11 @@ public class DefaultTableColumnModel
}
/**
- * createSelectionModel creates selection model that will keep track
- * of currently selected column(s)
+ * Creates a default selection model to track the currently selected
+ * column(s). This method is called by the constructor and returns a new
+ * instance of {@link DefaultListSelectionModel}.
*
- * @return ListSelectionModel selection model of the columns
+ * @return A new default column selection model.
*/
protected ListSelectionModel createSelectionModel()
{
@@ -537,9 +640,10 @@ public class DefaultTableColumnModel
}
/**
- * recalcWidthCache calculates total width of the columns.
- * If the current cache of the total width is in invalidated state,
- * then width is recalculated. Otherwise nothing is done.
+ * Recalculates the total width of the columns, if the cached value is
+ * <code>-1</code>. Otherwise this method does nothing.
+ *
+ * @see #getTotalColumnWidth()
*/
protected void recalcWidthCache()
{
@@ -548,13 +652,15 @@ public class DefaultTableColumnModel
totalColumnWidth = 0;
for (int i = 0; i < tableColumns.size(); ++i)
{
- totalColumnWidth += ((TableColumn)tableColumns.get(i)).getWidth();
+ totalColumnWidth += ((TableColumn) tableColumns.get(i)).getWidth();
}
}
}
/**
- * invalidateWidthCache
+ * Sets the {@link #totalColumnWidth} field to <code>-1</code>.
+ *
+ * @see #recalcWidthCache()
*/
private void invalidateWidthCache()
{
diff --git a/javax/swing/table/TableColumnModel.java b/javax/swing/table/TableColumnModel.java
index 66f52e619..7e8a70c3a 100644
--- a/javax/swing/table/TableColumnModel.java
+++ b/javax/swing/table/TableColumnModel.java
@@ -1,5 +1,5 @@
/* TableColumnModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,8 @@ import java.util.Enumeration;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
/**
@@ -50,7 +52,6 @@ import javax.swing.event.TableColumnModelListener;
*
* @author Andrew Selkirk
*/
-// FIXME: The API documentation in this class is incomplete.
public interface TableColumnModel
{
/**
@@ -80,21 +81,26 @@ public interface TableColumnModel
void moveColumn(int columnIndex, int newIndex);
/**
- * setColumnMargin
- * @param margin Margin of column
+ * Sets the column margin and sends a {@link ChangeEvent} to all registered
+ * {@link TableColumnModelListener}s registered with the model.
+ *
+ * @param margin the column margin.
+ *
+ * @see #getColumnMargin()
*/
void setColumnMargin(int margin);
/**
* Returns the number of columns in the model.
*
- * @return The column count
+ * @return The column count.
*/
int getColumnCount();
/**
- * getColumns
- * @return Enumeration of columns
+ * Returns an enumeration of the columns in the model.
+ *
+ * @return An enumeration of the columns in the model.
*/
Enumeration<TableColumn> getColumns();
@@ -123,30 +129,53 @@ public interface TableColumnModel
* Returns the column margin.
*
* @return The column margin.
+ *
+ * @see #setColumnMargin(int)
*/
int getColumnMargin();
/**
- * getColumnIndexAtX
- * @return Column index as position x
+ * Returns the index of the column that contains the specified x-coordinate,
+ * assuming that:
+ * <ul>
+ * <li>column zero begins at position zero;</li>
+ * <li>all columns appear in order;</li>
+ * <li>individual column widths are taken into account, but the column margin
+ * is ignored.</li>
+ * </ul>
+ * If no column contains the specified position, this method returns
+ * <code>-1</code>.
+ *
+ * @param xPosition the x-position.
+ *
+ * @return The column index, or <code>-1</code>.
*/
int getColumnIndexAtX(int xPosition);
/**
- * getTotalColumnWidth
- * @return Total column width
+ * Returns total width of all the columns in the model, ignoring the
+ * column margin (see {@link #getColumnMargin()}).
+ *
+ * @return The total width of all the columns.
*/
int getTotalColumnWidth();
/**
- * setColumnSelectionAllowed
- * @param value Set column selection
+ * Sets the flag that indicates whether or not column selection is allowed.
+ *
+ * @param allowed the new flag value.
+ *
+ * @see #getColumnSelectionAllowed()
*/
- void setColumnSelectionAllowed(boolean value);
+ void setColumnSelectionAllowed(boolean allowed);
/**
- * getColumnSelectionAllowed
- * @return true if column selection allowed, false otherwise
+ * Returns <code>true</code> if column selection is allowed, and
+ * <code>false</code> if column selection is not allowed.
+ *
+ * @return A boolean.
+ *
+ * @see #setColumnSelectionAllowed(boolean)
*/
boolean getColumnSelectionAllowed();
@@ -157,31 +186,47 @@ public interface TableColumnModel
int[] getSelectedColumns();
/**
- * getSelectedColumnCount
- * @return Count of selected columns
+ * Returns the number of selected columns in the model.
+ *
+ * @return The selected column count.
+ *
+ * @see #getSelectionModel()
*/
int getSelectedColumnCount();
/**
- * setSelectionModel
- * @param model ListSelectionModel
+ * Sets the selection model that will be used to keep track of the selected
+ * columns.
+ *
+ * @param model the selection model (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>model</code> is
+ * <code>null</code>.
*/
void setSelectionModel(ListSelectionModel model);
/**
- * getSelectionModel
+ * Returns the selection model used to track table column selections.
+ *
+ * @return The selection model.
+ *
+ * @see #setSelectionModel(ListSelectionModel)
*/
ListSelectionModel getSelectionModel();
/**
- * addColumnModelListener
- * @param listener TableColumnModelListener
+ * Registers a listener with the model, so that it will receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener (<code>null</code> ignored).
*/
void addColumnModelListener(TableColumnModelListener listener);
/**
- * removeColumnModelListener
- * @param listener TableColumnModelListener
+ * Deregisters a listener, so that it will no longer receive
+ * {@link TableColumnModelEvent} notifications.
+ *
+ * @param listener the listener.
*/
void removeColumnModelListener(TableColumnModelListener listener);
}
diff --git a/javax/swing/text/AbstractDocument.java b/javax/swing/text/AbstractDocument.java
index e656e7e9c..bb065044d 100644
--- a/javax/swing/text/AbstractDocument.java
+++ b/javax/swing/text/AbstractDocument.java
@@ -51,6 +51,7 @@ import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
+import javax.swing.text.DocumentFilter;
import javax.swing.tree.TreeNode;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CompoundEdit;
@@ -148,6 +149,11 @@ public abstract class AbstractDocument implements Document, Serializable
*/
Object documentCV = new Object();
+ /** An instance of a DocumentFilter.FilterBypass which allows calling
+ * the insert, remove and replace method without checking for an installed
+ * document filter.
+ */
+ DocumentFilter.FilterBypass bypass;
/**
* Creates a new <code>AbstractDocument</code> with the specified
@@ -180,6 +186,19 @@ public abstract class AbstractDocument implements Document, Serializable
content = doc;
context = ctx;
}
+
+ /** Returns the DocumentFilter.FilterBypass instance for this
+ * document and create it if it does not exist yet.
+ *
+ * @return This document's DocumentFilter.FilterBypass instance.
+ */
+ private DocumentFilter.FilterBypass getBypass()
+ {
+ if (bypass == null)
+ bypass = new Bypass();
+
+ return bypass;
+ }
/**
* Returns the paragraph {@link Element} that holds the specified position.
@@ -521,6 +540,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Inserts a String into this <code>Document</code> at the specified
* position and assigning the specified attributes to it.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the location at which the string should be inserted
* @param text the content to be inserted
@@ -532,6 +554,15 @@ public abstract class AbstractDocument implements Document, Serializable
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
+ if (documentFilter != null)
+ documentFilter.insertString(getBypass(), offset, text, attributes);
+ else
+ insertStringImpl(offset, text, attributes);
+ }
+
+ void insertStringImpl(int offset, String text, AttributeSet attributes)
+ throws BadLocationException
+ {
// Just return when no text to insert was given.
if (text == null || text.length() == 0)
return;
@@ -673,6 +704,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Removes a piece of content from this <code>Document</code>.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -683,6 +717,14 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void remove(int offset, int length) throws BadLocationException
{
+ if (documentFilter != null)
+ documentFilter.remove(getBypass(), offset, length);
+ else
+ removeImpl(offset, length);
+ }
+
+ void removeImpl(int offset, int length) throws BadLocationException
+ {
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.REMOVE);
@@ -707,6 +749,9 @@ public abstract class AbstractDocument implements Document, Serializable
/**
* Replaces a piece of content in this <code>Document</code> with
* another piece of content.
+ *
+ * <p>If a {@link DocumentFilter} is installed in this document, the
+ * corresponding method of the filter object is called.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -720,11 +765,21 @@ public abstract class AbstractDocument implements Document, Serializable
* @since 1.4
*/
public void replace(int offset, int length, String text,
+ AttributeSet attributes)
+ throws BadLocationException
+ {
+ if (documentFilter != null)
+ documentFilter.replace(getBypass(), offset, length, text, attributes);
+ else
+ replaceImpl(offset, length, text, attributes);
+ }
+
+ void replaceImpl(int offset, int length, String text,
AttributeSet attributes)
throws BadLocationException
{
- remove(offset, length);
- insertString(offset, text, attributes);
+ removeImpl(offset, length);
+ insertStringImpl(offset, text, attributes);
}
/**
@@ -2239,4 +2294,37 @@ public abstract class AbstractDocument implements Document, Serializable
+ getStartOffset() + "," + getEndOffset() + "\n");
}
}
+
+ /** A class whose methods delegate to the insert, remove and replace methods
+ * of this document which do not check for an installed DocumentFilter.
+ */
+ class Bypass extends DocumentFilter.FilterBypass
+ {
+
+ public Document getDocument()
+ {
+ return AbstractDocument.this;
+ }
+
+ public void insertString(int offset, String string, AttributeSet attr)
+ throws BadLocationException
+ {
+ AbstractDocument.this.insertStringImpl(offset, string, attr);
+ }
+
+ public void remove(int offset, int length)
+ throws BadLocationException
+ {
+ AbstractDocument.this.removeImpl(offset, length);
+ }
+
+ public void replace(int offset, int length, String string,
+ AttributeSet attrs)
+ throws BadLocationException
+ {
+ AbstractDocument.this.replaceImpl(offset, length, string, attrs);
+ }
+
+ }
+
}
diff --git a/javax/swing/text/AsyncBoxView.java b/javax/swing/text/AsyncBoxView.java
index 863c409ed..90447f86e 100644
--- a/javax/swing/text/AsyncBoxView.java
+++ b/javax/swing/text/AsyncBoxView.java
@@ -1367,7 +1367,7 @@ public class AsyncBoxView
/**
* Updates the layout for this view. This is implemented to trigger
- * {link ChildLocator#childChanged} for the changed view, if there is
+ * {@link ChildLocator#childChanged} for the changed view, if there is
* any.
*
* @param ec the element change, may be <code>null</code> if there were
diff --git a/javax/swing/text/CompositeView.java b/javax/swing/text/CompositeView.java
index 9195602ce..17f13dbed 100644
--- a/javax/swing/text/CompositeView.java
+++ b/javax/swing/text/CompositeView.java
@@ -633,8 +633,51 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is NORTH chose the View preceding the one that contains the
+ // offset 'pos' (imagine the views are stacked on top of each other where
+ // the top is 0 and the bottom is getViewCount()-1.
+ // Consecutively when the direction is SOUTH the View following the one
+ // the offset 'pos' lies in is questioned.
+ //
+ // This limitation is described as PR 27345.
+ int index = getViewIndex(pos, b);
+ View v = null;
+
+ if (index == -1)
+ return pos;
+
+ switch (direction)
+ {
+ case NORTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index <= 0)
+ return pos;
+
+ v = getView(index - 1);
+ break;
+ case SOUTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index >= getViewCount() - 1)
+ return pos;
+
+ v = getView(index + 1);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos, b, a, direction, biasRet);
}
/**
@@ -667,8 +710,55 @@ public abstract class CompositeView
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is EAST increase the offset by one and ask the View to
+ // which that index belong to calculate the 'next visual position'.
+ // If the direction is WEST do the same with offset 'pos' being decreased
+ // by one.
+ // This behavior will fail in a right-to-left or bidi environment!
+ //
+ // This limitation is described as PR 27346.
+ int index;
+
+ View v = null;
+
+ switch (direction)
+ {
+ case EAST:
+ index = getViewIndex(pos + 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ case WEST:
+ index = getViewIndex(pos - 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos,
+ b,
+ a,
+ direction,
+ biasRet);
}
/**
diff --git a/javax/swing/text/DefaultCaret.java b/javax/swing/text/DefaultCaret.java
index 9b6cd6b07..fc2aca0a0 100644
--- a/javax/swing/text/DefaultCaret.java
+++ b/javax/swing/text/DefaultCaret.java
@@ -59,6 +59,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.EventListenerList;
+import javax.swing.text.Position.Bias;
/**
* The default implementation of the {@link Caret} interface.
@@ -75,6 +76,31 @@ public class DefaultCaret extends Rectangle
*/
static JTextComponent componentWithSelection;
+ /** An implementation of NavigationFilter.FilterBypass which delegates
+ * to the corresponding methods of the <code>DefaultCaret</code>.
+ *
+ * @author Robert Schuster (robertschuster@fsfe.org)
+ */
+ class Bypass extends NavigationFilter.FilterBypass
+ {
+
+ public Caret getCaret()
+ {
+ return DefaultCaret.this;
+ }
+
+ public void moveDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.moveDotImpl(dot);
+ }
+
+ public void setDot(int dot, Bias bias)
+ {
+ DefaultCaret.this.setDotImpl(dot);
+ }
+
+ }
+
/**
* Controls the blinking of the caret.
*
@@ -299,12 +325,29 @@ public class DefaultCaret extends Rectangle
private BlinkTimerListener blinkListener;
/**
+ * A <code>NavigationFilter.FilterBypass</code> instance which
+ * is provided to the a <code>NavigationFilter</code> to
+ * unconditionally set or move the caret.
+ */
+ NavigationFilter.FilterBypass bypass;
+
+ /**
* Creates a new <code>DefaultCaret</code> instance.
*/
public DefaultCaret()
{
// Nothing to do here.
}
+
+ /** Returns the caret's <code>NavigationFilter.FilterBypass</code> instance
+ * and creates it if it does not yet exist.
+ *
+ * @return The caret's <code>NavigationFilter.FilterBypass</code> instance.
+ */
+ private NavigationFilter.FilterBypass getBypass()
+ {
+ return (bypass == null) ? bypass = new Bypass() : bypass;
+ }
/**
* Sets the Caret update policy.
@@ -946,12 +989,24 @@ public class DefaultCaret extends Rectangle
* Moves the <code>dot</code> location without touching the
* <code>mark</code>. This is used when making a selection.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot the location where to move the dot
*
* @see #setDot(int)
*/
public void moveDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.moveDot(getBypass(), dot, Bias.Forward);
+ else
+ moveDotImpl(dot);
+ }
+
+ void moveDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -970,12 +1025,24 @@ public class DefaultCaret extends Rectangle
* <code>Document</code>. This also sets the <code>mark</code> to the new
* location.
*
+ * <p>If the underlying text component has a {@link NavigationFilter}
+ * installed the caret will call the corresponding method of that object.</p>
+ *
* @param dot
* the new position to be set
* @see #moveDot(int)
*/
public void setDot(int dot)
{
+ NavigationFilter filter = textComponent.getNavigationFilter();
+ if (filter != null)
+ filter.setDot(getBypass(), dot, Bias.Forward);
+ else
+ setDotImpl(dot);
+ }
+
+ void setDotImpl(int dot)
+ {
if (dot >= 0)
{
Document doc = textComponent.getDocument();
@@ -1135,4 +1202,5 @@ public class DefaultCaret extends Rectangle
blinkTimer = new Timer(getBlinkRate(), blinkListener);
blinkTimer.setRepeats(true);
}
+
}
diff --git a/javax/swing/text/DefaultHighlighter.java b/javax/swing/text/DefaultHighlighter.java
index 58602c249..59f77316e 100644
--- a/javax/swing/text/DefaultHighlighter.java
+++ b/javax/swing/text/DefaultHighlighter.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
@@ -45,6 +47,7 @@ import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
+import javax.swing.SwingUtilities;
import javax.swing.plaf.TextUI;
public class DefaultHighlighter extends LayeredHighlighter
@@ -91,8 +94,18 @@ public class DefaultHighlighter extends LayeredHighlighter
Rectangle l0 = ui.modelToView(t, p0, null);
Rectangle l1 = ui.modelToView(t, p1, null);
+ // Note: The computed locations may lie outside of the allocation
+ // area if the text is scrolled.
+
if (l0.y == l1.y)
- paintHighlight(g, l0.union(l1));
+ {
+ SwingUtilities.computeUnion(l0.x, l0.y, l0.width, l0.height, l1);
+
+ // Paint only inside the allocation area.
+ SwingUtilities.computeIntersection(rect.x, rect.y, rect.width, rect.height, l1);
+
+ paintHighlight(g, l1);
+ }
else
{
// 1. The line of p0 is painted from the position of p0
@@ -104,7 +117,11 @@ public class DefaultHighlighter extends LayeredHighlighter
// position of p1.
// Highlight first line until the end.
- l0.width = rect.width - l0.x;
+ // If rect.x is non-zero the calculation will properly adjust the
+ // area to be painted.
+ l0.x -= rect.x;
+ l0.width = rect.width - l0.x - rect.x;
+
paintHighlight(g, l0);
int posBelow = Utilities.getPositionBelow(t, p0, l0.x);
@@ -358,6 +375,7 @@ public class DefaultHighlighter extends LayeredHighlighter
public void paintLayeredHighlights(Graphics g, int p0, int p1,
Shape viewBounds, JTextComponent editor,
View view)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
diff --git a/javax/swing/text/FieldView.java b/javax/swing/text/FieldView.java
index 928949b56..127f32f53 100644
--- a/javax/swing/text/FieldView.java
+++ b/javax/swing/text/FieldView.java
@@ -236,8 +236,13 @@ public class FieldView extends PlainView
checkContainer();
Shape newAlloc = adjustAllocation(s);
-
+
+ // Set a clip to prevent drawing outside of the allocation area.
+ // TODO: Is there a better way to achieve this?
+ Shape clip = g.getClip();
+ g.setClip(s);
super.paint(g, newAlloc);
+ g.setClip(clip);
}
public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
diff --git a/javax/swing/text/FlowView.java b/javax/swing/text/FlowView.java
index 8be8f41e9..8ca55d834 100644
--- a/javax/swing/text/FlowView.java
+++ b/javax/swing/text/FlowView.java
@@ -433,7 +433,7 @@ public abstract class FlowView extends BoxView
/**
* Loads the children of this view. The <code>FlowView</code> does not
* directly load its children. Instead it creates a logical view
- * (@{link #layoutPool}) which is filled by the logical child views.
+ * ({@link #layoutPool}) which is filled by the logical child views.
* The real children are created at layout time and each represent one
* row.
*
diff --git a/javax/swing/text/Utilities.java b/javax/swing/text/Utilities.java
index 3149048f7..f154e55aa 100644
--- a/javax/swing/text/Utilities.java
+++ b/javax/swing/text/Utilities.java
@@ -48,6 +48,7 @@ import java.text.BreakIterator;
* inside this package.
*
* @author Roman Kennke (roman@ontographics.com)
+ * @author Robert Schuster (robertschuster@fsfe.org)
*/
public class Utilities
{
@@ -238,34 +239,39 @@ public class Utilities
// At the end of the for loop, this holds the requested model location
int pos;
int currentX = x0;
+ int width = 0;
for (pos = 0; pos < s.count; pos++)
{
char nextChar = s.array[s.offset+pos];
if (nextChar == 0)
- {
- if (! round && pos > 0)
- pos--;
break;
- }
+
if (nextChar != '\t')
- currentX += fm.charWidth(nextChar);
+ width = fm.charWidth(nextChar);
else
{
if (te == null)
- currentX += fm.charWidth(' ');
+ width = fm.charWidth(' ');
else
- currentX = (int) te.nextTabStop(currentX, pos);
+ width = ((int) te.nextTabStop(currentX, pos)) - currentX;
}
- if (currentX >= x)
+ if (round)
{
- if (! round && pos > 0)
- pos--;
- break;
+ if (currentX + (width>>1) > x)
+ break;
}
+ else
+ {
+ if (currentX + width > x)
+ break;
+ }
+
+ currentX += width;
}
+
return pos + p0;
}
@@ -316,21 +322,31 @@ public class Utilities
String text = c.getText();
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
+
int last = wb.following(offs);
int current = wb.next();
+ int cp;
+
while (current != BreakIterator.DONE)
{
for (int i = last; i < current; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ cp = text.codePointAt(i);
+
+ // Return the last found bound if there is a letter at the current
+ // location or is not whitespace (meaning it is a number or
+ // punctuation). The first case means that 'last' denotes the
+ // beginning of a word while the second case means it is the start
+ // of some else.
+ if (Character.isLetter(cp)
+ || !Character.isWhitespace(cp))
return last;
}
last = current;
current = wb.next();
}
- return BreakIterator.DONE;
+
+ throw new BadLocationException("no more word", offs);
}
/**
@@ -359,9 +375,7 @@ public class Utilities
{
for (int i = last; i < offs; i++)
{
- // FIXME: Should use isLetter(int) and text.codePointAt(int)
- // instead, but isLetter(int) isn't implemented yet
- if (Character.isLetter(text.charAt(i)))
+ if (Character.isLetter(text.codePointAt(i)))
return last;
}
last = current;
@@ -511,24 +525,28 @@ public class Utilities
int x0, int x, TabExpander e,
int startOffset)
{
- int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset);
+ int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset, false);
BreakIterator breaker = BreakIterator.getWordInstance();
breaker.setText(s);
- // If mark is equal to the end of the string, just use that position
- if (mark >= s.count)
+ // If startOffset and s.offset differ then we need to use
+ // that difference two convert the offset between the two metrics.
+ int shift = startOffset - s.offset;
+
+ // If mark is equal to the end of the string, just use that position.
+ if (mark >= shift + s.count)
return mark;
// Try to find a word boundary previous to the mark at which we
- // can break the text
- int preceding = breaker.preceding(mark + 1);
+ // can break the text.
+ int preceding = breaker.preceding(mark + 1 - shift);
if (preceding != 0)
- return preceding;
- else
- // If preceding is 0 we couldn't find a suitable word-boundary so
- // just break it on the character boundary
- return mark;
+ return preceding + shift;
+
+ // If preceding is 0 we couldn't find a suitable word-boundary so
+ // just break it on the character boundary
+ return mark;
}
/**
diff --git a/javax/swing/text/View.java b/javax/swing/text/View.java
index 2feaf29a4..d8ad5f585 100644
--- a/javax/swing/text/View.java
+++ b/javax/swing/text/View.java
@@ -1,5 +1,5 @@
/* View.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -733,23 +733,38 @@ public abstract class View implements SwingConstants
throws BadLocationException
{
int ret = pos;
+ Rectangle r;
+ View parent;
+
switch (d)
{
- case WEST:
- ret = pos - 1;
- break;
case EAST:
- ret = pos + 1;
+ // TODO: take component orientation into account?
+ // Note: If pos is below zero the implementation will return
+ // pos + 1 regardless of whether that value is a correct offset
+ // in the document model. However this is what the RI does.
+ ret = Math.min(pos + 1, getEndOffset());
+ break;
+ case WEST:
+ // TODO: take component orientation into account?
+ ret = Math.max(pos - 1, getStartOffset());
break;
case NORTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area above.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x, r.y - 1, a, biasRet);
break;
case SOUTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area below.
+ parent = getParent();
+ r = parent.modelToView(pos, a, b).getBounds();
+ ret = parent.viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
break;
default:
throw new IllegalArgumentException("Illegal value for d");
}
+
return ret;
}
}
diff --git a/javax/swing/text/WrappedPlainView.java b/javax/swing/text/WrappedPlainView.java
index 9477f23f7..1cd85b515 100644
--- a/javax/swing/text/WrappedPlainView.java
+++ b/javax/swing/text/WrappedPlainView.java
@@ -275,7 +275,17 @@ public class WrappedPlainView extends BoxView implements TabExpander
protected int calculateBreakPosition(int p0, int p1)
{
Container c = getContainer();
- Rectangle alloc = new Rectangle(0, 0, getWidth(), getHeight());
+
+ int li = getLeftInset();
+ int ti = getTopInset();
+
+ Rectangle alloc = new Rectangle(li, ti,
+ getWidth()-getRightInset()-li,
+ getHeight()-getBottomInset()-ti);
+
+ // Mimic a behavior observed in the RI.
+ if (alloc.isEmpty())
+ return 0;
updateMetrics();
@@ -288,10 +298,10 @@ public class WrappedPlainView extends BoxView implements TabExpander
// this shouldn't happen
throw new InternalError("Invalid offsets p0: " + p0 + " - p1: " + p1);
}
- // FIXME: Should we account for the insets of the container?
+
if (wordWrap)
- return p0 + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
- alloc.x + alloc.width, this, 0);
+ return Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
+ alloc.x + alloc.width, this, p0);
else
return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
alloc.x + alloc.width, this, 0,
@@ -419,7 +429,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
class WrappedLine extends View
{
/** Used to cache the number of lines for this View **/
- int numLines;
+ int numLines = 1;
public WrappedLine(Element elem)
{
@@ -437,17 +447,30 @@ public class WrappedPlainView extends BoxView implements TabExpander
int end = getEndOffset();
int currStart = getStartOffset();
- int currEnd;
+ int currEnd;
+ int count = 0;
while (currStart < end)
{
currEnd = calculateBreakPosition(currStart, end);
+
drawLine(currStart, currEnd, g, rect.x, rect.y + metrics.getAscent());
+
rect.y += lineHeight;
if (currEnd == currStart)
currStart ++;
else
- currStart = currEnd;
+ currStart = currEnd;
+
+ count++;
+
+ }
+
+ if (count != numLines)
+ {
+ numLines = count;
+ preferenceChanged(this, false, true);
}
+
}
/**
@@ -470,6 +493,9 @@ public class WrappedPlainView extends BoxView implements TabExpander
// depending on which position calculateBreakPosition returns
breakPoint = calculateBreakPosition(i, end);
+ if (breakPoint == 0)
+ return;
+
// If breakPoint is equal to the current index no further
// line is needed and we can end the loop.
if (breakPoint == i)
@@ -492,7 +518,7 @@ public class WrappedPlainView extends BoxView implements TabExpander
if (axis == X_AXIS)
return getWidth();
else if (axis == Y_AXIS)
- return numLines * metrics.getHeight();
+ return numLines * metrics.getHeight();
throw new IllegalArgumentException("Invalid axis for getPreferredSpan: "
+ axis);
@@ -578,13 +604,15 @@ public class WrappedPlainView extends BoxView implements TabExpander
Rectangle rect = a.getBounds();
int currLineStart = getStartOffset();
- // WrappedLine does not represent the last possible offset in a line.
- // So we should never return that offset. Behavior observed in the RI.
- int end = getEndOffset() - 1;
+ // Although calling modelToView with the last possible offset will
+ // cause a BadLocationException in CompositeView it is allowed
+ // to return that offset in viewToModel.
+ int end = getEndOffset();
int lineHeight = metrics.getHeight();
if (y < rect.y)
return currLineStart;
+
if (y > rect.y + rect.height)
return end;
@@ -592,9 +620,10 @@ public class WrappedPlainView extends BoxView implements TabExpander
// text but the area where text *may* be painted. This means the width
// is most of the time identical to the component's width.
- while (true)
+ while (currLineStart != end)
{
int currLineEnd = calculateBreakPosition(currLineStart, end);
+
// If we're at the right y-position that means we're on the right
// logical line and we should look for the character
if (y >= rect.y && y < rect.y + lineHeight)
@@ -608,18 +637,27 @@ public class WrappedPlainView extends BoxView implements TabExpander
// Shouldn't happen
}
- return Utilities.getTabbedTextOffset(s, metrics, rect.x,
+ int offset = Utilities.getTabbedTextOffset(s, metrics, rect.x,
(int) x,
WrappedPlainView.this,
currLineStart);
+ // If the calculated offset is the end of the line (in the
+ // document (= start of the next line) return the preceding
+ // offset instead. This makes sure that clicking right besides
+ // the last character in a line positions the cursor after the
+ // last character and not in the beginning of the next line.
+ return (offset == currLineEnd) ? offset - 1 : offset;
}
// Increment rect.y so we're checking the next logical line
rect.y += lineHeight;
// Increment currLineStart to the model position of the start
- // of the next logical line
+ // of the next logical line.
currLineStart = currLineEnd;
+
}
+
+ return end;
}
/**
@@ -632,6 +670,16 @@ public class WrappedPlainView extends BoxView implements TabExpander
*/
void updateDamage (Rectangle a)
{
+ // If the allocation area is empty we can't do anything useful.
+ // As determining the number of lines is impossible in that state we
+ // reset it to an invalid value which can then be recalculated at a
+ // later point.
+ if (a.isEmpty())
+ {
+ numLines = 1;
+ return;
+ }
+
int oldNumLines = numLines;
determineNumLines();
diff --git a/javax/swing/tree/AbstractLayoutCache.java b/javax/swing/tree/AbstractLayoutCache.java
index 445aa233e..713c9cae7 100644
--- a/javax/swing/tree/AbstractLayoutCache.java
+++ b/javax/swing/tree/AbstractLayoutCache.java
@@ -44,6 +44,7 @@ import java.awt.Rectangle;
import java.util.Enumeration;
import javax.swing.event.TreeModelEvent;
+import javax.swing.tree.VariableHeightLayoutCache.NodeRecord;
/**
* class AbstractLayoutCache
@@ -66,19 +67,21 @@ public abstract class AbstractLayoutCache
// Do nothing here.
}
- /**
- * getNodeDimensions
- *
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
- * @param value3 TODO
- * @param value4 TODO
- * @return Rectangle
- */
- public abstract Rectangle getNodeDimensions(Object value0, int value1,
- int value2, boolean value3,
- Rectangle value4);
+ /**
+ * Get the node dimensions. The NodeDimensions property must be set (unless
+ * the method is overridden, like if {@link FixedHeightLayoutCache}. If the
+ * method is not overridden and the property is not set, the InternalError is
+ * thrown.
+ *
+ * @param value the last node in the path
+ * @param row the node row
+ * @param depth the indentation depth
+ * @param expanded true if this node is expanded, false otherwise
+ * @param bounds the area where the tree is displayed
+ */
+ public abstract Rectangle getNodeDimensions(Object value, int row,
+ int depth, boolean expanded,
+ Rectangle bounds);
}
/**
@@ -204,6 +207,7 @@ public abstract class AbstractLayoutCache
public void setRowHeight(int height)
{
rowHeight = height;
+ invalidateSizes();
}
/**
@@ -237,29 +241,51 @@ public abstract class AbstractLayoutCache
}
/**
- * getPreferredHeight
- *
- * @return int
+ * Get the sum of heights for all rows. This class provides a general not
+ * optimized implementation that is overridded in derived classes
+ * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for
+ * the better performance.
*/
- public int getPreferredHeight()
- throws NotImplementedException
+ public int getPreferredHeight()
{
- return 0; // TODO
+ int height = 0;
+ int n = getRowCount();
+ Rectangle r = new Rectangle();
+ for (int i = 0; i < n; i++)
+ {
+ TreePath path = getPathForRow(i);
+ height += getBounds(path, r).height;
+ }
+ return height;
}
/**
- * getPreferredWidth
+ * Get the maximal width. This class provides a general not
+ * optimized implementation that is overridded in derived classes
+ * ({@link VariableHeightLayoutCache}, {@link FixedHeightLayoutCache}) for
+ * the better performance.
*
- * @param value0 TODO
- *
- * @return int
+ * @param rect the rectangle that is used during the method work
*/
- public int getPreferredWidth(Rectangle value0)
- throws NotImplementedException
+ public int getPreferredWidth(Rectangle rect)
{
- return 0; // TODO
+ int maximalWidth = 0;
+ Rectangle r = new Rectangle();
+ int n = getRowCount();
+ for (int i = 0; i < n; i++)
+ {
+ TreePath path = getPathForRow(i);
+ r.setBounds(0,0,0,0);
+ r = getBounds(path, r);
+ if (r.x + r.width > maximalWidth)
+ maximalWidth = r.x + r.width;
+ // Invalidate the cached value as this may be the very early call
+ // before the heigth is properly set (the vertical coordinate may
+ // not be correct).
+ invalidatePathBounds(path);
+ }
+ return maximalWidth;
}
-
/**
* isExpanded
*
@@ -409,13 +435,14 @@ public abstract class AbstractLayoutCache
}
/**
- * isFixedRowHeight
+ * Returns true if this layout supposes that all rows have the fixed
+ * height.
*
- * @return boolean
+ * @return boolean true if all rows in the tree must have the fixed
+ * height (false by default).
*/
protected boolean isFixedRowHeight()
- throws NotImplementedException
{
- return false; // TODO
+ return false;
}
}
diff --git a/javax/swing/tree/DefaultMutableTreeNode.java b/javax/swing/tree/DefaultMutableTreeNode.java
index 3569ebdbb..389101be1 100644
--- a/javax/swing/tree/DefaultMutableTreeNode.java
+++ b/javax/swing/tree/DefaultMutableTreeNode.java
@@ -154,6 +154,8 @@ public class DefaultMutableTreeNode
/**
* Adds a new child node to this node and sets this node as the parent of
* the child node. The child node must not be an ancestor of this node.
+ * If the tree uses the {@link DefaultTreeModel}, you must subsequently
+ * call {@link DefaultTreeModel#reload(TreeNode)}.
*
* @param child the child node (<code>null</code> not permitted).
*
diff --git a/javax/swing/tree/DefaultTreeCellEditor.java b/javax/swing/tree/DefaultTreeCellEditor.java
index e28c9261b..cc19501d2 100644
--- a/javax/swing/tree/DefaultTreeCellEditor.java
+++ b/javax/swing/tree/DefaultTreeCellEditor.java
@@ -77,17 +77,6 @@ public class DefaultTreeCellEditor
implements ActionListener, TreeCellEditor, TreeSelectionListener
{
/**
- * The gap between the icon and editing component during editing.
- */
- static int ICON_TEXT_GAP = 3;
-
- /**
- * The left margin of the editing container (the gap between the tree and
- * the editing component of the editing icon.
- */
- static int TREE_ICON_GAP = ICON_TEXT_GAP;
-
- /**
* The number of the fast mouse clicks, required to start the editing
* session.
*/
@@ -141,7 +130,7 @@ public class DefaultTreeCellEditor
{
// From the previous version, the left margin is taken as half
// of the icon width.
- editingIcon.paintIcon(this, g, TREE_ICON_GAP, 0);
+ editingIcon.paintIcon(this, g, 0, 0);
}
super.paint(g);
}
@@ -157,7 +146,7 @@ public class DefaultTreeCellEditor
// Move the component to the left, leaving room for the editing icon:
if (editingIcon != null)
- eOffset = TREE_ICON_GAP + editingIcon.getIconWidth() + ICON_TEXT_GAP;
+ eOffset = editingIcon.getIconWidth();
else
eOffset = 0;
@@ -166,7 +155,7 @@ public class DefaultTreeCellEditor
c.setLocation(eOffset, 0);
// Span the editing component near over all window width.
- c.setSize(bounds.width - eOffset - TREE_ICON_GAP, bounds.height);
+ c.setSize(bounds.width - eOffset, bounds.height);
/*
* @specnote the Sun sets some more narrow editing component width (it is
* not documented how does it is calculated). However as our text field is
@@ -542,7 +531,8 @@ public class DefaultTreeCellEditor
* If the realEditor returns true to this message, prepareForEditing
* is messaged and true is returned.
*
- * @param event - the event the editor should use to consider whether to begin editing or not
+ * @param event - the event the editor should use to consider whether to
+ * begin editing or not
* @return true if editing can be started
*/
public boolean isCellEditable(EventObject event)
diff --git a/javax/swing/tree/DefaultTreeCellRenderer.java b/javax/swing/tree/DefaultTreeCellRenderer.java
index df70ba7fb..5e93145ae 100644
--- a/javax/swing/tree/DefaultTreeCellRenderer.java
+++ b/javax/swing/tree/DefaultTreeCellRenderer.java
@@ -407,7 +407,7 @@ public class DefaultTreeCellRenderer
this.hasFocus = hasFocus;
setHorizontalAlignment(LEFT);
setOpaque(false);
- setVerticalAlignment(TOP);
+ setVerticalAlignment(CENTER);
setEnabled(true);
super.setFont(UIManager.getFont("Tree.font"));
@@ -445,8 +445,7 @@ public class DefaultTreeCellRenderer
/**
* Paints the value. The background is filled based on selected.
*
- * @param g
- * the graphics device.
+ * @param g the graphics device.
*/
public void paint(Graphics g)
{
@@ -468,17 +467,27 @@ public class DefaultTreeCellRenderer
getHorizontalTextPosition(), vr, ir, tr,
getIconTextGap());
+ // Reusing one rectangle.
+ Rectangle bounds = getBounds(ir);
+
+ bounds.x = tr.x - insets.left;
+ bounds.width = tr.width + insets.left+insets.right;
+
g.setColor(super.getBackground());
- g.fillRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
- // paint border
- Color b = getBorderSelectionColor();
- if (b != null)
+ super.paint(g);
+
+ // Paint the border of the focused element only (lead selection)
+ if (hasFocus)
{
- g.setColor(b);
- g.drawRect(tr.x, tr.y, tr.width, tr.height - insets.top - insets.bottom);
+ Color b = getBorderSelectionColor();
+ if (b != null)
+ {
+ g.setColor(b);
+ g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
+ }
}
- super.paint(g);
}
/**
diff --git a/javax/swing/tree/DefaultTreeModel.java b/javax/swing/tree/DefaultTreeModel.java
index e462b1c8b..713343811 100644
--- a/javax/swing/tree/DefaultTreeModel.java
+++ b/javax/swing/tree/DefaultTreeModel.java
@@ -223,27 +223,60 @@ public class DefaultTreeModel
}
/**
- * Invoke this method if you've modified the TreeNodes upon
- * which this model depends. The model will notify all of its
- * listeners that the model has changed.
+ * <p>
+ * Invoke this method if you've modified the TreeNodes upon which this model
+ * depends. The model will notify all of its listeners that the model has
+ * changed. It will fire the events, necessary to update the layout caches and
+ * repaint the tree. The tree will <i>not</i> be properly refreshed if you
+ * call the JTree.repaint instead.
+ * </p>
+ * <p>
+ * This method will refresh the information about whole tree from the root. If
+ * only part of the tree should be refreshed, it is more effective to call
+ * {@link #reload(TreeNode)}.
+ * </p>
*/
public void reload()
- throws NotImplementedException
{
- // TODO
+ // Need to duplicate the code because the root can formally be
+ // no an instance of the TreeNode.
+ int n = getChildCount(root);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(root, i);
+ }
+
+ fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
}
/**
- * Invoke this method if you've modified the TreeNodes upon
- * which this model depends. The model will notify all of its
- * listeners that the model has changed.
+ * Invoke this method if you've modified the TreeNodes upon which this model
+ * depends. The model will notify all of its listeners that the model has
+ * changed. It will fire the events, necessary to update the layout caches and
+ * repaint the tree. The tree will <i>not</i> be properly refreshed if you
+ * call the JTree.repaint instead.
*
- * @param node - TODO
+ * @param node - the tree node, from which the tree nodes have changed
+ * (inclusive). If you do not know this node, call {@link #reload()}
+ * instead.
*/
public void reload(TreeNode node)
- throws NotImplementedException
{
- // TODO
+ int n = getChildCount(node);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(node, i);
+ }
+
+ fireTreeStructureChanged(this, getPathToRoot(node), childIdx, children);
}
/**
@@ -392,9 +425,18 @@ public class DefaultTreeModel
* @param node that had its children and grandchildren changed.
*/
public void nodeStructureChanged(TreeNode node)
- throws NotImplementedException
{
- // TODO
+ int n = getChildCount(root);
+ int[] childIdx = new int[n];
+ Object[] children = new Object[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ childIdx[i] = i;
+ children[i] = getChild(root, i);
+ }
+
+ fireTreeStructureChanged(this, new Object[] { root }, childIdx, children);
}
/**
diff --git a/javax/swing/tree/DefaultTreeSelectionModel.java b/javax/swing/tree/DefaultTreeSelectionModel.java
index f0e8f4932..e38850af8 100644
--- a/javax/swing/tree/DefaultTreeSelectionModel.java
+++ b/javax/swing/tree/DefaultTreeSelectionModel.java
@@ -38,14 +38,15 @@ exception statement from your version. */
package javax.swing.tree;
-import gnu.classpath.NotImplementedException;
-
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Vector;
import javax.swing.DefaultListSelectionModel;
@@ -61,6 +62,7 @@ import javax.swing.event.TreeSelectionListener;
* expansion events.
*
* @author Andrew Selkirk
+ * @author Audrius Meskauskas
*/
public class DefaultTreeSelectionModel
implements Cloneable, Serializable, TreeSelectionModel
@@ -145,19 +147,33 @@ public class DefaultTreeSelectionModel
// Clone the selection and the list selection model.
cloned.selection = (TreePath[]) selection.clone();
- cloned.listSelectionModel =
- (DefaultListSelectionModel) listSelectionModel.clone();
+ if (listSelectionModel!=null)
+ cloned.listSelectionModel =
+ (DefaultListSelectionModel) listSelectionModel.clone();
return cloned;
}
/**
* Returns a string that shows this object's properties.
+ * The returned string lists the selected tree rows, if any.
*
* @return a string that shows this object's properties
*/
- public String toString() throws NotImplementedException
+ public String toString()
{
- return null; // TODO
+ if (isSelectionEmpty())
+ return "[selection empty]";
+ else
+ {
+ StringBuffer b = new StringBuffer("selected rows: [");
+ for (int i = 0; i < selection.length; i++)
+ {
+ b.append(getRow(selection[i]));
+ b.append(' ');
+ }
+ b.append(", lead "+getLeadSelectionRow());
+ return b.toString();
+ }
}
/**
@@ -221,6 +237,7 @@ public class DefaultTreeSelectionModel
public void setSelectionMode(int mode)
{
selectionMode = mode;
+ insureRowContinuity();
}
/**
@@ -245,7 +262,60 @@ public class DefaultTreeSelectionModel
*/
public void setSelectionPath(TreePath path)
{
+ // The most frequently only one cell in the tree is selected.
+ TreePath[] ose = selection;
selection = new TreePath[] { path };
+ TreePath oldLead = leadPath;
+ leadIndex = 0;
+ leadRow = getRow(path);
+ leadPath = path;
+
+ TreeSelectionEvent event;
+
+ if (ose != null && ose.length > 0)
+ {
+ // The first item in the path list is the selected path.
+ // The remaining items are unselected pathes.
+ TreePath[] changed = new TreePath[ose.length + 1];
+ boolean[] news = new boolean[changed.length];
+ news[0] = true;
+ changed[0] = path;
+ System.arraycopy(ose, 0, changed, 1, ose.length);
+ event = new TreeSelectionEvent(this, changed, news, oldLead, path);
+ }
+ else
+ {
+ event = new TreeSelectionEvent(this, path, true, oldLead, path);
+ }
+ fireValueChanged(event);
+ }
+
+ /**
+ * Get the number of the tree row for the given path.
+ *
+ * @param path the tree path
+ * @return the tree row for this path or -1 if the path is not visible.
+ */
+ int getRow(TreePath path)
+ {
+ RowMapper mapper = getRowMapper();
+
+ if (mapper instanceof AbstractLayoutCache)
+ {
+ // The absolute majority of cases, unless the TreeUI is very
+ // seriously rewritten
+ AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
+ return ama.getRowForPath(path);
+ }
+ else
+ {
+ // Generic non optimized implementation.
+ int[] rows = mapper.getRowsForPaths(new TreePath[] { path });
+ if (rows.length == 0)
+ return - 1;
+ else
+ return rows[0];
+ }
}
/**
@@ -256,11 +326,11 @@ public class DefaultTreeSelectionModel
* @param paths the paths to set as selection
*/
public void setSelectionPaths(TreePath[] paths)
- throws NotImplementedException
{
// Must be called, as defined in JDK API 1.4.
insureUniqueness();
- // TODO
+ clearSelection();
+ addSelectionPaths(paths);
}
/**
@@ -268,13 +338,17 @@ public class DefaultTreeSelectionModel
* is already selected and doesn't add the same path twice. If this changes
* the selection the registered TreeSelectionListeners are notified.
*
+ * The lead path is changed to the added path. This also happen if the
+ * passed path was already selected before.
+ *
* @param path the path to add to the selection
*/
public void addSelectionPath(TreePath path)
{
if (! isPathSelected(path))
{
- if (isSelectionEmpty())
+ if (selectionMode == SINGLE_TREE_SELECTION || isSelectionEmpty()
+ || ! canPathBeAdded(path))
setSelectionPath(path);
else
{
@@ -284,9 +358,16 @@ public class DefaultTreeSelectionModel
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
}
+ }
+
+ if (path!=leadPath)
+ {
+ TreePath oldLead = leadPath;
leadPath = path;
- fireValueChanged(new TreeSelectionEvent(this, path, true, leadPath,
- path));
+ leadRow = getRow(path);
+ leadIndex = selection.length - 1;
+ fireValueChanged(new TreeSelectionEvent(this, path, true, oldLead,
+ leadPath));
}
}
@@ -301,7 +382,7 @@ public class DefaultTreeSelectionModel
{
// Must be called, as defined in JDK API 1.4.
insureUniqueness();
-
+
if (paths != null)
{
TreePath v0 = null;
@@ -320,11 +401,16 @@ public class DefaultTreeSelectionModel
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
}
+ TreePath oldLead = leadPath;
leadPath = paths[paths.length - 1];
+ leadRow = getRow(leadPath);
+ leadIndex = selection.length - 1;
+
fireValueChanged(new TreeSelectionEvent(this, v0, true,
- leadPath, paths[0]));
+ oldLead, leadPath));
}
}
+ insureRowContinuity();
}
}
@@ -336,6 +422,9 @@ public class DefaultTreeSelectionModel
*/
public void removeSelectionPath(TreePath path)
{
+ if (isSelectionEmpty())
+ return;
+
int index = - 1;
if (isPathSelected(path))
{
@@ -353,9 +442,15 @@ public class DefaultTreeSelectionModel
- index - 1);
selection = new TreePath[temp.length];
System.arraycopy(temp, 0, selection, 0, temp.length);
-
- fireValueChanged(new TreeSelectionEvent(this, path, false, leadPath,
- path));
+
+ // If the removed path was the lead path, set the lead path to null.
+ TreePath oldLead = leadPath;
+ if (path!=null && leadPath!=null && path.equals(leadPath))
+ leadPath = null;
+
+ fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead,
+ leadPath));
+ insureRowContinuity();
}
}
@@ -367,10 +462,13 @@ public class DefaultTreeSelectionModel
*/
public void removeSelectionPaths(TreePath[] paths)
{
+ if (isSelectionEmpty())
+ return;
if (paths != null)
{
int index = - 1;
TreePath v0 = null;
+ TreePath oldLead = leadPath;
for (int i = 0; i < paths.length; i++)
{
v0 = paths[i];
@@ -383,6 +481,8 @@ public class DefaultTreeSelectionModel
index = x;
break;
}
+ if (leadPath != null && leadPath.equals(v0))
+ leadPath = null;
}
TreePath[] temp = new TreePath[selection.length - 1];
System.arraycopy(selection, 0, temp, 0, index);
@@ -392,9 +492,10 @@ public class DefaultTreeSelectionModel
System.arraycopy(temp, 0, selection, 0, temp.length);
fireValueChanged(new TreeSelectionEvent(this, v0, false,
- leadPath, paths[0]));
+ oldLead, leadPath));
}
}
+ insureRowContinuity();
}
}
@@ -467,12 +568,23 @@ public class DefaultTreeSelectionModel
}
/**
- * Removes all paths from the selection.
+ * Removes all paths from the selection. Fire the unselection event.
*/
public void clearSelection()
{
- leadPath = null;
- selection = null;
+ if (! isSelectionEmpty())
+ {
+ TreeSelectionEvent event = new TreeSelectionEvent(
+ this, selection, new boolean[selection.length], leadPath, null);
+ leadPath = null;
+ selection = null;
+ fireValueChanged(event);
+ }
+ else
+ {
+ leadPath = null;
+ selection = null;
+ }
}
/**
@@ -588,18 +700,43 @@ public class DefaultTreeSelectionModel
* @param row the index of the row to check
* @return <code>true</code> if the row is in this selection,
* <code>false</code> otherwise
+ * @throws NullPointerException if the row mapper is not set (can only happen
+ * if the user has plugged in the custom incorrect TreeUI
+ * implementation.
*/
- public boolean isRowSelected(int row) throws NotImplementedException
+ public boolean isRowSelected(int row)
{
- return false; // TODO
+ // Return false if nothing is selected.
+ if (isSelectionEmpty())
+ return false;
+
+ RowMapper mapper = getRowMapper();
+
+ if (mapper instanceof AbstractLayoutCache)
+ {
+ // The absolute majority of cases, unless the TreeUI is very
+ // seriously rewritten
+ AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
+ TreePath path = ama.getPathForRow(row);
+ return isPathSelected(path);
+ }
+ else
+ {
+ // Generic non optimized implementation.
+ int[] rows = mapper.getRowsForPaths(selection);
+ for (int i = 0; i < rows.length; i++)
+ if (rows[i] == row)
+ return true;
+ return false;
+ }
}
/**
* Updates the mappings from TreePaths to row indices.
*/
- public void resetRowSelection() throws NotImplementedException
+ public void resetRowSelection()
{
- // TODO
+ // Nothing to do here.
}
/**
@@ -609,10 +746,7 @@ public class DefaultTreeSelectionModel
*/
public int getLeadSelectionRow()
{
- if ((rowMapper == null) || (leadPath == null))
- return - 1;
- else
- return rowMapper.getRowsForPaths(new TreePath[] { leadPath })[0];
+ return leadRow;
}
/**
@@ -665,23 +799,93 @@ public class DefaultTreeSelectionModel
* has more than one path, the selection is reset to the contain only the
* first path.
*/
- protected void insureRowContinuity() throws NotImplementedException
+ protected void insureRowContinuity()
{
- // TODO
+ if (selection == null || selection.length < 2)
+ return;
+ else if (selectionMode == CONTIGUOUS_TREE_SELECTION)
+ {
+ if (rowMapper == null)
+ // This is the best we can do without the row mapper:
+ selectOne();
+ else
+ {
+ int[] rows = rowMapper.getRowsForPaths(selection);
+ Arrays.sort(rows);
+ int i;
+ for (i = 1; i < rows.length; i++)
+ {
+ if (rows[i - 1] != rows[i] - 1)
+ // Break if no longer continuous.
+ break;
+ }
+
+ if (i < rows.length)
+ {
+ TreePath[] ns = new TreePath[i];
+ for (int j = 0; j < ns.length; j++)
+ ns[i] = getPath(j);
+ setSelectionPaths(ns);
+ }
+ }
+ }
+ else if (selectionMode == SINGLE_TREE_SELECTION)
+ selectOne();
+ }
+
+ /**
+ * Keep only one (normally last or leading) path in the selection.
+ */
+ private void selectOne()
+ {
+ if (leadIndex > 0 && leadIndex < selection.length)
+ setSelectionPath(selection[leadIndex]);
+ else
+ setSelectionPath(selection[selection.length -1]);
+ }
+
+ /**
+ * Get path for the given row that must be in the current selection.
+ */
+ private TreePath getPath(int row)
+ {
+ if (rowMapper instanceof AbstractLayoutCache)
+ return ((AbstractLayoutCache) rowMapper).getPathForRow(row);
+ else
+ {
+ int[] rows = rowMapper.getRowsForPaths(selection);
+ for (int i = 0; i < rows.length; i++)
+ if (rows[i] == row)
+ return selection[i];
+ }
+ throw new InternalError(row + " not in selection");
}
/**
- * Returns <code>true</code> if the paths are contiguous or we have no
- * RowMapper assigned.
+ * Returns <code>true</code> if the paths are contiguous (take subsequent
+ * rows in the diplayed tree view. The method returns <code>true</code> if
+ * we have no RowMapper assigned.
*
* @param paths the paths to check for continuity
* @return <code>true</code> if the paths are contiguous or we have no
* RowMapper assigned
*/
protected boolean arePathsContiguous(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || paths.length < 2)
+ return true;
+
+ int[] rows = rowMapper.getRowsForPaths(paths);
+
+ // The patches may not be sorted.
+ Arrays.sort(rows);
+
+ for (int i = 1; i < rows.length; i++)
+ {
+ if (rows[i-1] != rows[i] - 1)
+ return false;
+ }
+ return true;
}
/**
@@ -699,9 +903,32 @@ public class DefaultTreeSelectionModel
* selectionMode
*/
protected boolean canPathsBeAdded(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ TreePath [] all = new TreePath[paths.length + selection.length];
+ System.arraycopy(paths, 0, all, 0, paths.length);
+ System.arraycopy(selection, 0, all, paths.length, selection.length);
+
+ return arePathsContiguous(all);
+ }
+
+ /**
+ * Checks if the single path can be added to selection.
+ */
+ private boolean canPathBeAdded(TreePath path)
+ {
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ TreePath[] all = new TreePath[selection.length + 1];
+ System.arraycopy(selection, 0, all, 0, selection.length);
+ all[all.length - 1] = path;
+
+ return arePathsContiguous(all);
}
/**
@@ -713,29 +940,74 @@ public class DefaultTreeSelectionModel
* selectionMode
*/
protected boolean canPathsBeRemoved(TreePath[] paths)
- throws NotImplementedException
{
- return false; // STUB
+ if (rowMapper == null || isSelectionEmpty()
+ || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ return true;
+
+ HashSet set = new HashSet();
+ for (int i = 0; i < selection.length; i++)
+ set.add(selection[i]);
+
+ for (int i = 0; i < paths.length; i++)
+ set.remove(paths[i]);
+
+ TreePath[] remaining = new TreePath[set.size()];
+ Iterator iter = set.iterator();
+
+ for (int i = 0; i < remaining.length; i++)
+ remaining[i] = (TreePath) iter.next();
+
+ return arePathsContiguous(remaining);
}
/**
- * notifyPathChange
+ * Notify the installed listeners that the given patches have changed. This
+ * method will call listeners if invoked, but it is not called from the
+ * implementation of this class.
*
- * @param value0 TODO
- * @param value1 TODO
+ * @param vPathes the vector of the changed patches
+ * @param oldLeadSelection the old selection index
*/
- protected void notifyPathChange(Vector value0, TreePath value1)
- throws NotImplementedException
+ protected void notifyPathChange(Vector vPathes, TreePath oldLeadSelection)
{
- // STUB
+ TreePath[] pathes = new TreePath[vPathes.size()];
+ for (int i = 0; i < pathes.length; i++)
+ pathes[i] = (TreePath) vPathes.get(i);
+
+ boolean[] news = new boolean[pathes.length];
+ for (int i = 0; i < news.length; i++)
+ news[i] = isPathSelected(pathes[i]);
+
+ TreeSelectionEvent event = new TreeSelectionEvent(this, pathes, news,
+ oldLeadSelection,
+ leadPath);
+ fireValueChanged(event);
}
/**
- * Updates the lead index instance field.
+ * Updates the lead selection row number after changing the lead selection
+ * path.
*/
- protected void updateLeadIndex() throws NotImplementedException
+ protected void updateLeadIndex()
{
- // STUB
+ if (isSelectionEmpty())
+ {
+ leadRow = leadIndex = - 1;
+ }
+ else
+ {
+ leadRow = getRow(leadPath);
+ for (int i = 0; i < selection.length; i++)
+ {
+ if (selection[i].equals(leadPath))
+ {
+ leadIndex = i;
+ break;
+ }
+ }
+ leadIndex = leadRow;
+ }
}
/**
diff --git a/javax/swing/tree/FixedHeightLayoutCache.java b/javax/swing/tree/FixedHeightLayoutCache.java
index c4cc560fc..b8192211d 100644
--- a/javax/swing/tree/FixedHeightLayoutCache.java
+++ b/javax/swing/tree/FixedHeightLayoutCache.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package javax.swing.tree;
+import gnu.javax.swing.tree.GnuPath;
+
import java.awt.Rectangle;
import java.util.Enumeration;
import java.util.HashSet;
@@ -45,22 +47,21 @@ import java.util.LinkedList;
import java.util.Set;
import java.util.Vector;
-import javax.swing.UIManager;
import javax.swing.event.TreeModelEvent;
+
/**
* The fixed height tree layout. This class assumes that all cells in the tree
* have the same fixed height. This may be not the case, for instance, if leaves
* and branches have different height, of if the tree rows may have arbitrary
* variable height. This class will also work if the NodeDimensions are not
- * set. If they are set, the size calculations are just forwarded to the set
- * instance.
+ * set.
*
* @author Audrius Meskauskas
* @author Andrew Selkirk
*/
public class FixedHeightLayoutCache
- extends AbstractLayoutCache
+ extends VariableHeightLayoutCache
{
/**
* The cached node record.
@@ -114,26 +115,61 @@ public class FixedHeightLayoutCache
*/
private TreePath path;
+ /**
+ * Get the path for this node. The derived class is returned,
+ * making check for the last child of some parent easier.
+ */
TreePath getPath()
{
if (path == null)
{
+ boolean lastChild = false;
+ if (parent != null)
+ {
+ int nc = treeModel.getChildCount(parent);
+ if (nc > 0)
+ {
+ int n = treeModel.getIndexOfChild(parent, node);
+ if (n == nc - 1)
+ lastChild = true;
+ }
+ }
+
LinkedList lpath = new LinkedList();
NodeRecord rp = this;
while (rp != null)
{
lpath.addFirst(rp.node);
if (rp.parent != null)
- rp = (NodeRecord) nodes.get(rp.parent);
+ {
+ Object parent = rp.parent;
+ rp = (NodeRecord) nodes.get(parent);
+ // Add the root node, even if it is not visible.
+ if (rp == null)
+ lpath.addFirst(parent);
+ }
else
rp = null;
}
- path = new TreePath(lpath.toArray());
+ path = new GnuPath(lpath.toArray(), lastChild);
}
return path;
}
+
+ /**
+ * Get the rectangle bounds (compute, if required).
+ */
+ Rectangle getBounds()
+ {
+ // This method may be called in the context when the tree rectangle is
+ // not known. To work around this, it is assumed near infinitely large.
+ if (bounds==null)
+ bounds = getNodeDimensions(node, row, depth, isExpanded,
+ new Rectangle());
+ return bounds;
+ }
}
-
+
/**
* The set of all expanded tree nodes.
*/
@@ -153,6 +189,16 @@ public class FixedHeightLayoutCache
* If true, the row map must be recomputed before using.
*/
boolean dirty;
+
+ /**
+ * The cumulative height of all rows.
+ */
+ int totalHeight;
+
+ /**
+ * The maximal width.
+ */
+ int maximalWidth;
/**
* Creates the unitialised instance. Before using the class, the row height
@@ -184,6 +230,8 @@ public class FixedHeightLayoutCache
{
nodes.clear();
row2node.clear();
+
+ totalHeight = maximalWidth = 0;
Object root = treeModel.getRoot();
@@ -197,7 +245,7 @@ public class FixedHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 1);
+ countRows(child, root, 0);
}
}
dirty = false;
@@ -211,9 +259,11 @@ public class FixedHeightLayoutCache
Integer n = new Integer(row2node.size());
row2node.put(n, node);
- nodes.put(node, new NodeRecord(n.intValue(), depth, node, parent));
-
- if (expanded.contains(node) || parent == null)
+ NodeRecord nr = new NodeRecord(n.intValue(), depth, node, parent);
+ nodes.put(node, nr);
+
+ // For expanded nodes and for the root node.
+ if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
@@ -226,14 +276,15 @@ public class FixedHeightLayoutCache
}
/**
- * This should invalidate the width of the last path component, but
- * following the JDK 1.4 API it is not cached and the method should return
- * without action.
- * @param path the path being invalidated, ignored.
+ * Discard the bound information for the given path.
+ *
+ * @param path the path, for that the bound information must be recomputed.
*/
public void invalidatePathBounds(TreePath path)
{
- // Following JDK 1.4 API, should return without action.
+ NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
+ if (r!=null)
+ r.bounds = null;
}
/**
@@ -277,29 +328,34 @@ public class FixedHeightLayoutCache
* Get bounds for the given tree path.
*
* @param path the tree path
- * @param rect the rectangle, specifying the area where the path should be
- * displayed.
+ * @param rect the rectangle that will be reused to return the result.
* @return Rectangle the bounds of the last line, defined by the given path.
*/
public Rectangle getBounds(TreePath path, Rectangle rect)
{
+ if (path == null)
+ return null;
if (dirty)
update();
Object last = path.getLastPathComponent();
NodeRecord r = (NodeRecord) nodes.get(last);
if (r == null)
- // This node is not visible.
- return new Rectangle();
+ // This node is not visible.
+ {
+ rect.x = rect.y = rect.width = rect.height = 0;
+ }
else
{
if (r.bounds == null)
{
- Rectangle dim = getNodeDimensions(last, r.row, r.depth, r.isExpanded,
- rect);
+ Rectangle dim = getNodeDimensions(last, r.row, r.depth,
+ r.isExpanded, rect);
r.bounds = dim;
}
- return r.bounds;
+
+ rect.setRect(r.bounds);
}
+ return rect;
}
/**
@@ -330,6 +386,9 @@ public class FixedHeightLayoutCache
*/
public int getRowForPath(TreePath path)
{
+ if (path == null)
+ return -1;
+
if (dirty) update();
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
@@ -351,28 +410,59 @@ public class FixedHeightLayoutCache
if (dirty)
update();
- // We do not need to iterate because all rows have the same height.
- int row = y / rowHeight;
- if (row < 0)
- row = 0;
- if (row > getRowCount())
- row = getRowCount() - 1;
+ // As the rows have arbitrary height, we need to iterate.
+ NodeRecord best = null;
+ NodeRecord r;
+ Enumeration en = nodes.elements();
- if (row < 0)
- return null; // Empty tree - nothing to return.
-
- Object node = row2node.get(new Integer(row));
- NodeRecord nr = (NodeRecord) nodes.get(node);
- return nr.getPath();
+ int dist = Integer.MAX_VALUE;
+
+ while (en.hasMoreElements() && dist > 0)
+ {
+ r = (NodeRecord) en.nextElement();
+ if (best == null)
+ {
+ best = r;
+ dist = distance(r.getBounds(), x, y);
+ }
+ else
+ {
+ int rr = distance(r.getBounds(), x, y);
+ if (rr < dist)
+ {
+ best = r;
+ dist = rr;
+ }
+ }
+ }
+
+ if (best == null)
+ return null;
+ else
+ return best.getPath();
}
+
+ /**
+ * Get the closest distance from this point till the given rectangle. Only
+ * vertical distance is taken into consideration.
+ */
+ int distance(Rectangle r, int x, int y)
+ {
+ if (y < r.y)
+ return r.y - y;
+ else if (y > r.y + r.height)
+ return y - (r.y + r.height);
+ else
+ return 0;
+ }
/**
- * Get the number of the visible childs for the given tree path. If the
- * node is not expanded, 0 is returned. Otherwise, the number of children
- * is obtained from the model as the number of children for the last path
+ * Get the number of the visible childs for the given tree path. If the node
+ * is not expanded, 0 is returned. Otherwise, the number of children is
+ * obtained from the model as the number of children for the last path
* component.
*
- * @param path the tree path
+ * @param path the tree path
* @return int the number of the visible childs (for row).
*/
public int getVisibleChildCount(TreePath path)
@@ -466,7 +556,9 @@ public class FixedHeightLayoutCache
*/
public void setModel(TreeModel newModel)
{
- super.setModel(newModel);
+ treeModel = newModel;
+ // The root node is expanded by default.
+ expanded.add(treeModel.getRoot());
dirty = true;
}
@@ -484,32 +576,53 @@ public class FixedHeightLayoutCache
}
/**
- * Get the node dimensions. If the NodeDimensions are not set, this method
- * calculates dimensions assuming the fixed row height.
- *
- * @param value the last node in the path
- * @param row the node row
- * @param depth the indentation depth
- * @param expanded true if this node is expanded, false otherwise
- * @param bounds the area where the tree is displayed
- */
- protected Rectangle getNodeDimensions(Object value, int row, int depth,
- boolean expanded, Rectangle bounds)
+ * Get the sum of heights for all rows.
+ */
+ public int getPreferredHeight()
{
- if (nodeDimensions != null)
- return nodeDimensions.getNodeDimensions(value, row, depth, expanded,
- bounds);
- else
+ if (dirty)
+ update();
+ totalHeight = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
{
- Rectangle r = new Rectangle(bounds);
-
- int indent = depth * UIManager.getInt("Tree.rightChildIndent");
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ totalHeight += r.height;
+ }
+ return totalHeight;
+ }
- r.x = indent;
- r.y = row * getRowHeight();
- r.width = bounds.width = r.x;
- r.height = getRowHeight();
- return r;
+ /**
+ * Get the maximal width.
+ */
+ public int getPreferredWidth(Rectangle value)
+ {
+ if (dirty)
+ update();
+
+ maximalWidth = 0;
+ Enumeration en = nodes.elements();
+ while (en.hasMoreElements())
+ {
+ NodeRecord nr = (NodeRecord) en.nextElement();
+ Rectangle r = nr.getBounds();
+ if (r.x + r.width > maximalWidth)
+ maximalWidth = r.x + r.width;
}
+ return maximalWidth;
+ }
+
+ /**
+ * Returns true if this layout supposes that all rows have the fixed
+ * height.
+ *
+ * @return boolean true if all rows in the tree must have the fixed
+ * height (true by default).
+ */
+ protected boolean isFixedRowHeight()
+ {
+ return true;
}
+
}
diff --git a/javax/swing/tree/TreePath.java b/javax/swing/tree/TreePath.java
index 89f36f0ff..4671c4be5 100644
--- a/javax/swing/tree/TreePath.java
+++ b/javax/swing/tree/TreePath.java
@@ -57,6 +57,11 @@ public class TreePath implements Serializable
* assumes that the TreePath is immutable, so it is marked final here.
*/
private final Object[] path;
+
+ /**
+ * The parent path (to be reused).
+ */
+ private transient TreePath parentPath;
/**
@@ -294,7 +299,12 @@ public class TreePath implements Serializable
// is what the JDK does.
if (path.length <= 1)
return null;
-
- return new TreePath(this.getPath(), path.length - 1);
+
+ // Reuse the parent path, if possible. The parent path is requested
+ // during the tree repainting, so reusing generates a lot less garbage.
+ if (parentPath == null)
+ parentPath = new TreePath(this.getPath(), path.length - 1);
+
+ return parentPath;
}
}
diff --git a/javax/swing/tree/VariableHeightLayoutCache.java b/javax/swing/tree/VariableHeightLayoutCache.java
index 3758a4fc0..302fb0e45 100644
--- a/javax/swing/tree/VariableHeightLayoutCache.java
+++ b/javax/swing/tree/VariableHeightLayoutCache.java
@@ -115,31 +115,38 @@ public class VariableHeightLayoutCache
private TreePath path;
/**
- * Get the path for this node. The derived class is returned,
- * making check for the last child of some parent easier.
+ * Get the path for this node. The derived class is returned, making check
+ * for the last child of some parent easier.
*/
TreePath getPath()
{
- boolean lastChild = false;
- if (parent!=null)
+ if (path == null)
{
- int nc = treeModel.getChildCount(parent);
- if (nc > 0)
+ boolean lastChild = false;
+ if (parent != null)
{
- int n = treeModel.getIndexOfChild(parent, node);
- if (n == nc-1)
- lastChild = true;
+ int nc = treeModel.getChildCount(parent);
+ if (nc > 0)
+ {
+ int n = treeModel.getIndexOfChild(parent, node);
+ if (n == nc - 1)
+ lastChild = true;
+ }
}
- }
- if (path == null)
- {
+
LinkedList lpath = new LinkedList();
NodeRecord rp = this;
while (rp != null)
{
lpath.addFirst(rp.node);
if (rp.parent != null)
- rp = (NodeRecord) nodes.get(rp.parent);
+ {
+ Object parent = rp.parent;
+ rp = (NodeRecord) nodes.get(parent);
+ // Add the root node, even if it is not visible.
+ if (rp == null)
+ lpath.addFirst(parent);
+ }
else
rp = null;
}
@@ -157,8 +164,7 @@ public class VariableHeightLayoutCache
// not known. To work around this, it is assumed near infinitely large.
if (bounds==null)
bounds = getNodeDimensions(node, row, depth, isExpanded,
- new Rectangle(Integer.MAX_VALUE/2,
- Integer.MAX_VALUE/2));
+ new Rectangle());
return bounds;
}
}
@@ -238,7 +244,7 @@ public class VariableHeightLayoutCache
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(root, i);
- countRows(child, root, 1);
+ countRows(child, root, 0);
}
}
dirty = false;
@@ -255,8 +261,8 @@ public class VariableHeightLayoutCache
NodeRecord nr = new NodeRecord(n.intValue(), depth, node, parent);
nodes.put(node, nr);
- // For expanded nodes and for the root node.
- if (expanded.contains(node) || parent == null)
+ // For expanded nodes
+ if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
int deeper = depth+1;
@@ -326,6 +332,8 @@ public class VariableHeightLayoutCache
*/
public Rectangle getBounds(TreePath path, Rectangle rect)
{
+ if (path == null)
+ return null;
if (dirty)
update();
Object last = path.getLastPathComponent();
@@ -377,6 +385,8 @@ public class VariableHeightLayoutCache
*/
public int getRowForPath(TreePath path)
{
+ if (path == null)
+ return -1;
if (dirty) update();
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
@@ -545,6 +555,8 @@ public class VariableHeightLayoutCache
public void setModel(TreeModel newModel)
{
treeModel = newModel;
+ // The root node is expanded by default.
+ expanded.add(treeModel.getRoot());
dirty = true;
}
diff --git a/javax/xml/datatype/DatatypeFactory.java b/javax/xml/datatype/DatatypeFactory.java
index c5bc96ed2..14f507416 100644
--- a/javax/xml/datatype/DatatypeFactory.java
+++ b/javax/xml/datatype/DatatypeFactory.java
@@ -37,15 +37,23 @@ exception statement from your version. */
package javax.xml.datatype;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.Properties;
+import gnu.classpath.ServiceFactory;
/**
* Factory class to create new datatype objects mapping XML to and from Java
* objects.
*
- * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
+ * @author Chris Burdess
* @since 1.5
*/
public abstract class DatatypeFactory
@@ -59,7 +67,7 @@ public abstract class DatatypeFactory
/**
* JAXP 1.3 default implementation class name.
*/
- public static final java.lang.String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
+ public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
protected DatatypeFactory()
{
@@ -73,12 +81,35 @@ public abstract class DatatypeFactory
{
try
{
+ // 1. system property
+ String className = System.getProperty(DATATYPEFACTORY_PROPERTY);
+ if (className != null)
+ return (DatatypeFactory) Class.forName(className).newInstance();
+ // 2. jaxp.properties property
+ File javaHome = new File(System.getProperty("java.home"));
+ File javaHomeLib = new File(javaHome, "lib");
+ File jaxpProperties = new File(javaHomeLib, "jaxp.properties");
+ if (jaxpProperties.exists())
+ {
+ FileInputStream in = new FileInputStream(jaxpProperties);
+ Properties p = new Properties();
+ p.load(in);
+ in.close();
+ className = p.getProperty(DATATYPEFACTORY_PROPERTY);
+ if (className != null)
+ return (DatatypeFactory) Class.forName(className).newInstance();
+ }
+ // 3. services
+ Iterator i = ServiceFactory.lookupProviders(DatatypeFactory.class);
+ if (i.hasNext())
+ return (DatatypeFactory) i.next();
+ // 4. fallback
Class t = Class.forName(DATATYPEFACTORY_IMPLEMENTATION_CLASS);
return (DatatypeFactory) t.newInstance();
}
catch (Exception e)
{
- throw new DatatypeConfigurationException (e);
+ throw new DatatypeConfigurationException(e);
}
}
diff --git a/lib/.cvsignore b/lib/.cvsignore
index beb0f009b..fb82f0fd0 100644
--- a/lib/.cvsignore
+++ b/lib/.cvsignore
@@ -33,3 +33,4 @@ META-INF
Makefile.deps
lists
copy-vmresources.sh
+classes.2
diff --git a/native/fdlibm/Makefile.am b/native/fdlibm/Makefile.am
index 64b3b3936..09d868106 100644
--- a/native/fdlibm/Makefile.am
+++ b/native/fdlibm/Makefile.am
@@ -58,7 +58,7 @@ libfdlibm_la_SOURCES = \
w_sqrt.c \
namespace.h
-AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_LDFLAGS = @CLASSPATH_CONVENIENCE@
# We just want the standard flags for fdlibm since it is an upstream lib
# and our normal -pedantic -Wall -Werror breaks this lib. So no AM_CFLAGS.
diff --git a/native/fdlibm/ieeefp.h b/native/fdlibm/ieeefp.h
index 1dda99b32..1a9740f66 100644
--- a/native/fdlibm/ieeefp.h
+++ b/native/fdlibm/ieeefp.h
@@ -123,7 +123,7 @@
#define __IEEE_LITTLE_ENDIAN
#endif
-#if defined (__PPC__) || defined (__ppc__) || defined (__powerpc__) || defined (__ppc64__)
+#if defined (__PPC__) || defined (__ppc__) || defined (__powerpc__) || defined (__ppc64__) || defined (_POWER) || defined (_IBMR2)
#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) || defined (__BIG_ENDIAN__)|| defined (__APPLE__)
#define __IEEE_BIG_ENDIAN
#else
diff --git a/native/jni/classpath/Makefile.am b/native/jni/classpath/Makefile.am
index a26ab832b..d996df636 100644
--- a/native/jni/classpath/Makefile.am
+++ b/native/jni/classpath/Makefile.am
@@ -7,6 +7,6 @@ libclasspath_la_SOURCES = jcl.c jcl.h \
jnilink.c jnilink.h \
native_state.c native_state.h
-AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_LDFLAGS = @CLASSPATH_CONVENIENCE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/native/jni/java-lang/java_lang_VMProcess.c b/native/jni/java-lang/java_lang_VMProcess.c
index af14edaa8..f13a94f18 100644
--- a/native/jni/java-lang/java_lang_VMProcess.c
+++ b/native/jni/java-lang/java_lang_VMProcess.c
@@ -263,7 +263,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this,
}
close (fds[1][1]);
}
- if (pipe_count == 3)
+ if (pipe_count == 2)
{
/* Duplicate stdout to stderr. */
if (dup2 (1, 2) == -1)
@@ -315,6 +315,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this,
goto done;
for (i = 0; i < pipe_count; i++)
{
+ /* Mode is WRITE (2) for in and READ (1) for out and err. */
const int fd = fds[i][i == 0];
const int mode = ((i == 0)
? gnu_java_nio_channels_FileChannelImpl_WRITE
diff --git a/native/jni/java-net/Makefile.am b/native/jni/java-net/Makefile.am
index 5ad257f5a..e48173a16 100644
--- a/native/jni/java-net/Makefile.am
+++ b/native/jni/java-net/Makefile.am
@@ -1,11 +1,20 @@
nativeexeclib_LTLIBRARIES = libjavanet.la
+if ENABLE_LOCAL_SOCKETS
+local_sources = gnu_java_net_local_LocalSocketImpl.c \
+ local.c \
+ local.h
+else
+local_sources = gnu_java_net_local_LocalSocketImpl.c
+endif
+
libjavanet_la_SOURCES = javanet.c \
javanet.h \
java_net_VMInetAddress.c \
java_net_VMNetworkInterface.c \
gnu_java_net_VMPlainDatagramSocketImpl.c \
- gnu_java_net_VMPlainSocketImpl.c
+ gnu_java_net_VMPlainSocketImpl.c \
+ $(local_sources)
libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo
diff --git a/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c b/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c
new file mode 100644
index 000000000..3b29001a7
--- /dev/null
+++ b/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c
@@ -0,0 +1,538 @@
+/* gnu_java_net_local_LocalSocketImpl.c -- native local socket implementation.
+ 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. */
+
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <gnu_java_net_local_LocalSocketImpl.h>
+
+#include <stddef.h>
+#include "local.h"
+
+#ifdef DEBUG
+#define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg)
+#else
+#define TRACE(msg)
+#endif
+
+static void
+_throw (JNIEnv *env, const char *exception, const char *msg)
+{
+ jclass _theclass = (*env)->FindClass (env, exception);
+ TRACE("begin");
+ if (!_theclass)
+ {
+ (*env)->FatalError (env, "exception class not found");
+ }
+ (*env)->ThrowNew (env, _theclass, msg);
+ TRACE("end");
+}
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject this, jboolean stream)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd, created;
+ jclass clazz;
+ jint fd = (jint) local_create ((int) stream);
+
+ TRACE("begin");
+
+ if (fd < 0)
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ return;
+ }
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ created = (*env)->GetFieldID (env, clazz, "created", "Z");
+ if (!created)
+ {
+ return;
+ }
+ (*env)->SetIntField (env, this, socket_fd, fd);
+ (*env)->SetBooleanField (env, this, created, JNI_TRUE);
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) stream;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject this, jint backlog)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ int fd;
+
+ TRACE("begin");
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ if (local_listen (fd, (int) backlog))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ return;
+ }
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) backlog;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject this, jobject socket)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jmethodID addr_init;
+ jfieldID socket_fd, remote_addr, local_addr;
+ jclass clazz1, clazz2;
+ jobject remote, local;
+ jint fd;
+ char path[108];
+
+ TRACE("begin");
+
+ clazz1 = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (*env)->GetIntField (env, this, socket_fd);
+ fd = (jint) local_accept ((int) fd, path);
+ if (fd < 0)
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ return;
+ }
+
+ clazz2 = (*env)->FindClass (env, "gnu/java/net/local/LocalSocketAddress");
+ if (!clazz2)
+ {
+ return;
+ }
+ addr_init = (*env)->GetMethodID (env, clazz2, "<init>", "(Ljava/lang/String;)V");
+ if (!addr_init)
+ {
+ return;
+ }
+ remote = (*env)->NewObject (env, clazz2, addr_init, (*env)->NewStringUTF (env, path));
+
+ remote_addr = (*env)->GetFieldID (env, clazz1, "remote", "Lgnu/java/net/local/LocalSocketAddress;");
+ if (!remote_addr)
+ {
+ return;
+ }
+ local_addr = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;");
+ if (!local_addr)
+ {
+ return;
+ }
+ local = (*env)->GetObjectField (env, this, local_addr);
+ (*env)->SetIntField (env, socket, socket_fd, fd);
+ (*env)->SetObjectField (env, socket, remote_addr, remote);
+ (*env)->SetObjectField (env, socket, local_addr, local);
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) socket;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+jint
+Java_gnu_java_net_local_LocalSocketImpl_available (JNIEnv *env, jobject this)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ jint avail;
+
+ TRACE("begin");
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return 0;
+ }
+ avail = (jint) local_available ((int) (*env)->GetIntField (env, this, socket_fd));
+ if (avail < 0)
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ return 0;
+ }
+
+ TRACE("end");
+
+ return avail;
+#else
+ (void) this;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+ return -1;
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject this)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ int fd;
+
+ TRACE("begin");
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ if (local_close (fd))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+
+ TRACE("end");
+#else
+ (void) this;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject this)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID local;
+ jmethodID get_path;
+ jclass clazz1, clazz2;
+ jobject local_ref, path;
+ char *addr_path;
+
+ TRACE("begin");
+
+ clazz1 = (*env)->GetObjectClass (env, this);
+ local = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;");
+ if (!local)
+ {
+ return;
+ }
+ local_ref = (*env)->GetObjectField (env, this, local);
+ clazz2 = (*env)->GetObjectClass (env, local_ref);
+ get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
+ if (!get_path)
+ {
+ return;
+ }
+ path = (*env)->CallObjectMethod (env, local_ref, get_path);
+ addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL);
+ if (local_unlink (addr_path))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+ (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
+
+ TRACE("end");
+#else
+ (void) this;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject this __attribute__((unused)), jint data __attribute__((unused)))
+{
+ /* XXX I don't remember why I have this. Probably should just
+ remove. */
+ (*env)->FatalError (env, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented");
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject this)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ int fd;
+
+ TRACE("begin");
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (*env)->GetIntField (env, this, socket_fd);
+ if (local_shutdown_input (fd))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+
+ TRACE("end");
+#else
+ (void) this;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject this)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ int fd;
+
+ TRACE("begin");
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (*env)->GetIntField (env, this, socket_fd);
+ if (local_shutdown_output (fd))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+
+ TRACE("end");
+#else
+ (void) this;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject this, jobject address)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jmethodID get_path;
+ jobject path;
+ jclass clazz1, clazz2;
+ const char *addr_path;
+ int fd;
+
+ TRACE("begin");
+
+ clazz1 = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ clazz2 = (*env)->GetObjectClass (env, address);
+ get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
+ path = (*env)->CallObjectMethod (env, address, get_path);
+ addr_path = (*env)->GetStringUTFChars (env, (jstring) path, NULL);
+ if (local_bind (fd, addr_path))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+ (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) address;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject this, jobject address)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jmethodID get_path;
+ jobject path;
+ jclass clazz1, clazz2;
+ char *addr_path;
+ int fd;
+
+ TRACE("begin");
+
+ clazz1 = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ clazz2 = (*env)->GetObjectClass (env, address);
+ get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;");
+ path = (*env)->CallObjectMethod (env, address, get_path);
+ addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL);
+ if (local_connect (fd, addr_path))
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+ (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path);
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) address;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+jint
+Java_gnu_java_net_local_LocalSocketImpl_read (JNIEnv *env, jobject this, jbyteArray buf, jint off, jint len)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ jbyte *buffer;
+ jint count;
+ int fd;
+
+ TRACE("begin");
+
+ if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf))
+ {
+ _throw (env, "java/lang/ArrayIndexOutOfBoundsException", "");
+ }
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return 0;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ buffer = (*env)->GetByteArrayElements (env, buf, NULL);
+ count = (jint) local_read (fd, (void *) (buffer + off), (int) len);
+ if (count < 0)
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+ (*env)->ReleaseByteArrayElements (env, buf, buffer, 0);
+
+ TRACE("end");
+
+ return count;
+#else
+ (void) this;
+ (void) buf;
+ (void) off;
+ (void) len;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+ return -1;
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
+
+
+void
+Java_gnu_java_net_local_LocalSocketImpl_write (JNIEnv *env, jobject this, jbyteArray buf, jint off, jint len)
+{
+#ifdef ENABLE_LOCAL_SOCKETS
+ jfieldID socket_fd;
+ jclass clazz;
+ jbyte *buffer;
+ int fd;
+
+ TRACE("begin");
+
+ if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf))
+ {
+ _throw (env, "java/lang/ArrayIndexOutOfBoundsException", "");
+ }
+
+ clazz = (*env)->GetObjectClass (env, this);
+ socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I");
+ if (!socket_fd)
+ {
+ return;
+ }
+ fd = (int) (*env)->GetIntField (env, this, socket_fd);
+ buffer = (*env)->GetByteArrayElements (env, buf, NULL);
+ if (local_write (fd, (void *) (buffer + off), (int) len) < 0)
+ {
+ _throw (env, "java/io/IOException", local_error ());
+ }
+ (*env)->ReleaseByteArrayElements (env, buf, buffer, JNI_ABORT);
+
+ TRACE("end");
+#else
+ (void) this;
+ (void) buf;
+ (void) off;
+ (void) len;
+ _throw (env, "java/lang/Error", "support for local sockets not available");
+#endif /* ENABLE_LOCAL_SOCKETS */
+}
diff --git a/native/jni/java-net/local.c b/native/jni/java-net/local.c
new file mode 100644
index 000000000..cdddd89ef
--- /dev/null
+++ b/native/jni/java-net/local.c
@@ -0,0 +1,193 @@
+/* local.c -- implementation of unix-domain sockets.
+ 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. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef ENABLE_LOCAL_SOCKETS
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <stdio.h>
+
+#include "local.h"
+
+const char *
+local_error (void)
+{
+ return strerror (errno);
+}
+
+int
+local_create (int stream)
+{
+ return socket (PF_UNIX, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+}
+
+static int gcc_sucks = 0;
+
+int
+local_bind (int fd, const char *addr)
+{
+ struct sockaddr_un saddr;
+
+ /* For some reason, GCC 4.0.1 on Darwin/x86 MODIFIES the `addr'
+ pointer in the CALLER's STACK FRAME after calling this function,
+ but if we add this statement below, it doesn't! */
+ if (gcc_sucks)
+ fprintf (stderr, "bind %p\n", addr);
+
+ if (strlen (addr) > sizeof (saddr.sun_path))
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ strncpy (saddr.sun_path, addr, sizeof (saddr.sun_path));
+ saddr.sun_path[sizeof (saddr.sun_path)] = '\0';
+ saddr.sun_family = AF_LOCAL;
+
+ return bind (fd, (struct sockaddr *) &saddr, SUN_LEN (&saddr));
+}
+
+int
+local_listen (int fd, int backlog)
+{
+ return listen (fd, backlog);
+}
+
+int
+local_accept (int fd, char *path)
+{
+ int newfd;
+ struct sockaddr_un addr;
+ socklen_t sz = SUN_LEN(&addr);
+
+ newfd = accept (fd, (struct sockaddr *) &addr, &sz);
+ if (newfd >= 0)
+ {
+ /** sun_path is some crazy statically-sized buffer, and it's
+ size is different on different OSes. */
+ int n = sizeof (addr.sun_path);
+ strncpy (path, addr.sun_path, n);
+ path[n] = '\0';
+ }
+ return newfd;
+}
+
+int
+local_available (int fd)
+{
+ int val;
+ if (ioctl (fd, FIONREAD, &val))
+ {
+ return -1;
+ }
+ return val;
+}
+
+int
+local_close (int fd)
+{
+ return close (fd);
+}
+
+int
+local_unlink (char *path)
+{
+ return unlink (path);
+}
+
+int
+local_shutdown_input (int fd)
+{
+ return shutdown (fd, 0);
+}
+
+int
+local_shutdown_output (int fd)
+{
+ return shutdown (fd, 1);
+}
+
+int
+local_connect (int fd, char *path)
+{
+ struct sockaddr_un saddr;
+
+ strncpy (saddr.sun_path, path, sizeof (saddr.sun_path));
+ saddr.sun_path[sizeof (saddr.sun_path) - 1] = '\0';
+ saddr.sun_family = AF_UNIX;
+
+ return connect (fd, (struct sockaddr *) &saddr, SUN_LEN(&saddr));
+}
+
+int
+local_read (int fd, void *buf, int len)
+{
+ int count = -1;
+ do
+ {
+ count = read (fd, buf, len);
+ }
+ while (count == -1 && errno == EINTR);
+ return count;
+}
+
+int
+local_write (int fd, void *buf, int len)
+{
+ int count = -1;
+ do
+ {
+ count = write (fd, buf, len);
+ }
+ while (count == -1 && errno == EINTR);
+ return count;
+}
+
+#endif /* ENABLE_LOCAL_SOCKETS */
diff --git a/native/jni/java-net/local.h b/native/jni/java-net/local.h
new file mode 100644
index 000000000..035996a80
--- /dev/null
+++ b/native/jni/java-net/local.h
@@ -0,0 +1,28 @@
+#ifndef __LOCAL_H__
+#define __LOCAL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#define __EMACSEN__ }
+
+extern const char *local_error (void);
+extern int local_create (int);
+extern int local_bind (int, const char *);
+extern int local_listen (int, int);
+extern int local_accept (int, char *);
+extern int local_available (int);
+extern int local_close (int);
+extern int local_shutdown_input (int);
+extern int local_shutdown_output (int);
+extern int local_connect (int, char *);
+extern int local_unlink (char *);
+extern int local_read (int, void *, int);
+extern int local_write (int, void *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LOCAL_H__ */
diff --git a/resource/java/security/classpath.security b/resource/java/security/classpath.security
index cc7d49378..13d691bfe 100644
--- a/resource/java/security/classpath.security
+++ b/resource/java/security/classpath.security
@@ -35,8 +35,9 @@
# obligated to do so. If you do not wish to do so, delete this
# exception statement from your version.
-
+# Note that the settings and ordering here are mirrored in Security.
security.provider.1=gnu.java.security.provider.Gnu
security.provider.2=gnu.javax.crypto.jce.GnuCrypto
security.provider.3=gnu.javax.crypto.jce.GnuSasl
security.provider.4=gnu.javax.net.ssl.provider.Jessie
+security.provider.5=gnu.javax.security.auth.callback.GnuCallbacks
diff --git a/tools/gnu/classpath/tools/HelpPrinter.java b/tools/gnu/classpath/tools/HelpPrinter.java
index 61a3e683b..89468918a 100644
--- a/tools/gnu/classpath/tools/HelpPrinter.java
+++ b/tools/gnu/classpath/tools/HelpPrinter.java
@@ -70,30 +70,47 @@ public class HelpPrinter
}
/**
- * Prints the help message and terminates.
+ * Prints the contents of the resource specified by the designated path.
*
- * @param helpResourcePath the path to the help resource, related to the
+ * @param helpResourcePath the path to a help resource, related to the
* HelpPrinter class.
*/
- public static void printHelpAndExit(String helpResourcePath)
+ public static void printHelp(String helpResourcePath)
{
InputStream in = HelpPrinter.class.getResourceAsStream(helpResourcePath);
- BufferedReader r = new BufferedReader(new InputStreamReader(in));
-
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
try
{
String s;
- while ((s = r.readLine()) != null)
- {
- System.out.println(s);
- }
- r.close();
+ while ((s = br.readLine()) != null)
+ System.out.println(s);
}
- catch (IOException e)
+ catch (IOException x)
{
System.err.print("Resource loading is broken:");
- e.printStackTrace();
+ x.printStackTrace(System.err);
+ }
+ finally
+ {
+ try
+ {
+ br.close();
+ }
+ catch (IOException ignored)
+ {
+ }
}
+ }
+
+ /**
+ * Prints the help message and terminates.
+ *
+ * @param helpResourcePath the path to the help resource, related to the
+ * HelpPrinter class.
+ */
+ public static void printHelpAndExit(String helpResourcePath)
+ {
+ printHelp(helpResourcePath);
System.exit(0);
}
}
diff --git a/tools/gnu/classpath/tools/jarsigner/HashUtils.java b/tools/gnu/classpath/tools/jarsigner/HashUtils.java
index a81a0d34d..2286063f1 100644
--- a/tools/gnu/classpath/tools/jarsigner/HashUtils.java
+++ b/tools/gnu/classpath/tools/jarsigner/HashUtils.java
@@ -16,7 +16,24 @@ 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. */
+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.tools.jarsigner;
diff --git a/tools/gnu/classpath/tools/jarsigner/JarSigner.java b/tools/gnu/classpath/tools/jarsigner/JarSigner.java
index 1b58c5072..e6106a600 100644
--- a/tools/gnu/classpath/tools/jarsigner/JarSigner.java
+++ b/tools/gnu/classpath/tools/jarsigner/JarSigner.java
@@ -16,7 +16,24 @@ 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. */
+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.tools.jarsigner;
diff --git a/tools/gnu/classpath/tools/jarsigner/JarVerifier.java b/tools/gnu/classpath/tools/jarsigner/JarVerifier.java
index 8bca89270..1d3a98dda 100644
--- a/tools/gnu/classpath/tools/jarsigner/JarVerifier.java
+++ b/tools/gnu/classpath/tools/jarsigner/JarVerifier.java
@@ -16,7 +16,24 @@ 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. */
+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.tools.jarsigner;
diff --git a/tools/gnu/classpath/tools/jarsigner/Main.java b/tools/gnu/classpath/tools/jarsigner/Main.java
index 794055f45..360a88e56 100644
--- a/tools/gnu/classpath/tools/jarsigner/Main.java
+++ b/tools/gnu/classpath/tools/jarsigner/Main.java
@@ -16,7 +16,24 @@ 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. */
+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.tools.jarsigner;
@@ -96,6 +113,8 @@ public class Main
private char[] passwordChars;
private PrivateKey signerPrivateKey;
private Certificate[] signerCertificateChain;
+ /** The callback handler to use when needing to interact with user. */
+ private CallbackHandler handler;
private Main()
{
@@ -423,10 +442,9 @@ public class Main
if (ksPassword == null)
{
// ask the user to provide one
- CallbackHandler handler = new ConsoleCallbackHandler();
PasswordCallback pcb = new PasswordCallback("Enter keystore password: ",
false);
- handler.handle(new Callback[] { pcb });
+ getCallbackHandler().handle(new Callback[] { pcb });
ksPasswordChars = pcb.getPassword();
}
else
@@ -456,10 +474,9 @@ public class Main
catch (UnrecoverableKeyException x)
{
// ask the user to provide one
- CallbackHandler handler = new ConsoleCallbackHandler();
PasswordCallback pcb = new PasswordCallback("Enter key password for "
+ alias + ": ", false);
- handler.handle(new Callback[] { pcb });
+ getCallbackHandler().handle(new Callback[] { pcb });
passwordChars = pcb.getPassword();
// take 2
key = store.getKey(alias, passwordChars);
@@ -548,4 +565,74 @@ public class Main
{
return this.signedJarFileName;
}
+
+ /**
+ * Return a CallbackHandler which uses the Console (System.in and System.out)
+ * for interacting with the user.
+ * <p>
+ * This method first finds all currently installed security providers capable
+ * of providing such service and then in turn attempts to instantiate the
+ * handler from those providers. As soon as one provider returns a non-null
+ * instance of the callback handler, the search stops and that instance is
+ * set to be used from now on.
+ * <p>
+ * If no installed providers were found, this method falls back on the GNU
+ * provider, by-passing the Security search mechanism. The default console
+ * callback handler implementation is {@link ConsoleCallbackHandler}.
+ *
+ * @return a console-based {@link CallbackHandler}.
+ */
+ protected CallbackHandler getCallbackHandler()
+ {
+ if (handler == null)
+ {
+ String service = "CallbackHandler.Console"; //$NON-NLS-1$
+ Provider[] providers = Security.getProviders(service);
+ if (providers != null)
+ for (int i = 0; i < providers.length; i++)
+ {
+ Provider p = providers[i];
+ String className = p.getProperty(service);
+ if (className != null)
+ try
+ {
+ handler = (CallbackHandler) Class.forName(className).newInstance();
+ }
+ catch (InstantiationException x)
+ {
+ log.fine("InstantiationException while creating [" //$NON-NLS-1$
+ + className + "] from provider [" + p.getName() //$NON-NLS-1$
+ + "]. Ignore"); //$NON-NLS-1$
+ }
+ catch (IllegalAccessException x)
+ {
+ log.fine("IllegalAccessException while creating [" //$NON-NLS-1$
+ + className + "] from provider [" + p.getName() //$NON-NLS-1$
+ + "]. Ignore"); //$NON-NLS-1$
+ }
+ catch (ClassNotFoundException x)
+ {
+ log.fine("ClassNotFoundException while creating [" //$NON-NLS-1$
+ + className + "] from provider [" + p.getName() //$NON-NLS-1$
+ + "]. Ignore"); //$NON-NLS-1$
+ }
+
+ if (handler != null)
+ {
+
+ log.fine("Will use [" + handler.getClass().getName() //$NON-NLS-1$
+ + "] from [" + p.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ }
+
+ if (handler == null)
+ {
+ log.fine("No console callback handler found. Will use ours"); //$NON-NLS-1$
+ handler = new ConsoleCallbackHandler();
+ }
+ }
+
+ return handler;
+ }
}
diff --git a/tools/gnu/classpath/tools/jarsigner/SFHelper.java b/tools/gnu/classpath/tools/jarsigner/SFHelper.java
index 38caa44aa..cf72cfc2a 100644
--- a/tools/gnu/classpath/tools/jarsigner/SFHelper.java
+++ b/tools/gnu/classpath/tools/jarsigner/SFHelper.java
@@ -16,7 +16,24 @@ 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. */
+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.tools.jarsigner;
diff --git a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt b/tools/gnu/classpath/tools/jarsigner/jarsigner.txt
index a4e4c02ef..499c81fc9 100644
--- a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt
+++ b/tools/gnu/classpath/tools/jarsigner/jarsigner.txt
@@ -1,6 +1,6 @@
Java ARchive (JAR) file signing and verification tool.
-Copyright 2006 Free Software Foundation, Inc.
+Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/tools/jarsigner.sh.in b/tools/jarsigner.sh.in
index ced5c8cd0..cea95a288 100644
--- a/tools/jarsigner.sh.in
+++ b/tools/jarsigner.sh.in
@@ -1,6 +1,6 @@
#!/bin/sh
-## Copyright 2006 Free Software Foundation, Inc.
+## Copyright (C) 2006 Free Software Foundation, Inc.
##
## This file is a part of GNU Classpath.
##
@@ -19,6 +19,23 @@
## 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.
+##
##
## A simple shell script to launch the GNU Classpath jarsigner tool.
##
@@ -43,4 +60,4 @@ if [ -z "${JAVA}" ] ; then
fi
fi
-exec "${JAVA}" -cp "${tools_cp}" gnu.classpath.tools.jarsigner.Main $@
+exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.jarsigner.Main $@
diff --git a/vm/reference/java/lang/VMClass.java b/vm/reference/java/lang/VMClass.java
index 47a91da8c..25965068d 100644
--- a/vm/reference/java/lang/VMClass.java
+++ b/vm/reference/java/lang/VMClass.java
@@ -157,7 +157,7 @@ final class VMClass
* @param klass the Class object that's calling us
* @return the direct superclass of this class
*/
- static native <T> Class<? super T> getSuperclass(Class<T> klass);
+ static native Class getSuperclass(Class klass);
/**
* Get the interfaces this class <EM>directly</EM> implements, in the
@@ -284,31 +284,6 @@ final class VMClass
static native void throwException(Throwable t);
/**
- * Returns true if this class is a synthetic class, generated by the
- * compiler.
- *
- * @param klass the Class object that's calling us
- * @return whether this class is synthetic or not
- */
- static native boolean isSynthetic(Class klass);
-
- /**
- * Returns true if this class represents an annotation.
- *
- * @param klass the Class object that's calling us
- * @return whether this class is an annotation or not
- */
- static native boolean isAnnotation(Class klass);
-
- /**
- * Returns true if this class was declared as an enum.
- *
- * @param klass the Class object that's calling us
- * @return whether this class is an enumeration or not
- */
- static native boolean isEnum(Class klass);
-
- /**
* Returns the simple name for the specified class, as used in the source
* code. For normal classes, this is the content returned by
* <code>getName()</code> which follows the last ".". Anonymous
diff --git a/vm/reference/java/lang/VMClassLoader.java b/vm/reference/java/lang/VMClassLoader.java
index 48652c879..4caa58c2a 100644
--- a/vm/reference/java/lang/VMClassLoader.java
+++ b/vm/reference/java/lang/VMClassLoader.java
@@ -1,6 +1,6 @@
/* VMClassLoader.java -- Reference implementation of native interface
required by ClassLoader
- Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation
+ Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -39,20 +39,23 @@ exception statement from your version. */
package java.lang;
-import gnu.classpath.SystemProperties;
import gnu.classpath.Configuration;
-
+import gnu.classpath.SystemProperties;
import gnu.java.lang.InstrumentationImpl;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.lang.instrument.Instrumentation;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.zip.ZipFile;
@@ -239,12 +242,46 @@ final class VMClassLoader
/**
* Returns a String[] of native package names. The default
- * implementation returns an empty array, or you may decide
- * this needs native help.
+ * implementation tries to load a list of package from
+ * the META-INF/INDEX.LIST file in the boot jar file.
+ * If not found or if any exception is raised, it returns
+ * an empty array. You may decide this needs native help.
*/
private static String[] getBootPackages()
{
- return new String[0];
+ URL indexList = getResource("META-INF/INDEX.LIST");
+ if (indexList != null)
+ {
+ try
+ {
+ Set packageSet = new HashSet();
+ String line;
+ int lineToSkip = 3;
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(
+ indexList.openStream()));
+ while ((line = reader.readLine()) != null)
+ {
+ if (lineToSkip == 0)
+ {
+ if (line.length() == 0)
+ lineToSkip = 1;
+ else
+ packageSet.add(line.replace('/', '.'));
+ }
+ else
+ lineToSkip--;
+ }
+ reader.close();
+ return (String[]) packageSet.toArray(new String[packageSet.size()]);
+ }
+ catch (IOException e)
+ {
+ return new String[0];
+ }
+ }
+ else
+ return new String[0];
}
diff --git a/vm/reference/java/lang/VMProcess.java b/vm/reference/java/lang/VMProcess.java
index 1538178a3..076e5999d 100644
--- a/vm/reference/java/lang/VMProcess.java
+++ b/vm/reference/java/lang/VMProcess.java
@@ -42,6 +42,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -306,15 +307,19 @@ final class VMProcess extends Process
return new VMProcess(cmd, env, dir, false);
}
- static Process exec(List<String> cmd, Map<String, String> env,
+ static Process exec(List cmd, Map env,
File dir, boolean redirect) throws IOException
{
- String[] acmd = cmd.toArray(new String[cmd.size()]);
+ String[] acmd = (String[]) cmd.toArray(new String[cmd.size()]);
String[] aenv = new String[env.size()];
int i = 0;
- for (Map.Entry<String, String> entry : env.entrySet())
- aenv[i++] = entry.getKey() + "=" + entry.getValue();
+ Iterator iter = env.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ aenv[i++] = entry.getKey() + "=" + entry.getValue();
+ }
return new VMProcess(acmd, aenv, dir, redirect);
}
diff --git a/vm/reference/java/lang/VMSystem.java b/vm/reference/java/lang/VMSystem.java
index 5ed2228c8..f96986df3 100644
--- a/vm/reference/java/lang/VMSystem.java
+++ b/vm/reference/java/lang/VMSystem.java
@@ -1,5 +1,5 @@
/* VMSystem.java -- helper for java.lang.system
- Copyright (C) 1998, 2002, 2004, 2005 Free Software Foundation
+ Copyright (C) 1998, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -137,6 +137,31 @@ final class VMSystem
*/
public static native long currentTimeMillis();
+ /**
+ * <p>
+ * Returns the current value of a nanosecond-precise system timer.
+ * The value of the timer is an offset relative to some arbitrary fixed
+ * time, which may be in the future (making the value negative). This
+ * method is useful for timing events where nanosecond precision is
+ * required. This is achieved by calling this method before and after the
+ * event, and taking the difference betweent the two times:
+ * </p>
+ * <p>
+ * <code>long startTime = System.nanoTime();</code><br />
+ * <code>... <emph>event code</emph> ...</code><br />
+ * <code>long endTime = System.nanoTime();</code><br />
+ * <code>long duration = endTime - startTime;</code><br />
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63.
+ * </p>
+ *
+ * @return the time of a system timer in nanoseconds.
+ * @since 1.5
+ */
public static long nanoTime()
{
return currentTimeMillis() * 1000;
@@ -151,17 +176,6 @@ final class VMSystem
static native List environ();
/**
- * Gets the value of an environment variable from the current
- * environment.
- * Always returning null is a valid (but not very useful) implementation.
- *
- * @param name The name of the environment variable (will not be null).
- * @return The string value of the variable or null when the
- * environment variable is not defined.
- */
- static native String getenv(String k);
-
- /**
* Helper method which creates the standard input stream.
* VM implementors may choose to construct these streams differently.
* This method can also return null if the stream is created somewhere
@@ -182,7 +196,7 @@ final class VMSystem
{
return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
}
-
+
/**
* Helper method which creates the standard error stream.
* VM implementors may choose to construct these streams differently.
@@ -193,5 +207,14 @@ final class VMSystem
{
return new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
}
-
+
+ /**
+ * Gets the value of an environment variable.
+ * Always returning null is a valid (but not very useful) implementation.
+ *
+ * @param name The name of the environment variable (will not be null).
+ * @return The string value of the variable or null when the
+ * environment variable is not defined.
+ */
+ static native String getenv(String name);
}
diff --git a/vm/reference/java/lang/VMThread.java b/vm/reference/java/lang/VMThread.java
index b864b7f81..302de6c35 100644
--- a/vm/reference/java/lang/VMThread.java
+++ b/vm/reference/java/lang/VMThread.java
@@ -1,5 +1,5 @@
/* VMThread -- VM interface for Thread of executable code
- Copyright (C) 2003, 2004, 2005 Free Software Foundation
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -123,9 +123,8 @@ final class VMThread
{
try
{
- Thread.UncaughtExceptionHandler handler = thread.getUncaughtExceptionHandler();
- if (handler == null)
- handler = thread.group;
+ Thread.UncaughtExceptionHandler handler;
+ handler = thread.getUncaughtExceptionHandler();
handler.uncaughtException(thread, t);
}
catch(Throwable ignore)
diff --git a/vm/reference/java/security/VMSecureRandom.java b/vm/reference/java/security/VMSecureRandom.java
new file mode 100644
index 000000000..dc67d8719
--- /dev/null
+++ b/vm/reference/java/security/VMSecureRandom.java
@@ -0,0 +1,134 @@
+/* VMSecureRandom.java -- random seed generator.
+ 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 java.security;
+
+import gnu.classpath.SystemProperties;
+import gnu.java.security.action.GetSecurityPropertyAction;
+
+import java.net.URL;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+ /**
+ * Generate a random seed. Implementations are free to generate
+ * fewer random bytes than are requested, and leave the remaining
+ * bytes of the destination buffer as zeros. Implementations SHOULD,
+ * however, make a best-effort attempt to satisfy the request.
+ *
+ * @param buffer The destination buffer.
+ * @param offset The offset in the buffer to start putting bytes.
+ * @param length The number of random bytes to generate.
+ */
+ static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("length must be nonnegative");
+ if (offset < 0 || offset + length > buffer.length)
+ throw new IndexOutOfBoundsException();
+
+ Spinner[] spinners = new Spinner[8];
+ int n = 0x1;
+ for (int i = 0; i < spinners.length; i++)
+ {
+ spinners[i] = new Spinner((byte) n);
+ Thread t = new Thread(spinners[i]);
+ t.start();
+ n <<= 1;
+ }
+
+ // Wait until at least one spinner has started.
+ while (!(spinners[0].running || spinners[1].running || spinners[2].running
+ || spinners[3].running || spinners[4].running || spinners[5].running
+ || spinners[6].running || spinners[7].running))
+ {
+ Thread.yield();
+ }
+
+ for (int i = offset; i < length; i++)
+ {
+ buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+ ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+ ^ spinners[6].value ^ spinners[7].value);
+ Thread.yield();
+ }
+
+ for (int i = 0; i < spinners.length; i++)
+ spinners[i].stop();
+
+ return length;
+ }
+
+ static class Spinner implements Runnable
+ {
+ volatile byte value;
+ volatile boolean running;
+
+ Spinner(final byte initial)
+ {
+ value = initial;
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ value++;
+ }
+
+ private void stop()
+ {
+ running = false;
+ }
+ }
+} \ No newline at end of file